@intlayer/config 9.3.3 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +4 -1
  2. package/dist/cjs/callers/base.cjs +41 -28
  3. package/dist/cjs/callers/base.cjs.map +1 -1
  4. package/dist/cjs/configFile/buildBrowserConfiguration.cjs +38 -38
  5. package/dist/cjs/configFile/buildBrowserConfiguration.cjs.map +1 -1
  6. package/dist/cjs/configFile/buildConfigurationFields.cjs +7 -1
  7. package/dist/cjs/configFile/buildConfigurationFields.cjs.map +1 -1
  8. package/dist/cjs/defaultValues/analytics.cjs +3 -2
  9. package/dist/cjs/defaultValues/analytics.cjs.map +1 -1
  10. package/dist/cjs/envVars/envVars.cjs.map +1 -1
  11. package/dist/cjs/secrets.browser.cjs +21 -0
  12. package/dist/cjs/secrets.browser.cjs.map +1 -0
  13. package/dist/cjs/secrets.cjs +47 -0
  14. package/dist/cjs/secrets.cjs.map +1 -0
  15. package/dist/cjs/utils/index.cjs +2 -0
  16. package/dist/cjs/utils/isPackageInstalled.cjs +39 -0
  17. package/dist/cjs/utils/isPackageInstalled.cjs.map +1 -0
  18. package/dist/esm/bundle/index.mjs +1 -1
  19. package/dist/esm/callers/base.mjs +41 -28
  20. package/dist/esm/callers/base.mjs.map +1 -1
  21. package/dist/esm/configFile/buildBrowserConfiguration.mjs +38 -38
  22. package/dist/esm/configFile/buildBrowserConfiguration.mjs.map +1 -1
  23. package/dist/esm/configFile/buildConfigurationFields.mjs +7 -1
  24. package/dist/esm/configFile/buildConfigurationFields.mjs.map +1 -1
  25. package/dist/esm/defaultValues/analytics.mjs +3 -2
  26. package/dist/esm/defaultValues/analytics.mjs.map +1 -1
  27. package/dist/esm/envVars/envVars.mjs.map +1 -1
  28. package/dist/esm/secrets.browser.mjs +20 -0
  29. package/dist/esm/secrets.browser.mjs.map +1 -0
  30. package/dist/esm/secrets.mjs +46 -0
  31. package/dist/esm/secrets.mjs.map +1 -0
  32. package/dist/esm/utils/index.mjs +2 -1
  33. package/dist/esm/utils/isPackageInstalled.mjs +38 -0
  34. package/dist/esm/utils/isPackageInstalled.mjs.map +1 -0
  35. package/dist/types/configFile/buildBrowserConfiguration.d.ts +21 -8
  36. package/dist/types/configFile/buildBrowserConfiguration.d.ts.map +1 -1
  37. package/dist/types/configFile/buildConfigurationFields.d.ts.map +1 -1
  38. package/dist/types/defaultValues/analytics.d.ts +3 -2
  39. package/dist/types/defaultValues/analytics.d.ts.map +1 -1
  40. package/dist/types/secrets.browser.d.ts +19 -0
  41. package/dist/types/secrets.browser.d.ts.map +1 -0
  42. package/dist/types/secrets.d.ts +45 -0
  43. package/dist/types/secrets.d.ts.map +1 -0
  44. package/dist/types/utils/index.d.ts +2 -1
  45. package/dist/types/utils/isPackageInstalled.d.ts +23 -0
  46. package/dist/types/utils/isPackageInstalled.d.ts.map +1 -0
  47. package/package.json +15 -3
@@ -1 +1 @@
1
- {"version":3,"file":"buildConfigurationFields.mjs","names":[],"sources":["../../../src/configFile/buildConfigurationFields.ts"],"sourcesContent":["import { statSync } from 'node:fs';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type {\n AiConfig,\n BuildConfig,\n CompilerConfig,\n ContentConfig,\n CustomIntlayerConfig,\n DictionaryConfig,\n IntlayerConfig,\n LogFunctions,\n SystemConfig,\n} from '@intlayer/types/config';\nimport {\n BUILD_MODE,\n CACHE,\n CHUNK_GROUPING,\n DICTIONARIES_PRELOAD,\n MINIFY,\n OUTPUT_FORMAT,\n PURGE,\n TRAVERSE_PATTERN,\n TYPE_CHECKING,\n} from '../defaultValues/build';\nimport {\n COMPILER_DICTIONARY_KEY_PREFIX,\n COMPILER_ENABLED,\n COMPILER_NO_METADATA,\n COMPILER_SAVE_COMPONENTS,\n} from '../defaultValues/compiler';\nimport {\n CODE_DIR,\n CONTENT_DIR,\n EXCLUDED_PATHS,\n FILE_EXTENSIONS,\n WATCH,\n} from '../defaultValues/content';\nimport {\n CONTENT_AUTO_TRANSFORMATION,\n FILL,\n IMPORT_MODE,\n LOCATION,\n} from '../defaultValues/dictionary';\nimport {\n CACHE_DIR,\n CONFIG_DIR,\n DICTIONARIES_DIR,\n DYNAMIC_DICTIONARIES_DIR,\n FETCH_DICTIONARIES_DIR,\n MAIN_DIR,\n MODULE_AUGMENTATION_DIR,\n REMOTE_DICTIONARIES_DIR,\n TEMP_DIR,\n TYPES_DIR,\n UNMERGED_DICTIONARIES_DIR,\n} from '../defaultValues/system';\nimport { getProjectRequire } from '../utils';\nimport {\n buildAnalyticsFields,\n buildBrowserConfiguration,\n buildEditorFields,\n buildInternationalizationFields,\n buildLogFields,\n} from './buildBrowserConfiguration';\nimport { intlayerConfigSchema } from './configurationSchema';\n\nexport {\n type BrowserIntlayerConfig,\n buildAnalyticsFields,\n buildBrowserConfiguration,\n buildEditorFields,\n buildInternationalizationFields,\n buildLogFields,\n buildRoutingFields,\n extractBrowserConfiguration,\n} from './buildBrowserConfiguration';\n\nlet storedConfiguration: IntlayerConfig;\n\n// ---------------------------------------------------------------------------\n// Server-only field builders (Node.js — not browser-safe)\n// ---------------------------------------------------------------------------\n\n/**\n * Build the `system` section of the Intlayer configuration.\n *\n * Resolves all directory paths (dictionaries, types, cache, …) relative to\n * the project base directory, using Node.js `require.resolve` where available\n * and falling back to `path.join` otherwise.\n *\n * @param baseDir - Project root directory. Defaults to `process.cwd()`.\n * @param customConfiguration - Partial user-supplied system config.\n * @returns A fully-resolved {@link SystemConfig}.\n */\nconst buildSystemFields = (\n baseDir?: string,\n customConfiguration?: Partial<SystemConfig>\n): SystemConfig => {\n const projectBaseDir = baseDir ?? process.cwd();\n\n const optionalJoinBaseDir = (pathInput: string) => {\n let absolutePath: string;\n\n try {\n const requireFunction = getProjectRequire(projectBaseDir);\n try {\n absolutePath = requireFunction.resolve(pathInput, {\n paths: [projectBaseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = requireFunction.resolve(`${pathInput}/package.json`, {\n paths: [projectBaseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n absolutePath = isAbsolute(pathInput)\n ? pathInput\n : join(projectBaseDir, pathInput);\n }\n\n try {\n const stats = statSync(absolutePath);\n if (stats.isFile()) {\n return dirname(absolutePath);\n }\n } catch {\n if (/\\.[a-z0-9]+$/i.test(absolutePath)) {\n return dirname(absolutePath);\n }\n }\n\n return absolutePath;\n };\n\n const dictionariesDir = optionalJoinBaseDir(\n customConfiguration?.dictionariesDir ?? DICTIONARIES_DIR\n );\n\n return {\n baseDir: projectBaseDir,\n moduleAugmentationDir: optionalJoinBaseDir(\n customConfiguration?.moduleAugmentationDir ?? MODULE_AUGMENTATION_DIR\n ),\n unmergedDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.unmergedDictionariesDir ?? UNMERGED_DICTIONARIES_DIR\n ),\n remoteDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.remoteDictionariesDir ?? REMOTE_DICTIONARIES_DIR\n ),\n dictionariesDir,\n dynamicDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.dynamicDictionariesDir ?? DYNAMIC_DICTIONARIES_DIR\n ),\n fetchDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.fetchDictionariesDir ?? FETCH_DICTIONARIES_DIR\n ),\n typesDir: optionalJoinBaseDir(customConfiguration?.typesDir ?? TYPES_DIR),\n mainDir: optionalJoinBaseDir(customConfiguration?.mainDir ?? MAIN_DIR),\n configDir: optionalJoinBaseDir(\n customConfiguration?.configDir ?? CONFIG_DIR\n ),\n cacheDir: optionalJoinBaseDir(customConfiguration?.cacheDir ?? CACHE_DIR),\n tempDir: optionalJoinBaseDir(customConfiguration?.tempDir ?? TEMP_DIR),\n };\n};\n\n/**\n * Build the `content` section of the Intlayer configuration.\n *\n * Resolves content and code directories relative to the project base using\n * `require.resolve`, falling back to `path.join`.\n *\n * @param systemConfig - Already-built system configuration (provides `baseDir`).\n * @param customConfiguration - Partial user-supplied content config.\n * @returns A fully-resolved {@link ContentConfig}.\n */\nconst buildContentFields = (\n systemConfig: SystemConfig,\n customConfiguration?: Partial<ContentConfig>\n): ContentConfig => {\n const fileExtensions = customConfiguration?.fileExtensions ?? FILE_EXTENSIONS;\n\n const optionalJoinBaseDir = (pathInput: string) => {\n let absolutePath: string;\n\n try {\n const requireFunction = getProjectRequire(systemConfig.baseDir);\n try {\n absolutePath = requireFunction.resolve(pathInput, {\n paths: [systemConfig.baseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = requireFunction.resolve(`${pathInput}/package.json`, {\n paths: [systemConfig.baseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n try {\n try {\n absolutePath = require.resolve(pathInput, {\n paths: [systemConfig.baseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = require.resolve(`${pathInput}/package.json`, {\n paths: [systemConfig.baseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n absolutePath = isAbsolute(pathInput)\n ? pathInput\n : join(systemConfig.baseDir, pathInput);\n }\n }\n\n try {\n const stats = statSync(absolutePath);\n if (stats.isFile()) {\n return dirname(absolutePath);\n }\n } catch {\n if (/\\.[a-z0-9]+$/i.test(absolutePath)) {\n return dirname(absolutePath);\n }\n }\n\n return absolutePath;\n };\n\n const contentDir = (customConfiguration?.contentDir ?? CONTENT_DIR).map(\n optionalJoinBaseDir\n );\n const codeDir = (customConfiguration?.codeDir ?? CODE_DIR).map(\n optionalJoinBaseDir\n );\n\n return {\n fileExtensions,\n contentDir,\n codeDir,\n excludedPath: customConfiguration?.excludedPath ?? EXCLUDED_PATHS,\n watch: customConfiguration?.watch ?? WATCH,\n formatCommand: customConfiguration?.formatCommand,\n };\n};\n\n/**\n * Build the `ai` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied AI config.\n * @returns A fully-defaulted {@link AiConfig}.\n */\nconst buildAiFields = (customConfiguration?: Partial<AiConfig>): AiConfig => ({\n /**\n * AI configuration\n */\n provider: customConfiguration?.provider,\n\n /**\n * API key\n */\n apiKey: customConfiguration?.apiKey,\n\n /**\n * API model\n */\n model: customConfiguration?.model,\n\n /**\n * Temperature\n */\n temperature: customConfiguration?.temperature,\n\n /**\n * Application context\n *\n * Default: undefined\n *\n * The application context.\n *\n * Example: `'My application context'`\n *\n * Note: Can be used to provide additional context about the application to the AI model. You can add more rules (e.g. \"You should not transform urls\").\n */\n applicationContext: customConfiguration?.applicationContext,\n\n /**\n * Base URL for the AI API\n *\n * Default: undefined\n *\n * The base URL for the AI API.\n *\n * Example: `'http://localhost:5000'`\n *\n * Note: Can be used to point to a local, or custom AI API endpoint.\n */\n baseURL: customConfiguration?.baseURL,\n\n /**\n * Data serialization\n *\n * Options:\n * - \"json\": The industry standard. Highly reliable and structured, but consumes more tokens.\n * - \"toon\": An optimized format designed to reduce token consumption (cost-effective). However, it may slightly increase the risk of output inconsistency compared to standard JSON\n *\n * Default: `\"json\"`\n */\n dataSerialization: customConfiguration?.dataSerialization,\n});\n\n/**\n * Build the `build` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied build config.\n * @returns A fully-defaulted {@link BuildConfig}.\n */\nconst buildBuildFields = (\n customConfiguration?: Partial<BuildConfig>\n): BuildConfig => ({\n /**\n * Indicates the mode of the build\n *\n * Default: 'auto'\n *\n * If 'auto', the build will be enabled automatically when the application is built.\n * If 'manual', the build will be set only when the build command is executed.\n *\n * Can be used to disable dictionaries build, for instance when execution on Node.js environment should be avoided.\n */\n mode: customConfiguration?.mode ?? BUILD_MODE,\n\n /**\n * Indicates if the build should be optimized\n *\n * Default: process.env.NODE_ENV === 'production'\n *\n * If true, the build will be optimized.\n * If false, the build will not be optimized.\n *\n * Intlayer will replace all calls of dictionaries to optimize chunking. That way the final bundle will import only the dictionaries that are used.\n * All imports will stay as static import to avoid async processing when loading the dictionaries.\n *\n * Note:\n * - Intlayer will replace all call of `useIntlayer` with the defined mode by the `importMode` option.\n * - Intlayer will replace all call of `getIntlayer` with `getDictionary`.\n * - This option relies on the `@intlayer/babel` and `@intlayer/swc` plugins.\n * - In most cases, \"dynamic\" will be used for React applications, \"async\" for Vue.js applications.\n * - Ensure all keys are declared statically in the `useIntlayer` calls. e.g. `useIntlayer('navbar')`.\n */\n optimize: customConfiguration?.optimize,\n\n /**\n * Indicates the mode of import to use for the dictionaries.\n *\n * Available modes:\n * - \"static\": The dictionaries are imported statically.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionary`.\n * - \"dynamic\": The dictionaries are imported dynamically in a synchronous component using the suspense API.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionaryDynamic`.\n * - \"live\": The dictionaries are imported dynamically using the live sync API.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionaryDynamic`.\n * Live mode will use the live sync API to fetch the dictionaries. If the API call fails, the dictionaries will be imported dynamically as \"dynamic\" mode.\n *\n * Default: \"static\"\n *\n * By default, when a dictionary is loaded, it imports content for all locales as it's imported statically.\n *\n * Note:\n * - Dynamic imports rely on Suspense and may slightly impact rendering performance.\n * - If disabled all locales will be loaded at once, even if they are not used.\n * - This option relies on the `@intlayer/babel` and `@intlayer/swc` plugins.\n * - Ensure all keys are declared statically in the `useIntlayer` calls. e.g. `useIntlayer('navbar')`.\n * - This option will be ignored if `optimize` is disabled.\n * - This option will not impact the `getIntlayer`, `getDictionary`, `useDictionary`, `useDictionaryAsync` and `useDictionaryDynamic` functions. You can still use them to refine you code on manual optimization.\n * - The \"live\" allows to sync the dictionaries to the live sync server.\n *\n * @deprecated Use `dictionary.importMode` instead.\n */\n importMode: customConfiguration?.importMode,\n\n /**\n * Minify the dictionaries to reduce the bundle size.\n *\n * Default: false\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - This option will be ignore if `editor.enabled` is true.\n * - If there is edge cases where the minification is not working properly, the dictionary will be not minified.\n */\n minify: customConfiguration?.minify ?? MINIFY,\n\n /**\n * Purge the unused keys in a dictionaries\n *\n * Default: false\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - This option will be ignored if `editor.enabled` is true.\n */\n purge: customConfiguration?.purge ?? PURGE,\n\n /**\n * Group the per-locale dictionary chunks by the code-split boundary that uses\n * them, so a lazily loaded page fetches its content in one request.\n *\n * Default: true\n *\n * Note:\n * - Only applies to dictionaries using `importMode: 'dynamic'`.\n * - Only applies to the client build, and only when bundling (not in dev).\n */\n chunkGrouping: customConfiguration?.chunkGrouping ?? CHUNK_GROUPING,\n\n /**\n * Load a dictionary together with the chunk that uses it, instead of fetching\n * it once that chunk renders — so a reader renders synchronously rather than\n * suspending, and navigating no longer flashes a loading state.\n *\n * Default: true\n *\n * Note:\n * - Only applies to dictionaries using `importMode: 'dynamic'`.\n * - Only applies to the client build; the server keeps loading on demand.\n * - Requires a bundler supporting top-level await (Vite, esbuild).\n */\n dictionariesPreload:\n customConfiguration?.dictionariesPreload ?? DICTIONARIES_PRELOAD,\n\n /**\n * Pattern to traverse the code to optimize.\n *\n * Allows to avoid to traverse the code that is not relevant to the optimization.\n * Improve build performance.\n *\n * Default: ['**\\/*.{js,ts,mjs,cjs,jsx,tsx}', '!**\\/node_modules/**']\n *\n * Example: `['src/**\\/*.{ts,tsx}', '../ui-library/**\\/*.{ts,tsx}']`\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - Use glob pattern.\n */\n traversePattern: customConfiguration?.traversePattern ?? TRAVERSE_PATTERN,\n\n /**\n * Output format of the dictionaries\n *\n * Can be set on large projects to improve build performance.\n *\n * Default: ['cjs', 'esm']\n *\n * The output format of the dictionaries. It can be either 'cjs' or 'esm'.\n * - 'cjs': The dictionaries are outputted as CommonJS modules.\n * - 'esm': The dictionaries are outputted as ES modules.\n */\n outputFormat: customConfiguration?.outputFormat ?? OUTPUT_FORMAT,\n\n /**\n * Cache\n */\n cache: customConfiguration?.cache ?? CACHE,\n\n /**\n * Require function\n */\n require: customConfiguration?.require,\n\n /**\n * Indicates if the build should check TypeScript types\n *\n * Default: `false`\n *\n * If true, the build will check TypeScript types and log errors.\n * Note: This can slow down the build.\n */\n checkTypes: customConfiguration?.checkTypes ?? TYPE_CHECKING,\n});\n\n/**\n * Build the `compiler` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied compiler config.\n * @returns A fully-defaulted {@link CompilerConfig}.\n */\nconst buildCompilerFields = (\n customConfiguration?: Partial<CompilerConfig>\n): CompilerConfig => ({\n /**\n * Indicates if the compiler should be enabled\n */\n enabled: customConfiguration?.enabled ?? COMPILER_ENABLED,\n\n /**\n * Prefix for the extracted dictionary keys\n */\n dictionaryKeyPrefix:\n customConfiguration?.dictionaryKeyPrefix ?? COMPILER_DICTIONARY_KEY_PREFIX,\n\n /**\n * Pattern to traverse the code to optimize.\n *\n * @deprecated use `build.traversePattern` instead\n */\n transformPattern: customConfiguration?.transformPattern,\n\n /**\n * Pattern to exclude from the optimization.\n *\n * @deprecated use `build.traversePattern` instead\n */\n excludePattern: customConfiguration?.excludePattern,\n\n /**\n * Defines the output files path. Replaces `outputDir`.\n *\n * - `./` paths are resolved relative to the component directory.\n * - `/` paths are resolved relative to the project root (`baseDir`).\n *\n * - Including the `{{locale}}` variable in the path will trigger the generation of separate dictionaries per locale.\n *\n * @example:\n * ```ts\n * {\n * // Create Multilingual .content.ts files close to the component\n * output: ({ fileName, extension }) => `./${fileName}${extension}`,\n *\n * // output: './{{fileName}}{{extension}}', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create centralize per-locale JSON at the root of the project\n * output: ({ key, locale }) => `/locales/${locale}/${key}.content.json`,\n *\n * // output: '/locales/{{locale}}/{{key}}.content.json', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create per-locale JSON files with locale-specific output paths\n * output: {\n * en: ({ fileName, locale }) => `${fileName}.${locale}.content.json`,\n * fr: '{{fileName}}.{{locale}}.content.json',\n * es: false, // skip this locale\n * },\n * }\n * ```\n *\n * Variable list:\n * - `fileName`: The name of the file.\n * - `key`: The key of the content.\n * - `locale`: The locale of the content.\n * - `extension`: The extension of the file.\n * - `componentFileName`: The name of the component file.\n * - `componentExtension`: The extension of the component file.\n * - `format`: The format of the dictionary.\n * - `componentFormat`: The format of the component dictionary.\n * - `componentDirPath`: The directory path of the component.\n */\n output: customConfiguration?.output,\n\n /**\n * Indicates if the metadata should be saved in the file.\n *\n * If true, the compiler will not save the metadata of the dictionaries.\n *\n * If `true`:\n *\n * ```json\n * {\n * \"key\": \"value\"\n * }\n * ```\n *\n * If `false`:\n *\n * ```json\n * {\n * \"key\": \"value\",\n * \"content\": {\n * \"key\": \"value\"\n * }\n * }\n * ```\n *\n * Default: `false`\n *\n * Note: Useful if used with loadJSON plugin\n */\n noMetadata: customConfiguration?.noMetadata ?? COMPILER_NO_METADATA,\n\n /**\n * Indicates if the components should be saved after being transformed.\n */\n saveComponents:\n customConfiguration?.saveComponents ?? COMPILER_SAVE_COMPONENTS,\n});\n\n/**\n * Build the `dictionary` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied dictionary config.\n * @returns A fully-defaulted {@link DictionaryConfig}.\n */\nconst buildDictionaryFields = (\n customConfiguration?: Partial<DictionaryConfig>\n): DictionaryConfig => {\n const contentAutoTransformation =\n customConfiguration?.contentAutoTransformation ??\n CONTENT_AUTO_TRANSFORMATION;\n\n return {\n /**\n * Indicate how the dictionary should be filled using AI.\n *\n * Default: `true`\n *\n * - If `true`, will consider the `compiler.output` field.\n * - If `false`, will skip the fill process.\n *\n * - `./` paths are resolved relative to the component directory.\n * - `/` paths are resolved relative to the project root (`baseDir`).\n *\n * - If includes `{{locale}}` variable in the path, will trigger the generation of separate dictionaries per locale.\n *\n * Example:\n * ```ts\n * {\n * // Create Multilingual .content.ts files close to the component\n * fill: ({ fileName, extension }) => `./${fileName}${extension}`,\n *\n * // fill: './{{fileName}}{{extension}}', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create centralize per-locale JSON at the root of the project\n * fill: ({ key, locale }) => `/locales/${locale}/${key}.content.json`,\n *\n * // fill: '/locales/{{locale}}/{{key}}.content.json', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create custom output based on the locale\n * fill: {\n * en: ({ key }) => `/locales/en/${key}.content.json`,\n * fr: '/locales/fr/{{key}}.content.json',\n * es: false,\n * de: true,\n * },\n * }\n * ```\n *\n *\n * Variable list:\n * - `fileName`: The name of the file.\n * - `key`: The key of the content.\n * - `locale`: The locale of the content.\n * - `extension`: The extension of the file.\n * - `componentFileName`: The name of the component file.\n * - `componentExtension`: The extension of the component file.\n * - `format`: The format of the dictionary.\n * - `componentFormat`: The format of the component dictionary.\n * - `componentDirPath`: The directory path of the component.\n */\n fill: customConfiguration?.fill ?? FILL,\n\n /**\n * Indicates if the content of the dictionary should be automatically transformed.\n *\n * Default: `false`\n */\n contentAutoTransformation:\n typeof contentAutoTransformation === 'object'\n ? {\n markdown: contentAutoTransformation.markdown ?? false,\n html: contentAutoTransformation.html ?? false,\n insertion: contentAutoTransformation.insertion ?? false,\n }\n : contentAutoTransformation,\n\n /**\n * The location of the dictionary.\n *\n * Default: `\"local\"`\n */\n location: customConfiguration?.location ?? LOCATION,\n\n /**\n * Transform the dictionary in a per-locale dictionary.\n * Each field declared in a per-locale dictionary will be transformed in a translation node.\n * If missing, the dictionary will be treated as a multilingual dictionary.\n */\n locale: customConfiguration?.locale,\n\n /**\n * The title of the dictionary.\n */\n title: customConfiguration?.title,\n\n /**\n * The description of the dictionary.\n */\n description: customConfiguration?.description,\n\n /**\n * Tags to categorize the dictionaries.\n */\n tags: customConfiguration?.tags,\n\n /**\n * The priority of the dictionary.\n */\n priority: customConfiguration?.priority,\n\n /**\n * Indicates the mode of import to use for the dictionary.\n *\n * Available modes:\n * - \"static\": The dictionaries are imported statically.\n * - \"dynamic\": The dictionaries are imported dynamically in a synchronous component using the suspense API.\n * - \"live\": The dictionaries are imported dynamically using the live sync API.\n *\n * Default: `\"static\"`\n */\n importMode: customConfiguration?.importMode ?? IMPORT_MODE,\n\n /**\n * The default message format for all dictionaries in the project.\n *\n * Default: 'intlayer'\n */\n format: customConfiguration?.format,\n };\n};\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Build the complete Intlayer configuration by merging user-supplied values\n * with defaults.\n *\n * Internally this function:\n * 1. Calls {@link buildBrowserConfiguration} to produce the browser-safe\n * subset (internationalization, routing, editor public fields, log, metadata).\n * 2. Extends the result with full server-side fields:\n * - `internationalization` — adds `requiredLocales` and `strictMode`.\n * - `editor` — adds `clientId` and `clientSecret`.\n * - `log` — adds custom log functions.\n * - `system`, `content`, `ai`, `build`, `compiler`, `dictionary`.\n *\n * @param customConfiguration - Optional user-supplied configuration object.\n * @param baseDir - Project root directory. Defaults to `process.cwd()`.\n * @param logFunctions - Optional custom logging functions.\n * @returns A fully-built {@link IntlayerConfig}.\n */\nexport const buildConfigurationFields = (\n customConfiguration?: CustomIntlayerConfig,\n baseDir?: string,\n logFunctions?: LogFunctions\n): IntlayerConfig => {\n if (customConfiguration) {\n const result = intlayerConfigSchema.safeParse(customConfiguration);\n\n if (!result.success) {\n const logError = logFunctions?.error ?? console.error;\n\n for (const issue of result.error.issues) {\n logError(`${issue.path.join('.')}: ${issue.message}`);\n }\n }\n }\n\n // build browser-safe config (shared defaults, no Node.js deps)\n const browserConfig = buildBrowserConfiguration(customConfiguration);\n\n // extend shared fields with server-only additions\n const internationalizationConfig = buildInternationalizationFields(\n customConfiguration?.internationalization\n );\n\n const editorConfig = buildEditorFields(customConfiguration?.editor);\n\n const logConfig = buildLogFields(customConfiguration?.log, logFunctions);\n\n // build server-only fields\n const systemConfig = buildSystemFields(baseDir, customConfiguration?.system);\n\n const contentConfig = buildContentFields(\n systemConfig,\n customConfiguration?.content\n );\n\n storedConfiguration = {\n // Shared browser fields\n routing: browserConfig.routing,\n // Full (extended) shared fields\n internationalization: internationalizationConfig,\n editor: editorConfig,\n analytics: buildAnalyticsFields(customConfiguration?.analytics),\n log: logConfig,\n // Server-only fields\n system: systemConfig,\n content: contentConfig,\n ai: buildAiFields(customConfiguration?.ai),\n build: buildBuildFields(customConfiguration?.build),\n compiler: buildCompilerFields(customConfiguration?.compiler),\n dictionary: buildDictionaryFields(customConfiguration?.dictionary),\n plugins: customConfiguration?.plugins,\n schemas: customConfiguration?.schemas,\n } as IntlayerConfig;\n\n return storedConfiguration;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"buildConfigurationFields.mjs","names":[],"sources":["../../../src/configFile/buildConfigurationFields.ts"],"sourcesContent":["import { statSync } from 'node:fs';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type {\n AiConfig,\n BuildConfig,\n CompilerConfig,\n ContentConfig,\n CustomIntlayerConfig,\n DictionaryConfig,\n IntlayerConfig,\n LogFunctions,\n SystemConfig,\n} from '@intlayer/types/config';\nimport {\n BUILD_MODE,\n CACHE,\n CHUNK_GROUPING,\n DICTIONARIES_PRELOAD,\n MINIFY,\n OUTPUT_FORMAT,\n PURGE,\n TRAVERSE_PATTERN,\n TYPE_CHECKING,\n} from '../defaultValues/build';\nimport {\n COMPILER_DICTIONARY_KEY_PREFIX,\n COMPILER_ENABLED,\n COMPILER_NO_METADATA,\n COMPILER_SAVE_COMPONENTS,\n} from '../defaultValues/compiler';\nimport {\n CODE_DIR,\n CONTENT_DIR,\n EXCLUDED_PATHS,\n FILE_EXTENSIONS,\n WATCH,\n} from '../defaultValues/content';\nimport {\n CONTENT_AUTO_TRANSFORMATION,\n FILL,\n IMPORT_MODE,\n LOCATION,\n} from '../defaultValues/dictionary';\nimport {\n CACHE_DIR,\n CONFIG_DIR,\n DICTIONARIES_DIR,\n DYNAMIC_DICTIONARIES_DIR,\n FETCH_DICTIONARIES_DIR,\n MAIN_DIR,\n MODULE_AUGMENTATION_DIR,\n REMOTE_DICTIONARIES_DIR,\n TEMP_DIR,\n TYPES_DIR,\n UNMERGED_DICTIONARIES_DIR,\n} from '../defaultValues/system';\nimport { getProjectRequire, isPackageInstalled } from '../utils';\nimport {\n buildAnalyticsFields,\n buildBrowserConfiguration,\n buildEditorFields,\n buildInternationalizationFields,\n buildLogFields,\n} from './buildBrowserConfiguration';\nimport { intlayerConfigSchema } from './configurationSchema';\n\nexport {\n type BrowserIntlayerConfig,\n buildAnalyticsFields,\n buildBrowserConfiguration,\n buildEditorFields,\n buildInternationalizationFields,\n buildLogFields,\n buildRoutingFields,\n extractBrowserConfiguration,\n} from './buildBrowserConfiguration';\n\nlet storedConfiguration: IntlayerConfig;\n\n/**\n * Optional companion package whose presence in the project dependency tree\n * opts the application into analytics collection.\n */\nconst ANALYTICS_PACKAGE_NAME = '@intlayer/analytics';\n\n// ---------------------------------------------------------------------------\n// Server-only field builders (Node.js — not browser-safe)\n// ---------------------------------------------------------------------------\n\n/**\n * Build the `system` section of the Intlayer configuration.\n *\n * Resolves all directory paths (dictionaries, types, cache, …) relative to\n * the project base directory, using Node.js `require.resolve` where available\n * and falling back to `path.join` otherwise.\n *\n * @param baseDir - Project root directory. Defaults to `process.cwd()`.\n * @param customConfiguration - Partial user-supplied system config.\n * @returns A fully-resolved {@link SystemConfig}.\n */\nconst buildSystemFields = (\n baseDir?: string,\n customConfiguration?: Partial<SystemConfig>\n): SystemConfig => {\n const projectBaseDir = baseDir ?? process.cwd();\n\n const optionalJoinBaseDir = (pathInput: string) => {\n let absolutePath: string;\n\n try {\n const requireFunction = getProjectRequire(projectBaseDir);\n try {\n absolutePath = requireFunction.resolve(pathInput, {\n paths: [projectBaseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = requireFunction.resolve(`${pathInput}/package.json`, {\n paths: [projectBaseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n absolutePath = isAbsolute(pathInput)\n ? pathInput\n : join(projectBaseDir, pathInput);\n }\n\n try {\n const stats = statSync(absolutePath);\n if (stats.isFile()) {\n return dirname(absolutePath);\n }\n } catch {\n if (/\\.[a-z0-9]+$/i.test(absolutePath)) {\n return dirname(absolutePath);\n }\n }\n\n return absolutePath;\n };\n\n const dictionariesDir = optionalJoinBaseDir(\n customConfiguration?.dictionariesDir ?? DICTIONARIES_DIR\n );\n\n return {\n baseDir: projectBaseDir,\n moduleAugmentationDir: optionalJoinBaseDir(\n customConfiguration?.moduleAugmentationDir ?? MODULE_AUGMENTATION_DIR\n ),\n unmergedDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.unmergedDictionariesDir ?? UNMERGED_DICTIONARIES_DIR\n ),\n remoteDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.remoteDictionariesDir ?? REMOTE_DICTIONARIES_DIR\n ),\n dictionariesDir,\n dynamicDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.dynamicDictionariesDir ?? DYNAMIC_DICTIONARIES_DIR\n ),\n fetchDictionariesDir: optionalJoinBaseDir(\n customConfiguration?.fetchDictionariesDir ?? FETCH_DICTIONARIES_DIR\n ),\n typesDir: optionalJoinBaseDir(customConfiguration?.typesDir ?? TYPES_DIR),\n mainDir: optionalJoinBaseDir(customConfiguration?.mainDir ?? MAIN_DIR),\n configDir: optionalJoinBaseDir(\n customConfiguration?.configDir ?? CONFIG_DIR\n ),\n cacheDir: optionalJoinBaseDir(customConfiguration?.cacheDir ?? CACHE_DIR),\n tempDir: optionalJoinBaseDir(customConfiguration?.tempDir ?? TEMP_DIR),\n };\n};\n\n/**\n * Build the `content` section of the Intlayer configuration.\n *\n * Resolves content and code directories relative to the project base using\n * `require.resolve`, falling back to `path.join`.\n *\n * @param systemConfig - Already-built system configuration (provides `baseDir`).\n * @param customConfiguration - Partial user-supplied content config.\n * @returns A fully-resolved {@link ContentConfig}.\n */\nconst buildContentFields = (\n systemConfig: SystemConfig,\n customConfiguration?: Partial<ContentConfig>\n): ContentConfig => {\n const fileExtensions = customConfiguration?.fileExtensions ?? FILE_EXTENSIONS;\n\n const optionalJoinBaseDir = (pathInput: string) => {\n let absolutePath: string;\n\n try {\n const requireFunction = getProjectRequire(systemConfig.baseDir);\n try {\n absolutePath = requireFunction.resolve(pathInput, {\n paths: [systemConfig.baseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = requireFunction.resolve(`${pathInput}/package.json`, {\n paths: [systemConfig.baseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n try {\n try {\n absolutePath = require.resolve(pathInput, {\n paths: [systemConfig.baseDir],\n });\n } catch (err) {\n if (!pathInput.startsWith('.') && !isAbsolute(pathInput)) {\n absolutePath = require.resolve(`${pathInput}/package.json`, {\n paths: [systemConfig.baseDir],\n });\n } else {\n throw err;\n }\n }\n } catch {\n absolutePath = isAbsolute(pathInput)\n ? pathInput\n : join(systemConfig.baseDir, pathInput);\n }\n }\n\n try {\n const stats = statSync(absolutePath);\n if (stats.isFile()) {\n return dirname(absolutePath);\n }\n } catch {\n if (/\\.[a-z0-9]+$/i.test(absolutePath)) {\n return dirname(absolutePath);\n }\n }\n\n return absolutePath;\n };\n\n const contentDir = (customConfiguration?.contentDir ?? CONTENT_DIR).map(\n optionalJoinBaseDir\n );\n const codeDir = (customConfiguration?.codeDir ?? CODE_DIR).map(\n optionalJoinBaseDir\n );\n\n return {\n fileExtensions,\n contentDir,\n codeDir,\n excludedPath: customConfiguration?.excludedPath ?? EXCLUDED_PATHS,\n watch: customConfiguration?.watch ?? WATCH,\n formatCommand: customConfiguration?.formatCommand,\n };\n};\n\n/**\n * Build the `ai` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied AI config.\n * @returns A fully-defaulted {@link AiConfig}.\n */\nconst buildAiFields = (customConfiguration?: Partial<AiConfig>): AiConfig => ({\n /**\n * AI configuration\n */\n provider: customConfiguration?.provider,\n\n /**\n * API key\n */\n apiKey: customConfiguration?.apiKey,\n\n /**\n * API model\n */\n model: customConfiguration?.model,\n\n /**\n * Temperature\n */\n temperature: customConfiguration?.temperature,\n\n /**\n * Application context\n *\n * Default: undefined\n *\n * The application context.\n *\n * Example: `'My application context'`\n *\n * Note: Can be used to provide additional context about the application to the AI model. You can add more rules (e.g. \"You should not transform urls\").\n */\n applicationContext: customConfiguration?.applicationContext,\n\n /**\n * Base URL for the AI API\n *\n * Default: undefined\n *\n * The base URL for the AI API.\n *\n * Example: `'http://localhost:5000'`\n *\n * Note: Can be used to point to a local, or custom AI API endpoint.\n */\n baseURL: customConfiguration?.baseURL,\n\n /**\n * Data serialization\n *\n * Options:\n * - \"json\": The industry standard. Highly reliable and structured, but consumes more tokens.\n * - \"toon\": An optimized format designed to reduce token consumption (cost-effective). However, it may slightly increase the risk of output inconsistency compared to standard JSON\n *\n * Default: `\"json\"`\n */\n dataSerialization: customConfiguration?.dataSerialization,\n});\n\n/**\n * Build the `build` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied build config.\n * @returns A fully-defaulted {@link BuildConfig}.\n */\nconst buildBuildFields = (\n customConfiguration?: Partial<BuildConfig>\n): BuildConfig => ({\n /**\n * Indicates the mode of the build\n *\n * Default: 'auto'\n *\n * If 'auto', the build will be enabled automatically when the application is built.\n * If 'manual', the build will be set only when the build command is executed.\n *\n * Can be used to disable dictionaries build, for instance when execution on Node.js environment should be avoided.\n */\n mode: customConfiguration?.mode ?? BUILD_MODE,\n\n /**\n * Indicates if the build should be optimized\n *\n * Default: process.env.NODE_ENV === 'production'\n *\n * If true, the build will be optimized.\n * If false, the build will not be optimized.\n *\n * Intlayer will replace all calls of dictionaries to optimize chunking. That way the final bundle will import only the dictionaries that are used.\n * All imports will stay as static import to avoid async processing when loading the dictionaries.\n *\n * Note:\n * - Intlayer will replace all call of `useIntlayer` with the defined mode by the `importMode` option.\n * - Intlayer will replace all call of `getIntlayer` with `getDictionary`.\n * - This option relies on the `@intlayer/babel` and `@intlayer/swc` plugins.\n * - In most cases, \"dynamic\" will be used for React applications, \"async\" for Vue.js applications.\n * - Ensure all keys are declared statically in the `useIntlayer` calls. e.g. `useIntlayer('navbar')`.\n */\n optimize: customConfiguration?.optimize,\n\n /**\n * Indicates the mode of import to use for the dictionaries.\n *\n * Available modes:\n * - \"static\": The dictionaries are imported statically.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionary`.\n * - \"dynamic\": The dictionaries are imported dynamically in a synchronous component using the suspense API.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionaryDynamic`.\n * - \"live\": The dictionaries are imported dynamically using the live sync API.\n * In that case, Intlayer will replace all calls to `useIntlayer` with `useDictionaryDynamic`.\n * Live mode will use the live sync API to fetch the dictionaries. If the API call fails, the dictionaries will be imported dynamically as \"dynamic\" mode.\n *\n * Default: \"static\"\n *\n * By default, when a dictionary is loaded, it imports content for all locales as it's imported statically.\n *\n * Note:\n * - Dynamic imports rely on Suspense and may slightly impact rendering performance.\n * - If disabled all locales will be loaded at once, even if they are not used.\n * - This option relies on the `@intlayer/babel` and `@intlayer/swc` plugins.\n * - Ensure all keys are declared statically in the `useIntlayer` calls. e.g. `useIntlayer('navbar')`.\n * - This option will be ignored if `optimize` is disabled.\n * - This option will not impact the `getIntlayer`, `getDictionary`, `useDictionary`, `useDictionaryAsync` and `useDictionaryDynamic` functions. You can still use them to refine you code on manual optimization.\n * - The \"live\" allows to sync the dictionaries to the live sync server.\n *\n * @deprecated Use `dictionary.importMode` instead.\n */\n importMode: customConfiguration?.importMode,\n\n /**\n * Minify the dictionaries to reduce the bundle size.\n *\n * Default: false\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - This option will be ignore if `editor.enabled` is true.\n * - If there is edge cases where the minification is not working properly, the dictionary will be not minified.\n */\n minify: customConfiguration?.minify ?? MINIFY,\n\n /**\n * Purge the unused keys in a dictionaries\n *\n * Default: false\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - This option will be ignored if `editor.enabled` is true.\n */\n purge: customConfiguration?.purge ?? PURGE,\n\n /**\n * Group the per-locale dictionary chunks by the code-split boundary that uses\n * them, so a lazily loaded page fetches its content in one request.\n *\n * Default: true\n *\n * Note:\n * - Only applies to dictionaries using `importMode: 'dynamic'`.\n * - Only applies to the client build, and only when bundling (not in dev).\n */\n chunkGrouping: customConfiguration?.chunkGrouping ?? CHUNK_GROUPING,\n\n /**\n * Load a dictionary together with the chunk that uses it, instead of fetching\n * it once that chunk renders — so a reader renders synchronously rather than\n * suspending, and navigating no longer flashes a loading state.\n *\n * Default: true\n *\n * Note:\n * - Only applies to dictionaries using `importMode: 'dynamic'`.\n * - Only applies to the client build; the server keeps loading on demand.\n * - Requires a bundler supporting top-level await (Vite, esbuild).\n */\n dictionariesPreload:\n customConfiguration?.dictionariesPreload ?? DICTIONARIES_PRELOAD,\n\n /**\n * Pattern to traverse the code to optimize.\n *\n * Allows to avoid to traverse the code that is not relevant to the optimization.\n * Improve build performance.\n *\n * Default: ['**\\/*.{js,ts,mjs,cjs,jsx,tsx}', '!**\\/node_modules/**']\n *\n * Example: `['src/**\\/*.{ts,tsx}', '../ui-library/**\\/*.{ts,tsx}']`\n *\n * Note:\n * - This option will be ignored if `optimize` is disabled.\n * - Use glob pattern.\n */\n traversePattern: customConfiguration?.traversePattern ?? TRAVERSE_PATTERN,\n\n /**\n * Output format of the dictionaries\n *\n * Can be set on large projects to improve build performance.\n *\n * Default: ['cjs', 'esm']\n *\n * The output format of the dictionaries. It can be either 'cjs' or 'esm'.\n * - 'cjs': The dictionaries are outputted as CommonJS modules.\n * - 'esm': The dictionaries are outputted as ES modules.\n */\n outputFormat: customConfiguration?.outputFormat ?? OUTPUT_FORMAT,\n\n /**\n * Cache\n */\n cache: customConfiguration?.cache ?? CACHE,\n\n /**\n * Require function\n */\n require: customConfiguration?.require,\n\n /**\n * Indicates if the build should check TypeScript types\n *\n * Default: `false`\n *\n * If true, the build will check TypeScript types and log errors.\n * Note: This can slow down the build.\n */\n checkTypes: customConfiguration?.checkTypes ?? TYPE_CHECKING,\n});\n\n/**\n * Build the `compiler` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied compiler config.\n * @returns A fully-defaulted {@link CompilerConfig}.\n */\nconst buildCompilerFields = (\n customConfiguration?: Partial<CompilerConfig>\n): CompilerConfig => ({\n /**\n * Indicates if the compiler should be enabled\n */\n enabled: customConfiguration?.enabled ?? COMPILER_ENABLED,\n\n /**\n * Prefix for the extracted dictionary keys\n */\n dictionaryKeyPrefix:\n customConfiguration?.dictionaryKeyPrefix ?? COMPILER_DICTIONARY_KEY_PREFIX,\n\n /**\n * Pattern to traverse the code to optimize.\n *\n * @deprecated use `build.traversePattern` instead\n */\n transformPattern: customConfiguration?.transformPattern,\n\n /**\n * Pattern to exclude from the optimization.\n *\n * @deprecated use `build.traversePattern` instead\n */\n excludePattern: customConfiguration?.excludePattern,\n\n /**\n * Defines the output files path. Replaces `outputDir`.\n *\n * - `./` paths are resolved relative to the component directory.\n * - `/` paths are resolved relative to the project root (`baseDir`).\n *\n * - Including the `{{locale}}` variable in the path will trigger the generation of separate dictionaries per locale.\n *\n * @example:\n * ```ts\n * {\n * // Create Multilingual .content.ts files close to the component\n * output: ({ fileName, extension }) => `./${fileName}${extension}`,\n *\n * // output: './{{fileName}}{{extension}}', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create centralize per-locale JSON at the root of the project\n * output: ({ key, locale }) => `/locales/${locale}/${key}.content.json`,\n *\n * // output: '/locales/{{locale}}/{{key}}.content.json', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create per-locale JSON files with locale-specific output paths\n * output: {\n * en: ({ fileName, locale }) => `${fileName}.${locale}.content.json`,\n * fr: '{{fileName}}.{{locale}}.content.json',\n * es: false, // skip this locale\n * },\n * }\n * ```\n *\n * Variable list:\n * - `fileName`: The name of the file.\n * - `key`: The key of the content.\n * - `locale`: The locale of the content.\n * - `extension`: The extension of the file.\n * - `componentFileName`: The name of the component file.\n * - `componentExtension`: The extension of the component file.\n * - `format`: The format of the dictionary.\n * - `componentFormat`: The format of the component dictionary.\n * - `componentDirPath`: The directory path of the component.\n */\n output: customConfiguration?.output,\n\n /**\n * Indicates if the metadata should be saved in the file.\n *\n * If true, the compiler will not save the metadata of the dictionaries.\n *\n * If `true`:\n *\n * ```json\n * {\n * \"key\": \"value\"\n * }\n * ```\n *\n * If `false`:\n *\n * ```json\n * {\n * \"key\": \"value\",\n * \"content\": {\n * \"key\": \"value\"\n * }\n * }\n * ```\n *\n * Default: `false`\n *\n * Note: Useful if used with loadJSON plugin\n */\n noMetadata: customConfiguration?.noMetadata ?? COMPILER_NO_METADATA,\n\n /**\n * Indicates if the components should be saved after being transformed.\n */\n saveComponents:\n customConfiguration?.saveComponents ?? COMPILER_SAVE_COMPONENTS,\n});\n\n/**\n * Build the `dictionary` section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied dictionary config.\n * @returns A fully-defaulted {@link DictionaryConfig}.\n */\nconst buildDictionaryFields = (\n customConfiguration?: Partial<DictionaryConfig>\n): DictionaryConfig => {\n const contentAutoTransformation =\n customConfiguration?.contentAutoTransformation ??\n CONTENT_AUTO_TRANSFORMATION;\n\n return {\n /**\n * Indicate how the dictionary should be filled using AI.\n *\n * Default: `true`\n *\n * - If `true`, will consider the `compiler.output` field.\n * - If `false`, will skip the fill process.\n *\n * - `./` paths are resolved relative to the component directory.\n * - `/` paths are resolved relative to the project root (`baseDir`).\n *\n * - If includes `{{locale}}` variable in the path, will trigger the generation of separate dictionaries per locale.\n *\n * Example:\n * ```ts\n * {\n * // Create Multilingual .content.ts files close to the component\n * fill: ({ fileName, extension }) => `./${fileName}${extension}`,\n *\n * // fill: './{{fileName}}{{extension}}', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create centralize per-locale JSON at the root of the project\n * fill: ({ key, locale }) => `/locales/${locale}/${key}.content.json`,\n *\n * // fill: '/locales/{{locale}}/{{key}}.content.json', // Equivalent using template string\n * }\n * ```\n *\n * ```ts\n * {\n * // Create custom output based on the locale\n * fill: {\n * en: ({ key }) => `/locales/en/${key}.content.json`,\n * fr: '/locales/fr/{{key}}.content.json',\n * es: false,\n * de: true,\n * },\n * }\n * ```\n *\n *\n * Variable list:\n * - `fileName`: The name of the file.\n * - `key`: The key of the content.\n * - `locale`: The locale of the content.\n * - `extension`: The extension of the file.\n * - `componentFileName`: The name of the component file.\n * - `componentExtension`: The extension of the component file.\n * - `format`: The format of the dictionary.\n * - `componentFormat`: The format of the component dictionary.\n * - `componentDirPath`: The directory path of the component.\n */\n fill: customConfiguration?.fill ?? FILL,\n\n /**\n * Indicates if the content of the dictionary should be automatically transformed.\n *\n * Default: `false`\n */\n contentAutoTransformation:\n typeof contentAutoTransformation === 'object'\n ? {\n markdown: contentAutoTransformation.markdown ?? false,\n html: contentAutoTransformation.html ?? false,\n insertion: contentAutoTransformation.insertion ?? false,\n }\n : contentAutoTransformation,\n\n /**\n * The location of the dictionary.\n *\n * Default: `\"local\"`\n */\n location: customConfiguration?.location ?? LOCATION,\n\n /**\n * Transform the dictionary in a per-locale dictionary.\n * Each field declared in a per-locale dictionary will be transformed in a translation node.\n * If missing, the dictionary will be treated as a multilingual dictionary.\n */\n locale: customConfiguration?.locale,\n\n /**\n * The title of the dictionary.\n */\n title: customConfiguration?.title,\n\n /**\n * The description of the dictionary.\n */\n description: customConfiguration?.description,\n\n /**\n * Tags to categorize the dictionaries.\n */\n tags: customConfiguration?.tags,\n\n /**\n * The priority of the dictionary.\n */\n priority: customConfiguration?.priority,\n\n /**\n * Indicates the mode of import to use for the dictionary.\n *\n * Available modes:\n * - \"static\": The dictionaries are imported statically.\n * - \"dynamic\": The dictionaries are imported dynamically in a synchronous component using the suspense API.\n * - \"live\": The dictionaries are imported dynamically using the live sync API.\n *\n * Default: `\"static\"`\n */\n importMode: customConfiguration?.importMode ?? IMPORT_MODE,\n\n /**\n * The default message format for all dictionaries in the project.\n *\n * Default: 'intlayer'\n */\n format: customConfiguration?.format,\n };\n};\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Build the complete Intlayer configuration by merging user-supplied values\n * with defaults.\n *\n * Internally this function:\n * 1. Calls {@link buildBrowserConfiguration} to produce the browser-safe\n * subset (internationalization, routing, editor public fields, log, metadata).\n * 2. Extends the result with full server-side fields:\n * - `internationalization` — adds `requiredLocales` and `strictMode`.\n * - `editor` — adds `clientId` and `clientSecret`.\n * - `log` — adds custom log functions.\n * - `system`, `content`, `ai`, `build`, `compiler`, `dictionary`.\n *\n * @param customConfiguration - Optional user-supplied configuration object.\n * @param baseDir - Project root directory. Defaults to `process.cwd()`.\n * @param logFunctions - Optional custom logging functions.\n * @returns A fully-built {@link IntlayerConfig}.\n */\nexport const buildConfigurationFields = (\n customConfiguration?: CustomIntlayerConfig,\n baseDir?: string,\n logFunctions?: LogFunctions\n): IntlayerConfig => {\n if (customConfiguration) {\n const result = intlayerConfigSchema.safeParse(customConfiguration);\n\n if (!result.success) {\n const logError = logFunctions?.error ?? console.error;\n\n for (const issue of result.error.issues) {\n logError(`${issue.path.join('.')}: ${issue.message}`);\n }\n }\n }\n\n // build browser-safe config (shared defaults, no Node.js deps)\n const browserConfig = buildBrowserConfiguration(customConfiguration);\n\n // extend shared fields with server-only additions\n const internationalizationConfig = buildInternationalizationFields(\n customConfiguration?.internationalization\n );\n\n const editorConfig = buildEditorFields(customConfiguration?.editor);\n\n const logConfig = buildLogFields(customConfiguration?.log, logFunctions);\n\n // build server-only fields\n const systemConfig = buildSystemFields(baseDir, customConfiguration?.system);\n\n const contentConfig = buildContentFields(\n systemConfig,\n customConfiguration?.content\n );\n\n storedConfiguration = {\n // Shared browser fields\n routing: browserConfig.routing,\n // Full (extended) shared fields\n internationalization: internationalizationConfig,\n editor: editorConfig,\n analytics: buildAnalyticsFields(\n customConfiguration?.analytics,\n isPackageInstalled(ANALYTICS_PACKAGE_NAME, systemConfig.baseDir)\n ),\n log: logConfig,\n // Server-only fields\n system: systemConfig,\n content: contentConfig,\n ai: buildAiFields(customConfiguration?.ai),\n build: buildBuildFields(customConfiguration?.build),\n compiler: buildCompilerFields(customConfiguration?.compiler),\n dictionary: buildDictionaryFields(customConfiguration?.dictionary),\n plugins: customConfiguration?.plugins,\n schemas: customConfiguration?.schemas,\n } as IntlayerConfig;\n\n return storedConfiguration;\n};\n"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  //#region src/defaultValues/analytics.ts
2
2
  /**
3
3
  * Default values for the `analytics` configuration block.
4
- * Analytics is strictly opt-indisabled unless the user enables it.
4
+ * Analytics is opt-outenabled unless the user disables it, and only
5
+ * effective once the optional `@intlayer/analytics` package is installed.
5
6
  */
6
- const ANALYTICS_ENABLED = false;
7
+ const ANALYTICS_ENABLED = true;
7
8
  const ANALYTICS_FLUSH_INTERVAL = 2e4;
8
9
  const ANALYTICS_SAMPLE_RATE = 1;
9
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.mjs","names":[],"sources":["../../../src/defaultValues/analytics.ts"],"sourcesContent":["/**\n * Default values for the `analytics` configuration block.\n * Analytics is strictly opt-indisabled unless the user enables it.\n */\nexport const ANALYTICS_ENABLED = false;\nexport const ANALYTICS_FLUSH_INTERVAL = 20_000;\nexport const ANALYTICS_SAMPLE_RATE = 1;\n"],"mappings":";;;;;AAIA,MAAa,oBAAoB;AACjC,MAAa,2BAA2B;AACxC,MAAa,wBAAwB"}
1
+ {"version":3,"file":"analytics.mjs","names":[],"sources":["../../../src/defaultValues/analytics.ts"],"sourcesContent":["/**\n * Default values for the `analytics` configuration block.\n * Analytics is opt-outenabled unless the user disables it, and only\n * effective once the optional `@intlayer/analytics` package is installed.\n */\nexport const ANALYTICS_ENABLED = true;\nexport const ANALYTICS_FLUSH_INTERVAL = 20_000;\nexport const ANALYTICS_SAMPLE_RATE = 1;\n"],"mappings":";;;;;;AAKA,MAAa,oBAAoB;AACjC,MAAa,2BAA2B;AACxC,MAAa,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"envVars.mjs","names":[],"sources":["../../../src/envVars/envVars.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\n/**\n * Converts a camelCase node-type string to SCREAMING_SNAKE_CASE so that\n * the generated env-var name matches what the plugin source files check.\n *\n * @example\n * toScreamingSnakeCase('reactNode') // 'REACT_NODE'\n * toScreamingSnakeCase('markdown') // 'MARKDOWN'\n */\nconst toScreamingSnakeCase = (str: string): string =>\n str\n .replace(/([A-Z])/g, '_$1')\n .toUpperCase()\n .replace(/^_/, ''); // strip any leading underscore\n\n/**\n * Converts a list of unused NodeType keys into env-var definitions.\n * Set to `\"false\"` so bundlers can eliminate the corresponding plugin code.\n *\n * @example\n * formatNodeTypeToEnvVar(['enumeration'])\n * // { 'INTLAYER_NODE_TYPE_ENUMERATION': '\"false\"' }\n *\n * formatNodeTypeToEnvVar(['reactNode'], (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_NODE_TYPE_REACT_NODE': '\"false\"' }\n */\nexport const formatNodeTypeToEnvVar = (\n nodeTypes: string[],\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n nodeTypes.reduce(\n (acc, nodeType) => {\n acc[wrapKey(`INTLAYER_NODE_TYPE_${toScreamingSnakeCase(nodeType)}`)] =\n wrapValue('false');\n return acc;\n },\n {} as Record<string, string>\n );\n\n/**\n * Returns the env-var definition disabling the dictionary-selector resolution\n * path (collections, variants) when no built dictionary declares\n * a qualifier. Set to `\"false\"` so bundlers can dead-code-eliminate the\n * selector branch in `getIntlayer` / `useIntlayer`.\n *\n * Emits nothing when selectors are used, leaving the runtime default in place.\n *\n * @example\n * formatDictionarySelectorEnvVar(false)\n * // { INTLAYER_DICTIONARY_SELECTOR: '\"false\"' }\n *\n * formatDictionarySelectorEnvVar(true)\n * // {}\n *\n * formatDictionarySelectorEnvVar(false, (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_DICTIONARY_SELECTOR': '\"false\"' }\n */\nexport const formatDictionarySelectorEnvVar = (\n hasDictionarySelector: boolean,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n hasDictionarySelector\n ? {}\n : { [wrapKey('INTLAYER_DICTIONARY_SELECTOR')]: wrapValue('false') };\n\n/**\n * Returns the env-var definition selecting the local `nest()` resolver, which\n * reads the nest targets the optimizer attached to each dictionary instead of\n * looking them up in the global registry.\n *\n * Emit it only when the optimize transform actually runs, since it is that\n * transform which injects the attachment. Setting it to `\"true\"` lets bundlers\n * dead-code-eliminate the registry-based resolver, and with it the\n * `@intlayer/dictionaries-entry` import — which is what allows the dictionaries\n * entry to be emptied while nesting keeps working.\n *\n * @example\n * formatOptimizedNestingEnvVar(true)\n * // { INTLAYER_OPTIMIZED_NESTING: '\"true\"' }\n *\n * formatOptimizedNestingEnvVar(false)\n * // {}\n *\n * formatOptimizedNestingEnvVar(true, (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_OPTIMIZED_NESTING': '\"true\"' }\n */\nexport const formatOptimizedNestingEnvVar = (\n isOptimized: boolean,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n isOptimized\n ? { [wrapKey('INTLAYER_OPTIMIZED_NESTING')]: wrapValue('true') }\n : {};\n\n/**\n * Returns env-var definitions for the full Intlayer config to be injected at\n * build time. Allows bundlers to dead-code-eliminate unused routing modes,\n * rewrite logic, storage mechanisms, and editor code.\n *\n * @example\n * getConfigEnvVars(config)\n * // { INTLAYER_ROUTING_MODE: '\"prefix-no-default\"', INTLAYER_ROUTING_REWRITE_RULES: '\"false\"', ... }\n *\n * getConfigEnvVars(config, true)\n * // { 'process.env.INTLAYER_ROUTING_MODE': '\"prefix-no-default\"', ... }\n */\nexport const getConfigEnvVars = (\n config: IntlayerConfig,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> => {\n const { routing, editor, analytics } = config;\n\n const envVars: Record<string, string> = {\n [wrapKey('INTLAYER_ROUTING_MODE')]: wrapValue(routing.mode),\n };\n\n // Only the two explicit states are emitted. An absent variable means the\n // option was left unset, which `resolveProxyMode` reads as auto mode — it\n // then defers to the configuration value available at runtime.\n if (routing.enableProxy === false) {\n envVars[wrapKey('INTLAYER_ROUTING_ENABLE_PROXY')] = wrapValue('false');\n } else if (routing.enableProxy === true) {\n envVars[wrapKey('INTLAYER_ROUTING_ENABLE_PROXY')] = wrapValue('true');\n }\n\n if (!routing.rewrite) {\n envVars[wrapKey('INTLAYER_ROUTING_REWRITE_RULES')] = wrapValue('false');\n }\n\n if (!routing.domains || Object.keys(routing.domains).length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_DOMAINS')] = wrapValue('false');\n }\n\n if (!routing.storage.cookies || routing.storage.cookies.length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_COOKIES')] = wrapValue('false');\n }\n\n if (\n !routing.storage.localStorage ||\n routing.storage.localStorage.length === 0\n ) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_LOCALSTORAGE')] =\n wrapValue('false');\n }\n\n if (\n !routing.storage.sessionStorage ||\n routing.storage.sessionStorage.length === 0\n ) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_SESSIONSTORAGE')] =\n wrapValue('false');\n }\n\n if (!routing.storage.headers || routing.storage.headers.length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_HEADERS')] = wrapValue('false');\n }\n\n if (editor?.enabled === false) {\n envVars[wrapKey('INTLAYER_EDITOR_ENABLED')] = wrapValue('false');\n }\n\n // Analytics is strictly opt-in (`analytics.enabled === true`) and requires a\n // project key (`editor.clientId`) for attribution. Otherwise, disable it so\n // bundlers dead-code-eliminate the whole `@intlayer/analytics` integration\n // (providers + node plugins).\n if (analytics?.enabled !== true || !editor?.clientId) {\n envVars[wrapKey('INTLAYER_ANALYTICS_ENABLED')] = wrapValue('false');\n }\n\n return envVars;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,wBAAwB,QAC5B,IACG,QAAQ,YAAY,KAAK,CAAC,CAC1B,YAAY,CAAC,CACb,QAAQ,MAAM,EAAE;;;;;;;;;;;;AAarB,MAAa,0BACX,WACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,UAAU,QACP,KAAK,aAAa;CACjB,IAAI,QAAQ,sBAAsB,qBAAqB,QAAQ,GAAG,KAChE,UAAU,OAAO;CACnB,OAAO;AACT,GACA,CAAC,CACH;;;;;;;;;;;;;;;;;;;AAoBF,MAAa,kCACX,uBACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,wBACI,CAAC,IACD,GAAG,QAAQ,8BAA8B,IAAI,UAAU,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;AAuBtE,MAAa,gCACX,aACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,cACI,GAAG,QAAQ,4BAA4B,IAAI,UAAU,MAAM,EAAE,IAC7D,CAAC;;;;;;;;;;;;;AAcP,MAAa,oBACX,QACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UACJ;CAC3B,MAAM,EAAE,SAAS,QAAQ,cAAc;CAEvC,MAAM,UAAkC,GACrC,QAAQ,uBAAuB,IAAI,UAAU,QAAQ,IAAI,EAC5D;CAKA,IAAI,QAAQ,gBAAgB,OAC1B,QAAQ,QAAQ,+BAA+B,KAAK,UAAU,OAAO;MAChE,IAAI,QAAQ,gBAAgB,MACjC,QAAQ,QAAQ,+BAA+B,KAAK,UAAU,MAAM;CAGtE,IAAI,CAAC,QAAQ,SACX,QAAQ,QAAQ,gCAAgC,KAAK,UAAU,OAAO;CAGxE,IAAI,CAAC,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,CAAC,CAAC,WAAW,GAC9D,QAAQ,QAAQ,0BAA0B,KAAK,UAAU,OAAO;CAGlE,IAAI,CAAC,QAAQ,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,WAAW,GACjE,QAAQ,QAAQ,kCAAkC,KAAK,UAAU,OAAO;CAG1E,IACE,CAAC,QAAQ,QAAQ,gBACjB,QAAQ,QAAQ,aAAa,WAAW,GAExC,QAAQ,QAAQ,uCAAuC,KACrD,UAAU,OAAO;CAGrB,IACE,CAAC,QAAQ,QAAQ,kBACjB,QAAQ,QAAQ,eAAe,WAAW,GAE1C,QAAQ,QAAQ,yCAAyC,KACvD,UAAU,OAAO;CAGrB,IAAI,CAAC,QAAQ,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,WAAW,GACjE,QAAQ,QAAQ,kCAAkC,KAAK,UAAU,OAAO;CAG1E,IAAI,QAAQ,YAAY,OACtB,QAAQ,QAAQ,yBAAyB,KAAK,UAAU,OAAO;CAOjE,IAAI,WAAW,YAAY,QAAQ,CAAC,QAAQ,UAC1C,QAAQ,QAAQ,4BAA4B,KAAK,UAAU,OAAO;CAGpE,OAAO;AACT"}
1
+ {"version":3,"file":"envVars.mjs","names":[],"sources":["../../../src/envVars/envVars.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\n/**\n * Converts a camelCase node-type string to SCREAMING_SNAKE_CASE so that\n * the generated env-var name matches what the plugin source files check.\n *\n * @example\n * toScreamingSnakeCase('reactNode') // 'REACT_NODE'\n * toScreamingSnakeCase('markdown') // 'MARKDOWN'\n */\nconst toScreamingSnakeCase = (str: string): string =>\n str\n .replace(/([A-Z])/g, '_$1')\n .toUpperCase()\n .replace(/^_/, ''); // strip any leading underscore\n\n/**\n * Converts a list of unused NodeType keys into env-var definitions.\n * Set to `\"false\"` so bundlers can eliminate the corresponding plugin code.\n *\n * @example\n * formatNodeTypeToEnvVar(['enumeration'])\n * // { 'INTLAYER_NODE_TYPE_ENUMERATION': '\"false\"' }\n *\n * formatNodeTypeToEnvVar(['reactNode'], (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_NODE_TYPE_REACT_NODE': '\"false\"' }\n */\nexport const formatNodeTypeToEnvVar = (\n nodeTypes: string[],\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n nodeTypes.reduce(\n (acc, nodeType) => {\n acc[wrapKey(`INTLAYER_NODE_TYPE_${toScreamingSnakeCase(nodeType)}`)] =\n wrapValue('false');\n return acc;\n },\n {} as Record<string, string>\n );\n\n/**\n * Returns the env-var definition disabling the dictionary-selector resolution\n * path (collections, variants) when no built dictionary declares\n * a qualifier. Set to `\"false\"` so bundlers can dead-code-eliminate the\n * selector branch in `getIntlayer` / `useIntlayer`.\n *\n * Emits nothing when selectors are used, leaving the runtime default in place.\n *\n * @example\n * formatDictionarySelectorEnvVar(false)\n * // { INTLAYER_DICTIONARY_SELECTOR: '\"false\"' }\n *\n * formatDictionarySelectorEnvVar(true)\n * // {}\n *\n * formatDictionarySelectorEnvVar(false, (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_DICTIONARY_SELECTOR': '\"false\"' }\n */\nexport const formatDictionarySelectorEnvVar = (\n hasDictionarySelector: boolean,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n hasDictionarySelector\n ? {}\n : { [wrapKey('INTLAYER_DICTIONARY_SELECTOR')]: wrapValue('false') };\n\n/**\n * Returns the env-var definition selecting the local `nest()` resolver, which\n * reads the nest targets the optimizer attached to each dictionary instead of\n * looking them up in the global registry.\n *\n * Emit it only when the optimize transform actually runs, since it is that\n * transform which injects the attachment. Setting it to `\"true\"` lets bundlers\n * dead-code-eliminate the registry-based resolver, and with it the\n * `@intlayer/dictionaries-entry` import — which is what allows the dictionaries\n * entry to be emptied while nesting keeps working.\n *\n * @example\n * formatOptimizedNestingEnvVar(true)\n * // { INTLAYER_OPTIMIZED_NESTING: '\"true\"' }\n *\n * formatOptimizedNestingEnvVar(false)\n * // {}\n *\n * formatOptimizedNestingEnvVar(true, (k) => `process.env.${k}`, (v) => `\"${v}\"`)\n * // { 'process.env.INTLAYER_OPTIMIZED_NESTING': '\"true\"' }\n */\nexport const formatOptimizedNestingEnvVar = (\n isOptimized: boolean,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> =>\n isOptimized\n ? { [wrapKey('INTLAYER_OPTIMIZED_NESTING')]: wrapValue('true') }\n : {};\n\n/**\n * Returns env-var definitions for the full Intlayer config to be injected at\n * build time. Allows bundlers to dead-code-eliminate unused routing modes,\n * rewrite logic, storage mechanisms, and editor code.\n *\n * @example\n * getConfigEnvVars(config)\n * // { INTLAYER_ROUTING_MODE: '\"prefix-no-default\"', INTLAYER_ROUTING_REWRITE_RULES: '\"false\"', ... }\n *\n * getConfigEnvVars(config, true)\n * // { 'process.env.INTLAYER_ROUTING_MODE': '\"prefix-no-default\"', ... }\n */\nexport const getConfigEnvVars = (\n config: IntlayerConfig,\n wrapKey = (key: string) => key,\n wrapValue = (value: string) => value\n): Record<string, string> => {\n const { routing, editor, analytics } = config;\n\n const envVars: Record<string, string> = {\n [wrapKey('INTLAYER_ROUTING_MODE')]: wrapValue(routing.mode),\n };\n\n // Only the two explicit states are emitted. An absent variable means the\n // option was left unset, which `resolveProxyMode` reads as auto mode — it\n // then defers to the configuration value available at runtime.\n if (routing.enableProxy === false) {\n envVars[wrapKey('INTLAYER_ROUTING_ENABLE_PROXY')] = wrapValue('false');\n } else if (routing.enableProxy === true) {\n envVars[wrapKey('INTLAYER_ROUTING_ENABLE_PROXY')] = wrapValue('true');\n }\n\n if (!routing.rewrite) {\n envVars[wrapKey('INTLAYER_ROUTING_REWRITE_RULES')] = wrapValue('false');\n }\n\n if (!routing.domains || Object.keys(routing.domains).length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_DOMAINS')] = wrapValue('false');\n }\n\n if (!routing.storage.cookies || routing.storage.cookies.length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_COOKIES')] = wrapValue('false');\n }\n\n if (\n !routing.storage.localStorage ||\n routing.storage.localStorage.length === 0\n ) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_LOCALSTORAGE')] =\n wrapValue('false');\n }\n\n if (\n !routing.storage.sessionStorage ||\n routing.storage.sessionStorage.length === 0\n ) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_SESSIONSTORAGE')] =\n wrapValue('false');\n }\n\n if (!routing.storage.headers || routing.storage.headers.length === 0) {\n envVars[wrapKey('INTLAYER_ROUTING_STORAGE_HEADERS')] = wrapValue('false');\n }\n\n if (editor?.enabled === false) {\n envVars[wrapKey('INTLAYER_EDITOR_ENABLED')] = wrapValue('false');\n }\n\n // Analytics is opt-out: `analytics.enabled` defaults to `true` and is\n // resolved to `false` when the optional `@intlayer/analytics` package is not\n // installed. It also requires a project key (`editor.clientId`) for\n // attribution. Otherwise, disable it so bundlers dead-code-eliminate the\n // whole `@intlayer/analytics` integration (providers + node plugins).\n if (analytics?.enabled !== true || !editor?.clientId) {\n envVars[wrapKey('INTLAYER_ANALYTICS_ENABLED')] = wrapValue('false');\n }\n\n return envVars;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,wBAAwB,QAC5B,IACG,QAAQ,YAAY,KAAK,CAAC,CAC1B,YAAY,CAAC,CACb,QAAQ,MAAM,EAAE;;;;;;;;;;;;AAarB,MAAa,0BACX,WACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,UAAU,QACP,KAAK,aAAa;CACjB,IAAI,QAAQ,sBAAsB,qBAAqB,QAAQ,GAAG,KAChE,UAAU,OAAO;CACnB,OAAO;AACT,GACA,CAAC,CACH;;;;;;;;;;;;;;;;;;;AAoBF,MAAa,kCACX,uBACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,wBACI,CAAC,IACD,GAAG,QAAQ,8BAA8B,IAAI,UAAU,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;AAuBtE,MAAa,gCACX,aACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UAE/B,cACI,GAAG,QAAQ,4BAA4B,IAAI,UAAU,MAAM,EAAE,IAC7D,CAAC;;;;;;;;;;;;;AAcP,MAAa,oBACX,QACA,WAAW,QAAgB,KAC3B,aAAa,UAAkB,UACJ;CAC3B,MAAM,EAAE,SAAS,QAAQ,cAAc;CAEvC,MAAM,UAAkC,GACrC,QAAQ,uBAAuB,IAAI,UAAU,QAAQ,IAAI,EAC5D;CAKA,IAAI,QAAQ,gBAAgB,OAC1B,QAAQ,QAAQ,+BAA+B,KAAK,UAAU,OAAO;MAChE,IAAI,QAAQ,gBAAgB,MACjC,QAAQ,QAAQ,+BAA+B,KAAK,UAAU,MAAM;CAGtE,IAAI,CAAC,QAAQ,SACX,QAAQ,QAAQ,gCAAgC,KAAK,UAAU,OAAO;CAGxE,IAAI,CAAC,QAAQ,WAAW,OAAO,KAAK,QAAQ,OAAO,CAAC,CAAC,WAAW,GAC9D,QAAQ,QAAQ,0BAA0B,KAAK,UAAU,OAAO;CAGlE,IAAI,CAAC,QAAQ,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,WAAW,GACjE,QAAQ,QAAQ,kCAAkC,KAAK,UAAU,OAAO;CAG1E,IACE,CAAC,QAAQ,QAAQ,gBACjB,QAAQ,QAAQ,aAAa,WAAW,GAExC,QAAQ,QAAQ,uCAAuC,KACrD,UAAU,OAAO;CAGrB,IACE,CAAC,QAAQ,QAAQ,kBACjB,QAAQ,QAAQ,eAAe,WAAW,GAE1C,QAAQ,QAAQ,yCAAyC,KACvD,UAAU,OAAO;CAGrB,IAAI,CAAC,QAAQ,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,WAAW,GACjE,QAAQ,QAAQ,kCAAkC,KAAK,UAAU,OAAO;CAG1E,IAAI,QAAQ,YAAY,OACtB,QAAQ,QAAQ,yBAAyB,KAAK,UAAU,OAAO;CAQjE,IAAI,WAAW,YAAY,QAAQ,CAAC,QAAQ,UAC1C,QAAQ,QAAQ,4BAA4B,KAAK,UAAU,OAAO;CAGpE,OAAO;AACT"}
@@ -0,0 +1,20 @@
1
+ //#region src/secrets.browser.ts
2
+ /**
3
+ * Browser stub for {@link file://./secrets.ts}.
4
+ *
5
+ * Selected through the `browser` export condition of
6
+ * `@intlayer/config/secrets`, so a client bundle resolves the credential
7
+ * accessor to an inert function instead of pulling the configuration loader —
8
+ * and the secret itself — into a public asset.
9
+ */
10
+ /**
11
+ * Always `undefined` in the browser: the CMS client secret grants project-wide
12
+ * API access and must never leave the server.
13
+ *
14
+ * @returns `undefined`.
15
+ */
16
+ const getEditorClientSecret = () => void 0;
17
+
18
+ //#endregion
19
+ export { getEditorClientSecret };
20
+ //# sourceMappingURL=secrets.browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.browser.mjs","names":[],"sources":["../../src/secrets.browser.ts"],"sourcesContent":["/**\n * Browser stub for {@link file://./secrets.ts}.\n *\n * Selected through the `browser` export condition of\n * `@intlayer/config/secrets`, so a client bundle resolves the credential\n * accessor to an inert function instead of pulling the configuration loader —\n * and the secret itself — into a public asset.\n */\n\n/**\n * Always `undefined` in the browser: the CMS client secret grants project-wide\n * API access and must never leave the server.\n *\n * @returns `undefined`.\n */\nexport const getEditorClientSecret = (): string | undefined => undefined;\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,8BAAkD"}
@@ -0,0 +1,46 @@
1
+ //#region src/secrets.ts
2
+ /**
3
+ * Server-only access to the sensitive parts of the Intlayer configuration.
4
+ *
5
+ * `@intlayer/config/built` is aliased by every framework integration to a
6
+ * generated file that the bundle **inlines**, and the same alias is installed
7
+ * for the client and the server build. Anything it carries that browser code
8
+ * imports therefore ends up in a public asset, which is why the generated file
9
+ * never contains `editor.clientSecret`.
10
+ *
11
+ * This module is the server-side counterpart. It is deliberately *not* aliased:
12
+ * it resolves through the package's export map, whose `browser` condition
13
+ * points at {@link file://./secrets.browser.ts} — an inert stub. Every
14
+ * major bundler (webpack, Rspack, Turbopack, Vite, Rollup, esbuild, Metro)
15
+ * honours that condition, so a browser build resolves to the stub without any
16
+ * integration-specific configuration.
17
+ *
18
+ * It intentionally imports nothing: pulling the configuration loader in here
19
+ * would drag the whole resolved configuration — and the machinery that builds
20
+ * it — into every server bundle that touches a credentialed API.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { getEditorClientSecret } from '@intlayer/config/secrets';
25
+ *
26
+ * const clientSecret = config.editor.clientSecret ?? getEditorClientSecret();
27
+ * ```
28
+ */
29
+ /**
30
+ * Returns the CMS client secret from the environment, or `undefined` when it is
31
+ * not set.
32
+ *
33
+ * The configuration file stays the source of truth for *whether* credentials
34
+ * are active — a project opts in by wiring `clientId` (conventionally
35
+ * `clientId: process.env.INTLAYER_CLIENT_ID`), and callers gate on the public
36
+ * `editor.clientId` from `@intlayer/config/built` before asking for the secret.
37
+ * This function only supplies the confidential half, which the generated
38
+ * configuration deliberately does not carry.
39
+ *
40
+ * @returns The OAuth2 client secret, or `undefined`.
41
+ */
42
+ const getEditorClientSecret = () => typeof process === "undefined" ? void 0 : process.env?.INTLAYER_CLIENT_SECRET;
43
+
44
+ //#endregion
45
+ export { getEditorClientSecret };
46
+ //# sourceMappingURL=secrets.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.mjs","names":[],"sources":["../../src/secrets.ts"],"sourcesContent":["/**\n * Server-only access to the sensitive parts of the Intlayer configuration.\n *\n * `@intlayer/config/built` is aliased by every framework integration to a\n * generated file that the bundle **inlines**, and the same alias is installed\n * for the client and the server build. Anything it carries that browser code\n * imports therefore ends up in a public asset, which is why the generated file\n * never contains `editor.clientSecret`.\n *\n * This module is the server-side counterpart. It is deliberately *not* aliased:\n * it resolves through the package's export map, whose `browser` condition\n * points at {@link file://./secrets.browser.ts} — an inert stub. Every\n * major bundler (webpack, Rspack, Turbopack, Vite, Rollup, esbuild, Metro)\n * honours that condition, so a browser build resolves to the stub without any\n * integration-specific configuration.\n *\n * It intentionally imports nothing: pulling the configuration loader in here\n * would drag the whole resolved configuration — and the machinery that builds\n * it — into every server bundle that touches a credentialed API.\n *\n * @example\n * ```ts\n * import { getEditorClientSecret } from '@intlayer/config/secrets';\n *\n * const clientSecret = config.editor.clientSecret ?? getEditorClientSecret();\n * ```\n */\n\n/**\n * Returns the CMS client secret from the environment, or `undefined` when it is\n * not set.\n *\n * The configuration file stays the source of truth for *whether* credentials\n * are active — a project opts in by wiring `clientId` (conventionally\n * `clientId: process.env.INTLAYER_CLIENT_ID`), and callers gate on the public\n * `editor.clientId` from `@intlayer/config/built` before asking for the secret.\n * This function only supplies the confidential half, which the generated\n * configuration deliberately does not carry.\n *\n * @returns The OAuth2 client secret, or `undefined`.\n */\nexport const getEditorClientSecret = (): string | undefined =>\n typeof process === 'undefined'\n ? undefined\n : process.env?.INTLAYER_CLIENT_SECRET;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAa,8BACX,OAAO,YAAY,cACf,SACA,QAAQ,KAAK"}
@@ -12,6 +12,7 @@ import { extractErrorMessage } from "./extractErrorMessage.mjs";
12
12
  import { getHasDictionarySelector } from "./getDictionarySelectorUsage.mjs";
13
13
  import { getStorageAttributes } from "./getStorageAttributes.mjs";
14
14
  import { getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync } from "./getUsedNodeTypes.mjs";
15
+ import { isPackageInstalled } from "./isPackageInstalled.mjs";
15
16
  import { logStack } from "./logStack.mjs";
16
17
  import { parseFilePathPattern, parseStringPattern } from "./parseFilePathPattern.mjs";
17
18
  import { assertPathWithin } from "./pathSecurity.mjs";
@@ -22,4 +23,4 @@ import { camelCaseToSentence } from "./stringFormatter/camelCaseToSentence.mjs";
22
23
  import { kebabCaseToCamelCase } from "./stringFormatter/kebabCaseToCamelCase.mjs";
23
24
  import { toLowerCamelCase } from "./stringFormatter/toLowerCamelCase.mjs";
24
25
 
25
- export { BUILT_CONFIG_KEYS, assertPathWithin, cacheDisk, cacheMemory, camelCaseToKebabCase, camelCaseToSentence, clearAllCache, clearCache, clearDiskCacheMemory, clearModuleCache, compareVersions, computeKeyId, configESMxCJSRequire, extractErrorMessage, getAlias, getCache, getExtension, getHasDictionarySelector, getPackageJsonPath, getProjectRequire, getStorageAttributes, getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync, isESModule, kebabCaseToCamelCase, logStack, normalizePath, parseFilePathPattern, parseStringPattern, retryManager, setCache, setIntlayerIdentifier, stableStringify, toLowerCamelCase };
26
+ export { BUILT_CONFIG_KEYS, assertPathWithin, cacheDisk, cacheMemory, camelCaseToKebabCase, camelCaseToSentence, clearAllCache, clearCache, clearDiskCacheMemory, clearModuleCache, compareVersions, computeKeyId, configESMxCJSRequire, extractErrorMessage, getAlias, getCache, getExtension, getHasDictionarySelector, getPackageJsonPath, getProjectRequire, getStorageAttributes, getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync, isESModule, isPackageInstalled, kebabCaseToCamelCase, logStack, normalizePath, parseFilePathPattern, parseStringPattern, retryManager, setCache, setIntlayerIdentifier, stableStringify, toLowerCamelCase };
@@ -0,0 +1,38 @@
1
+ import { getProjectRequire } from "./ESMxCJSHelpers.mjs";
2
+
3
+ //#region src/utils/isPackageInstalled.ts
4
+ /**
5
+ * Checks whether a package can be resolved from the user project.
6
+ *
7
+ * Used to detect optional companion packages (e.g. `@intlayer/analytics`)
8
+ * whose mere presence in the dependency tree opts the project into a feature.
9
+ *
10
+ * Resolution is attempted on the package manifest first, so packages that
11
+ * expose no root entry point — or whose entry point cannot be loaded in the
12
+ * current module format — are still detected.
13
+ *
14
+ * Note: resolution starts at the project root, so a package installed only as
15
+ * a transitive dependency may stay invisible under strict package managers
16
+ * (pnpm). Callers should treat a `false` result as a default, not as a veto.
17
+ *
18
+ * @param packageName - Name of the package to look up, e.g. `'@intlayer/analytics'`.
19
+ * @param baseDir - Directory the resolution starts from. Defaults to the current working directory.
20
+ * @returns `true` when the package is installed in the project, `false` otherwise.
21
+ */
22
+ const isPackageInstalled = (packageName, baseDir) => {
23
+ try {
24
+ const projectRequire = getProjectRequire(baseDir);
25
+ try {
26
+ projectRequire.resolve(`${packageName}/package.json`);
27
+ } catch {
28
+ projectRequire.resolve(packageName);
29
+ }
30
+ return true;
31
+ } catch {
32
+ return false;
33
+ }
34
+ };
35
+
36
+ //#endregion
37
+ export { isPackageInstalled };
38
+ //# sourceMappingURL=isPackageInstalled.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isPackageInstalled.mjs","names":[],"sources":["../../../src/utils/isPackageInstalled.ts"],"sourcesContent":["import { getProjectRequire } from './ESMxCJSHelpers';\n\n/**\n * Checks whether a package can be resolved from the user project.\n *\n * Used to detect optional companion packages (e.g. `@intlayer/analytics`)\n * whose mere presence in the dependency tree opts the project into a feature.\n *\n * Resolution is attempted on the package manifest first, so packages that\n * expose no root entry point — or whose entry point cannot be loaded in the\n * current module format — are still detected.\n *\n * Note: resolution starts at the project root, so a package installed only as\n * a transitive dependency may stay invisible under strict package managers\n * (pnpm). Callers should treat a `false` result as a default, not as a veto.\n *\n * @param packageName - Name of the package to look up, e.g. `'@intlayer/analytics'`.\n * @param baseDir - Directory the resolution starts from. Defaults to the current working directory.\n * @returns `true` when the package is installed in the project, `false` otherwise.\n */\nexport const isPackageInstalled = (\n packageName: string,\n baseDir?: string\n): boolean => {\n try {\n const projectRequire = getProjectRequire(baseDir);\n\n try {\n projectRequire.resolve(`${packageName}/package.json`);\n } catch {\n projectRequire.resolve(packageName);\n }\n\n return true;\n } catch {\n return false;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,sBACX,aACA,YACY;CACZ,IAAI;EACF,MAAM,iBAAiB,kBAAkB,OAAO;EAEhD,IAAI;GACF,eAAe,QAAQ,GAAG,YAAY,cAAc;EACtD,QAAQ;GACN,eAAe,QAAQ,WAAW;EACpC;EAEA,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -4,13 +4,18 @@ import { AnalyticsConfig, CustomIntlayerConfig, CustomRoutingConfig, EditorConfi
4
4
  * Browser-safe subset of {@link IntlayerConfig}.
5
5
  *
6
6
  * Excludes server-only fields (`system`, `content`, `build`, `compiler`,
7
- * `dictionary`, `ai`) and sensitive editor credentials (`clientId`,
8
- * `clientSecret`) that must never be shipped to the browser.
7
+ * `dictionary`, `ai`) and the `editor.clientSecret`, which must never be
8
+ * shipped to the browser.
9
+ *
10
+ * `editor.clientId` is kept: it is the **public** project key, used by
11
+ * `@intlayer/analytics` to identify the project when exchanging it for a
12
+ * short-lived ingest token. It grants nothing on its own — every credentialed
13
+ * backend call needs the secret, which only ever exists server-side.
9
14
  */
10
15
  type BrowserIntlayerConfig = {
11
16
  internationalization: Pick<InternationalizationConfig, 'locales' | 'defaultLocale'>;
12
17
  routing: RoutingConfig;
13
- editor: Omit<EditorConfig, 'clientId' | 'clientSecret'>;
18
+ editor: Omit<EditorConfig, 'clientSecret'>;
14
19
  analytics: AnalyticsConfig;
15
20
  log: Pick<LogConfig, 'mode' | 'prefix'>;
16
21
  };
@@ -56,14 +61,21 @@ declare const buildEditorFields: (customConfiguration?: Partial<EditorConfig>) =
56
61
  /**
57
62
  * Build the analytics section of the Intlayer configuration.
58
63
  *
59
- * Analytics is strictly opt-in: `enabled` defaults to `false` and, even when
60
- * enabled, the runtime additionally requires a project key (`editor.clientId`)
61
- * for attribution before collecting anything.
64
+ * Analytics is opt-out: `enabled` defaults to `true`, so installing the
65
+ * optional `@intlayer/analytics` package is enough to turn it on. The runtime
66
+ * additionally requires a project key (`editor.clientId`) for attribution
67
+ * before collecting anything.
68
+ *
69
+ * An explicit `enabled` value always wins, so a project whose package manager
70
+ * hides the package from the project root can still opt back in.
62
71
  *
63
72
  * @param customConfiguration - Partial user-supplied analytics config.
73
+ * @param isPackageInstalled - Whether `@intlayer/analytics` is installed in the
74
+ * project. Browser callers cannot resolve packages and pass `true`, letting
75
+ * the runtime dynamic `import()` fail silently when it is absent.
64
76
  * @returns A fully-defaulted {@link AnalyticsConfig}.
65
77
  */
66
- declare const buildAnalyticsFields: (customConfiguration?: Partial<AnalyticsConfig>) => AnalyticsConfig;
78
+ declare const buildAnalyticsFields: (customConfiguration?: Partial<AnalyticsConfig>, isPackageInstalled?: boolean) => AnalyticsConfig;
67
79
  /**
68
80
  * Build the log section of the Intlayer configuration.
69
81
  *
@@ -77,7 +89,8 @@ declare const buildLogFields: (customConfiguration?: Partial<LogConfig>, logFunc
77
89
  *
78
90
  * Applies defaults for every field and strips all server-only or sensitive
79
91
  * information (`system`, `content`, `build`, `compiler`, `dictionary`, `ai`,
80
- * `editor.clientId`, `editor.clientSecret`).
92
+ * `editor.clientSecret`). The public `editor.clientId` is kept — see
93
+ * {@link BrowserIntlayerConfig}.
81
94
  *
82
95
  * This is the browser counterpart of `buildConfigurationFields`. It is safe
83
96
  * to call in browser environments because it has no Node.js dependencies.
@@ -1 +1 @@
1
- {"version":3,"file":"buildBrowserConfiguration.d.ts","names":[],"sources":["../../../src/configFile/buildBrowserConfiguration.ts"],"mappings":";;;;;;;;;KAqDY;EACV,sBAAsB,KACpB;EAGF,SAAS;EACT,QAAQ,KAAK;EACb,WAAW;EACX,KAAK,KAAK;;QAGJ;YACI;;IAER,kBAAkB;;;;;;;;;cAiBT,kCAA+B,sBACpB,QAAQ,gCAC7B;;;;;;;cA+CU,qBAAkB,sBACP,QAAQ,yBAC7B;;;;;;;;;;;;;;;;;;;cA4HU,oBAAiB,sBACN,QAAQ,kBAC7B;;;;;;;;;;;cAsIU,uBAAoB,sBACT,QAAQ,qBAC7B;;;;;;;;cA8BU,iBAAc,sBACH,QAAQ,YAAU,eACzB,iBACd;;;;;;;;;;;;;;;;;;;;;;;cAwDU,4BAAyB,eACrB,yBACd;;;;;;;;;;;;cAiCU,8BAA2B,QAC9B,mBACP"}
1
+ {"version":3,"file":"buildBrowserConfiguration.d.ts","names":[],"sources":["../../../src/configFile/buildBrowserConfiguration.ts"],"mappings":";;;;;;;;;;;;;;KA0DY;EACV,sBAAsB,KACpB;EAGF,SAAS;EACT,QAAQ,KAAK;EACb,WAAW;EACX,KAAK,KAAK;;QAGJ;YACI;;IAER,kBAAkB;;;;;;;;;cAiBT,kCAA+B,sBACpB,QAAQ,gCAC7B;;;;;;;cA+CU,qBAAkB,sBACP,QAAQ,yBAC7B;;;;;;;;;;;;;;;;;;;cA4HU,oBAAiB,sBACN,QAAQ,kBAC7B;;;;;;;;;;;;;;;;;;cA6IU,uBAAoB,sBACT,QAAQ,kBAAgB,iCAE7C;;;;;;;;cA+BU,iBAAc,sBACH,QAAQ,YAAU,eACzB,iBACd;;;;;;;;;;;;;;;;;;;;;;;;cAyDU,4BAAyB,eACrB,yBACd;;;;;;;;;;;;cA+BU,8BAA2B,QAC9B,mBACP"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildConfigurationFields.d.ts","names":[],"sources":["../../../src/configFile/buildConfigurationFields.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;cAywBa,2BAAwB,sBACb,sBAAoB,kBAC1B,eACD,iBACd"}
1
+ {"version":3,"file":"buildConfigurationFields.d.ts","names":[],"sources":["../../../src/configFile/buildConfigurationFields.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;cA+wBa,2BAAwB,sBACb,sBAAoB,kBAC1B,eACD,iBACd"}
@@ -1,9 +1,10 @@
1
1
  //#region src/defaultValues/analytics.d.ts
2
2
  /**
3
3
  * Default values for the `analytics` configuration block.
4
- * Analytics is strictly opt-indisabled unless the user enables it.
4
+ * Analytics is opt-outenabled unless the user disables it, and only
5
+ * effective once the optional `@intlayer/analytics` package is installed.
5
6
  */
6
- declare const ANALYTICS_ENABLED = false;
7
+ declare const ANALYTICS_ENABLED = true;
7
8
  declare const ANALYTICS_FLUSH_INTERVAL = 20000;
8
9
  declare const ANALYTICS_SAMPLE_RATE = 1;
9
10
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","names":[],"sources":["../../../src/defaultValues/analytics.ts"],"mappings":";;;;;cAIa;cACA;cACA"}
1
+ {"version":3,"file":"analytics.d.ts","names":[],"sources":["../../../src/defaultValues/analytics.ts"],"mappings":";;;;;;cAKa;cACA;cACA"}
@@ -0,0 +1,19 @@
1
+ //#region src/secrets.browser.d.ts
2
+ /**
3
+ * Browser stub for {@link file://./secrets.ts}.
4
+ *
5
+ * Selected through the `browser` export condition of
6
+ * `@intlayer/config/secrets`, so a client bundle resolves the credential
7
+ * accessor to an inert function instead of pulling the configuration loader —
8
+ * and the secret itself — into a public asset.
9
+ */
10
+ /**
11
+ * Always `undefined` in the browser: the CMS client secret grants project-wide
12
+ * API access and must never leave the server.
13
+ *
14
+ * @returns `undefined`.
15
+ */
16
+ declare const getEditorClientSecret: () => string | undefined;
17
+ //#endregion
18
+ export { getEditorClientSecret };
19
+ //# sourceMappingURL=secrets.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.browser.d.ts","names":[],"sources":["../../src/secrets.browser.ts"],"mappings":";;;;;;;;;;;;;;;cAea"}
@@ -0,0 +1,45 @@
1
+ //#region src/secrets.d.ts
2
+ /**
3
+ * Server-only access to the sensitive parts of the Intlayer configuration.
4
+ *
5
+ * `@intlayer/config/built` is aliased by every framework integration to a
6
+ * generated file that the bundle **inlines**, and the same alias is installed
7
+ * for the client and the server build. Anything it carries that browser code
8
+ * imports therefore ends up in a public asset, which is why the generated file
9
+ * never contains `editor.clientSecret`.
10
+ *
11
+ * This module is the server-side counterpart. It is deliberately *not* aliased:
12
+ * it resolves through the package's export map, whose `browser` condition
13
+ * points at {@link file://./secrets.browser.ts} — an inert stub. Every
14
+ * major bundler (webpack, Rspack, Turbopack, Vite, Rollup, esbuild, Metro)
15
+ * honours that condition, so a browser build resolves to the stub without any
16
+ * integration-specific configuration.
17
+ *
18
+ * It intentionally imports nothing: pulling the configuration loader in here
19
+ * would drag the whole resolved configuration — and the machinery that builds
20
+ * it — into every server bundle that touches a credentialed API.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { getEditorClientSecret } from '@intlayer/config/secrets';
25
+ *
26
+ * const clientSecret = config.editor.clientSecret ?? getEditorClientSecret();
27
+ * ```
28
+ */
29
+ /**
30
+ * Returns the CMS client secret from the environment, or `undefined` when it is
31
+ * not set.
32
+ *
33
+ * The configuration file stays the source of truth for *whether* credentials
34
+ * are active — a project opts in by wiring `clientId` (conventionally
35
+ * `clientId: process.env.INTLAYER_CLIENT_ID`), and callers gate on the public
36
+ * `editor.clientId` from `@intlayer/config/built` before asking for the secret.
37
+ * This function only supplies the confidential half, which the generated
38
+ * configuration deliberately does not carry.
39
+ *
40
+ * @returns The OAuth2 client secret, or `undefined`.
41
+ */
42
+ declare const getEditorClientSecret: () => string | undefined;
43
+ //#endregion
44
+ export { getEditorClientSecret };
45
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","names":[],"sources":["../../src/secrets.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAyCa"}
@@ -18,7 +18,8 @@ import { getExtension } from "./getExtension.js";
18
18
  import { getPackageJsonPath } from "./getPackageJsonPath.js";
19
19
  import { getStorageAttributes } from "./getStorageAttributes.js";
20
20
  import { PluginNodeType, getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync } from "./getUsedNodeTypes.js";
21
+ import { isPackageInstalled } from "./isPackageInstalled.js";
21
22
  import { parseFilePathPattern, parseStringPattern } from "./parseFilePathPattern.js";
22
23
  import { assertPathWithin } from "./pathSecurity.js";
23
24
  import { RetryManagerOptions, retryManager } from "./retryManager.js";
24
- export { BUILT_CONFIG_KEYS, BuiltConfigKey, CacheKey, GetAliasOptions, PluginNodeType, RetryManagerOptions, WindowsWithIntlayer, assertPathWithin, cacheDisk, cacheMemory, camelCaseToKebabCase, camelCaseToSentence, clearAllCache, clearCache, clearDiskCacheMemory, clearModuleCache, compareVersions, computeKeyId, configESMxCJSRequire, extractErrorMessage, getAlias, getCache, getExtension, getHasDictionarySelector, getPackageJsonPath, getProjectRequire, getStorageAttributes, getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync, isESModule, kebabCaseToCamelCase, logStack, normalizePath, parseFilePathPattern, parseStringPattern, retryManager, setCache, setIntlayerIdentifier, stableStringify, toLowerCamelCase };
25
+ export { BUILT_CONFIG_KEYS, BuiltConfigKey, CacheKey, GetAliasOptions, PluginNodeType, RetryManagerOptions, WindowsWithIntlayer, assertPathWithin, cacheDisk, cacheMemory, camelCaseToKebabCase, camelCaseToSentence, clearAllCache, clearCache, clearDiskCacheMemory, clearModuleCache, compareVersions, computeKeyId, configESMxCJSRequire, extractErrorMessage, getAlias, getCache, getExtension, getHasDictionarySelector, getPackageJsonPath, getProjectRequire, getStorageAttributes, getUnusedNodeTypes, getUnusedNodeTypesAsync, getUsedNodeTypes, getUsedNodeTypesAsync, isESModule, isPackageInstalled, kebabCaseToCamelCase, logStack, normalizePath, parseFilePathPattern, parseStringPattern, retryManager, setCache, setIntlayerIdentifier, stableStringify, toLowerCamelCase };
@@ -0,0 +1,23 @@
1
+ //#region src/utils/isPackageInstalled.d.ts
2
+ /**
3
+ * Checks whether a package can be resolved from the user project.
4
+ *
5
+ * Used to detect optional companion packages (e.g. `@intlayer/analytics`)
6
+ * whose mere presence in the dependency tree opts the project into a feature.
7
+ *
8
+ * Resolution is attempted on the package manifest first, so packages that
9
+ * expose no root entry point — or whose entry point cannot be loaded in the
10
+ * current module format — are still detected.
11
+ *
12
+ * Note: resolution starts at the project root, so a package installed only as
13
+ * a transitive dependency may stay invisible under strict package managers
14
+ * (pnpm). Callers should treat a `false` result as a default, not as a veto.
15
+ *
16
+ * @param packageName - Name of the package to look up, e.g. `'@intlayer/analytics'`.
17
+ * @param baseDir - Directory the resolution starts from. Defaults to the current working directory.
18
+ * @returns `true` when the package is installed in the project, `false` otherwise.
19
+ */
20
+ declare const isPackageInstalled: (packageName: string, baseDir?: string) => boolean;
21
+ //#endregion
22
+ export { isPackageInstalled };
23
+ //# sourceMappingURL=isPackageInstalled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isPackageInstalled.d.ts","names":[],"sources":["../../../src/utils/isPackageInstalled.ts"],"mappings":";;;;;;;;;;;;;;;;;;;cAoBa,qBAAkB,qBACV"}