UNPKG

@lucidcms/core

Version:

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

1 lines 12.4 kB
{"version":3,"file":"build.mjs","names":["cliLogger","constants"],"sources":["../../../../src/libs/cli/commands/build.ts"],"sourcesContent":["import { mkdir, readdir, rm, stat } from \"node:fs/promises\";\nimport path, { join } from \"node:path\";\nimport constants from \"../../../constants/constants.js\";\nimport loadBuildProject from \"../../compile/load-build-project.js\";\nimport prepareBuildArtifacts from \"../../compile/prepare-build-artifacts.js\";\nimport prepareEmailTemplates from \"../../email/templates/prepare-email-templates.js\";\nimport {\n\tcreateTranslator,\n\twriteTranslationArtifact,\n} from \"../../i18n/index.js\";\nimport {\n\tstartLoggerBuffering,\n\tstopLoggerBuffering,\n} from \"../../logger/index.js\";\nimport checkAllPluginsCompatibility from \"../../plugins/check-all-plugins-compatibility.js\";\nimport vite from \"../../vite/index.js\";\nimport cliLogger from \"../logger.js\";\nimport calculateOutDirSize from \"../services/calculate-outdir-size.js\";\nimport copyPublicAssets from \"../services/copy-public-assets.js\";\n\n/**\n * The CLI build command. Responsible for calling the adapters build handler.\n */\nconst buildCommand = async (options?: {\n\tcacheSpa?: boolean;\n\tsilent?: boolean;\n\tremote?: boolean;\n}) => {\n\tstartLoggerBuffering();\n\tconst startTime = cliLogger.startTimer();\n\tconst silent = options?.silent ?? false;\n\n\ttry {\n\t\tconst buildProject = await loadBuildProject({\n\t\t\tsilent,\n\t\t\tloadEmailTemplates: false,\n\t\t\tprepareRuntime: true,\n\t\t});\n\t\tconst { configPath, loaded: configRes } = buildProject;\n\t\tconst translate = createTranslator({\n\t\t\tstore: configRes.translationStore,\n\t\t\tlocale: \"en\",\n\t\t});\n\n\t\tconst adapterRuntime = configRes.adapter;\n\t\tconst adapterCLI = adapterRuntime.cli;\n\n\t\tif (!adapterCLI) {\n\t\t\tcliLogger.error(\n\t\t\t\t`Lucid could not load CLI handlers from the \"${configRes.adapter.key}\" runtime adapter.`,\n\t\t\t\t{\n\t\t\t\t\tsilent,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait stopLoggerBuffering();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait checkAllPluginsCompatibility({\n\t\t\truntimeContext: configRes.runtimeContext,\n\t\t\tconfig: configRes.config,\n\t\t});\n\n\t\tif (options?.cacheSpa) {\n\t\t\tawait partialBuildDirClear(configRes.config.build.paths.outDir);\n\t\t} else {\n\t\t\tawait rm(configRes.config.build.paths.outDir, {\n\t\t\t\trecursive: true,\n\t\t\t\tforce: true,\n\t\t\t});\n\t\t\tawait mkdir(configRes.config.build.paths.outDir);\n\t\t}\n\n\t\t//* the path to the config, relative from the CWD\n\t\tconst relativeConfigPath = path.relative(process.cwd(), configPath);\n\t\tcliLogger.info(\n\t\t\t\"Loaded config from:\",\n\t\t\tcliLogger.color.green(`./${relativeConfigPath}`),\n\t\t\t{\n\t\t\t\tsilent,\n\t\t\t},\n\t\t);\n\n\t\t//* the path to the config, relative from the output directory\n\t\tconst outputRelativeConfigPath = path.relative(\n\t\t\tconfigRes.config.build.paths.outDir,\n\t\t\tconfigPath,\n\t\t);\n\t\tconst normalisedOutputRelativePath = outputRelativeConfigPath.replace(\n\t\t\t/\\.ts$/,\n\t\t\t\".js\",\n\t\t);\n\n\t\tawait writeTranslationArtifact({\n\t\t\ttranslationStore: configRes.translationStore,\n\t\t\toutputPath: configRes.config.build.paths.outDir,\n\t\t});\n\n\t\tconst [emailTemplatesRes, publicAssetsRes] = await Promise.all([\n\t\t\tprepareEmailTemplates({\n\t\t\t\tconfig: configRes.config,\n\t\t\t\tsilent,\n\t\t\t\tverbose: true,\n\t\t\t}),\n\t\t\tcopyPublicAssets({\n\t\t\t\tconfig: configRes.config,\n\t\t\t\tsilent,\n\t\t\t\tverbose: true,\n\t\t\t}),\n\t\t]);\n\t\tif (emailTemplatesRes.error) {\n\t\t\tcliLogger.error(\n\t\t\t\ttranslate.english(emailTemplatesRes.error.message) ??\n\t\t\t\t\t\"Failed to prepare email templates\",\n\t\t\t\t{\n\t\t\t\t\tsilent,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait stopLoggerBuffering();\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (publicAssetsRes.error) {\n\t\t\tcliLogger.error(\n\t\t\t\ttranslate.english(publicAssetsRes.error.message) ??\n\t\t\t\t\t\"Failed to copy public assets\",\n\t\t\t\t{\n\t\t\t\t\tsilent,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait stopLoggerBuffering();\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst translationStore = configRes.translationStore;\n\t\tconst processedArtifacts = await prepareBuildArtifacts({\n\t\t\tconfig: configRes.config,\n\t\t\ttranslationStore,\n\t\t\tdefinition: configRes.definition,\n\t\t\tsilent,\n\t\t\tconfigPath,\n\t\t\toutputPath: configRes.config.build.paths.outDir,\n\t\t\toutputRelativeConfigPath: normalisedOutputRelativePath,\n\t\t\tcustomArtifactTypes: adapterRuntime.config?.customBuildArtifacts,\n\t\t});\n\t\tconst [viteBuildRes, runtimeBuildRes] = await Promise.all([\n\t\t\tvite.buildApp(configRes.config),\n\t\t\tadapterCLI.build({\n\t\t\t\tconfig: configRes.config,\n\t\t\t\ttranslationStore,\n\t\t\t\tdefinition: configRes.definition,\n\t\t\t\tconfigPath,\n\t\t\t\toutputPath: configRes.config.build.paths.outDir,\n\t\t\t\toutputRelativeConfigPath: normalisedOutputRelativePath,\n\t\t\t\tbuildArtifacts: processedArtifacts,\n\t\t\t\tlogger: {\n\t\t\t\t\tinstance: cliLogger,\n\t\t\t\t\tsilent,\n\t\t\t\t},\n\t\t\t}),\n\t\t]);\n\t\tif (viteBuildRes.error) {\n\t\t\tcliLogger.error(\n\t\t\t\ttranslate.english(viteBuildRes.error.message) ??\n\t\t\t\t\t\"There was an error while building the SPA or component plugins\",\n\t\t\t\t{\n\t\t\t\t\tsilent,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait stopLoggerBuffering();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait checkAllPluginsCompatibility({\n\t\t\truntimeContext: runtimeBuildRes.runtimeContext,\n\t\t\tconfig: configRes.config,\n\t\t});\n\n\t\tconst relativeBuildPath = path.relative(\n\t\t\tprocess.cwd(),\n\t\t\tconfigRes.config.build.paths.outDir,\n\t\t);\n\n\t\tcliLogger.info(\n\t\t\t\"SPA and component plugins built:\",\n\t\t\tcliLogger.color.green(\n\t\t\t\t`./${relativeBuildPath}/${constants.directories.public}/${constants.directories.base}`,\n\t\t\t),\n\t\t\t{\n\t\t\t\tsilent,\n\t\t\t},\n\t\t);\n\n\t\tlet fieldCount = 0;\n\t\tconst collectionKeys = new Set<string>();\n\t\tconst brickKeys = new Set<string>();\n\t\tfor (const collection of configRes.config.collections) {\n\t\t\tif (!collection.key) continue;\n\t\t\tcollectionKeys.add(collection.key);\n\t\t\tfor (const brick of collection.brickInstances) {\n\t\t\t\tif (brickKeys.has(brick.key)) continue;\n\t\t\t\tbrickKeys.add(brick.key);\n\t\t\t\tfieldCount += brick.flatFields.length;\n\t\t\t}\n\t\t\tfieldCount += collection.flatFields.length;\n\t\t}\n\t\tcliLogger.info(\n\t\t\tcliLogger.color.yellow(collectionKeys.size),\n\t\t\t`collection${collectionKeys.size === 1 ? \"\" : \"s\"} with`,\n\t\t\tcliLogger.color.yellow(brickKeys.size),\n\t\t\t`brick${brickKeys.size === 1 ? \"\" : \"s\"} and`,\n\t\t\tcliLogger.color.yellow(fieldCount),\n\t\t\t`field${fieldCount === 1 ? \"\" : \"s\"}`,\n\t\t\t{\n\t\t\t\tsilent,\n\t\t\t},\n\t\t);\n\t\tcliLogger.info(\n\t\t\tcliLogger.color.yellow(configRes.config.plugins.length),\n\t\t\t`plugin${configRes.config.plugins.length === 1 ? \"\" : \"s\"} loaded`,\n\t\t\t{\n\t\t\t\tsilent,\n\t\t\t},\n\t\t);\n\n\t\tawait runtimeBuildRes?.onComplete?.();\n\t\tconst endTime = startTime();\n\n\t\tconst distSize = await calculateOutDirSize(\n\t\t\tconfigRes.config.build.paths.outDir,\n\t\t);\n\n\t\tcliLogger.log(\n\t\t\tcliLogger.createBadge(\"LUCID CMS\"),\n\t\t\t\"Build completed\",\n\t\t\t\"successfully\",\n\t\t\t\"in\",\n\t\t\tcliLogger.color.green(cliLogger.formatMilliseconds(endTime)),\n\t\t\tcliLogger.color.green(`(${cliLogger.formatBytes(distSize)})`),\n\t\t\t{\n\t\t\t\tspaceAfter: true,\n\t\t\t\tspaceBefore: true,\n\t\t\t\tsilent,\n\t\t\t},\n\t\t);\n\n\t\tawait stopLoggerBuffering();\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tcliLogger.errorInstance(error, \"Failed to build the application\");\n\t\t} else {\n\t\t\tcliLogger.error(\"Failed to build the application\", \"Unknown error\");\n\t\t}\n\t\tawait stopLoggerBuffering();\n\t\tprocess.exit(1);\n\t}\n};\n\n/**\n * Partially clear the build directory while preserving the SPA build output\n */\nconst partialBuildDirClear = async (outDir: string | undefined) => {\n\tif (!outDir) return;\n\n\tconst items = await readdir(outDir, { recursive: true });\n\n\tconst preservePaths = [\n\t\tpath.join(constants.directories.public, constants.directories.base),\n\t];\n\n\tfor (const item of items) {\n\t\tconst itemPath = join(outDir, item);\n\n\t\ttry {\n\t\t\tconst stats = await stat(itemPath);\n\t\t\tif (!stats.isFile()) continue;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst shouldPreserve = preservePaths.some(\n\t\t\t(preservePath) =>\n\t\t\t\titem.includes(preservePath) ||\n\t\t\t\titem === preservePath ||\n\t\t\t\titemPath.includes(preservePath) ||\n\t\t\t\titemPath === join(outDir, preservePath),\n\t\t);\n\n\t\tif (!shouldPreserve) {\n\t\t\tawait rm(itemPath, { force: true });\n\t\t}\n\t}\n};\n\nexport default buildCommand;\n"],"mappings":"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"}