@intlayer/engine 9.0.0-canary.14 → 9.0.0-canary.16
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.
- package/dist/cjs/cli.cjs +1 -0
- package/dist/cjs/init/index.cjs +8 -6
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/init/utils/configManipulation.cjs +39 -5
- package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
- package/dist/cjs/init/utils/githubActions.cjs +133 -18
- package/dist/cjs/init/utils/githubActions.cjs.map +1 -1
- package/dist/cjs/init/utils/index.cjs +3 -1
- package/dist/cjs/init/utils/packageManager.cjs +8 -0
- package/dist/cjs/init/utils/packageManager.cjs.map +1 -1
- package/dist/cjs/listProjects.cjs +3 -1
- package/dist/cjs/listProjects.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs +4 -2
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs.map +1 -1
- package/dist/esm/cli.mjs +2 -2
- package/dist/esm/init/index.mjs +10 -8
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/init/utils/configManipulation.mjs +39 -6
- package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
- package/dist/esm/init/utils/githubActions.mjs +133 -19
- package/dist/esm/init/utils/githubActions.mjs.map +1 -1
- package/dist/esm/init/utils/index.mjs +4 -4
- package/dist/esm/init/utils/packageManager.mjs +8 -0
- package/dist/esm/init/utils/packageManager.mjs.map +1 -1
- package/dist/esm/listProjects.mjs +3 -2
- package/dist/esm/listProjects.mjs.map +1 -1
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs +4 -2
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs.map +1 -1
- package/dist/types/cli.d.ts +2 -2
- package/dist/types/init/index.d.ts.map +1 -1
- package/dist/types/init/utils/configManipulation.d.ts +9 -1
- package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
- package/dist/types/init/utils/githubActions.d.ts +57 -3
- package/dist/types/init/utils/githubActions.d.ts.map +1 -1
- package/dist/types/init/utils/index.d.ts +3 -3
- package/dist/types/init/utils/packageManager.d.ts.map +1 -1
- package/dist/types/listProjects.d.ts +6 -1
- package/dist/types/listProjects.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ensureNamedImport, firstInsertIndex, isModuleScopeBinding } from "./astImports.mjs";
|
|
2
|
-
import { enableIntlayerEditorConfig, getMetroConfigTemplate, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.mjs";
|
|
2
|
+
import { enableIntlayerEditorConfig, getMetroConfigTemplate, hasIntlayerVitePlugin, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.mjs";
|
|
3
3
|
import { detectJsonLocalePattern, detectLinguiCatalogPattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.mjs";
|
|
4
4
|
import { isVersionAtLeast } from "./version.mjs";
|
|
5
|
-
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows } from "./githubActions.mjs";
|
|
6
|
-
import { parseJSONWithComments } from "./jsonParser.mjs";
|
|
7
5
|
import { detectMissingIntlayerPackages, detectOutdatedIntlayerPackages, detectPackageManager, getInstalledPackageVersion, installPackages, isIntlayerPackageName, normalizeVersion, upgradePackages } from "./packageManager.mjs";
|
|
6
|
+
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows, resolveGithubWorkflowsContext } from "./githubActions.mjs";
|
|
7
|
+
import { parseJSONWithComments } from "./jsonParser.mjs";
|
|
8
8
|
import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, setupNextCompilerBabelConfig } from "./nextCompilerBabel.mjs";
|
|
9
9
|
import { findTsConfigFiles } from "./tsConfig.mjs";
|
|
10
10
|
|
|
11
|
-
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
11
|
+
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, resolveGithubWorkflowsContext, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
@@ -83,6 +83,10 @@ const detectMissingIntlayerPackages = (allDependencies, options = {}) => {
|
|
|
83
83
|
format: "i18next",
|
|
84
84
|
sourceTemplate: "./src/locales/${locale}/${key}.json"
|
|
85
85
|
};
|
|
86
|
+
if (!isInstalled("react-i18next") && !isInstalled("@intlayer/react-i18next")) compatVitePluginConfig ??= {
|
|
87
|
+
pluginFunctionName: "i18nextVitePlugin",
|
|
88
|
+
pluginPackageSource: "@intlayer/i18next/plugin"
|
|
89
|
+
};
|
|
86
90
|
}
|
|
87
91
|
if (isInstalled("react-i18next") || isInstalled("@intlayer/react-i18next")) {
|
|
88
92
|
addIfMissing("@intlayer/react-i18next");
|
|
@@ -91,6 +95,10 @@ const detectMissingIntlayerPackages = (allDependencies, options = {}) => {
|
|
|
91
95
|
format: "i18next",
|
|
92
96
|
sourceTemplate: "./src/locales/${locale}/${key}.json"
|
|
93
97
|
};
|
|
98
|
+
compatVitePluginConfig ??= {
|
|
99
|
+
pluginFunctionName: "reactI18nextVitePlugin",
|
|
100
|
+
pluginPackageSource: "@intlayer/react-i18next/plugin"
|
|
101
|
+
};
|
|
94
102
|
}
|
|
95
103
|
if (isInstalled("vue-i18n") || isInstalled("@intlayer/vue-i18n")) {
|
|
96
104
|
addIfMissing("@intlayer/vue-i18n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageManager.mjs","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { compareVersions } from '@intlayer/config/utils';\n\n/** Package managers supported for dependency installation. */\nexport type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';\n\n/**\n * Configuration for the syncJSON plugin injected into intlayer.config\n * when a compat i18n library is detected.\n */\nexport type CompatSyncConfig = {\n /**\n * Which sync plugin ingests the catalogs:\n * - `'json'` → `syncJSON` from `@intlayer/sync-json-plugin` (default).\n * - `'po'` → `syncPO` from `@intlayer/sync-po-plugin` (lingui's default\n * format).\n */\n plugin?: 'json' | 'po';\n /**\n * JSON format matching the compat library's conventions. Ignored when\n * `plugin` is `'po'` (PO catalogs are always serialized as gettext).\n */\n format: 'icu' | 'i18next' | 'vue-i18n';\n /**\n * Source path template using ${locale} and ${key} placeholders.\n * Rendered as a template literal in the generated config.\n */\n sourceTemplate: string;\n /**\n * Force `splitKeys: true` in the generated `syncJSON(...)` call so each\n * top-level key of a single per-locale file becomes its own dictionary.\n *\n * Set for libraries whose single `messages/${locale}.json` file groups\n * namespaces by its first-level keys (`next-intl` / `use-intl`, where\n * `useTranslations('Hero')` resolves to the `Hero` dictionary). Left\n * undefined for libraries whose top-level keys are plain message keys\n * (e.g. `i18next`, `react-intl`); for those, syncJSON's auto-detection\n * (split only when the source has no `${key}` segment) stays in control.\n *\n * Only meaningful for flat templates (no `${key}` segment); it is dropped\n * automatically when the resolved template addresses one namespace per file.\n */\n splitKeys?: boolean;\n};\n\n/**\n * Configuration for injecting a compat vite plugin into vite.config.\n * The plugin replaces the generic `intlayer` plugin for libraries that\n * require alias injection (e.g. `vue-i18n` → `@intlayer/vue-i18n`).\n */\nexport type CompatVitePluginConfig = {\n /** Exported function name from the plugin package, e.g. `'vueI18nVitePlugin'`. */\n pluginFunctionName: string;\n /** Import path for the plugin package, e.g. `'@intlayer/vue-i18n/plugin'`. */\n pluginPackageSource: string;\n /**\n * Set when the compat plugin is a drop-in replacement for an i18n library's\n * own Vite plugin (e.g. lingui ships `@lingui/vite-plugin`). When the original\n * import is present, init rewrites only that import's module source to\n * `pluginPackageSource` — keeping the binding and its call site — instead of\n * injecting a second import and appending another plugin to the array.\n */\n replacesVitePlugin?: {\n /** Imported binding to keep, e.g. `'lingui'`. */\n importName: string;\n /** Original package source to rewrite, e.g. `'@lingui/vite-plugin'`. */\n fromPackageSource: string;\n };\n};\n\n/** Result of analyzing project dependencies for intlayer package gaps. */\nexport type IntlayerPackageAnalysis = {\n /** Intlayer packages that are referenced but not yet installed. */\n packagesToInstall: string[];\n /** Intlayer dev packages that are referenced but not yet installed. */\n devPackagesToInstall: string[];\n /**\n * syncJSON plugin configuration to inject when a compat i18n library is\n * detected. Undefined when no compat library is present or format is not\n * yet implemented.\n */\n compatSyncConfig: CompatSyncConfig | undefined;\n /**\n * Vite config plugin to inject when a vite-based compat library is\n * detected. Undefined for Next.js/Nuxt-only compat libs or when no compat\n * library requires alias injection.\n */\n compatVitePluginConfig: CompatVitePluginConfig | undefined;\n};\n\n/**\n * Detects the package manager in use by checking for lock files in the\n * project root. Falls back to npm when no lock file is found.\n */\nexport const detectPackageManager = (rootDir: string): PackageManager => {\n if (\n existsSync(join(rootDir, 'bun.lock')) ||\n existsSync(join(rootDir, 'bun.lockb'))\n ) {\n return 'bun';\n }\n if (existsSync(join(rootDir, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(join(rootDir, 'yarn.lock'))) {\n return 'yarn';\n }\n return 'npm';\n};\n\n/**\n * Returns the install command for the given package manager and package list.\n */\nconst buildInstallCommand = (\n packageManager: PackageManager,\n packages: string[],\n isDev: boolean = false\n): string => {\n const packageList = packages.join(' ');\n switch (packageManager) {\n case 'bun':\n return `bun add ${isDev ? '-d ' : ''}${packageList}`;\n case 'pnpm':\n return `pnpm add ${isDev ? '-D ' : ''}${packageList}`;\n case 'yarn':\n return `yarn add ${isDev ? '-D ' : ''}${packageList}`;\n case 'npm':\n return `npm install ${isDev ? '-D ' : ''}${packageList}`;\n }\n};\n\n/**\n * Analyzes existing project dependencies to determine which intlayer packages\n * are missing and what syncJSON configuration to inject when compat i18n\n * libraries are present.\n */\n/** Extra signals (from a filesystem scan) that refine compat detection. */\nexport type DetectMissingPackagesOptions = {\n /**\n * Catalog format detected for a lingui project (`'po'` or `'json'`), or\n * `null`/undefined when none was found. Decides which sync plugin + dev\n * dependency the lingui compat setup uses.\n */\n linguiCatalogFormat?: 'po' | 'json' | null;\n /**\n * Extra package names injected by the interactive init prompt when the user\n * selects a compat i18n library that is not yet in `package.json`.\n * These are merged with the real dependency map before running detection so\n * the correct sync plugin and compat adapter are scheduled for installation.\n */\n hintDependencies?: Record<string, string>;\n};\n\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>,\n options: DetectMissingPackagesOptions = {}\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n // Merge hint deps supplied by the interactive init prompt so that compat\n // libraries the user declared (but hasn't installed yet) are treated the same\n // as pre-existing deps when building the install and config lists.\n const effectiveDependencies: Record<string, string> = {\n ...allDependencies,\n ...(options.hintDependencies ?? {}),\n };\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(effectiveDependencies[packageName]);\n\n const addIfMissing = (packageName: string): void => {\n if (!isInstalled(packageName)) {\n packagesToInstall.push(packageName);\n }\n };\n\n const addDevIfMissing = (packageName: string): void => {\n if (!isInstalled(packageName)) {\n devPackagesToInstall.push(packageName);\n }\n };\n\n // Core package — always required\n addIfMissing('intlayer');\n\n // Framework-specific runtime integrations\n if (isInstalled('next')) {\n addIfMissing('next-intlayer');\n } else if (isInstalled('react')) {\n addIfMissing('react-intlayer');\n }\n\n // React Native / Expo — the Metro plugin lives in react-native-intlayer,\n // installed as a dev dependency (it is only used by the bundler).\n if (isInstalled('react-native') || isInstalled('expo')) {\n addDevIfMissing('react-native-intlayer');\n }\n\n if (isInstalled('svelte')) {\n addIfMissing('svelte-intlayer');\n }\n\n if (isInstalled('solid-js')) {\n addIfMissing('solid-intlayer');\n }\n\n if (isInstalled('@angular/core')) {\n addIfMissing('angular-intlayer');\n }\n\n if (isInstalled('vue')) {\n addIfMissing('vue-intlayer');\n }\n\n if (isInstalled('vite')) {\n addIfMissing('vite-intlayer');\n }\n\n // -------------------------------------------------------------------------\n // Compat adapters for existing i18n libraries.\n //\n // Detection order matters: more specific libraries are checked first so that\n // `compatSyncConfig ??=` and `compatVitePluginConfig ??=` capture the most\n // relevant match. Libraries that only affect the Next.js or Nuxt config do\n // not set `compatVitePluginConfig` (handled separately in init/index.ts).\n // Libraries whose JSON format is not yet supported leave `compatSyncConfig`\n // undefined so no syncJSON plugin is injected.\n // -------------------------------------------------------------------------\n\n // next-intl — next.js only, ICU format. Default layout is a single file per\n // locale (`messages/${locale}.json`) whose top-level keys are namespaces;\n // syncJSON `splitKeys` auto-detection (no `${key}` segment) turns each\n // top-level key into its own dictionary. The exact path is refined from\n // `i18n/request.ts` in init/index.ts when present.\n if (isInstalled('next-intl') || isInstalled('@intlayer/next-intl')) {\n addIfMissing('@intlayer/next-intl');\n addIfMissing('next-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './messages/${locale}.json',\n // next-intl groups namespaces by the first-level keys of one file.\n splitKeys: true,\n };\n // next config handled via updateNextConfigForNextIntl in init/index.ts\n }\n\n // next-i18next — next.js only, i18next JSON format\n if (isInstalled('next-i18next') || isInstalled('@intlayer/next-i18next')) {\n addIfMissing('@intlayer/next-i18next');\n addIfMissing('next-i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n // next config handled via updateNextConfigForNextI18next in init/index.ts\n }\n\n // next-translate — next.js only, i18next-style flat-namespace JSON\n if (\n isInstalled('next-translate') ||\n isInstalled('@intlayer/next-translate')\n ) {\n addIfMissing('@intlayer/next-translate');\n addIfMissing('next-translate');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n // next config handled via updateNextConfigForNextTranslate in init/index.ts\n }\n\n // i18next — explicit import from @intlayer/i18next (no alias injection needed)\n if (isInstalled('i18next') || isInstalled('@intlayer/i18next')) {\n addIfMissing('@intlayer/i18next');\n // Ensure the required peer dependency is installed\n addIfMissing('i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n }\n\n // react-i18next — explicit import from @intlayer/react-i18next (no alias)\n if (isInstalled('react-i18next') || isInstalled('@intlayer/react-i18next')) {\n addIfMissing('@intlayer/react-i18next');\n // Ensure the required peer dependency is installed\n addIfMissing('react-i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n }\n\n // vue-i18n — vite alias injection required\n if (isInstalled('vue-i18n') || isInstalled('@intlayer/vue-i18n')) {\n addIfMissing('@intlayer/vue-i18n');\n addIfMissing('vue-i18n');\n compatSyncConfig ??= {\n format: 'vue-i18n',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'vueI18nVitePlugin',\n pluginPackageSource: '@intlayer/vue-i18n/plugin',\n };\n }\n\n // use-intl — framework-agnostic React core of next-intl; vite alias\n // injection required, ICU format. Commonly a single `messages/${locale}.json`\n // file whose top-level keys are namespaces, handled by syncJSON `splitKeys`\n // auto-detection (no `${key}` segment in the source template).\n if (isInstalled('use-intl') || isInstalled('@intlayer/use-intl')) {\n addIfMissing('@intlayer/use-intl');\n addIfMissing('use-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './messages/${locale}.json',\n // use-intl (the core of next-intl) uses the same single-file namespace model.\n splitKeys: true,\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'useIntlVitePlugin',\n pluginPackageSource: '@intlayer/use-intl/plugin',\n };\n }\n\n // react-intl — vite alias injection required, ICU format\n if (isInstalled('react-intl') || isInstalled('@intlayer/react-intl')) {\n addIfMissing('@intlayer/react-intl');\n addIfMissing('react-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './src/i18n/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'reactIntlVitePlugin',\n pluginPackageSource: '@intlayer/react-intl/plugin',\n };\n }\n\n // @ngneat/transloco — vite alias injection required\n // @todo syncJSON format not yet implemented for transloco\n if (isInstalled('@ngneat/transloco') || isInstalled('@intlayer/transloco')) {\n addIfMissing('@intlayer/transloco');\n addIfMissing('@ngneat/transloco');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'translocoVitePlugin',\n pluginPackageSource: '@intlayer/transloco/plugin',\n };\n }\n\n // svelte-i18n — vite alias injection required, flat JSON (i18next-compatible)\n if (isInstalled('svelte-i18n') || isInstalled('@intlayer/svelte-i18n')) {\n addIfMissing('@intlayer/svelte-i18n');\n addIfMissing('svelte-i18n');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'svelteI18nVitePlugin',\n pluginPackageSource: '@intlayer/svelte-i18n/plugin',\n };\n }\n\n // node-polyglot — vite alias injection required\n // @todo syncJSON format not yet implemented for polyglot\n if (isInstalled('node-polyglot') || isInstalled('@intlayer/polyglot')) {\n addIfMissing('@intlayer/polyglot');\n addIfMissing('node-polyglot');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'polyglotVitePlugin',\n pluginPackageSource: '@intlayer/polyglot/plugin',\n };\n }\n\n // @nuxtjs/i18n — nuxt module (no vite plugin), vue-i18n JSON format\n if (isInstalled('@nuxtjs/i18n') || isInstalled('@intlayer/nuxtjs-i18n')) {\n addIfMissing('@intlayer/nuxtjs-i18n');\n addIfMissing('@nuxtjs/i18n');\n compatSyncConfig ??= {\n format: 'vue-i18n',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n // nuxt config handled via updateNuxtConfigForNuxtjsI18n in init/index.ts\n }\n\n // @ngx-translate/core — vite alias injection required, flat JSON (i18next)\n if (\n isInstalled('@ngx-translate/core') ||\n isInstalled('@intlayer/ngx-translate')\n ) {\n addIfMissing('@intlayer/ngx-translate');\n addIfMissing('@ngx-translate/core');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './assets/i18n/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'ngxTranslateVitePlugin',\n pluginPackageSource: '@intlayer/ngx-translate/plugin',\n };\n }\n\n // @lingui/core — vite alias injection required.\n // lingui keeps one catalog file per locale (default name `messages`), as\n // `.po` (its default) or `.json`. The catalog filename is captured by the\n // `${key}` segment so the produced dictionary key is `messages`, matching the\n // fixed `messages` namespace the lingui compat runtime reads from.\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n\n const linguiUsesPo = options.linguiCatalogFormat === 'po';\n compatSyncConfig ??= linguiUsesPo\n ? {\n plugin: 'po',\n format: 'icu',\n sourceTemplate: './src/locales/${locale}/${key}.po',\n }\n : {\n plugin: 'json',\n format: 'icu',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n\n compatVitePluginConfig ??= {\n // `@intlayer/lingui/plugin` exports `lingui` as a drop-in replacement for\n // `@lingui/vite-plugin`, so a fresh project gets `lingui()` injected and a\n // project already using `@lingui/vite-plugin` only has its import source\n // rewritten (see `replacesVitePlugin`).\n pluginFunctionName: 'lingui',\n pluginPackageSource: '@intlayer/lingui/plugin',\n replacesVitePlugin: {\n importName: 'lingui',\n fromPackageSource: '@lingui/vite-plugin',\n },\n };\n }\n\n // i18n-js — vite alias injection required\n // @todo syncJSON format not yet implemented for i18n-js\n if (isInstalled('i18n-js') || isInstalled('@intlayer/i18n-js')) {\n addIfMissing('@intlayer/i18n-js');\n addIfMissing('i18n-js');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'i18nJsVitePlugin',\n pluginPackageSource: '@intlayer/i18n-js/plugin',\n };\n }\n\n if (compatSyncConfig) {\n addDevIfMissing(\n compatSyncConfig.plugin === 'po'\n ? '@intlayer/sync-po-plugin'\n : '@intlayer/sync-json-plugin'\n );\n }\n\n return {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n };\n};\n\n/**\n * Runs the package install command synchronously.\n * Throws if the install process exits with a non-zero code.\n */\nexport const installPackages = (\n rootDir: string,\n packages: string[],\n packageManager: PackageManager,\n isDev: boolean = false\n): void => {\n const command = buildInstallCommand(packageManager, packages, isDev);\n execSync(command, { cwd: rootDir, stdio: 'inherit' });\n};\n\n/**\n * Determines whether a dependency name belongs to the Intlayer ecosystem.\n *\n * Matches the core `intlayer` package, every scoped `@intlayer/*` package\n * (including compat adapters such as `@intlayer/next-intl`) and the framework\n * runtime integrations that follow the `<framework>-intlayer` convention\n * (e.g. `next-intlayer`, `react-intlayer`, `express-intlayer`).\n */\nexport const isIntlayerPackageName = (packageName: string): boolean =>\n packageName === 'intlayer' ||\n packageName.startsWith('@intlayer/') ||\n /-intlayer$/.test(packageName);\n\n/**\n * Reduces a semver range or full version to its `major.minor.patch` core,\n * stripping range prefixes (`^`, `~`), pre-release identifiers and build\n * metadata. Returns `null` when no `major.minor.patch` can be extracted.\n *\n * @example normalizeVersion('^9.0.0-canary.3') // '9.0.0'\n */\nexport const normalizeVersion = (version?: string): string | null => {\n if (!version || typeof version !== 'string') return null;\n const match = version.match(/(\\d+)\\.(\\d+)\\.(\\d+)/);\n return match ? `${match[1]}.${match[2]}.${match[3]}` : null;\n};\n\n/**\n * Reads the installed version of a package from its `package.json` inside the\n * project's `node_modules`. Returns `null` when the package is not installed or\n * its manifest cannot be read.\n */\nexport const getInstalledPackageVersion = (\n rootDir: string,\n packageName: string\n): string | null => {\n try {\n const manifestPath = join(\n rootDir,\n 'node_modules',\n packageName,\n 'package.json'\n );\n if (!existsSync(manifestPath)) return null;\n const { version } = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n return typeof version === 'string' ? version : null;\n } catch {\n return null;\n }\n};\n\n/**\n * Returns the Intlayer packages from `dependencies` whose installed version is\n * behind `targetVersion` (compared on `major.minor.patch`). Packages that are\n * not installed yet are ignored — those are handled by\n * {@link detectMissingIntlayerPackages}.\n */\nexport const detectOutdatedIntlayerPackages = (\n rootDir: string,\n dependencies: Record<string, string>,\n targetVersion: string\n): string[] => {\n const normalizedTarget = normalizeVersion(targetVersion);\n if (!normalizedTarget) return [];\n\n return Object.keys(dependencies)\n .filter(isIntlayerPackageName)\n .filter((packageName) => {\n const installedVersion = getInstalledPackageVersion(rootDir, packageName);\n const normalizedInstalled = normalizeVersion(\n installedVersion ?? undefined\n );\n if (!normalizedInstalled) return false;\n return compareVersions(normalizedInstalled, '<', normalizedTarget);\n });\n};\n\n/**\n * Upgrades the given packages to `targetVersion` synchronously, preserving the\n * dependency type via the `isDev` flag. Throws if the install process exits\n * with a non-zero code.\n */\nexport const upgradePackages = (\n rootDir: string,\n packages: string[],\n packageManager: PackageManager,\n targetVersion: string,\n isDev: boolean = false\n): void => {\n if (packages.length === 0) return;\n const versionedPackages = packages.map(\n (packageName) => `${packageName}@${targetVersion}`\n );\n const command = buildInstallCommand(packageManager, versionedPackages, isDev);\n execSync(command, { cwd: rootDir, stdio: 'inherit' });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"packageManager.mjs","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { compareVersions } from '@intlayer/config/utils';\n\n/** Package managers supported for dependency installation. */\nexport type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';\n\n/**\n * Configuration for the syncJSON plugin injected into intlayer.config\n * when a compat i18n library is detected.\n */\nexport type CompatSyncConfig = {\n /**\n * Which sync plugin ingests the catalogs:\n * - `'json'` → `syncJSON` from `@intlayer/sync-json-plugin` (default).\n * - `'po'` → `syncPO` from `@intlayer/sync-po-plugin` (lingui's default\n * format).\n */\n plugin?: 'json' | 'po';\n /**\n * JSON format matching the compat library's conventions. Ignored when\n * `plugin` is `'po'` (PO catalogs are always serialized as gettext).\n */\n format: 'icu' | 'i18next' | 'vue-i18n';\n /**\n * Source path template using ${locale} and ${key} placeholders.\n * Rendered as a template literal in the generated config.\n */\n sourceTemplate: string;\n /**\n * Force `splitKeys: true` in the generated `syncJSON(...)` call so each\n * top-level key of a single per-locale file becomes its own dictionary.\n *\n * Set for libraries whose single `messages/${locale}.json` file groups\n * namespaces by its first-level keys (`next-intl` / `use-intl`, where\n * `useTranslations('Hero')` resolves to the `Hero` dictionary). Left\n * undefined for libraries whose top-level keys are plain message keys\n * (e.g. `i18next`, `react-intl`); for those, syncJSON's auto-detection\n * (split only when the source has no `${key}` segment) stays in control.\n *\n * Only meaningful for flat templates (no `${key}` segment); it is dropped\n * automatically when the resolved template addresses one namespace per file.\n */\n splitKeys?: boolean;\n};\n\n/**\n * Configuration for injecting a compat vite plugin into vite.config.\n * The plugin replaces the generic `intlayer` plugin for libraries that\n * require alias injection (e.g. `vue-i18n` → `@intlayer/vue-i18n`).\n */\nexport type CompatVitePluginConfig = {\n /** Exported function name from the plugin package, e.g. `'vueI18nVitePlugin'`. */\n pluginFunctionName: string;\n /** Import path for the plugin package, e.g. `'@intlayer/vue-i18n/plugin'`. */\n pluginPackageSource: string;\n /**\n * Set when the compat plugin is a drop-in replacement for an i18n library's\n * own Vite plugin (e.g. lingui ships `@lingui/vite-plugin`). When the original\n * import is present, init rewrites only that import's module source to\n * `pluginPackageSource` — keeping the binding and its call site — instead of\n * injecting a second import and appending another plugin to the array.\n */\n replacesVitePlugin?: {\n /** Imported binding to keep, e.g. `'lingui'`. */\n importName: string;\n /** Original package source to rewrite, e.g. `'@lingui/vite-plugin'`. */\n fromPackageSource: string;\n };\n};\n\n/** Result of analyzing project dependencies for intlayer package gaps. */\nexport type IntlayerPackageAnalysis = {\n /** Intlayer packages that are referenced but not yet installed. */\n packagesToInstall: string[];\n /** Intlayer dev packages that are referenced but not yet installed. */\n devPackagesToInstall: string[];\n /**\n * syncJSON plugin configuration to inject when a compat i18n library is\n * detected. Undefined when no compat library is present or format is not\n * yet implemented.\n */\n compatSyncConfig: CompatSyncConfig | undefined;\n /**\n * Vite config plugin to inject when a vite-based compat library is\n * detected. Undefined for Next.js/Nuxt-only compat libs or when no compat\n * library requires alias injection.\n */\n compatVitePluginConfig: CompatVitePluginConfig | undefined;\n};\n\n/**\n * Detects the package manager in use by checking for lock files in the\n * project root. Falls back to npm when no lock file is found.\n */\nexport const detectPackageManager = (rootDir: string): PackageManager => {\n if (\n existsSync(join(rootDir, 'bun.lock')) ||\n existsSync(join(rootDir, 'bun.lockb'))\n ) {\n return 'bun';\n }\n if (existsSync(join(rootDir, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(join(rootDir, 'yarn.lock'))) {\n return 'yarn';\n }\n return 'npm';\n};\n\n/**\n * Returns the install command for the given package manager and package list.\n */\nconst buildInstallCommand = (\n packageManager: PackageManager,\n packages: string[],\n isDev: boolean = false\n): string => {\n const packageList = packages.join(' ');\n switch (packageManager) {\n case 'bun':\n return `bun add ${isDev ? '-d ' : ''}${packageList}`;\n case 'pnpm':\n return `pnpm add ${isDev ? '-D ' : ''}${packageList}`;\n case 'yarn':\n return `yarn add ${isDev ? '-D ' : ''}${packageList}`;\n case 'npm':\n return `npm install ${isDev ? '-D ' : ''}${packageList}`;\n }\n};\n\n/**\n * Analyzes existing project dependencies to determine which intlayer packages\n * are missing and what syncJSON configuration to inject when compat i18n\n * libraries are present.\n */\n/** Extra signals (from a filesystem scan) that refine compat detection. */\nexport type DetectMissingPackagesOptions = {\n /**\n * Catalog format detected for a lingui project (`'po'` or `'json'`), or\n * `null`/undefined when none was found. Decides which sync plugin + dev\n * dependency the lingui compat setup uses.\n */\n linguiCatalogFormat?: 'po' | 'json' | null;\n /**\n * Extra package names injected by the interactive init prompt when the user\n * selects a compat i18n library that is not yet in `package.json`.\n * These are merged with the real dependency map before running detection so\n * the correct sync plugin and compat adapter are scheduled for installation.\n */\n hintDependencies?: Record<string, string>;\n};\n\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>,\n options: DetectMissingPackagesOptions = {}\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n // Merge hint deps supplied by the interactive init prompt so that compat\n // libraries the user declared (but hasn't installed yet) are treated the same\n // as pre-existing deps when building the install and config lists.\n const effectiveDependencies: Record<string, string> = {\n ...allDependencies,\n ...(options.hintDependencies ?? {}),\n };\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(effectiveDependencies[packageName]);\n\n const addIfMissing = (packageName: string): void => {\n if (!isInstalled(packageName)) {\n packagesToInstall.push(packageName);\n }\n };\n\n const addDevIfMissing = (packageName: string): void => {\n if (!isInstalled(packageName)) {\n devPackagesToInstall.push(packageName);\n }\n };\n\n // Core package — always required\n addIfMissing('intlayer');\n\n // Framework-specific runtime integrations\n if (isInstalled('next')) {\n addIfMissing('next-intlayer');\n } else if (isInstalled('react')) {\n addIfMissing('react-intlayer');\n }\n\n // React Native / Expo — the Metro plugin lives in react-native-intlayer,\n // installed as a dev dependency (it is only used by the bundler).\n if (isInstalled('react-native') || isInstalled('expo')) {\n addDevIfMissing('react-native-intlayer');\n }\n\n if (isInstalled('svelte')) {\n addIfMissing('svelte-intlayer');\n }\n\n if (isInstalled('solid-js')) {\n addIfMissing('solid-intlayer');\n }\n\n if (isInstalled('@angular/core')) {\n addIfMissing('angular-intlayer');\n }\n\n if (isInstalled('vue')) {\n addIfMissing('vue-intlayer');\n }\n\n if (isInstalled('vite')) {\n addIfMissing('vite-intlayer');\n }\n\n // -------------------------------------------------------------------------\n // Compat adapters for existing i18n libraries.\n //\n // Detection order matters: more specific libraries are checked first so that\n // `compatSyncConfig ??=` and `compatVitePluginConfig ??=` capture the most\n // relevant match. Libraries that only affect the Next.js or Nuxt config do\n // not set `compatVitePluginConfig` (handled separately in init/index.ts).\n // Libraries whose JSON format is not yet supported leave `compatSyncConfig`\n // undefined so no syncJSON plugin is injected.\n // -------------------------------------------------------------------------\n\n // next-intl — next.js only, ICU format. Default layout is a single file per\n // locale (`messages/${locale}.json`) whose top-level keys are namespaces;\n // syncJSON `splitKeys` auto-detection (no `${key}` segment) turns each\n // top-level key into its own dictionary. The exact path is refined from\n // `i18n/request.ts` in init/index.ts when present.\n if (isInstalled('next-intl') || isInstalled('@intlayer/next-intl')) {\n addIfMissing('@intlayer/next-intl');\n addIfMissing('next-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './messages/${locale}.json',\n // next-intl groups namespaces by the first-level keys of one file.\n splitKeys: true,\n };\n // next config handled via updateNextConfigForNextIntl in init/index.ts\n }\n\n // next-i18next — next.js only, i18next JSON format\n if (isInstalled('next-i18next') || isInstalled('@intlayer/next-i18next')) {\n addIfMissing('@intlayer/next-i18next');\n addIfMissing('next-i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n // next config handled via updateNextConfigForNextI18next in init/index.ts\n }\n\n // next-translate — next.js only, i18next-style flat-namespace JSON\n if (\n isInstalled('next-translate') ||\n isInstalled('@intlayer/next-translate')\n ) {\n addIfMissing('@intlayer/next-translate');\n addIfMissing('next-translate');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n // next config handled via updateNextConfigForNextTranslate in init/index.ts\n }\n\n // i18next — vite alias injection (`i18next` → `@intlayer/i18next`) so existing\n // `import … from 'i18next'` is served by Intlayer without touching call sites.\n if (isInstalled('i18next') || isInstalled('@intlayer/i18next')) {\n addIfMissing('@intlayer/i18next');\n // Ensure the required peer dependency is installed\n addIfMissing('i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n // When react-i18next is also present, its wrapper plugin aliases both\n // `react-i18next` and `i18next`, so it must win — only inject the bare\n // i18next plugin when no React wrapper is installed.\n if (\n !isInstalled('react-i18next') &&\n !isInstalled('@intlayer/react-i18next')\n ) {\n compatVitePluginConfig ??= {\n pluginFunctionName: 'i18nextVitePlugin',\n pluginPackageSource: '@intlayer/i18next/plugin',\n };\n }\n }\n\n // react-i18next — vite alias injection (`react-i18next` → `@intlayer/react-i18next`\n // and `i18next` → `@intlayer/i18next`) so components keep importing from\n // `react-i18next` unchanged.\n if (isInstalled('react-i18next') || isInstalled('@intlayer/react-i18next')) {\n addIfMissing('@intlayer/react-i18next');\n // Ensure the required peer dependency is installed\n addIfMissing('react-i18next');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'reactI18nextVitePlugin',\n pluginPackageSource: '@intlayer/react-i18next/plugin',\n };\n }\n\n // vue-i18n — vite alias injection required\n if (isInstalled('vue-i18n') || isInstalled('@intlayer/vue-i18n')) {\n addIfMissing('@intlayer/vue-i18n');\n addIfMissing('vue-i18n');\n compatSyncConfig ??= {\n format: 'vue-i18n',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'vueI18nVitePlugin',\n pluginPackageSource: '@intlayer/vue-i18n/plugin',\n };\n }\n\n // use-intl — framework-agnostic React core of next-intl; vite alias\n // injection required, ICU format. Commonly a single `messages/${locale}.json`\n // file whose top-level keys are namespaces, handled by syncJSON `splitKeys`\n // auto-detection (no `${key}` segment in the source template).\n if (isInstalled('use-intl') || isInstalled('@intlayer/use-intl')) {\n addIfMissing('@intlayer/use-intl');\n addIfMissing('use-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './messages/${locale}.json',\n // use-intl (the core of next-intl) uses the same single-file namespace model.\n splitKeys: true,\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'useIntlVitePlugin',\n pluginPackageSource: '@intlayer/use-intl/plugin',\n };\n }\n\n // react-intl — vite alias injection required, ICU format\n if (isInstalled('react-intl') || isInstalled('@intlayer/react-intl')) {\n addIfMissing('@intlayer/react-intl');\n addIfMissing('react-intl');\n compatSyncConfig ??= {\n format: 'icu',\n sourceTemplate: './src/i18n/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'reactIntlVitePlugin',\n pluginPackageSource: '@intlayer/react-intl/plugin',\n };\n }\n\n // @ngneat/transloco — vite alias injection required\n // @todo syncJSON format not yet implemented for transloco\n if (isInstalled('@ngneat/transloco') || isInstalled('@intlayer/transloco')) {\n addIfMissing('@intlayer/transloco');\n addIfMissing('@ngneat/transloco');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'translocoVitePlugin',\n pluginPackageSource: '@intlayer/transloco/plugin',\n };\n }\n\n // svelte-i18n — vite alias injection required, flat JSON (i18next-compatible)\n if (isInstalled('svelte-i18n') || isInstalled('@intlayer/svelte-i18n')) {\n addIfMissing('@intlayer/svelte-i18n');\n addIfMissing('svelte-i18n');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './src/locales/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'svelteI18nVitePlugin',\n pluginPackageSource: '@intlayer/svelte-i18n/plugin',\n };\n }\n\n // node-polyglot — vite alias injection required\n // @todo syncJSON format not yet implemented for polyglot\n if (isInstalled('node-polyglot') || isInstalled('@intlayer/polyglot')) {\n addIfMissing('@intlayer/polyglot');\n addIfMissing('node-polyglot');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'polyglotVitePlugin',\n pluginPackageSource: '@intlayer/polyglot/plugin',\n };\n }\n\n // @nuxtjs/i18n — nuxt module (no vite plugin), vue-i18n JSON format\n if (isInstalled('@nuxtjs/i18n') || isInstalled('@intlayer/nuxtjs-i18n')) {\n addIfMissing('@intlayer/nuxtjs-i18n');\n addIfMissing('@nuxtjs/i18n');\n compatSyncConfig ??= {\n format: 'vue-i18n',\n sourceTemplate: './locales/${locale}/${key}.json',\n };\n // nuxt config handled via updateNuxtConfigForNuxtjsI18n in init/index.ts\n }\n\n // @ngx-translate/core — vite alias injection required, flat JSON (i18next)\n if (\n isInstalled('@ngx-translate/core') ||\n isInstalled('@intlayer/ngx-translate')\n ) {\n addIfMissing('@intlayer/ngx-translate');\n addIfMissing('@ngx-translate/core');\n compatSyncConfig ??= {\n format: 'i18next',\n sourceTemplate: './assets/i18n/${locale}.json',\n };\n compatVitePluginConfig ??= {\n pluginFunctionName: 'ngxTranslateVitePlugin',\n pluginPackageSource: '@intlayer/ngx-translate/plugin',\n };\n }\n\n // @lingui/core — vite alias injection required.\n // lingui keeps one catalog file per locale (default name `messages`), as\n // `.po` (its default) or `.json`. The catalog filename is captured by the\n // `${key}` segment so the produced dictionary key is `messages`, matching the\n // fixed `messages` namespace the lingui compat runtime reads from.\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n\n const linguiUsesPo = options.linguiCatalogFormat === 'po';\n compatSyncConfig ??= linguiUsesPo\n ? {\n plugin: 'po',\n format: 'icu',\n sourceTemplate: './src/locales/${locale}/${key}.po',\n }\n : {\n plugin: 'json',\n format: 'icu',\n sourceTemplate: './src/locales/${locale}/${key}.json',\n };\n\n compatVitePluginConfig ??= {\n // `@intlayer/lingui/plugin` exports `lingui` as a drop-in replacement for\n // `@lingui/vite-plugin`, so a fresh project gets `lingui()` injected and a\n // project already using `@lingui/vite-plugin` only has its import source\n // rewritten (see `replacesVitePlugin`).\n pluginFunctionName: 'lingui',\n pluginPackageSource: '@intlayer/lingui/plugin',\n replacesVitePlugin: {\n importName: 'lingui',\n fromPackageSource: '@lingui/vite-plugin',\n },\n };\n }\n\n // i18n-js — vite alias injection required\n // @todo syncJSON format not yet implemented for i18n-js\n if (isInstalled('i18n-js') || isInstalled('@intlayer/i18n-js')) {\n addIfMissing('@intlayer/i18n-js');\n addIfMissing('i18n-js');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'i18nJsVitePlugin',\n pluginPackageSource: '@intlayer/i18n-js/plugin',\n };\n }\n\n if (compatSyncConfig) {\n addDevIfMissing(\n compatSyncConfig.plugin === 'po'\n ? '@intlayer/sync-po-plugin'\n : '@intlayer/sync-json-plugin'\n );\n }\n\n return {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n };\n};\n\n/**\n * Runs the package install command synchronously.\n * Throws if the install process exits with a non-zero code.\n */\nexport const installPackages = (\n rootDir: string,\n packages: string[],\n packageManager: PackageManager,\n isDev: boolean = false\n): void => {\n const command = buildInstallCommand(packageManager, packages, isDev);\n execSync(command, { cwd: rootDir, stdio: 'inherit' });\n};\n\n/**\n * Determines whether a dependency name belongs to the Intlayer ecosystem.\n *\n * Matches the core `intlayer` package, every scoped `@intlayer/*` package\n * (including compat adapters such as `@intlayer/next-intl`) and the framework\n * runtime integrations that follow the `<framework>-intlayer` convention\n * (e.g. `next-intlayer`, `react-intlayer`, `express-intlayer`).\n */\nexport const isIntlayerPackageName = (packageName: string): boolean =>\n packageName === 'intlayer' ||\n packageName.startsWith('@intlayer/') ||\n /-intlayer$/.test(packageName);\n\n/**\n * Reduces a semver range or full version to its `major.minor.patch` core,\n * stripping range prefixes (`^`, `~`), pre-release identifiers and build\n * metadata. Returns `null` when no `major.minor.patch` can be extracted.\n *\n * @example normalizeVersion('^9.0.0-canary.3') // '9.0.0'\n */\nexport const normalizeVersion = (version?: string): string | null => {\n if (!version || typeof version !== 'string') return null;\n const match = version.match(/(\\d+)\\.(\\d+)\\.(\\d+)/);\n return match ? `${match[1]}.${match[2]}.${match[3]}` : null;\n};\n\n/**\n * Reads the installed version of a package from its `package.json` inside the\n * project's `node_modules`. Returns `null` when the package is not installed or\n * its manifest cannot be read.\n */\nexport const getInstalledPackageVersion = (\n rootDir: string,\n packageName: string\n): string | null => {\n try {\n const manifestPath = join(\n rootDir,\n 'node_modules',\n packageName,\n 'package.json'\n );\n if (!existsSync(manifestPath)) return null;\n const { version } = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n return typeof version === 'string' ? version : null;\n } catch {\n return null;\n }\n};\n\n/**\n * Returns the Intlayer packages from `dependencies` whose installed version is\n * behind `targetVersion` (compared on `major.minor.patch`). Packages that are\n * not installed yet are ignored — those are handled by\n * {@link detectMissingIntlayerPackages}.\n */\nexport const detectOutdatedIntlayerPackages = (\n rootDir: string,\n dependencies: Record<string, string>,\n targetVersion: string\n): string[] => {\n const normalizedTarget = normalizeVersion(targetVersion);\n if (!normalizedTarget) return [];\n\n return Object.keys(dependencies)\n .filter(isIntlayerPackageName)\n .filter((packageName) => {\n const installedVersion = getInstalledPackageVersion(rootDir, packageName);\n const normalizedInstalled = normalizeVersion(\n installedVersion ?? undefined\n );\n if (!normalizedInstalled) return false;\n return compareVersions(normalizedInstalled, '<', normalizedTarget);\n });\n};\n\n/**\n * Upgrades the given packages to `targetVersion` synchronously, preserving the\n * dependency type via the `isDev` flag. Throws if the install process exits\n * with a non-zero code.\n */\nexport const upgradePackages = (\n rootDir: string,\n packages: string[],\n packageManager: PackageManager,\n targetVersion: string,\n isDev: boolean = false\n): void => {\n if (packages.length === 0) return;\n const versionedPackages = packages.map(\n (packageName) => `${packageName}@${targetVersion}`\n );\n const command = buildInstallCommand(packageManager, versionedPackages, isDev);\n execSync(command, { cwd: rootDir, stdio: 'inherit' });\n};\n"],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@ import simpleGit from "simple-git";
|
|
|
5
5
|
|
|
6
6
|
//#region src/listProjects.ts
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Returns the git repository root directory, or `null` when the given
|
|
9
|
+
* directory is not inside a git repository.
|
|
9
10
|
*/
|
|
10
11
|
const getGitRootDir = async (cwd) => {
|
|
11
12
|
try {
|
|
@@ -40,5 +41,5 @@ const listProjects = async (options) => {
|
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
//#endregion
|
|
43
|
-
export { listProjects };
|
|
44
|
+
export { getGitRootDir, listProjects };
|
|
44
45
|
//# sourceMappingURL=listProjects.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listProjects.mjs","names":[],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"listProjects.mjs","names":[],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n * Returns the git repository root directory, or `null` when the given\n * directory is not inside a git repository.\n */\nexport const getGitRootDir = async (cwd?: string): Promise<string | null> => {\n try {\n const git = cwd ? simpleGit(cwd) : simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (_error) {\n return null;\n }\n};\n\n/**\n * List all Intlayer projects by searching for configuration files\n *\n * @param options - Options for listing projects\n * @returns Array of absolute paths to project directories containing Intlayer config\n */\nexport const listProjects = async (\n options?: ListProjectsOptions\n): Promise<{ searchDir: string; projectsPath: string[] }> => {\n let searchDir = options?.baseDir ?? process.cwd();\n\n // If gitRoot option is enabled, try to get the git root directory\n if (options?.gitRoot) {\n const gitRootDir = await getGitRootDir(searchDir);\n if (gitRootDir) {\n searchDir = gitRootDir;\n }\n }\n\n // Build glob patterns for all config file candidates\n const configPatterns = configurationFilesCandidates.map(\n (fileName) => `**/${fileName}`\n );\n\n // Search for all config files\n const configFiles = await fg(configPatterns, {\n cwd: searchDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.git/**'],\n dot: true, // Include dot files like .intlayerrc\n });\n\n // Extract unique directory paths from config files\n const projectDirs = [...new Set(configFiles.map((file) => dirname(file)))];\n\n // Sort alphabetically for consistent output\n return { searchDir, projectsPath: projectDirs.sort() };\n};\n"],"mappings":";;;;;;;;;;AAsBA,MAAa,gBAAgB,OAAO,QAAyC;AAC3E,KAAI;AAGF,UAAO,OAFK,MAAM,UAAU,IAAI,GAAG,WAAW,EACpB,SAAS,CAAC,kBAAkB,CAAC,EACxC,MAAM;UACd,QAAQ;AACf,SAAO;;;;;;;;;AAUX,MAAa,eAAe,OAC1B,YAC2D;CAC3D,IAAI,YAAY,SAAS,WAAW,QAAQ,KAAK;AAGjD,KAAI,SAAS,SAAS;EACpB,MAAM,aAAa,MAAM,cAAc,UAAU;AACjD,MAAI,WACF,aAAY;;CAUhB,MAAM,cAAc,MAAM,GALH,6BAA6B,KACjD,aAAa,MAAM,WAIqB,EAAE;EAC3C,KAAK;EACL,UAAU;EACV,QAAQ,CAAC,sBAAsB,aAAa;EAC5C,KAAK;EACN,CAAC;CAGF,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,KAAK,SAAS,QAAQ,KAAK,CAAC,CAAC,CAAC;AAG1E,QAAO;EAAE;EAAW,cAAc,YAAY,MAAM;EAAE"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
//#region src/writeConfiguration/generateConfigurationContent.ts
|
|
2
2
|
const generateConfigurationContent = (configuration, format) => {
|
|
3
|
-
const { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler } = configuration;
|
|
3
|
+
const { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler } = configuration;
|
|
4
4
|
let fileContent = "";
|
|
5
5
|
fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\n`;
|
|
6
6
|
fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\n`;
|
|
7
7
|
fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\n`;
|
|
8
|
+
fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\n`;
|
|
8
9
|
fileContent += `const log = ${JSON.stringify(log, null, 2)};\n`;
|
|
9
10
|
fileContent += `const system = ${JSON.stringify(system, null, 2)};\n`;
|
|
10
11
|
fileContent += `const content = ${JSON.stringify(content, null, 2)};\n`;
|
|
@@ -12,11 +13,12 @@ const generateConfigurationContent = (configuration, format) => {
|
|
|
12
13
|
fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\n`;
|
|
13
14
|
fileContent += `const build = ${JSON.stringify(build, null, 2)};\n`;
|
|
14
15
|
fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\n`;
|
|
15
|
-
if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\n`;
|
|
16
|
+
if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\n`;
|
|
16
17
|
else {
|
|
17
18
|
fileContent += `\nmodule.exports.internationalization = internationalization;\n`;
|
|
18
19
|
fileContent += `module.exports.routing = routing;\n`;
|
|
19
20
|
fileContent += `module.exports.editor = editor;\n`;
|
|
21
|
+
fileContent += `module.exports.analytics = analytics;\n`;
|
|
20
22
|
fileContent += `module.exports.log = log;\n`;
|
|
21
23
|
fileContent += `module.exports.system = system;\n`;
|
|
22
24
|
fileContent += `module.exports.content = content;\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
|
|
1
|
+
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n analytics,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.analytics = analytics;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,WACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,qBAAqB,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC;AACvE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -16,6 +16,6 @@ import { PLATFORMS, PLATFORMS_METADATA, Platform, PlatformMetadata, SKILLS, SKIL
|
|
|
16
16
|
import { MCPTransport, installMCP } from "./installMCP/installMCP.js";
|
|
17
17
|
import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.js";
|
|
18
18
|
import { DiffMode, ListGitFilesOptions, ListGitLinesOptions, listGitFiles, listGitLines } from "./listGitFiles.js";
|
|
19
|
-
import { ListProjectsOptions, listProjects } from "./listProjects.js";
|
|
19
|
+
import { ListProjectsOptions, getGitRootDir, listProjects } from "./listProjects.js";
|
|
20
20
|
import { logConfigDetails } from "./logConfigDetails.js";
|
|
21
|
-
export { type CmsCredentials, ContentStrategy, DictionaryStatus, DiffMode, InitOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, MCPTransport, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, type PackageManager, Platform, PlatformMetadata, type RoutingMode, SKILLS, SKILLS_METADATA, Skill, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
21
|
+
export { type CmsCredentials, ContentStrategy, DictionaryStatus, DiffMode, InitOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, MCPTransport, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, type PackageManager, Platform, PlatformMetadata, type RoutingMode, SKILLS, SKILLS_METADATA, Skill, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getGitRootDir, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;;;;AA6LA;;;cAAa,wBAAA,GACX,YAAA,EAAc,MAAA;;AAsBhB;;;;;AAQA;;;KARY,eAAA;;;;KAQA,WAAA;EACV,WAAA,YAEA;EAAA,eAAA;EAMA;;;EAFA,iBAAA,YAqBA;EAnBA,iBAAA,YA0BA;EAxBA,KAAA;EA+BA;;;;EA1BA,gBAAA;EA6hCD;;;;;EAvhCC,gBAAA;EA0BuE;;;;;EApBvE,WAAA,GAAc,WAAA;;;;;;;EAOd,gBAAA,GAAmB,MAAA;;;;;;;EAOnB,eAAA,GAAkB,eAAA;AAAA;;;;cAMP,YAAA,GAAsB,OAAA,UAAiB,OAAA,GAAU,WAAA,KAAW,OAAA"}
|
|
@@ -30,6 +30,14 @@ declare const setIntlayerConfigCompilerOutput: (content: string, extension: stri
|
|
|
30
30
|
* (JSON cannot reference `process.env`).
|
|
31
31
|
*/
|
|
32
32
|
declare const enableIntlayerEditorConfig: (content: string) => string;
|
|
33
|
+
/**
|
|
34
|
+
* Detects whether a Vite config already wires in an Intlayer plugin — either the
|
|
35
|
+
* base `vite-intlayer` plugin or one of the compat adapters (e.g.
|
|
36
|
+
* `reactI18nextVitePlugin` from `@intlayer/react-i18next/plugin`). The compat
|
|
37
|
+
* plugins internally wrap `intlayer()`, so a standalone `intlayer()` must not be
|
|
38
|
+
* appended when one is already present, otherwise the plugin runs twice.
|
|
39
|
+
*/
|
|
40
|
+
declare const hasIntlayerVitePlugin: (content: string) => boolean;
|
|
33
41
|
declare const updateViteConfig: (content: string, extension: string) => string;
|
|
34
42
|
declare const updateAstroConfig: (content: string, extension: string) => string;
|
|
35
43
|
declare const updateNextConfig: (content: string, extension: string) => string;
|
|
@@ -104,5 +112,5 @@ declare const updateNextConfigForNextIntl: (content: string, extension: string)
|
|
|
104
112
|
*/
|
|
105
113
|
declare const updateIntlayerConfigWithSyncPlugin: (content: string, extension: string, syncConfig: CompatSyncConfig) => string;
|
|
106
114
|
//#endregion
|
|
107
|
-
export { RoutingMode, enableIntlayerEditorConfig, getMetroConfigTemplate, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n };
|
|
115
|
+
export { RoutingMode, enableIntlayerEditorConfig, getMetroConfigTemplate, hasIntlayerVitePlugin, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n };
|
|
108
116
|
//# sourceMappingURL=configManipulation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configManipulation.d.ts","names":[],"sources":["../../../../src/init/utils/configManipulation.ts"],"mappings":";;;;;KAYY,WAAA,GAAc,aAAA;AAA1B;;;;;AA0FA;;AA1FA,cA0Fa,4BAAA,GACX,OAAA,UACA,SAAA,UACA,IAAA,EAAM,WAAA;;;;;;;;AA0CR;cAAa,+BAAA,GACX,OAAA,UACA,SAAA,UACA,cAAA;;;;;;;;AAyCF;cAAa,0BAAA,GAA8B,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"configManipulation.d.ts","names":[],"sources":["../../../../src/init/utils/configManipulation.ts"],"mappings":";;;;;KAYY,WAAA,GAAc,aAAA;AAA1B;;;;;AA0FA;;AA1FA,cA0Fa,4BAAA,GACX,OAAA,UACA,SAAA,UACA,IAAA,EAAM,WAAA;;;;;;;;AA0CR;cAAa,+BAAA,GACX,OAAA,UACA,SAAA,UACA,cAAA;;;;;;;;AAyCF;cAAa,0BAAA,GAA8B,OAAA;;;;AAmN3C;;;;cAAa,qBAAA,GAAyB,OAAA;AAAA,cAIzB,gBAAA,GACX,OAAA,UACA,SAAA;AAAA,cAmBW,iBAAA,GACX,OAAA,UACA,SAAA;AAAA,cAmBW,gBAAA,GACX,OAAA,UACA,SAAA;;;AAvBF;;;;;AAqBA;;;;;cA4Ea,iBAAA,GACX,OAAA,UACA,SAAA;;;;;AA0EF;;cAAa,sBAAA,GAA0B,MAAA;AAAA,cAgB1B,gBAAA,GAAoB,OAAA;;AAAjC;;;cA6Da,0BAAA,GACX,OAAA,UACA,SAAA;;AAFF;;;;cA+Ba,+BAAA,GACX,OAAA,UACA,SAAA,UACA,YAAA,EAAc,sBAAA;AAHhB;;;;;;;;;AAAA,cAoCa,mCAAA,GACX,OAAA,UACA,UAAA,UACA,iBAAA,UACA,eAAA;AAJF;;;;AAAA,cAwGa,gCAAA,GACX,OAAA,UACA,SAAA;;;;;cAaW,6BAAA,GAAiC,OAAA;AAf9C;;;;AAAA,cA8Ea,8BAAA,GACX,OAAA,UACA,SAAA;AAjEF;;;;;AA+DA;AA/DA,cAgFa,2BAAA,GACX,OAAA,UACA,SAAA;;;;AAFF;;cAiQa,kCAAA,GACX,OAAA,UACA,SAAA,UACA,UAAA,EAAY,gBAAA"}
|
|
@@ -6,14 +6,68 @@ type GithubWorkflowFile = {
|
|
|
6
6
|
/** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */filePath: string; /** Full YAML content of the workflow file. */
|
|
7
7
|
content: string;
|
|
8
8
|
};
|
|
9
|
+
/** Options controlling how the CI workflows are generated. */
|
|
10
|
+
type GithubWorkflowsOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* Route the intlayer commands through `intlayer ci` instead of calling them
|
|
13
|
+
* directly. The `ci` command discovers every Intlayer project of the
|
|
14
|
+
* repository (via `listProjects`) and runs the given command inside each of
|
|
15
|
+
* them, injecting per-project credentials from the
|
|
16
|
+
* `INTLAYER_PROJECT_CREDENTIALS` secret when provided. Required for
|
|
17
|
+
* monorepos where a single workflow must cover several projects.
|
|
18
|
+
*/
|
|
19
|
+
useCiCommand?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Repository-relative directory (posix separators) the workflow commands run
|
|
22
|
+
* in. Set when the Intlayer project lives in a subdirectory of the
|
|
23
|
+
* repository and the repository root has no workspace manifest to install
|
|
24
|
+
* dependencies from. Undefined = repository root.
|
|
25
|
+
*/
|
|
26
|
+
workingDirectory?: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Resolved placement and generation parameters for the CI workflows.
|
|
30
|
+
* See {@link resolveGithubWorkflowsContext}.
|
|
31
|
+
*/
|
|
32
|
+
type GithubWorkflowsContext = {
|
|
33
|
+
/**
|
|
34
|
+
* Directory the workflow files must be written to. GitHub only triggers
|
|
35
|
+
* workflows stored in `.github/workflows` at the repository root, so this is
|
|
36
|
+
* the git root whenever the project lives inside a git repository.
|
|
37
|
+
*/
|
|
38
|
+
workflowsRootDir: string; /** Package manager whose commands are baked into the workflows. */
|
|
39
|
+
packageManager: PackageManager; /** Generation options forwarded to {@link getGithubWorkflows}. */
|
|
40
|
+
options: GithubWorkflowsOptions;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Resolves where the CI workflows must be written and how their commands must
|
|
44
|
+
* be generated, based on the repository layout around `rootDir` (the Intlayer
|
|
45
|
+
* project being initialized):
|
|
46
|
+
*
|
|
47
|
+
* - Project at the repository root: workflows are written in place. When the
|
|
48
|
+
* repository is a monorepo (workspace manifest, or several Intlayer projects
|
|
49
|
+
* discovered by `listProjects`), the commands go through `intlayer ci` so
|
|
50
|
+
* every project is covered.
|
|
51
|
+
* - Project nested in a repository whose root has a `package.json`
|
|
52
|
+
* (workspace-managed monorepo): workflows are written at the git root —
|
|
53
|
+
* GitHub ignores `.github/workflows` in subdirectories — dependencies are
|
|
54
|
+
* installed at the root with the root's package manager, and the commands go
|
|
55
|
+
* through `intlayer ci` to iterate every Intlayer project.
|
|
56
|
+
* - Project nested in a repository without a root `package.json`: workflows
|
|
57
|
+
* are written at the git root but run inside the project directory
|
|
58
|
+
* (`working-directory`), keeping the project's own package manager.
|
|
59
|
+
*/
|
|
60
|
+
declare const resolveGithubWorkflowsContext: (rootDir: string, projectPackageManager: PackageManager) => Promise<GithubWorkflowsContext>;
|
|
9
61
|
/** Workflow file path constants, relative to the project root. */
|
|
10
62
|
declare const GITHUB_FILL_WORKFLOW_PATH = ".github/workflows/intlayer-fill.yml";
|
|
11
63
|
declare const GITHUB_TEST_WORKFLOW_PATH = ".github/workflows/intlayer-test.yml";
|
|
12
64
|
/**
|
|
13
65
|
* Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),
|
|
14
|
-
* generated with commands matching the detected package manager
|
|
66
|
+
* generated with commands matching the detected package manager and the
|
|
67
|
+
* repository layout (see {@link GithubWorkflowsOptions} for the monorepo and
|
|
68
|
+
* nested-project variants).
|
|
15
69
|
*/
|
|
16
|
-
declare const getGithubWorkflows: (packageManager: PackageManager) => GithubWorkflowFile[];
|
|
70
|
+
declare const getGithubWorkflows: (packageManager: PackageManager, options?: GithubWorkflowsOptions) => GithubWorkflowFile[];
|
|
17
71
|
//#endregion
|
|
18
|
-
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, getGithubWorkflows };
|
|
72
|
+
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, getGithubWorkflows, resolveGithubWorkflowsContext };
|
|
19
73
|
//# sourceMappingURL=githubActions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubActions.d.ts","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"githubActions.d.ts","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"mappings":";;;;KAMY,kBAAA;EAAA,qFAEV,QAAA;EAEA,OAAA;AAAA;AAIF;AAAA,KAAY,sBAAA;;;;AAuBZ;;;;;EAdE,YAAA;EAsBgB;;;;;AA2ClB;EA1DE,gBAAA;AAAA;;;;;KAOU,sBAAA;EAoDV;;;;;EA9CA,gBAAA,UAgD+B;EA9C/B,cAAA,EAAgB,cAAA,EA0VoB;EAxVpC,OAAA,EAAS,sBAAA;AAAA;;AAyVX;;;;;AAQA;;;;;;;;;;;;cAxTa,6BAAA,GACX,OAAA,UACA,qBAAA,EAAuB,cAAA,KACtB,OAAA,CAAQ,sBAAA;;cA4SE,yBAAA;AAAA,cACA,yBAAA;;;;;;;cAQA,kBAAA,GACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,sBAAA,KACR,kBAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions, IntlayerPackageAnalysis, PackageManager, detectMissingIntlayerPackages, detectOutdatedIntlayerPackages, detectPackageManager, getInstalledPackageVersion, installPackages, isIntlayerPackageName, normalizeVersion, upgradePackages } from "./packageManager.js";
|
|
2
|
-
import { RoutingMode, enableIntlayerEditorConfig, getMetroConfigTemplate, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.js";
|
|
2
|
+
import { RoutingMode, enableIntlayerEditorConfig, getMetroConfigTemplate, hasIntlayerVitePlugin, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.js";
|
|
3
3
|
import { ensureNamedImport, firstInsertIndex, isModuleScopeBinding } from "./astImports.js";
|
|
4
4
|
import { JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NextIntlMessagesPattern, detectJsonLocalePattern, detectLinguiCatalogPattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.js";
|
|
5
|
-
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, getGithubWorkflows } from "./githubActions.js";
|
|
5
|
+
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, getGithubWorkflows, resolveGithubWorkflowsContext } from "./githubActions.js";
|
|
6
6
|
import { parseJSONWithComments } from "./jsonParser.js";
|
|
7
7
|
import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, setupNextCompilerBabelConfig } from "./nextCompilerBabel.js";
|
|
8
8
|
import { findTsConfigFiles } from "./tsConfig.js";
|
|
9
9
|
import { isVersionAtLeast } from "./version.js";
|
|
10
|
-
export { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, NextIntlMessagesPattern, PackageManager, RoutingMode, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
10
|
+
export { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, NextIntlMessagesPattern, PackageManager, RoutingMode, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, resolveGithubWorkflowsContext, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageManager.d.ts","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"mappings":";;KAMY,cAAA;;;;;KAMA,gBAAA;EAAgB;;;;;;EAO1B,MAAA;EAyBS;;AAQX;;EA5BE,MAAA;EA4BgC;;;;EAvBhC,cAAA;EAuCE;;;AAKJ;;;;;;;;;;;EA7BE,SAAA;AAAA;;;;;AA+FF;KAvFY,sBAAA;oFAEV,kBAAA,UA2FA;EAzFA,mBAAA;EAgGmB;;;AAGrB;;;;EA3FE,kBAAA;IA8FC,iDA5FC,UAAA,
|
|
1
|
+
{"version":3,"file":"packageManager.d.ts","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"mappings":";;KAMY,cAAA;;;;;KAMA,gBAAA;EAAgB;;;;;;EAO1B,MAAA;EAyBS;;AAQX;;EA5BE,MAAA;EA4BgC;;;;EAvBhC,cAAA;EAuCE;;;AAKJ;;;;;;;;;;;EA7BE,SAAA;AAAA;;;;;AA+FF;KAvFY,sBAAA;oFAEV,kBAAA,UA2FA;EAzFA,mBAAA;EAgGmB;;;AAGrB;;;;EA3FE,kBAAA;IA8FC,iDA5FC,UAAA,UA2aH;IAzaG,iBAAA;EAAA;AAAA;;KAKQ,uBAAA;EAoaX,mEAlaC,iBAAA,YAwaW;EAtaX,oBAAA;;;;;;EAMA,gBAAA,EAAkB,gBAAA;EAoalB;;;AAcF;;EA5aE,sBAAA,EAAwB,sBAAA;AAAA;;AAwb1B;;;cAjba,oBAAA,GAAwB,OAAA,aAAkB,cAAA;;AA4bvD;;;;;KAjZY,4BAAA;EA4bX;;;;;EAtbC,mBAAA;EAuaA;;;AAsBF;;;EAtbE,gBAAA,GAAmB,MAAA;AAAA;AAAA,cAGR,6BAAA,GACX,eAAA,EAAiB,MAAA,kBACjB,OAAA,GAAS,4BAAA,KACR,uBAAA;;;;;cAqVU,eAAA,GACX,OAAA,UACA,QAAA,YACA,cAAA,EAAgB,cAAA,EAChB,KAAA;;;;;;;;;cAcW,qBAAA,GAAyB,WAAA;;;;;;;;cAYzB,gBAAA,GAAoB,OAAA;;;;;;cAWpB,0BAAA,GACX,OAAA,UACA,WAAA;;;;;;;cAuBW,8BAAA,GACX,OAAA,UACA,YAAA,EAAc,MAAA,kBACd,aAAA;;;;;;cAsBW,eAAA,GACX,OAAA,UACA,QAAA,YACA,cAAA,EAAgB,cAAA,EAChB,aAAA,UACA,KAAA"}
|
|
@@ -11,6 +11,11 @@ type ListProjectsOptions = {
|
|
|
11
11
|
*/
|
|
12
12
|
gitRoot?: boolean;
|
|
13
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Returns the git repository root directory, or `null` when the given
|
|
16
|
+
* directory is not inside a git repository.
|
|
17
|
+
*/
|
|
18
|
+
declare const getGitRootDir: (cwd?: string) => Promise<string | null>;
|
|
14
19
|
/**
|
|
15
20
|
* List all Intlayer projects by searching for configuration files
|
|
16
21
|
*
|
|
@@ -22,5 +27,5 @@ declare const listProjects: (options?: ListProjectsOptions) => Promise<{
|
|
|
22
27
|
projectsPath: string[];
|
|
23
28
|
}>;
|
|
24
29
|
//#endregion
|
|
25
|
-
export { ListProjectsOptions, listProjects };
|
|
30
|
+
export { ListProjectsOptions, getGitRootDir, listProjects };
|
|
26
31
|
//# sourceMappingURL=listProjects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listProjects.d.ts","names":[],"sources":["../../src/listProjects.ts"],"mappings":";KAKY,mBAAA;EAAA;;;;EAKV,OAAA;
|
|
1
|
+
{"version":3,"file":"listProjects.d.ts","names":[],"sources":["../../src/listProjects.ts"],"mappings":";KAKY,mBAAA;EAAA;;;;EAKV,OAAA;EAYW;;;;EAPX,OAAA;AAAA;;;;;cAOW,aAAA,GAAuB,GAAA,cAAe,OAAA;;;;;;;cAgBtC,YAAA,GACX,OAAA,GAAU,mBAAA,KACT,OAAA;EAAU,SAAA;EAAmB,YAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/engine",
|
|
3
|
-
"version": "9.0.0-canary.
|
|
3
|
+
"version": "9.0.0-canary.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Scans and builds Intlayer declaration files into dictionaries based on Intlayer configuration.",
|
|
6
6
|
"keywords": [
|
|
@@ -142,13 +142,13 @@
|
|
|
142
142
|
},
|
|
143
143
|
"dependencies": {
|
|
144
144
|
"@babel/parser": "7.29.7",
|
|
145
|
-
"@intlayer/api": "9.0.0-canary.
|
|
146
|
-
"@intlayer/config": "9.0.0-canary.
|
|
147
|
-
"@intlayer/core": "9.0.0-canary.
|
|
148
|
-
"@intlayer/dictionaries-entry": "9.0.0-canary.
|
|
149
|
-
"@intlayer/remote-dictionaries-entry": "9.0.0-canary.
|
|
150
|
-
"@intlayer/types": "9.0.0-canary.
|
|
151
|
-
"@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.
|
|
145
|
+
"@intlayer/api": "9.0.0-canary.16",
|
|
146
|
+
"@intlayer/config": "9.0.0-canary.16",
|
|
147
|
+
"@intlayer/core": "9.0.0-canary.16",
|
|
148
|
+
"@intlayer/dictionaries-entry": "9.0.0-canary.16",
|
|
149
|
+
"@intlayer/remote-dictionaries-entry": "9.0.0-canary.16",
|
|
150
|
+
"@intlayer/types": "9.0.0-canary.16",
|
|
151
|
+
"@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.16",
|
|
152
152
|
"@parcel/watcher": "2.5.6",
|
|
153
153
|
"defu": "6.1.7",
|
|
154
154
|
"fast-glob": "3.3.3",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"rimraf": "6.1.3",
|
|
165
165
|
"tsdown": "0.21.10",
|
|
166
166
|
"typescript": "6.0.3",
|
|
167
|
-
"vitest": "4.1.
|
|
167
|
+
"vitest": "4.1.10",
|
|
168
168
|
"zod": "4.4.3"
|
|
169
169
|
},
|
|
170
170
|
"engines": {
|