Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
feat(nuxt): interdependencies and sequencing of modules (#79)
Browse files Browse the repository at this point in the history
* feat: interdependencies and sequencing of modules

* fix: lint

* Refactor setupPergel function and update ResolvedPergelOptions interface

* Refactor definePergelModule function to use defu for options merging

* Add new seedPaths option to DrizzleConfig

* Refactor GraphQLYoga module configuration

* Update setupModules.ts to include additional parameters

* Update module configurations

* Refactor module options and setup in Nuxt runtime

* Enable drizzle in nuxt.config.ts and add drizzle-related scripts and configurations in README.yaml

* Add debug option to pergel configuration
productdevbook authored Dec 25, 2023
1 parent e9dc612 commit a0ae6e5
Showing 23 changed files with 561 additions and 372 deletions.
1 change: 1 addition & 0 deletions packages/nuxt/playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ export default defineNuxtConfig({
}),
],
pergel: {
debug: true,
projects: {
test: {
S3: true,
96 changes: 36 additions & 60 deletions packages/nuxt/src/runtime/core/definePergel.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,62 @@
import defu from 'defu'
import { useNuxt } from '@nuxt/kit'
import type {
ModuleDefinition,
ModuleOptions,
ModuleSetupReturn,
NuxtPergel,
PergelModule,
ResolvedModuleOptions,
} from './types'
import { generateProjectReadme } from './utils/generateYaml'

export function definePergelModule<OptionsT extends ModuleOptions>(
definition: ModuleDefinition<OptionsT> | PergelModule<OptionsT>,
): PergelModule<OptionsT> {
export function definePergelModule<RootOptions extends ModuleOptions = ModuleOptions, ResolvedOptions extends ModuleOptions = ModuleOptions>(
definition: ModuleDefinition<RootOptions, ResolvedOptions> | PergelModule<RootOptions, ResolvedOptions>,
): PergelModule<RootOptions, ResolvedOptions> {
if (typeof definition === 'function')
return definePergelModule({ setup: definition })

// Normalize definition and meta
const module: ModuleDefinition<OptionsT> & Required<Pick<ModuleDefinition<OptionsT>, 'meta'>> = defu(definition, { meta: {} })
const module: ModuleDefinition<RootOptions, ResolvedOptions> & Required<Pick<ModuleDefinition<RootOptions, ResolvedOptions>, 'meta'>> = defu(definition, { meta: {} })

if (module.meta.configKey === undefined)
module.meta.configKey = module.meta.name

async function preparationModule(data: { nuxt: NuxtPergel<OptionsT> }) {
const { nuxt } = data
const dependencies = module.meta.dependencies instanceof Function ? module.meta.dependencies(data.nuxt._pergel._module.options) : module.meta.dependencies ?? {}
const devDependencies = module.meta.devDependencies instanceof Function ? module.meta.devDependencies(data.nuxt._pergel._module.options) : module.meta.devDependencies ?? {}
async function getOptions(inlineOptions: RootOptions, moduleOptions: ResolvedModuleOptions, nuxt: NuxtPergel = useNuxt()) {
const defaultModule = module.defaults instanceof Function ? module.defaults({ nuxt, rootOptions: inlineOptions, moduleOptions }) : module.defaults

if (Object.keys(dependencies).length > 0 || Object.keys(devDependencies).length > 0) {
generateProjectReadme(nuxt, ({ addCommentBlock }) => ({
...addCommentBlock('If pergel cli is installed, you can run `pergel install` automatically to install'),
packageJson: {
dependencies: `"${Object.entries(dependencies).map(([name, version]) => `${name}@${version}`).join(', ')}"`,
devDependencies: `"${Object.entries(devDependencies).map(([name, version]) => `${name}@${version}`).join(', ')}"`,
},
}))
}

if (module.meta.name) {
nuxt._pergel.activeModules[nuxt._pergel._module.projectName] ??= {}
nuxt._pergel.activeModules[nuxt._pergel._module.projectName][module.meta.name] ??= {}
}

const defaultModule = module.defaults instanceof Function ? module.defaults({ nuxt }) : module.defaults
const rootOptions = (nuxt._pergel.rootOptions.projects[moduleOptions.projectName] as any)[moduleOptions.moduleName] ?? {}
const _options = defu(rootOptions, defaultModule)

const userModuleOptions = (nuxt._pergel.rootOptions.projects[nuxt._pergel._module.projectName] as any)[nuxt._pergel._module.moduleName] ?? {}
return Promise.resolve(_options)
}

const moduleOptions = defu({
...nuxt._pergel._module,
options: {
...userModuleOptions,
},
} satisfies NuxtPergel['_pergel']['_module'], {
// User send S3 module options
options: {
...defaultModule,
},
} as NuxtPergel['_pergel']['_module']) as NuxtPergel['_pergel']['_module']
async function normalizedModule(this: any, data: { nuxt: NuxtPergel, rootOptions: RootOptions, moduleOptions: ResolvedModuleOptions }) {
const options = await getOptions(data.rootOptions, data.moduleOptions, data.nuxt)

// TODO: Fix any type
// @ts-ignore
nuxt._pergel.projects[nuxt._pergel._module.projectName][nuxt._pergel._module.moduleName].options = moduleOptions.options as any
const key = `pergel:${module.meta.configKey}`
const mark = performance.mark(key)
if (!this.prepare) {
// Resolve module and options

// TODO: Fix any type
nuxt._pergel._module = moduleOptions as any
nuxt._pergel.activeModules[nuxt._pergel._module.projectName][nuxt._pergel._module.moduleName] = defu(
nuxt._pergel.activeModules[nuxt._pergel._module.projectName][nuxt._pergel._module.moduleName],
moduleOptions.options,
) as any
const res = await module.setup?.call(null as any, { nuxt: data.nuxt, options, rootOptions: data.rootOptions, moduleOptions: data.moduleOptions }) ?? {}
const perf = performance.measure(key, mark)
const setupTime = perf ? Math.round(perf.duration * 100) / 100 : 0

return Promise.resolve(moduleOptions)
}
// Check if module is ignored
if (res === false)
return false

async function normalizedModule(this: any, data: { nuxt: NuxtPergel<OptionsT> }) {
// Resolve module and options
await preparationModule({ nuxt: data.nuxt })
// Return module install result
return defu(res, <ModuleSetupReturn>{
timings: {
setup: setupTime,
},
})
}

const key = `pergel:${module.meta.configKey}`
const mark = performance.mark(key)
const res = await module.setup?.call(null as any, { nuxt: data.nuxt }) ?? {}
const res = {}
const perf = performance.measure(key, mark)
const setupTime = perf ? Math.round(perf.duration * 100) / 100 : 0

// Check if module is ignored
if (res === false)
return false

// Return module install result
return defu(res, <ModuleSetupReturn>{
timings: {
@@ -92,5 +65,8 @@ export function definePergelModule<OptionsT extends ModuleOptions>(
})
}

return normalizedModule as PergelModule<OptionsT>
normalizedModule.getMeta = () => Promise.resolve(module.meta) as any
normalizedModule.getOptions = getOptions as any

return normalizedModule
}
Loading

0 comments on commit a0ae6e5

Please sign in to comment.