@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 13.2 kB
Source Map (JSON)
{"version":3,"file":"dev.mjs","names":["cliLogger","constants"],"sources":["../../../../src/libs/cli/commands/dev.ts"],"sourcesContent":["import path from \"node:path\";\nimport chokidar from \"chokidar\";\nimport constants from \"../../../constants/constants.js\";\nimport getConfigPath from \"../../config/get-config-path.js\";\nimport loadConfigFile from \"../../config/load-config-file.js\";\nimport prepareEmailTemplates from \"../../email/templates/prepare-email-templates.js\";\nimport { createTranslator } from \"../../i18n/index.js\";\nimport prepareTranslations from \"../../i18n/prepare-translations.js\";\nimport {\n\tstartLoggerBuffering,\n\tstopLoggerBuffering,\n} from \"../../logger/index.js\";\nimport checkAllPluginsCompatibility from \"../../plugins/check-all-plugins-compatibility.js\";\nimport generateTypes from \"../../type-generation/index.js\";\nimport vite from \"../../vite/index.js\";\nimport cliLogger from \"../logger.js\";\nimport copyPublicAssets from \"../services/copy-public-assets.js\";\nimport updateAvailable from \"../services/update-available.js\";\nimport validateEnvVars from \"../services/validate-env-vars.js\";\nimport migrateCommand from \"./migrate.js\";\n\nconst devCommand = async (options?: {\n\twatch?: string | boolean;\n\tremote?: boolean;\n}) => {\n\tconst configPath = getConfigPath(process.cwd());\n\n\tconst coreUpdateAvailable = updateAvailable();\n\n\tlet serverDestroy: (() => Promise<void>) | undefined;\n\tlet rebuilding = false;\n\tlet isInitialRun = true;\n\tlet buildOutDir = \"dist\";\n\tlet buildWatchIgnore: string[] = [];\n\n\tconst startServer = async () => {\n\t\tif (rebuilding) return;\n\t\trebuilding = true;\n\n\t\tstartLoggerBuffering();\n\n\t\ttry {\n\t\t\tawait serverDestroy?.();\n\n\t\t\tconst configResult = await loadConfigFile({\n\t\t\t\tpath: configPath,\n\t\t\t\tprepareRuntime: true,\n\t\t\t});\n\t\t\tbuildOutDir = configResult.config.build.paths.outDir;\n\t\t\tbuildWatchIgnore = configResult.config.build.watch?.ignore ?? [];\n\n\t\t\tconst translations = await prepareTranslations({\n\t\t\t\tconfig: configResult.config,\n\t\t\t\tprojectRoot: configResult.projectRoot,\n\t\t\t\toutputPath: configResult.config.build.paths.outDir,\n\t\t\t});\n\t\t\tconst translationStore = translations.translationStore;\n\t\t\tconst translate = createTranslator({\n\t\t\t\tstore: translationStore,\n\t\t\t\tlocale: \"en\",\n\t\t\t});\n\t\t\tconst adapterCLI = configResult.adapter.cli;\n\n\t\t\tif (!adapterCLI) {\n\t\t\t\tcliLogger.error(\n\t\t\t\t\t`Lucid could not load CLI handlers from the \"${configResult.adapter.key}\" runtime adapter.`,\n\t\t\t\t);\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst envValid = await validateEnvVars({\n\t\t\t\tenvSchema: configResult.envSchema,\n\t\t\t\tenv: configResult.env,\n\t\t\t});\n\n\t\t\tgenerateTypes({\n\t\t\t\tenvSchema: configResult.envSchema,\n\t\t\t\tconfigPath: configPath,\n\t\t\t\tprojectRoot: configResult.projectRoot,\n\t\t\t\tcollections: configResult.config.collections,\n\t\t\t\tlocalization: configResult.config.localization,\n\t\t\t});\n\n\t\t\tif (!envValid) {\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst migrateResult = await migrateCommand({\n\t\t\t\tconfig: configResult.config,\n\t\t\t\tenv: configResult.env,\n\t\t\t\truntimeContext: configResult.runtimeContext,\n\t\t\t\ttranslationStore,\n\t\t\t\tprojectRoot: configResult.projectRoot,\n\t\t\t\tmode: \"return\",\n\t\t\t})({\n\t\t\t\tskipSyncSteps: !isInitialRun,\n\t\t\t\tskipEnvValidation: true,\n\t\t\t});\n\n\t\t\tif (!migrateResult) {\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\tprocess.exit(2);\n\t\t\t}\n\n\t\t\tconst viteBuildRes = await vite.buildApp(configResult.config);\n\t\t\tif (viteBuildRes.error) {\n\t\t\t\tcliLogger.error(\n\t\t\t\t\ttranslate.english(viteBuildRes.error.message) ??\n\t\t\t\t\t\t\"Failed to build app\",\n\t\t\t\t);\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\trebuilding = false;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst [emailTemplatesRes, publicAssetsRes] = await Promise.all([\n\t\t\t\tprepareEmailTemplates({\n\t\t\t\t\tconfig: configResult.config,\n\t\t\t\t\tsilent: false,\n\t\t\t\t\tverbose: false,\n\t\t\t\t}),\n\t\t\t\tcopyPublicAssets({\n\t\t\t\t\tconfig: configResult.config,\n\t\t\t\t\tsilent: false,\n\t\t\t\t\tverbose: false,\n\t\t\t\t}),\n\t\t\t]);\n\t\t\tif (emailTemplatesRes.error) {\n\t\t\t\tcliLogger.error(\n\t\t\t\t\ttranslate.english(emailTemplatesRes.error.message) ??\n\t\t\t\t\t\t\"Failed to prepare email templates\",\n\t\t\t\t);\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\trebuilding = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (publicAssetsRes.error) {\n\t\t\t\tcliLogger.error(\n\t\t\t\t\ttranslate.english(publicAssetsRes.error.message) ??\n\t\t\t\t\t\t\"Failed to copy public assets\",\n\t\t\t\t);\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\trebuilding = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tprocess.stdout.write(\"\\x1B[2J\\x1B[3J\\x1B[H\");\n\t\t\tcliLogger.success(\n\t\t\t\t\"Email templates and public assets prepared\",\n\t\t\t\tcliLogger.color.green(\"successfully\"),\n\t\t\t);\n\n\t\t\tconst serverRes = await adapterCLI.serve({\n\t\t\t\tconfig: configResult.config,\n\t\t\t\ttranslationStore,\n\t\t\t\tlogger: {\n\t\t\t\t\tinstance: cliLogger,\n\t\t\t\t\tsilent: false,\n\t\t\t\t},\n\t\t\t\tonListening: async (props) => {\n\t\t\t\t\tconst serverUrl =\n\t\t\t\t\t\ttypeof props.address === \"string\"\n\t\t\t\t\t\t\t? props.address\n\t\t\t\t\t\t\t: props.address\n\t\t\t\t\t\t\t\t? `http://${props.address.address === \"::\" ? \"localhost\" : props.address.address}:${props.address.port}`\n\t\t\t\t\t\t\t\t: \"unknown\";\n\n\t\t\t\t\tconst coreUpdateAvailabeRes = await coreUpdateAvailable;\n\t\t\t\t\tcoreUpdateAvailabeRes.renderUpdateBox();\n\n\t\t\t\t\tcliLogger.log(\n\t\t\t\t\t\tcliLogger.createBadge(\"LUCID CMS\"),\n\t\t\t\t\t\t\"Development server ready\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tspaceBefore: !coreUpdateAvailabeRes.show,\n\t\t\t\t\t\t\tspaceAfter: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tcliLogger.log(\n\t\t\t\t\t\t\"🔐 Admin panel \",\n\t\t\t\t\t\tcliLogger.color.blue(`${serverUrl}/lucid`),\n\t\t\t\t\t\t{ symbol: \"line\" },\n\t\t\t\t\t);\n\n\t\t\t\t\tcliLogger.log(\n\t\t\t\t\t\t\"📖 Documentation \",\n\t\t\t\t\t\tcliLogger.color.blue(constants.documentation),\n\t\t\t\t\t\t{ symbol: \"line\" },\n\t\t\t\t\t);\n\n\t\t\t\t\tcliLogger.log(\n\t\t\t\t\t\tcliLogger.color.gray(\"Press CTRL-C to stop the server\"),\n\t\t\t\t\t\t{ spaceBefore: true, spaceAfter: true },\n\t\t\t\t\t);\n\n\t\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\t},\n\t\t\t});\n\t\t\tserverDestroy = serverRes?.destroy;\n\n\t\t\tif (isInitialRun) {\n\t\t\t\tawait checkAllPluginsCompatibility({\n\t\t\t\t\truntimeContext: serverRes.runtimeContext,\n\t\t\t\t\tconfig: configResult.config,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait serverRes?.onComplete?.();\n\t\t\tisInitialRun = false;\n\t\t} catch (error) {\n\t\t\tawait serverDestroy?.();\n\t\t\tif (error instanceof Error) {\n\t\t\t\tcliLogger.errorInstance(error, \"Failed to start the server\");\n\t\t\t} else {\n\t\t\t\tcliLogger.error(\"Failed to start the server\", \"Unknown error\");\n\t\t\t}\n\t\t\tawait stopLoggerBuffering();\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\trebuilding = false;\n\t\t}\n\t};\n\n\tawait startServer();\n\n\tlet restartTimer: NodeJS.Timeout | undefined;\n\n\tconst watchPath =\n\t\ttypeof options?.watch === \"string\" ? options?.watch : process.cwd();\n\n\tconst distPath = path.join(process.cwd(), buildOutDir);\n\n\tconst ignorePatterns = [\n\t\t\"**/node_modules/**\",\n\t\t\"**/.git/**\",\n\t\t\"**/.lucid/**\",\n\t\t\"**/.wrangler/**\",\n\t\t\"**/.mf/**\",\n\t\tdistPath,\n\t\t\"**/*.log\",\n\t\t\"**/.DS_Store\",\n\t\t\"**/Thumbs.db\",\n\t\t\"*.sqlite\",\n\t\t\"*.sqlite-shm\",\n\t\t\"*.sqlite-wal\",\n\t\t\"**/*.sqlite\",\n\t\t\"**/*.sqlite-shm\",\n\t\t\"**/*.sqlite-wal\",\n\t\t`${constants.defaultUploadDirectory}/**`,\n\t\t...buildWatchIgnore,\n\t];\n\n\tconst isIgnoredFile = (filePath: string) => {\n\t\tconst relativePath = path.relative(watchPath, filePath);\n\t\treturn ignorePatterns.some((pattern) =>\n\t\t\tpath.matchesGlob(relativePath, pattern),\n\t\t);\n\t};\n\n\tconst watcher = chokidar\n\t\t.watch([watchPath, configPath], {\n\t\t\tignored: ignorePatterns,\n\t\t\tignoreInitial: true,\n\t\t\tpersistent: true,\n\t\t\tusePolling: false,\n\t\t\tawaitWriteFinish: {\n\t\t\t\tstabilityThreshold: 100,\n\t\t\t},\n\t\t})\n\t\t.on(\"change\", (changedPath) => {\n\t\t\tif (changedPath === configPath) {\n\t\t\t\tcliLogger.info(\"Config file changed, reloading...\");\n\t\t\t}\n\t\t\tif (isIgnoredFile(changedPath)) return;\n\t\t\tstartServer();\n\t\t})\n\t\t.on(\"add\", (addedPath) => {\n\t\t\tif (isIgnoredFile(addedPath)) return;\n\t\t\tstartServer();\n\t\t})\n\t\t.on(\"unlink\", (deletedPath) => {\n\t\t\tif (isIgnoredFile(deletedPath)) return;\n\t\t\tstartServer();\n\t\t});\n\n\tlet shutdownPromise: Promise<void> | undefined;\n\tconst shutdown = () => {\n\t\tshutdownPromise ??= (async () => {\n\t\t\ttry {\n\t\t\t\tif (restartTimer) clearTimeout(restartTimer);\n\t\t\t\tawait watcher?.close();\n\t\t\t\tawait serverDestroy?.();\n\t\t\t} catch (error) {\n\t\t\t\tcliLogger.error(\"Error during shutdown\");\n\t\t\t\tif (error instanceof Error) {\n\t\t\t\t\tcliLogger.error(error.message);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait stopLoggerBuffering();\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t})();\n\t\treturn shutdownPromise;\n\t};\n\n\tprocess.on(\"SIGINT\", shutdown);\n\tprocess.on(\"SIGTERM\", shutdown);\n\tprocess.on(\"SIGHUP\", shutdown);\n};\n\nexport default devCommand;\n"],"mappings":"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"}