@intlayer/chokidar
Version:
Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.
1 lines • 11.2 kB
Source Map (JSON)
{"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, extname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { loadMarkdownContentDeclaration } from './loadMarkdownContentDeclaration';\nimport { loadYamlContentDeclaration } from './loadYamlContentDeclaration';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n if (extname(path) === '.md' || extname(path) === '.mdx') {\n return loadMarkdownContentDeclaration(path);\n }\n\n if (extname(path) === '.yaml' || extname(path) === '.yml') {\n return loadYamlContentDeclaration(path);\n }\n\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":";;;;;;;;;;;;;AAmBA,MAAa,2BACX,oBACA,kBAEA,OAAO,QAAQ,kBAAkB,EAAE,KAAK,CAAC,cAAc,WAAW;CAChE,GAAG;CACH,UAAU,KAAK,YAAY,cAAc,YAAY,YAAY;CACjE,SAAS,GAAG,KAAK,IAAI,WAAW;CAChC,UAAU;AACZ,EAAE;AAEJ,MAAa,uBAAuB,OAClC,kBACoB;CACpB,MAAM,EAAE,WAAW;CAEnB,MAAM,EAAE,KAAK,YAAY,UAAU,eAAe,CAAC,iBAAiB,GAAG,EACrE,OAAO,MAAO,KAAK,KAAK,KAAK,EAC/B,CAAC;CAED,MAAM,WAAW,KAAK,OAAO,UAAU,qBAAqB;CAG5D,IAAI,CAAC,MAF2B,QAAQ,GAEhB;EAEtB,MAAM,UAAU,UAAU,MADG,kBAAkB,aAAa,CACpB;EACxC,MAAM,IAAI,IAAI;CAChB;CAEA,OAAO;AACT;AAOA,IAAI,qBAAsC;AAG1C,MAAM,kBAAkB,OAAO,YAAuC;CACpE,IAAI,oBACF,OAAO;CAGT,IAAI;EAGF,MAAM,cAAc,MAAM,SAFF,mBAAmB,OAG3B,EAAE,iBAChB,OACF;EACA,MAAM,iBAAiB,KAAK,MAAM,WAAW;EAC7C,MAAM,kBAAkB,OAAO,KAAK;GAClC,GAAG,eAAe;GAClB,GAAG,eAAe;EACpB,CAAC;EAGD,MAAM,sBAAgC,CAAC;EAEvC,MAAM,eAAe,gBAAgB,QAClC,QAAQ,CAAC,oBAAoB,SAAS,GAAG,CAC5C;EAEA,aAAa,KAAK,SAAS;EAG3B,qBAAqB;CACvB,SAAS,OAAO;EACd,QAAQ,KACN,uFACA,KACF;EACA,qBAAqB,CAAC,SAAS;CACjC;CAEA,OAAO;AACT;AAEA,MAAa,yBAAyB,OACpC,MACA,eACA,gBACA,YACoC;CACpC,IAAI,QAAQ,IAAI,MAAM,SAAS,QAAQ,IAAI,MAAM,QAC/C,OAAO,+BAA+B,IAAI;CAG5C,IAAI,QAAQ,IAAI,MAAM,WAAW,QAAQ,IAAI,MAAM,QACjD,OAAO,2BAA2B,IAAI;CAGxC,MAAM,EAAE,OAAO,WAAW;CAG1B,MAAM,eAAe,MAAM,gBAAgB,OAAO,OAAO;CAEzD,MAAM,yBACJ,kBAAmB,MAAM,qBAAqB,aAAa;CAE7D,IAAI;EA+BF,OAAO,MA9BkB,iBAAiB,MAAM;GAC9C,UAAU,SAAS;GACnB,gBAAgB,MAAM,WAAW,kBAAkB;GACnD,cAAc;IACZ,UAAU;IACV,UAAU;IACV,QAAQ,EACN,IAAI;KACF,oBAAoB,KAAK,UAAU,IAAI,EAAE;KACzC,mBAAmB,KAAK,UAAU,QAAQ,IAAI,CAAC,EAAE;KAIjD,oCAAoC,KAAK;KACzC,mCAAmC,cAAc,OAAO,QAAQ;IAClE,EAAE,KAAK,IAAI,EACb;GACF;GACA,SAAS,EACP,UAAU,uBACZ;GAIA,gBAAgB;IACd,oBAAoB;IACpB,mBAAmB,cAAc,OAAO;GAC1C;EACF,CAAC;CAGH,SAAS,OAAO;EACd,QAAQ,MAAM,wCAAwC,KAAK,IAAI,KAAK;EACpE;CACF;AACF;AAEA,MAAa,0BAA0B,OACrC,4BACA,eACA,gBACA,YAC0B;CAC1B,MAAM,EAAE,OAAO,WAAW;CAG1B,IAAI,MAAM,YACR,oBAAoB,4BAA4B,aAAa,EAAE,OAC5D,MAAM;EACL,QAAQ,MAAM,uCAAuC,CAAC;CACxD,CACF;CAGF,MAAM,iBAAiB,MAAM,qBAAqB,aAAa;CAE/D,IAAI;EACF,MAAM,uBAAuB,2BAA2B,IACtD,OAAO,SAAS;GAUd,OAAO;IAAE,cATY,SAAS,OAAO,SAAS,IAS1B;IAAG,kBAPE,uBACvB,MACA,eACA,gBACA,OACF;GAEkC;EACpC,CACF;EAaA,MAAM,sBAAoC,yBAVf,MADK,QAAQ,IAAI,oBAAoB,GACnB,QAC1C,KAAK,EAAE,cAAc,iBAAiB;GACrC,IAAI,YACF,IAAI,gBAAgB;GAEtB,OAAO;EACT,GACA,CAAC,CAIgB,GACjB,aACF,EAAE,QAAQ,eAAe,WAAW,aAAa,QAAQ;EAEzD,MAAM,wBAAwB,oBAAoB,KAAK,iBAAiB;GACtE,eAAe,YAAY;GAC3B,MAAM;GACN,QAAQ;EACV,EAAE;EAEF,iBAAiB,qBAAqB;EAsCtC,OAAO,0BAA0B,MApCG,YAClC,qBACA,OAAO,uBAAwD;GAC7D,IAAI,CAAC,oBACH;GAGF,iBAAiB,CACf;IACE,eAAe,mBAAmB;IAClC,MAAM;IACN,QAAQ;GACV,CACF,CAAC;GAED,MAAM,8BAA8B,MAAM,0BACxC,oBACA,aACF;GAEA,IAAI,CAAC,6BACH;GAGF,iBAAiB,CACf;IACE,eAAe,4BAA4B;IAC3C,MAAM;IACN,QAAQ;GACV,CACF,CAAC;GAED,OAAO;EACT,CACF,GAEwD,eAAe,EACrE,aAAa,MACf,CAAC;CACH,QAAQ;EACN,QAAQ,MAAM,oCAAoC;CACpD;CAEA,OAAO,CAAC;AACV"}