{"version":3,"file":"loadContentDeclaration.cjs","names":["getIntlayerBundle","loadMarkdownContentDeclaration","loadYamlContentDeclaration","filterInvalidDictionaries","parallelize","processContentDeclaration"],"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":"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"}