UNPKG

@lucidcms/core

Version:

The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.

1 lines 9.3 kB
{"version":3,"file":"resolve-config-definition.mjs","names":[],"sources":["../../../src/libs/config/resolve-config-definition.ts"],"sourcesContent":["import type z from \"zod\";\nimport type { Config } from \"../../types/config.js\";\nimport { LucidError } from \"../../utils/errors/index.js\";\nimport {\n\tcollectRuntimePrepareArtifacts,\n\tcreateRuntimePrepareArtifacts,\n} from \"../runtime/prepare-artifacts.js\";\nimport { resolveDatabaseAdapter } from \"../runtime/resolve-database-adapter.js\";\nimport type {\n\tAdapterRuntimeContext,\n\tEnvironmentVariables,\n\tGetEnvVarsLogger,\n\tLucidConfigDefinition,\n\tLucidConfigDefinitionMeta,\n\tRuntimeAdapter,\n\tRuntimeConfigureLucid,\n\tWrappedLucidConfigDefinition,\n} from \"../runtime/types.js\";\nimport processConfig from \"./process-config.js\";\n\nconst defaultLoggerInstance = {\n\tinfo: () => {},\n\twarn: () => {},\n\terror: () => {},\n\tlog: () => {},\n\tsuccess: () => {},\n\tcolor: {\n\t\tblue: (value: unknown) => String(value),\n\t\tgreen: (value: unknown) => String(value),\n\t},\n} as unknown as GetEnvVarsLogger[\"instance\"];\n\nexport const invalidConfigDefinitionMessage =\n\t\"Lucid config must default export configureLucid({ runtime, db, config }).\";\n\nexport type ResolveConfigDefinitionResult = {\n\tconfig: Config;\n\tadapter: RuntimeAdapter;\n\truntimeContext: AdapterRuntimeContext;\n\tenvSchema?: z.ZodType;\n\tenv: EnvironmentVariables | undefined;\n\tdefinition: WrappedLucidConfigDefinition;\n};\n\nconst isConfigDefinition = (value: unknown): value is LucidConfigDefinition => {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst definition = value as {\n\t\truntime?: unknown;\n\t\tdb?: unknown;\n\t\tconfig?: unknown;\n\t};\n\n\treturn (\n\t\tdefinition.runtime !== undefined &&\n\t\tdefinition.db !== undefined &&\n\t\ttypeof definition.config === \"function\"\n\t);\n};\n\n/**\n * Config modules should stay declarative. This guard keeps the failure focused\n * on the public config shape before Lucid attempts any adapter resolution.\n */\nconst assertConfigDefinition = (value: unknown): LucidConfigDefinition => {\n\tif (!isConfigDefinition(value)) {\n\t\tthrow new LucidError({\n\t\t\tmessage: invalidConfigDefinitionMessage,\n\t\t});\n\t}\n\n\treturn value;\n};\n\nconst resolveRuntimeAdapter = async (\n\truntime: LucidConfigDefinition[\"runtime\"],\n): Promise<RuntimeAdapter> => {\n\tconst adapter = typeof runtime === \"function\" ? runtime() : runtime;\n\tconst resolved = await adapter;\n\n\tif (!resolved || typeof resolved !== \"object\") {\n\t\tthrow new LucidError({\n\t\t\tmessage:\n\t\t\t\t\"Lucid could not resolve the configured runtime adapter. Pass a runtime adapter instance to `configureLucid({ runtime })`.\",\n\t\t});\n\t}\n\n\treturn resolved;\n};\n\n/**\n * Config resolution is the one place where Lucid bridges direct adapter values,\n * env loading, wrapper semantics and final config processing.\n */\nexport const resolveConfigDefinition = async (props: {\n\tdefinition: unknown;\n\tenvSchema?: z.ZodType;\n\tmeta?: LucidConfigDefinitionMeta;\n\tenv?: EnvironmentVariables;\n\tconfigureLucid?: RuntimeConfigureLucid;\n\tconfigPath?: string;\n\tprojectRoot?: string;\n\tprepareRuntime?: boolean;\n\tvalidateEnvSchema?: boolean;\n\tlogger?: GetEnvVarsLogger;\n\tprocessConfigOptions?: Parameters<typeof processConfig>[1];\n}): Promise<ResolveConfigDefinitionResult> => {\n\tconst definition = assertConfigDefinition(props.definition);\n\tconst adapter = await resolveRuntimeAdapter(definition.runtime);\n\tconst logger = props.logger ?? {\n\t\tinstance: defaultLoggerInstance,\n\t\tsilent: true,\n\t};\n\tconst runtimeContext = {\n\t\truntime: adapter.key,\n\t\tcompiled: false,\n\t\tgetConnectionInfo: () => ({}),\n\t\tconfigEntryPoint: null,\n\t} satisfies AdapterRuntimeContext;\n\n\t// Hosted integrations can supply their own configureLucid wrapper so the\n\t// runtime adapter identity stays separate from host-specific config shaping.\n\tconst configureLucid =\n\t\tprops.configureLucid ?? adapter.configureLucid ?? ((value) => value);\n\n\tconst wrappedDefinition = configureLucid(\n\t\t{\n\t\t\t...definition,\n\t\t\truntime: adapter,\n\t\t},\n\t\tprops.meta,\n\t);\n\n\tconst prepareRuntimeContext =\n\t\tprops.prepareRuntime &&\n\t\tadapter.cli?.prepare &&\n\t\tprops.configPath &&\n\t\tprops.projectRoot\n\t\t\t? {\n\t\t\t\t\tprepare: adapter.cli.prepare,\n\t\t\t\t\tconfigPath: props.configPath,\n\t\t\t\t\tprojectRoot: props.projectRoot,\n\t\t\t\t}\n\t\t\t: undefined;\n\n\tif (prepareRuntimeContext) {\n\t\tawait prepareRuntimeContext.prepare({\n\t\t\tconfigPath: prepareRuntimeContext.configPath,\n\t\t\tprojectRoot: prepareRuntimeContext.projectRoot,\n\t\t\tprepareArtifacts: createRuntimePrepareArtifacts(),\n\t\t\tlogger,\n\t\t});\n\t}\n\t// Env loading is optional because some hosts, like Astro Cloudflare, already\n\t// own request-time env loading and can pass it in directly.\n\tlet env =\n\t\tprops.env ??\n\t\t(adapter.getEnvVars\n\t\t\t? await adapter.getEnvVars({\n\t\t\t\t\tlogger,\n\t\t\t\t})\n\t\t\t: undefined);\n\n\tconst envSchema = props.envSchema;\n\n\t// Builds do not need runtime env validation; runtime commands validate env\n\t// before using it.\n\tconst shouldValidateEnvSchema = props.validateEnvSchema ?? true;\n\tconst validateEnv = (envVars: EnvironmentVariables | undefined) => {\n\t\tif (!shouldValidateEnvSchema || !envSchema || !envVars) {\n\t\t\treturn;\n\t\t}\n\n\t\tenvSchema.parse(envVars);\n\t};\n\n\tvalidateEnv(env);\n\n\tawait adapter.resolveOptions?.(env ?? {});\n\n\tlet rawConfig = wrappedDefinition.config(env || {});\n\tconst prepareArtifacts = prepareRuntimeContext\n\t\t? await collectRuntimePrepareArtifacts({\n\t\t\t\tdb: wrappedDefinition.db,\n\t\t\t\tplugins: rawConfig.plugins ?? [],\n\t\t\t\tenv: env ?? {},\n\t\t\t\tdefinition: wrappedDefinition,\n\t\t\t\tpaths: {\n\t\t\t\t\tconfigPath: prepareRuntimeContext.configPath,\n\t\t\t\t\tprojectRoot: prepareRuntimeContext.projectRoot,\n\t\t\t\t},\n\t\t\t\tcustomArtifactTypes: adapter.config?.customPrepareArtifacts,\n\t\t\t})\n\t\t: createRuntimePrepareArtifacts();\n\n\tif (prepareRuntimeContext && prepareArtifacts.custom.length > 0) {\n\t\tawait prepareRuntimeContext.prepare({\n\t\t\tconfigPath: prepareRuntimeContext.configPath,\n\t\t\tprojectRoot: prepareRuntimeContext.projectRoot,\n\t\t\tprepareArtifacts,\n\t\t\tlogger,\n\t\t});\n\n\t\tif (!props.env && adapter.getEnvVars) {\n\t\t\tenv = await adapter.getEnvVars({\n\t\t\t\tlogger,\n\t\t\t});\n\n\t\t\tvalidateEnv(env);\n\n\t\t\tawait adapter.resolveOptions?.(env ?? {});\n\t\t\trawConfig = wrappedDefinition.config(env || {});\n\t\t}\n\t}\n\n\tconst db = await resolveDatabaseAdapter(wrappedDefinition.db, env);\n\n\t// processConfig remains the shared source of truth for plugin init, merging\n\t// and validation once the adapter/env/bootstrap layer has been resolved.\n\tconst config = await processConfig(rawConfig, {\n\t\t...(props.processConfigOptions ?? {}),\n\t\trecipe: wrappedDefinition.recipe,\n\t\tresolvedDb: db,\n\t});\n\n\treturn {\n\t\tconfig,\n\t\tadapter,\n\t\truntimeContext,\n\t\tenvSchema,\n\t\tenv,\n\t\tdefinition: wrappedDefinition,\n\t};\n};\n\nexport default resolveConfigDefinition;\n"],"mappings":"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"}