{"version":3,"file":"prepareIntlayer.mjs","names":[],"sources":["../../src/prepareIntlayer.ts"],"sourcesContent":["import { stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport packageJson from '@intlayer/config/package.json' with { type: 'json' };\nimport { cacheDisk } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { buildDictionary } from './buildIntlayerDictionary/buildIntlayerDictionary';\nimport { writeRemoteDictionary } from './buildIntlayerDictionary/writeRemoteDictionary';\nimport { cleanOutputDir } from './cleanOutputDir';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint/createDictionaryEntryPoint';\nimport { createModuleAugmentation, createTypes } from './createType/index';\nimport { listDictionariesWithStats } from './listDictionariesPath';\nimport { loadDictionaries } from './loadDictionaries/loadDictionaries';\nimport { runOnce } from './utils/runOnce';\nimport {\n  isCachedConfigurationUpToDate,\n  writeConfiguration,\n} from './writeConfiguration';\n\ntype PrepareIntlayerOptions = {\n  clean?: boolean;\n  env?: 'prod' | 'dev';\n  format?: ('cjs' | 'esm')[];\n  forceRun?: boolean;\n  cacheTimeoutMs?: number;\n  onIsCached?: () => void | Promise<void>;\n};\n\nconst DEFAULT_PREPARE_INTLAYER_OPTIONS = {\n  clean: false,\n  env: 'dev',\n  format: ['cjs', 'esm'],\n  cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n} satisfies PrepareIntlayerOptions;\n\nexport const prepareIntlayer = async (\n  configuration: IntlayerConfig,\n  options?: PrepareIntlayerOptions\n) => {\n  const appLogger = getAppLogger(configuration);\n\n  const sentinelPath = join(\n    configuration.system.cacheDir,\n    'intlayer-prepared.lock'\n  );\n  // Clean output dir if the intlayer version has changed\n  const versionCache = cacheDisk(configuration, ['intlayer-version']);\n  const intlayerCacheVersion = await versionCache.get();\n  const isCorrectVersion = Boolean(\n    intlayerCacheVersion && intlayerCacheVersion === packageJson.version\n  );\n\n  const isConfigSimilar = await isCachedConfigurationUpToDate(configuration);\n\n  // Check if any dictionary has been changed to force a new rebuild\n  const dictionariesWithStats = await listDictionariesWithStats(configuration);\n  let isDictionaryChanged = false;\n  try {\n    // Try catch as sentinel file may not exist yet\n    const sentinelStats = await stat(sentinelPath);\n    isDictionaryChanged = dictionariesWithStats.some(\n      (dictionary) =>\n        dictionary.stats.mtime.getTime() > sentinelStats.mtime.getTime()\n    );\n  } catch {}\n\n  const resolvedPlugins = await Promise.all(configuration.plugins ?? []);\n  const hasPluginLoadDictionaries = resolvedPlugins.some((plugin) =>\n    Boolean(plugin.loadDictionaries)\n  ); // Disable cache if any plugin because it can have custom behavior\n\n  const { clean, format, forceRun, onIsCached, cacheTimeoutMs, env } = {\n    ...DEFAULT_PREPARE_INTLAYER_OPTIONS,\n    forceRun:\n      !isCorrectVersion ||\n      !isConfigSimilar ||\n      isDictionaryChanged ||\n      hasPluginLoadDictionaries,\n    ...(options ?? {}),\n  };\n\n  // Skip preparation if it has already been done recently\n  await runOnce(\n    sentinelPath,\n    async () => {\n      // comment because of issue with next and webpack\n      // await checkVersionsConsistency(configuration);\n\n      if (clean || !isCorrectVersion) {\n        await cleanOutputDir(configuration);\n      }\n\n      await versionCache.set(packageJson.version);\n\n      const preparationStartMs = Date.now();\n\n      appLogger([\n        'Preparing Intlayer',\n        colorize(`(v${packageJson.version})`, ANSIColors.GREY_DARK),\n      ]);\n\n      await writeConfiguration(configuration);\n\n      const configurationWrittenTime = Date.now();\n\n      appLogger(\n        [\n          'Configuration written',\n          colorize(\n            `(${configurationWrittenTime - preparationStartMs}ms)`,\n            ANSIColors.GREY_DARK\n          ),\n        ],\n        {\n          isVerbose: true,\n        }\n      );\n\n      const contentDeclarationPaths = dictionariesWithStats.map(\n        (dictionary) => dictionary.path\n      );\n\n      const dictionaries = await loadDictionaries(\n        contentDeclarationPaths,\n        configuration\n      );\n\n      const dictionariesLoadedTime = Date.now();\n\n      appLogger(\n        [\n          'Content loaded',\n          colorize(\n            [\n              dictionaries.remoteDictionaries.length +\n                dictionaries.pluginDictionaries.length >\n              0\n                ? [\n                    `(Total: ${dictionariesLoadedTime - configurationWrittenTime}ms`,\n                    dictionaries.localDictionaries.length > 0\n                      ? ` - Local: ${dictionaries.time.localDictionaries}ms`\n                      : '',\n                    dictionaries.remoteDictionaries.length > 0\n                      ? ` - Remote: ${dictionaries.time.remoteDictionaries}ms`\n                      : '',\n                    dictionaries.pluginDictionaries.length > 0\n                      ? ` - Plugin: ${dictionaries.time.pluginDictionaries}ms`\n                      : '',\n                    `)`,\n                  ].join('')\n                : `(${dictionariesLoadedTime - configurationWrittenTime}ms)`,\n            ].join(''),\n            ANSIColors.GREY_DARK\n          ),\n        ],\n        {\n          isVerbose: true,\n        }\n      );\n\n      // Build local dictionaries\n      const dictionariesOutput = await buildDictionary(\n        [\n          ...dictionaries.localDictionaries,\n          ...dictionaries.remoteDictionaries,\n          ...dictionaries.pluginDictionaries,\n        ],\n        configuration,\n        { formats: format, importOtherDictionaries: false, env }\n      );\n\n      // Write remote dictionaries\n      // Used as cache for next fetch\n      await writeRemoteDictionary(\n        dictionaries.remoteDictionaries,\n        configuration\n      );\n\n      const dictionariesToBuild = Object.values(\n        dictionariesOutput?.mergedDictionaries ?? {}\n      ).map((dictionary) => dictionary.dictionary);\n\n      await createTypes(dictionariesToBuild, configuration);\n\n      await createDictionaryEntryPoint(configuration, {\n        formats: options?.format,\n      });\n\n      const dictionariesBuiltTime = Date.now();\n\n      appLogger([\n        'Dictionaries built',\n        colorize(\n          `(${dictionariesBuiltTime - preparationStartMs}ms)`,\n          ANSIColors.GREY_DARK\n        ),\n      ]);\n\n      await createModuleAugmentation(configuration);\n\n      const moduleAugmentationBuiltTime = Date.now();\n\n      appLogger(\n        [\n          'Module augmentation built',\n          colorize(\n            `(${moduleAugmentationBuiltTime - dictionariesBuiltTime}ms)`,\n            ANSIColors.GREY_DARK\n          ),\n        ],\n        {\n          isVerbose: true,\n        }\n      );\n\n      // Plugin transformation\n      // Allow plugins to post-process the final build output (e.g., write back ICU JSON)\n      for await (const plugin of configuration.plugins ?? []) {\n        const { unmergedDictionaries, mergedDictionaries } = dictionariesOutput;\n\n        await plugin.afterBuild?.({\n          dictionaries: {\n            unmergedDictionaries,\n            mergedDictionaries,\n          },\n          configuration,\n        });\n      }\n\n      const preparationElapsedMs = Date.now() - preparationStartMs;\n      appLogger(\n        [`Done`, colorize(`${preparationElapsedMs}ms`, ANSIColors.GREEN)],\n        {\n          level: 'info',\n          isVerbose: true,\n        }\n      );\n    },\n    {\n      forceRun,\n      onIsCached,\n      cacheTimeoutMs,\n    }\n  );\n};\n"],"mappings":"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"}