@intlayer/chokidar 9.0.0-canary.2 → 9.0.0-canary.3

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.
@@ -228,9 +228,10 @@ const initIntlayer = async (rootDir, options) => {
228
228
  const detectedPattern = await require_init_utils_fileSystem.detectJsonLocalePattern(rootDir);
229
229
  await require_initConfig_index.initConfig(format, rootDir, detectedPattern?.locales);
230
230
  if (compatSyncConfig) {
231
- const resolvedSyncConfig = detectedPattern ? {
231
+ const sourceTemplate = (allDeps["next-intl"] || allDeps["@intlayer/next-intl"] || allDeps["use-intl"] || allDeps["@intlayer/use-intl"] ? await require_init_utils_fileSystem.detectNextIntlMessagesPattern(rootDir) : null)?.template ?? detectedPattern?.template;
232
+ const resolvedSyncConfig = sourceTemplate ? {
232
233
  ...compatSyncConfig,
233
- sourceTemplate: detectedPattern.template
234
+ sourceTemplate
234
235
  } : compatSyncConfig;
235
236
  for (const configFile of [
236
237
  "intlayer.config.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["ANSIColors","exists","x","readFileFromRoot","detectPackageManager","detectMissingIntlayerPackages","v","writeFileToRoot","getGithubWorkflows","ensureDirectory","parseJSONWithComments","findTsConfigFiles","detectJsonLocalePattern","initConfig","updateIntlayerConfigWithSyncPlugin","updateViteConfigForCompatPlugin","updateViteConfig","updateNextConfigForNextI18next","updateNextConfigForNextIntl","updateNextConfigForNextTranslate","updateNextConfig","updateAstroConfig","updateNuxtConfigForNuxtjsI18n","updateNuxtConfig"],"sources":["../../../src/init/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\n\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport {\n detectJsonLocalePattern,\n detectMissingIntlayerPackages,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n installPackages,\n parseJSONWithComments,\n readFileFromRoot,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n writeFileToRoot,\n} from './utils';\n\n/**\n * Documentation URL Constants\n */\nconst DocumentationRouter = {\n NextJS: 'https://intlayer.org/doc/environment/nextjs.md',\n NextJS_15: 'https://intlayer.org/doc/environment/nextjs/15.md',\n NextJS_14: 'https://intlayer.org/doc/environment/nextjs/14.md',\n CRA: 'https://intlayer.org/doc/environment/create-react-app.md',\n Astro: 'https://intlayer.org/doc/environment/astro.md',\n ViteAndReact: 'https://intlayer.org/doc/environment/vite-and-react.md',\n ViteAndReact_ReactRouterV7:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7.md',\n ViteAndReact_ReactRouterV7_FSRoutes:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7-fs-routes.md',\n ViteAndVue: 'https://intlayer.org/doc/environment/vite-and-vue.md',\n ViteAndSolid: 'https://intlayer.org/doc/environment/vite-and-solid.md',\n ViteAndSvelte: 'https://intlayer.org/doc/environment/vite-and-svelte.md',\n ViteAndPreact: 'https://intlayer.org/doc/environment/vite-and-preact.md',\n TanStackRouter: 'https://intlayer.org/doc/environment/tanstack.md',\n NuxtAndVue: 'https://intlayer.org/doc/environment/nuxt-and-vue.md',\n Angular: 'https://intlayer.org/doc/environment/angular.md',\n SvelteKit: 'https://intlayer.org/doc/environment/sveltekit.md',\n ReactNativeAndExpo:\n 'https://intlayer.org/doc/environment/react-native-and-expo.md',\n Lynx: 'https://intlayer.org/doc/environment/lynx-and-react.md',\n Express: 'https://intlayer.org/doc/environment/express.md',\n NestJS: 'https://intlayer.org/doc/environment/nestjs.md',\n Fastify: 'https://intlayer.org/doc/environment/fastify.md',\n Default: 'https://intlayer.org/doc/get-started',\n\n // Intlayer Language Server (Go-to-Definition from getter keys to .content files)\n LSP: 'https://intlayer.org/doc/lsp.md',\n\n // Check for competitors libs\n NextIntl: 'https://intlayer.org/blog/intlayer-with-next-intl.md',\n ReactI18Next: 'https://intlayer.org/blog/intlayer-with-react-i18next.md',\n ReactIntl: 'https://intlayer.org/blog/intlayer-with-react-intl.md',\n NextI18Next: 'https://intlayer.org/blog/intlayer-with-next-i18next.md',\n VueI18n: 'https://intlayer.org/blog/intlayer-with-vue-i18n.md',\n};\n\n/**\n * Helper: Detects the environment and returns the doc URL\n */\nconst getDocumentationUrl = (packageJson: any): string => {\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n /**\n * Helper to check if a version string matches a specific major version\n * Matches: \"15\", \"^15.0.0\", \"~15.2\", \"15.0.0-beta\"\n */\n const isVersion = (versionString: string, major: number): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const regex = new RegExp(`^[\\\\^~]?${major}(?:\\\\.|$)`);\n return regex.test(versionString);\n };\n\n // Mobile / Cross-platform\n if (deps['@lynx-js/react'] || deps['@lynx-js/core']) {\n return DocumentationRouter.Lynx;\n }\n if (deps['react-native'] || deps.expo) {\n return DocumentationRouter.ReactNativeAndExpo;\n }\n\n // Meta-frameworks (Next, Nuxt, Astro, SvelteKit)\n if (deps.next) {\n const version = deps.next;\n\n if (isVersion(version, 14)) {\n return DocumentationRouter.NextJS_14;\n }\n\n if (isVersion(version, 15)) {\n return DocumentationRouter.NextJS_15;\n }\n\n return DocumentationRouter.NextJS;\n }\n\n if (deps.nuxt) return DocumentationRouter.NuxtAndVue;\n if (deps.astro) return DocumentationRouter.Astro;\n if (deps['@sveltejs/kit']) return DocumentationRouter.SvelteKit;\n\n // Routers (TanStack & React Router v7)\n if (deps['@tanstack/react-router']) {\n return DocumentationRouter.TanStackRouter;\n }\n\n // Check for React Router v7\n const reactRouterVersion = deps['react-router'];\n if (reactRouterVersion && typeof reactRouterVersion === 'string') {\n // Distinguish between standard v7 and v7 with FS routes\n if (deps['@react-router/fs-routes']) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7_FSRoutes;\n }\n\n // Use Regex to ensure it is v7\n if (isVersion(reactRouterVersion, 7)) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7;\n }\n }\n\n // Vite Ecosystem (General)\n if (deps.vite) {\n if (deps.vue) return DocumentationRouter.ViteAndVue;\n if (deps['solid-js']) return DocumentationRouter.ViteAndSolid;\n if (deps.svelte) return DocumentationRouter.ViteAndSvelte;\n if (deps.preact) return DocumentationRouter.ViteAndPreact;\n\n // Default to React if Vite is present but specific other frameworks aren't found\n return DocumentationRouter.ViteAndReact;\n }\n\n // Other Web Frameworks\n if (deps['react-scripts']) return DocumentationRouter.CRA;\n if (deps['@angular/core']) return DocumentationRouter.Angular;\n\n // Backend\n if (deps['@nestjs/core']) return DocumentationRouter.NestJS;\n if (deps.express) return DocumentationRouter.Express;\n if (deps.fastify) return DocumentationRouter.Fastify;\n\n // Competitor Libs (Migration Guides)\n // We check these last as specific environment setup is usually higher priority,\n // but if no specific framework logic matched (or as a fallback), we guide to migration.\n if (deps['next-intl']) return DocumentationRouter.NextIntl;\n if (deps['react-i18next'] || deps.i18next)\n return DocumentationRouter.ReactI18Next;\n if (deps['react-intl']) return DocumentationRouter.ReactIntl;\n if (deps['next-i18next']) return DocumentationRouter.NextI18Next;\n if (deps['vue-i18n']) return DocumentationRouter.VueI18n;\n\n return DocumentationRouter.Default;\n};\n\n/**\n * OPTIONS\n */\nexport type InitOptions = {\n noGitignore?: boolean;\n /** Skip scaffolding the `fill` and `test` GitHub Actions workflows. */\n noGithubActions?: boolean;\n};\n\n/**\n * MAIN LOGIC\n */\nexport const initIntlayer = async (rootDir: string, options?: InitOptions) => {\n logger(colorize('Checking Intlayer configuration...', ANSIColors.CYAN));\n\n // READ PACKAGE.JSON\n const packageJsonPath = 'package.json';\n if (!(await exists(rootDir, packageJsonPath))) {\n logger(\n `${x} No ${colorizePath('package.json')} found. Please run this script from the project root.`,\n { level: 'error' }\n );\n process.exit(1);\n }\n\n const packageJsonContent = await readFileFromRoot(rootDir, packageJsonPath);\n let packageJson: Record<string, any>;\n try {\n packageJson = JSON.parse(packageJsonContent);\n } catch {\n logger(`${x} Could not parse ${colorizePath('package.json')}.`, {\n level: 'error',\n });\n process.exit(1);\n }\n\n // Determine the correct documentation URL based on dependencies\n const guideUrl = getDocumentationUrl(packageJson);\n\n const allDeps: Record<string, string> = {\n ...(packageJson.dependencies ?? {}),\n ...(packageJson.devDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(allDeps);\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(rootDir, packagesToInstall, packageManager);\n logger(\n `${v} Installed: ${packagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install packages. Please install manually: ${packagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n if (devPackagesToInstall.length > 0) {\n logger(\n colorize(\n 'Installing missing Intlayer dev dependencies...',\n ANSIColors.CYAN\n )\n );\n try {\n installPackages(rootDir, devPackagesToInstall, packageManager, true);\n logger(\n `${v} Installed: ${devPackagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install dev packages. Please install manually: ${devPackagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n // CHECK .GITIGNORE\n const gitignorePath = '.gitignore';\n if (!options?.noGitignore && (await exists(rootDir, gitignorePath))) {\n const gitignoreContent = await readFileFromRoot(rootDir, gitignorePath);\n\n if (!gitignoreContent.includes('intlayer')) {\n const newContent = `${gitignoreContent}\\n# Intlayer\\n.intlayer\\n`;\n await writeFileToRoot(rootDir, gitignorePath, newContent);\n logger(\n `${v} Added ${colorizePath('.intlayer')} to ${colorizePath(gitignorePath)}`\n );\n } else {\n logger(`${v} ${colorizePath(gitignorePath)} already includes .intlayer`);\n }\n }\n\n // SCAFFOLD GITHUB ACTIONS WORKFLOWS (fill + test)\n // Generate two workflows whose commands match the detected package manager:\n // - intlayer-fill.yml: auto-fills missing translations on pull requests\n // - intlayer-test.yml: fails the PR when required locales are missing\n if (!options?.noGithubActions) {\n const workflows = getGithubWorkflows(packageManager);\n\n for (const workflow of workflows) {\n if (await exists(rootDir, workflow.filePath)) {\n logger(`${v} ${colorizePath(workflow.filePath)} already exists`);\n continue;\n }\n\n try {\n await ensureDirectory(rootDir, join('.github', 'workflows'));\n await writeFileToRoot(rootDir, workflow.filePath, workflow.content);\n logger(\n `${v} Added GitHub Actions workflow ${colorizePath(workflow.filePath)}`\n );\n } catch {\n logger(\n `${x} Could not create ${colorizePath(workflow.filePath)}. You may need to add it manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // CHECK VS CODE EXTENSION RECOMMENDATIONS\n const vscodeDir = '.vscode';\n const extensionsJsonPath = join(vscodeDir, 'extensions.json');\n const extensionId = 'intlayer.intlayer-vs-code-extension';\n\n try {\n let extensionsConfig: { recommendations: string[] } = {\n recommendations: [],\n };\n\n if (await exists(rootDir, extensionsJsonPath)) {\n const content = await readFileFromRoot(rootDir, extensionsJsonPath);\n extensionsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n if (!extensionsConfig.recommendations) {\n extensionsConfig.recommendations = [];\n }\n\n if (!extensionsConfig.recommendations.includes(extensionId)) {\n extensionsConfig.recommendations.push(extensionId);\n await writeFileToRoot(\n rootDir,\n extensionsJsonPath,\n JSON.stringify(extensionsConfig, null, 2)\n );\n logger(\n `${v} Added ${colorize(extensionId, ANSIColors.MAGENTA)} to ${colorizePath(extensionsJsonPath)}`\n );\n } else {\n logger(\n `${v} ${colorizePath(extensionsJsonPath)} already includes ${colorize(extensionId, ANSIColors.MAGENTA)}`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(extensionsJsonPath)}. You may need to add ${colorize(extensionId, ANSIColors.MAGENTA)} manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n try {\n let settingsConfig: Record<string, unknown> = {};\n\n if (await exists(rootDir, settingsJsonPath)) {\n const content = await readFileFromRoot(rootDir, settingsJsonPath);\n settingsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n let settingsUpdated = false;\n\n if (!settingsConfig['intlayer.languageServer.command']) {\n settingsConfig['intlayer.languageServer.command'] = 'npx';\n settingsUpdated = true;\n }\n\n if (!settingsConfig['intlayer.languageServer.args']) {\n settingsConfig['intlayer.languageServer.args'] = ['@intlayer/lsp'];\n settingsUpdated = true;\n }\n\n if (settingsUpdated) {\n await writeFileToRoot(\n rootDir,\n settingsJsonPath,\n JSON.stringify(settingsConfig, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(settingsJsonPath)} with LSP configuration`\n );\n } else {\n logger(\n `${v} ${colorizePath(settingsJsonPath)} already includes LSP configuration`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(settingsJsonPath)}. You may need to add the LSP settings manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK TSCONFIGS\n const tsConfigFiles = await findTsConfigFiles(rootDir);\n let hasTsConfig = false;\n\n for (const fileName of tsConfigFiles) {\n if (await exists(rootDir, fileName)) {\n hasTsConfig = true;\n try {\n const fileContent = await readFileFromRoot(rootDir, fileName);\n const config = parseJSONWithComments(fileContent);\n const typeDefinition = '.intlayer/**/*.ts';\n\n let updated = false;\n\n if (!config.include) {\n // Skip if no include array (solution-style)\n } else if (\n Array.isArray(config.include) &&\n !(config.include as string[]).some((pattern: string) =>\n pattern.includes('.intlayer')\n )\n ) {\n config.include.push(typeDefinition);\n updated = true;\n } else if (config.include.includes(typeDefinition)) {\n logger(\n `${v} ${colorizePath(fileName)} already includes intlayer types`\n );\n }\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n fileName,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(fileName)} to include intlayer types`\n );\n }\n } catch {\n logger(\n `${x} Could not parse or update ${colorizePath(fileName)}. You may need to add ${colorizePath('.intlayer/types/**/*.ts')} manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // INITIALIZE CONFIG FILE\n const format = hasTsConfig ? 'intlayer.config.ts' : 'intlayer.config.mjs';\n\n // Detect the locale JSON file pattern already in the project so we can\n // insert the matching locales into the config and produce the most\n // accurate source template for compat libraries.\n const detectedPattern = await detectJsonLocalePattern(rootDir);\n\n await initConfig(format, rootDir, detectedPattern?.locales);\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES\n if (compatSyncConfig) {\n const resolvedSyncConfig = detectedPattern\n ? { ...compatSyncConfig, sourceTemplate: detectedPattern.template }\n : compatSyncConfig;\n\n const intlayerConfigCandidates = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n ];\n\n for (const configFile of intlayerConfigCandidates) {\n if (await exists(rootDir, configFile)) {\n const configContent = await readFileFromRoot(rootDir, configFile);\n\n if (!configContent.includes('@intlayer/sync-json-plugin')) {\n const extension = configFile.split('.').pop()!;\n const updatedConfigContent = updateIntlayerConfigWithSyncPlugin(\n configContent,\n extension,\n resolvedSyncConfig\n );\n await writeFileToRoot(rootDir, configFile, updatedConfigContent);\n logger(\n `${v} Updated ${colorizePath(configFile)} with syncJSON compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes syncJSON plugin`\n );\n }\n break;\n }\n }\n }\n\n let hasAliasConfiguration = false;\n\n // CHECK VITE CONFIG\n const viteConfigs = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];\n\n for (const file of viteConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (compatVitePluginConfig) {\n if (!content.includes(compatVitePluginConfig.pluginPackageSource)) {\n const updatedContent = updateViteConfigForCompatPlugin(\n content,\n extension,\n compatVitePluginConfig\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include ${compatVitePluginConfig.pluginFunctionName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n }\n } else if (!content.includes('vite-intlayer')) {\n const updatedContent = updateViteConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK NEXT CONFIG\n const nextConfigs = ['next.config.js', 'next.config.mjs', 'next.config.ts'];\n let isNextJsProject = false;\n\n for (const file of nextConfigs) {\n if (await exists(rootDir, file)) {\n isNextJsProject = true;\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (allDeps['next-i18next']) {\n if (!content.includes('@intlayer/next-i18next')) {\n const updatedContent = updateNextConfigForNextI18next(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-i18next compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-i18next`\n );\n }\n } else if (allDeps['next-intl']) {\n if (!content.includes('@intlayer/next-intl/plugin')) {\n const updatedContent = updateNextConfigForNextIntl(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-intl compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-intl/plugin`\n );\n }\n } else if (allDeps['next-translate']) {\n if (!content.includes('@intlayer/next-translate')) {\n const updatedContent = updateNextConfigForNextTranslate(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-translate compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-translate`\n );\n }\n } else if (!content.includes('next-intlayer')) {\n const updatedContent = updateNextConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK OTHER FRAMEWORKS CONFIG\n const astroConfigs = [\n 'astro.config.mjs',\n 'astro.config.js',\n 'astro.config.ts',\n 'astro.config.cjs',\n ];\n\n for (const file of astroConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n if (file.startsWith('astro.config.')) {\n const content = await readFileFromRoot(rootDir, file);\n\n if (!content.includes('astro-intlayer')) {\n const extension = file.split('.').pop()!;\n const updatedContent = updateAstroConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer integration`\n );\n }\n }\n break;\n }\n }\n\n const nuxtConfigs = ['nuxt.config.js', 'nuxt.config.ts'];\n for (const file of nuxtConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n const content = await readFileFromRoot(rootDir, file);\n\n if (allDeps['@nuxtjs/i18n']) {\n if (!content.includes('@intlayer/nuxtjs-i18n')) {\n const updatedContent = updateNuxtConfigForNuxtjsI18n(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include @intlayer/nuxtjs-i18n module`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/nuxtjs-i18n`\n );\n }\n } else if (!content.includes('nuxt-intlayer')) {\n const updatedContent = updateNuxtConfig(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer module`);\n }\n break;\n }\n }\n\n // UPDATE PACKAGE.JSON DEV SCRIPT\n // Next.js >= 16 uses a bun-specific wrapper; backend frameworks wrap whatever\n // the existing dev script is. Both use `intlayer watch --with`.\n const isVersionGreaterOrEqual = (\n versionString: string,\n major: number\n ): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const match = versionString.match(/^[^\\d]*(\\d+)/);\n\n if (!match?.[1]) return false;\n\n return parseInt(match[1], 10) >= major;\n };\n\n const backendIntlayerPackages = [\n 'express-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'hono-intlayer',\n ];\n\n const devScript = packageJson.scripts?.dev;\n\n let newDevScript: string | undefined;\n\n if (\n ((isNextJsProject &&\n allDeps.next &&\n isVersionGreaterOrEqual(allDeps.next, 16)) ||\n backendIntlayerPackages.some((pkg) => allDeps[pkg])) &&\n !devScript.includes('intlayer watch')\n ) {\n newDevScript = `intlayer watch --with '${devScript}'`;\n }\n\n if (newDevScript) {\n packageJson.scripts.dev = newDevScript;\n\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath('package.json')} dev script to run intlayer watch`\n );\n }\n\n // CHECK WEBPACK CONFIG\n const webpackConfigs = [\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'webpack.config.cjs',\n ];\n\n for (const file of webpackConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n logger(\n `${v} Found ${colorizePath(\n file\n )}. Make sure to configure aliases manually or use the Intlayer Webpack plugin.`\n );\n break;\n }\n }\n\n const backendConfigPackages = [\n 'express',\n 'fastify',\n '@adonisjs/core',\n 'hono',\n ...backendIntlayerPackages,\n ];\n\n if (backendConfigPackages.some((pkg) => allDeps[pkg])) {\n hasAliasConfiguration = true;\n }\n\n if (!hasAliasConfiguration) {\n const configuration = getConfiguration({ baseDir: rootDir });\n const aliases = getAlias({ configuration });\n\n if (hasTsConfig && tsConfigFiles.length > 0) {\n const tsConfigPath =\n tsConfigFiles.find((file) => file === 'tsconfig.json') ||\n tsConfigFiles[0];\n\n if (tsConfigPath) {\n const tsConfigContent = await readFileFromRoot(rootDir, tsConfigPath);\n const config = parseJSONWithComments(tsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n tsConfigPath,\n JSON.stringify(config, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath(\n tsConfigPath\n )} to include Intlayer aliases`\n );\n }\n }\n } else {\n const jsConfigPath = 'jsconfig.json';\n\n if (await exists(rootDir, jsConfigPath)) {\n const jsConfigContent = await readFileFromRoot(rootDir, jsConfigPath);\n const config = parseJSONWithComments(jsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n jsConfigPath,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n jsConfigPath\n )} to include Intlayer aliases`\n );\n }\n } else {\n packageJson.imports ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n const importAlias = alias.replace('@', '#');\n const importPath = path.startsWith('.') ? path : `./${path}`;\n\n if (!packageJson.imports[importAlias]) {\n packageJson.imports[importAlias] = importPath;\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n packageJsonPath\n )} to include Intlayer imports`\n );\n }\n }\n }\n }\n\n // FINAL SUCCESS MESSAGE\n logger(`${v} ${colorize('Intlayer init setup complete.', ANSIColors.GREEN)}`);\n logger([\n colorize('Next →', ANSIColors.MAGENTA),\n colorize(\n `Follow the instructions in the documentation to complete the setup:`,\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(guideUrl),\n ]);\n\n // INTLAYER LSP — instruction for the AI agent running `intlayer init`.\n // The Intlayer Language Server (`@intlayer/lsp`) provides Go-to-Definition\n // from `useIntlayer` / `getIntlayer` keys to their `.content` files, for both\n // IDEs and AI agents. Setup is editor-specific (VS Code, Cursor, Windsurf,\n // Zed, Neovim, Claude Code, …), so we don't scaffold anything here — instead\n // we point to the doc and ask the agent to confirm the target platform.\n logger([\n colorize('Intlayer LSP →', ANSIColors.MAGENTA),\n colorize(\n 'The Intlayer Language Server is available via the `@intlayer/lsp` package. It lets IDEs and AI agents jump from `useIntlayer`/`getIntlayer` keys to their `.content` files.',\n ANSIColors.GREY_LIGHT\n ),\n colorize(\n 'Ask the user which platform/editor they want to enable it on (VS Code, Cursor, Windsurf, Zed, Neovim, Claude Code, …), then follow the matching setup instructions:',\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(DocumentationRouter.LSP),\n ]);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["ANSIColors","exists","x","readFileFromRoot","detectPackageManager","detectMissingIntlayerPackages","v","writeFileToRoot","getGithubWorkflows","ensureDirectory","parseJSONWithComments","findTsConfigFiles","detectJsonLocalePattern","initConfig","detectNextIntlMessagesPattern","updateIntlayerConfigWithSyncPlugin","updateViteConfigForCompatPlugin","updateViteConfig","updateNextConfigForNextI18next","updateNextConfigForNextIntl","updateNextConfigForNextTranslate","updateNextConfig","updateAstroConfig","updateNuxtConfigForNuxtjsI18n","updateNuxtConfig"],"sources":["../../../src/init/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\n\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport {\n detectJsonLocalePattern,\n detectMissingIntlayerPackages,\n detectNextIntlMessagesPattern,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n installPackages,\n parseJSONWithComments,\n readFileFromRoot,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n writeFileToRoot,\n} from './utils';\n\n/**\n * Documentation URL Constants\n */\nconst DocumentationRouter = {\n NextJS: 'https://intlayer.org/doc/environment/nextjs.md',\n NextJS_15: 'https://intlayer.org/doc/environment/nextjs/15.md',\n NextJS_14: 'https://intlayer.org/doc/environment/nextjs/14.md',\n CRA: 'https://intlayer.org/doc/environment/create-react-app.md',\n Astro: 'https://intlayer.org/doc/environment/astro.md',\n ViteAndReact: 'https://intlayer.org/doc/environment/vite-and-react.md',\n ViteAndReact_ReactRouterV7:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7.md',\n ViteAndReact_ReactRouterV7_FSRoutes:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7-fs-routes.md',\n ViteAndVue: 'https://intlayer.org/doc/environment/vite-and-vue.md',\n ViteAndSolid: 'https://intlayer.org/doc/environment/vite-and-solid.md',\n ViteAndSvelte: 'https://intlayer.org/doc/environment/vite-and-svelte.md',\n ViteAndPreact: 'https://intlayer.org/doc/environment/vite-and-preact.md',\n TanStackRouter: 'https://intlayer.org/doc/environment/tanstack.md',\n NuxtAndVue: 'https://intlayer.org/doc/environment/nuxt-and-vue.md',\n Angular: 'https://intlayer.org/doc/environment/angular.md',\n SvelteKit: 'https://intlayer.org/doc/environment/sveltekit.md',\n ReactNativeAndExpo:\n 'https://intlayer.org/doc/environment/react-native-and-expo.md',\n Lynx: 'https://intlayer.org/doc/environment/lynx-and-react.md',\n Express: 'https://intlayer.org/doc/environment/express.md',\n NestJS: 'https://intlayer.org/doc/environment/nestjs.md',\n Fastify: 'https://intlayer.org/doc/environment/fastify.md',\n Default: 'https://intlayer.org/doc/get-started',\n\n // Intlayer Language Server (Go-to-Definition from getter keys to .content files)\n LSP: 'https://intlayer.org/doc/lsp.md',\n\n // Check for competitors libs\n NextIntl: 'https://intlayer.org/blog/intlayer-with-next-intl.md',\n ReactI18Next: 'https://intlayer.org/blog/intlayer-with-react-i18next.md',\n ReactIntl: 'https://intlayer.org/blog/intlayer-with-react-intl.md',\n NextI18Next: 'https://intlayer.org/blog/intlayer-with-next-i18next.md',\n VueI18n: 'https://intlayer.org/blog/intlayer-with-vue-i18n.md',\n};\n\n/**\n * Helper: Detects the environment and returns the doc URL\n */\nconst getDocumentationUrl = (packageJson: any): string => {\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n /**\n * Helper to check if a version string matches a specific major version\n * Matches: \"15\", \"^15.0.0\", \"~15.2\", \"15.0.0-beta\"\n */\n const isVersion = (versionString: string, major: number): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const regex = new RegExp(`^[\\\\^~]?${major}(?:\\\\.|$)`);\n return regex.test(versionString);\n };\n\n // Mobile / Cross-platform\n if (deps['@lynx-js/react'] || deps['@lynx-js/core']) {\n return DocumentationRouter.Lynx;\n }\n if (deps['react-native'] || deps.expo) {\n return DocumentationRouter.ReactNativeAndExpo;\n }\n\n // Meta-frameworks (Next, Nuxt, Astro, SvelteKit)\n if (deps.next) {\n const version = deps.next;\n\n if (isVersion(version, 14)) {\n return DocumentationRouter.NextJS_14;\n }\n\n if (isVersion(version, 15)) {\n return DocumentationRouter.NextJS_15;\n }\n\n return DocumentationRouter.NextJS;\n }\n\n if (deps.nuxt) return DocumentationRouter.NuxtAndVue;\n if (deps.astro) return DocumentationRouter.Astro;\n if (deps['@sveltejs/kit']) return DocumentationRouter.SvelteKit;\n\n // Routers (TanStack & React Router v7)\n if (deps['@tanstack/react-router']) {\n return DocumentationRouter.TanStackRouter;\n }\n\n // Check for React Router v7\n const reactRouterVersion = deps['react-router'];\n if (reactRouterVersion && typeof reactRouterVersion === 'string') {\n // Distinguish between standard v7 and v7 with FS routes\n if (deps['@react-router/fs-routes']) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7_FSRoutes;\n }\n\n // Use Regex to ensure it is v7\n if (isVersion(reactRouterVersion, 7)) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7;\n }\n }\n\n // Vite Ecosystem (General)\n if (deps.vite) {\n if (deps.vue) return DocumentationRouter.ViteAndVue;\n if (deps['solid-js']) return DocumentationRouter.ViteAndSolid;\n if (deps.svelte) return DocumentationRouter.ViteAndSvelte;\n if (deps.preact) return DocumentationRouter.ViteAndPreact;\n\n // Default to React if Vite is present but specific other frameworks aren't found\n return DocumentationRouter.ViteAndReact;\n }\n\n // Other Web Frameworks\n if (deps['react-scripts']) return DocumentationRouter.CRA;\n if (deps['@angular/core']) return DocumentationRouter.Angular;\n\n // Backend\n if (deps['@nestjs/core']) return DocumentationRouter.NestJS;\n if (deps.express) return DocumentationRouter.Express;\n if (deps.fastify) return DocumentationRouter.Fastify;\n\n // Competitor Libs (Migration Guides)\n // We check these last as specific environment setup is usually higher priority,\n // but if no specific framework logic matched (or as a fallback), we guide to migration.\n if (deps['next-intl']) return DocumentationRouter.NextIntl;\n if (deps['react-i18next'] || deps.i18next)\n return DocumentationRouter.ReactI18Next;\n if (deps['react-intl']) return DocumentationRouter.ReactIntl;\n if (deps['next-i18next']) return DocumentationRouter.NextI18Next;\n if (deps['vue-i18n']) return DocumentationRouter.VueI18n;\n\n return DocumentationRouter.Default;\n};\n\n/**\n * OPTIONS\n */\nexport type InitOptions = {\n noGitignore?: boolean;\n /** Skip scaffolding the `fill` and `test` GitHub Actions workflows. */\n noGithubActions?: boolean;\n};\n\n/**\n * MAIN LOGIC\n */\nexport const initIntlayer = async (rootDir: string, options?: InitOptions) => {\n logger(colorize('Checking Intlayer configuration...', ANSIColors.CYAN));\n\n // READ PACKAGE.JSON\n const packageJsonPath = 'package.json';\n if (!(await exists(rootDir, packageJsonPath))) {\n logger(\n `${x} No ${colorizePath('package.json')} found. Please run this script from the project root.`,\n { level: 'error' }\n );\n process.exit(1);\n }\n\n const packageJsonContent = await readFileFromRoot(rootDir, packageJsonPath);\n let packageJson: Record<string, any>;\n try {\n packageJson = JSON.parse(packageJsonContent);\n } catch {\n logger(`${x} Could not parse ${colorizePath('package.json')}.`, {\n level: 'error',\n });\n process.exit(1);\n }\n\n // Determine the correct documentation URL based on dependencies\n const guideUrl = getDocumentationUrl(packageJson);\n\n const allDeps: Record<string, string> = {\n ...(packageJson.dependencies ?? {}),\n ...(packageJson.devDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(allDeps);\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(rootDir, packagesToInstall, packageManager);\n logger(\n `${v} Installed: ${packagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install packages. Please install manually: ${packagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n if (devPackagesToInstall.length > 0) {\n logger(\n colorize(\n 'Installing missing Intlayer dev dependencies...',\n ANSIColors.CYAN\n )\n );\n try {\n installPackages(rootDir, devPackagesToInstall, packageManager, true);\n logger(\n `${v} Installed: ${devPackagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install dev packages. Please install manually: ${devPackagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n // CHECK .GITIGNORE\n const gitignorePath = '.gitignore';\n if (!options?.noGitignore && (await exists(rootDir, gitignorePath))) {\n const gitignoreContent = await readFileFromRoot(rootDir, gitignorePath);\n\n if (!gitignoreContent.includes('intlayer')) {\n const newContent = `${gitignoreContent}\\n# Intlayer\\n.intlayer\\n`;\n await writeFileToRoot(rootDir, gitignorePath, newContent);\n logger(\n `${v} Added ${colorizePath('.intlayer')} to ${colorizePath(gitignorePath)}`\n );\n } else {\n logger(`${v} ${colorizePath(gitignorePath)} already includes .intlayer`);\n }\n }\n\n // SCAFFOLD GITHUB ACTIONS WORKFLOWS (fill + test)\n // Generate two workflows whose commands match the detected package manager:\n // - intlayer-fill.yml: auto-fills missing translations on pull requests\n // - intlayer-test.yml: fails the PR when required locales are missing\n if (!options?.noGithubActions) {\n const workflows = getGithubWorkflows(packageManager);\n\n for (const workflow of workflows) {\n if (await exists(rootDir, workflow.filePath)) {\n logger(`${v} ${colorizePath(workflow.filePath)} already exists`);\n continue;\n }\n\n try {\n await ensureDirectory(rootDir, join('.github', 'workflows'));\n await writeFileToRoot(rootDir, workflow.filePath, workflow.content);\n logger(\n `${v} Added GitHub Actions workflow ${colorizePath(workflow.filePath)}`\n );\n } catch {\n logger(\n `${x} Could not create ${colorizePath(workflow.filePath)}. You may need to add it manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // CHECK VS CODE EXTENSION RECOMMENDATIONS\n const vscodeDir = '.vscode';\n const extensionsJsonPath = join(vscodeDir, 'extensions.json');\n const extensionId = 'intlayer.intlayer-vs-code-extension';\n\n try {\n let extensionsConfig: { recommendations: string[] } = {\n recommendations: [],\n };\n\n if (await exists(rootDir, extensionsJsonPath)) {\n const content = await readFileFromRoot(rootDir, extensionsJsonPath);\n extensionsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n if (!extensionsConfig.recommendations) {\n extensionsConfig.recommendations = [];\n }\n\n if (!extensionsConfig.recommendations.includes(extensionId)) {\n extensionsConfig.recommendations.push(extensionId);\n await writeFileToRoot(\n rootDir,\n extensionsJsonPath,\n JSON.stringify(extensionsConfig, null, 2)\n );\n logger(\n `${v} Added ${colorize(extensionId, ANSIColors.MAGENTA)} to ${colorizePath(extensionsJsonPath)}`\n );\n } else {\n logger(\n `${v} ${colorizePath(extensionsJsonPath)} already includes ${colorize(extensionId, ANSIColors.MAGENTA)}`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(extensionsJsonPath)}. You may need to add ${colorize(extensionId, ANSIColors.MAGENTA)} manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n try {\n let settingsConfig: Record<string, unknown> = {};\n\n if (await exists(rootDir, settingsJsonPath)) {\n const content = await readFileFromRoot(rootDir, settingsJsonPath);\n settingsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n let settingsUpdated = false;\n\n if (!settingsConfig['intlayer.languageServer.command']) {\n settingsConfig['intlayer.languageServer.command'] = 'npx';\n settingsUpdated = true;\n }\n\n if (!settingsConfig['intlayer.languageServer.args']) {\n settingsConfig['intlayer.languageServer.args'] = ['@intlayer/lsp'];\n settingsUpdated = true;\n }\n\n if (settingsUpdated) {\n await writeFileToRoot(\n rootDir,\n settingsJsonPath,\n JSON.stringify(settingsConfig, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(settingsJsonPath)} with LSP configuration`\n );\n } else {\n logger(\n `${v} ${colorizePath(settingsJsonPath)} already includes LSP configuration`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(settingsJsonPath)}. You may need to add the LSP settings manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK TSCONFIGS\n const tsConfigFiles = await findTsConfigFiles(rootDir);\n let hasTsConfig = false;\n\n for (const fileName of tsConfigFiles) {\n if (await exists(rootDir, fileName)) {\n hasTsConfig = true;\n try {\n const fileContent = await readFileFromRoot(rootDir, fileName);\n const config = parseJSONWithComments(fileContent);\n const typeDefinition = '.intlayer/**/*.ts';\n\n let updated = false;\n\n if (!config.include) {\n // Skip if no include array (solution-style)\n } else if (\n Array.isArray(config.include) &&\n !(config.include as string[]).some((pattern: string) =>\n pattern.includes('.intlayer')\n )\n ) {\n config.include.push(typeDefinition);\n updated = true;\n } else if (config.include.includes(typeDefinition)) {\n logger(\n `${v} ${colorizePath(fileName)} already includes intlayer types`\n );\n }\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n fileName,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(fileName)} to include intlayer types`\n );\n }\n } catch {\n logger(\n `${x} Could not parse or update ${colorizePath(fileName)}. You may need to add ${colorizePath('.intlayer/types/**/*.ts')} manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // INITIALIZE CONFIG FILE\n const format = hasTsConfig ? 'intlayer.config.ts' : 'intlayer.config.mjs';\n\n // Detect the locale JSON file pattern already in the project so we can\n // insert the matching locales into the config and produce the most\n // accurate source template for compat libraries.\n const detectedPattern = await detectJsonLocalePattern(rootDir);\n\n await initConfig(format, rootDir, detectedPattern?.locales);\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES\n if (compatSyncConfig) {\n // For next-intl / use-intl, the messages path is authoritatively declared\n // in `i18n/request.ts` (e.g. `import(`../messages/${locale}.json`)`), so we\n // read it directly. It usually resolves to a single file per locale (no\n // `${key}` segment), which `syncJSON` splits per top-level namespace key via\n // `splitKeys` auto-detection. Falls back to file-system globbing otherwise.\n const nextIntlMessagesPattern =\n allDeps['next-intl'] ||\n allDeps['@intlayer/next-intl'] ||\n allDeps['use-intl'] ||\n allDeps['@intlayer/use-intl']\n ? await detectNextIntlMessagesPattern(rootDir)\n : null;\n\n const sourceTemplate =\n nextIntlMessagesPattern?.template ?? detectedPattern?.template;\n\n const resolvedSyncConfig = sourceTemplate\n ? { ...compatSyncConfig, sourceTemplate }\n : compatSyncConfig;\n\n const intlayerConfigCandidates = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n ];\n\n for (const configFile of intlayerConfigCandidates) {\n if (await exists(rootDir, configFile)) {\n const configContent = await readFileFromRoot(rootDir, configFile);\n\n if (!configContent.includes('@intlayer/sync-json-plugin')) {\n const extension = configFile.split('.').pop()!;\n const updatedConfigContent = updateIntlayerConfigWithSyncPlugin(\n configContent,\n extension,\n resolvedSyncConfig\n );\n await writeFileToRoot(rootDir, configFile, updatedConfigContent);\n logger(\n `${v} Updated ${colorizePath(configFile)} with syncJSON compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes syncJSON plugin`\n );\n }\n break;\n }\n }\n }\n\n let hasAliasConfiguration = false;\n\n // CHECK VITE CONFIG\n const viteConfigs = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];\n\n for (const file of viteConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (compatVitePluginConfig) {\n if (!content.includes(compatVitePluginConfig.pluginPackageSource)) {\n const updatedContent = updateViteConfigForCompatPlugin(\n content,\n extension,\n compatVitePluginConfig\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include ${compatVitePluginConfig.pluginFunctionName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n }\n } else if (!content.includes('vite-intlayer')) {\n const updatedContent = updateViteConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK NEXT CONFIG\n const nextConfigs = ['next.config.js', 'next.config.mjs', 'next.config.ts'];\n let isNextJsProject = false;\n\n for (const file of nextConfigs) {\n if (await exists(rootDir, file)) {\n isNextJsProject = true;\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (allDeps['next-i18next']) {\n if (!content.includes('@intlayer/next-i18next')) {\n const updatedContent = updateNextConfigForNextI18next(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-i18next compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-i18next`\n );\n }\n } else if (allDeps['next-intl']) {\n if (!content.includes('@intlayer/next-intl/plugin')) {\n const updatedContent = updateNextConfigForNextIntl(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-intl compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-intl/plugin`\n );\n }\n } else if (allDeps['next-translate']) {\n if (!content.includes('@intlayer/next-translate')) {\n const updatedContent = updateNextConfigForNextTranslate(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-translate compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-translate`\n );\n }\n } else if (!content.includes('next-intlayer')) {\n const updatedContent = updateNextConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK OTHER FRAMEWORKS CONFIG\n const astroConfigs = [\n 'astro.config.mjs',\n 'astro.config.js',\n 'astro.config.ts',\n 'astro.config.cjs',\n ];\n\n for (const file of astroConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n if (file.startsWith('astro.config.')) {\n const content = await readFileFromRoot(rootDir, file);\n\n if (!content.includes('astro-intlayer')) {\n const extension = file.split('.').pop()!;\n const updatedContent = updateAstroConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer integration`\n );\n }\n }\n break;\n }\n }\n\n const nuxtConfigs = ['nuxt.config.js', 'nuxt.config.ts'];\n for (const file of nuxtConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n const content = await readFileFromRoot(rootDir, file);\n\n if (allDeps['@nuxtjs/i18n']) {\n if (!content.includes('@intlayer/nuxtjs-i18n')) {\n const updatedContent = updateNuxtConfigForNuxtjsI18n(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include @intlayer/nuxtjs-i18n module`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/nuxtjs-i18n`\n );\n }\n } else if (!content.includes('nuxt-intlayer')) {\n const updatedContent = updateNuxtConfig(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer module`);\n }\n break;\n }\n }\n\n // UPDATE PACKAGE.JSON DEV SCRIPT\n // Next.js >= 16 uses a bun-specific wrapper; backend frameworks wrap whatever\n // the existing dev script is. Both use `intlayer watch --with`.\n const isVersionGreaterOrEqual = (\n versionString: string,\n major: number\n ): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const match = versionString.match(/^[^\\d]*(\\d+)/);\n\n if (!match?.[1]) return false;\n\n return parseInt(match[1], 10) >= major;\n };\n\n const backendIntlayerPackages = [\n 'express-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'hono-intlayer',\n ];\n\n const devScript = packageJson.scripts?.dev;\n\n let newDevScript: string | undefined;\n\n if (\n ((isNextJsProject &&\n allDeps.next &&\n isVersionGreaterOrEqual(allDeps.next, 16)) ||\n backendIntlayerPackages.some((pkg) => allDeps[pkg])) &&\n !devScript.includes('intlayer watch')\n ) {\n newDevScript = `intlayer watch --with '${devScript}'`;\n }\n\n if (newDevScript) {\n packageJson.scripts.dev = newDevScript;\n\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath('package.json')} dev script to run intlayer watch`\n );\n }\n\n // CHECK WEBPACK CONFIG\n const webpackConfigs = [\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'webpack.config.cjs',\n ];\n\n for (const file of webpackConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n logger(\n `${v} Found ${colorizePath(\n file\n )}. Make sure to configure aliases manually or use the Intlayer Webpack plugin.`\n );\n break;\n }\n }\n\n const backendConfigPackages = [\n 'express',\n 'fastify',\n '@adonisjs/core',\n 'hono',\n ...backendIntlayerPackages,\n ];\n\n if (backendConfigPackages.some((pkg) => allDeps[pkg])) {\n hasAliasConfiguration = true;\n }\n\n if (!hasAliasConfiguration) {\n const configuration = getConfiguration({ baseDir: rootDir });\n const aliases = getAlias({ configuration });\n\n if (hasTsConfig && tsConfigFiles.length > 0) {\n const tsConfigPath =\n tsConfigFiles.find((file) => file === 'tsconfig.json') ||\n tsConfigFiles[0];\n\n if (tsConfigPath) {\n const tsConfigContent = await readFileFromRoot(rootDir, tsConfigPath);\n const config = parseJSONWithComments(tsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n tsConfigPath,\n JSON.stringify(config, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath(\n tsConfigPath\n )} to include Intlayer aliases`\n );\n }\n }\n } else {\n const jsConfigPath = 'jsconfig.json';\n\n if (await exists(rootDir, jsConfigPath)) {\n const jsConfigContent = await readFileFromRoot(rootDir, jsConfigPath);\n const config = parseJSONWithComments(jsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n jsConfigPath,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n jsConfigPath\n )} to include Intlayer aliases`\n );\n }\n } else {\n packageJson.imports ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n const importAlias = alias.replace('@', '#');\n const importPath = path.startsWith('.') ? path : `./${path}`;\n\n if (!packageJson.imports[importAlias]) {\n packageJson.imports[importAlias] = importPath;\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n packageJsonPath\n )} to include Intlayer imports`\n );\n }\n }\n }\n }\n\n // FINAL SUCCESS MESSAGE\n logger(`${v} ${colorize('Intlayer init setup complete.', ANSIColors.GREEN)}`);\n logger([\n colorize('Next →', ANSIColors.MAGENTA),\n colorize(\n `Follow the instructions in the documentation to complete the setup:`,\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(guideUrl),\n ]);\n\n // INTLAYER LSP — instruction for the AI agent running `intlayer init`.\n // The Intlayer Language Server (`@intlayer/lsp`) provides Go-to-Definition\n // from `useIntlayer` / `getIntlayer` keys to their `.content` files, for both\n // IDEs and AI agents. Setup is editor-specific (VS Code, Cursor, Windsurf,\n // Zed, Neovim, Claude Code, …), so we don't scaffold anything here — instead\n // we point to the doc and ask the agent to confirm the target platform.\n logger([\n colorize('Intlayer LSP →', ANSIColors.MAGENTA),\n colorize(\n 'The Intlayer Language Server is available via the `@intlayer/lsp` package. It lets IDEs and AI agents jump from `useIntlayer`/`getIntlayer` keys to their `.content` files.',\n ANSIColors.GREY_LIGHT\n ),\n colorize(\n 'Ask the user which platform/editor they want to enable it on (VS Code, Cursor, Windsurf, Zed, Neovim, Claude Code, …), then follow the matching setup instructions:',\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(DocumentationRouter.LSP),\n ]);\n};\n"],"mappings":"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"}
@@ -126,9 +126,54 @@ const detectJsonLocalePattern = async (rootDir) => {
126
126
  locales: Array.from(flatLocales)
127
127
  };
128
128
  };
129
+ /** Common locations of the `next-intl` request config, relative to the root. */
130
+ const NEXT_INTL_REQUEST_FILES = [
131
+ "i18n/request.ts",
132
+ "i18n/request.tsx",
133
+ "i18n/request.js",
134
+ "i18n/request.mjs",
135
+ "src/i18n/request.ts",
136
+ "src/i18n/request.tsx",
137
+ "src/i18n/request.js",
138
+ "src/i18n/request.mjs",
139
+ "app/i18n/request.ts",
140
+ "src/app/i18n/request.ts"
141
+ ];
142
+ /**
143
+ * Derives the messages source template from a `next-intl` `i18n/request.ts`
144
+ * file, which is the authoritative location of the messages path in a next-intl
145
+ * project (e.g. `messages: (await import(\`../messages/${locale}.json\`)).default`).
146
+ *
147
+ * Reading it removes the ambiguity of globbing the file system and yields the
148
+ * exact `source` template for `syncJSON`. When the resulting template has no
149
+ * `${key}` segment (the common single-file-per-locale layout, where top-level
150
+ * keys are namespaces), `syncJSON` `splitKeys` auto-detection turns each
151
+ * top-level key into its own dictionary.
152
+ *
153
+ * Returns `null` when no request file is found, the messages import cannot be
154
+ * parsed, or the path is not project-root-relative (e.g. uses a TS path alias).
155
+ *
156
+ * @param rootDir - Project root directory.
157
+ */
158
+ const detectNextIntlMessagesPattern = async (rootDir) => {
159
+ for (const requestFile of NEXT_INTL_REQUEST_FILES) {
160
+ if (!await exists(rootDir, requestFile)) continue;
161
+ const importPath = (await readFileFromRoot(rootDir, requestFile)).match(/import\(\s*`([^`]*\$\{\s*locale\s*\}[^`]*\.json)`/)?.[1];
162
+ if (!importPath) continue;
163
+ if (!importPath.startsWith(".")) continue;
164
+ const relativeTemplate = (0, node_path.relative)(rootDir, (0, node_path.resolve)((0, node_path.dirname)((0, node_path.resolve)(rootDir, requestFile)), importPath)).split(node_path.sep).join("/");
165
+ const template = relativeTemplate.startsWith(".") ? relativeTemplate : `./${relativeTemplate}`;
166
+ return {
167
+ type: template.includes("${key}") || template.includes("${namespace}") ? "nested" : "flat",
168
+ template
169
+ };
170
+ }
171
+ return null;
172
+ };
129
173
 
130
174
  //#endregion
131
175
  exports.detectJsonLocalePattern = detectJsonLocalePattern;
176
+ exports.detectNextIntlMessagesPattern = detectNextIntlMessagesPattern;
132
177
  exports.ensureDirectory = ensureDirectory;
133
178
  exports.exists = exists;
134
179
  exports.readFileFromRoot = readFileFromRoot;
@@ -1 +1 @@
1
- {"version":3,"file":"fileSystem.cjs","names":["ALL_LOCALES","EXCLUDED_PATHS"],"sources":["../../../../src/init/utils/fileSystem.ts"],"sourcesContent":["import { access, mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { EXCLUDED_PATHS } from '@intlayer/config/defaultValues';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\n\n/**\n * Helper to check if a file exists\n */\nexport const exists = async (rootDir: string, filePath: string) => {\n try {\n await access(join(rootDir, filePath));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Helper to read a file\n */\nexport const readFileFromRoot = async (rootDir: string, filePath: string) =>\n await readFile(join(rootDir, filePath), 'utf8');\n\n/**\n * Helper to write a file\n */\nexport const writeFileToRoot = async (\n rootDir: string,\n filePath: string,\n content: string\n) => await writeFile(join(rootDir, filePath), content, 'utf8');\n\n/**\n * Helper to ensure a directory exists\n */\nexport const ensureDirectory = async (rootDir: string, dirPath: string) => {\n try {\n await mkdir(join(rootDir, dirPath), { recursive: true });\n } catch {\n // Directory already exists or could not be created\n }\n};\n\n/**\n * Pattern type for locale JSON file organisation.\n * - 'nested': files are at `{base}/{locale}/{key}.json`\n * - 'flat': files are at `{base}/{locale}.json`\n */\nexport type JsonLocalePatternType = 'nested' | 'flat';\n\n/**\n * Detected locale JSON file pattern and the corresponding source template.\n * `template` uses `${locale}` and `${key}` as literal placeholders (not JS\n * expressions) so it can be embedded directly in a template-literal string.\n */\nexport type JsonLocalePattern = {\n type: JsonLocalePatternType;\n /**\n * Source path template for syncJSON `source` option.\n * Example nested: `./locales/${locale}/${key}.json`\n * Example flat: `./locales/${locale}.json`\n */\n template: string;\n /**\n * Detected locales in the directory.\n */\n locales: string[];\n};\n\n/**\n * Set of all known locale string values from the intlayer Locales registry\n * (e.g. `'en'`, `'fr'`, `'zh-TW'`). Keyed by the exact locale string so\n * `.has()` lookups are O(1) and common short directory names (`src`, `lib`,\n * `app`, …) are not mistaken for locales.\n */\nconst ALL_LOCALE_VALUES = new Set<string>(Object.values(ALL_LOCALES));\n\n/**\n * Returns true when `segment` matches a known BCP-47 locale identifier, e.g.\n * `en`, `fr`, `zh-TW`, `pt-BR`, `en-US`.\n */\nconst isLocaleSegment = (segment: string): boolean =>\n ALL_LOCALE_VALUES.has(segment);\n\n/** JSON filenames that are never locale translation files. */\nconst KNOWN_CONFIG_FILENAMES = new Set([\n 'package.json',\n 'tsconfig.json',\n 'jsconfig.json',\n 'biome.json',\n 'turbo.json',\n 'lerna.json',\n 'vercel.json',\n 'netlify.json',\n 'babel.config.json',\n 'jest.config.json',\n 'vitest.config.json',\n '.eslintrc.json',\n '.prettierrc.json',\n]);\n\n/**\n * Scans the project for JSON files and determines whether locale files are\n * organised as `{base}/{locale}/{key}.json` (nested) or `{base}/{locale}.json`\n * (flat). Returns the most likely source template, or `null` when no locale\n * JSON files are found.\n *\n * The returned `template` contains `${locale}` and `${key}` as **literal**\n * placeholder strings so it can be embedded inside a JS template literal.\n */\nexport const detectJsonLocalePattern = async (\n rootDir: string\n): Promise<JsonLocalePattern | null> => {\n const files = await fg('**/*.json', {\n cwd: rootDir,\n ignore: EXCLUDED_PATHS,\n absolute: false,\n onlyFiles: true,\n });\n\n const nestedBasePaths: string[] = [];\n const flatBasePaths: string[] = [];\n const nestedLocales = new Set<string>();\n const flatLocales = new Set<string>();\n\n for (const file of files) {\n const parts = file.split('/');\n const filename = parts[parts.length - 1] ?? '';\n\n if (KNOWN_CONFIG_FILENAMES.has(filename)) continue;\n\n // Nested: …/{locale}/{key}.json — parent directory is a locale code\n if (parts.length >= 3) {\n const localeDir = parts[parts.length - 2] ?? '';\n if (isLocaleSegment(localeDir)) {\n nestedBasePaths.push(parts.slice(0, -2).join('/') || '.');\n nestedLocales.add(localeDir);\n }\n }\n\n // Flat: …/{locale}.json — filename (without extension) is a locale code\n if (parts.length >= 2) {\n const baseName = filename.slice(0, -5); // strip \".json\"\n if (isLocaleSegment(baseName)) {\n flatBasePaths.push(parts.slice(0, -1).join('/') || '.');\n flatLocales.add(baseName);\n }\n }\n }\n\n if (nestedBasePaths.length === 0 && flatBasePaths.length === 0) {\n return null;\n }\n\n /**\n * Returns the path prefix that appears most frequently among the matches,\n * formatted as a relative path suitable for a source template.\n */\n const mostFrequentPrefix = (paths: string[]): string => {\n const counts = paths.reduce<Record<string, number>>((accumulator, path) => {\n accumulator[path] = (accumulator[path] ?? 0) + 1;\n return accumulator;\n }, {});\n const topEntry = Object.entries(counts).sort(([, a], [, b]) => b - a)[0];\n const basePath = topEntry?.[0] ?? '.';\n return basePath === '.' ? '.' : `./${basePath}`;\n };\n\n if (nestedBasePaths.length >= flatBasePaths.length) {\n const prefix = mostFrequentPrefix(nestedBasePaths);\n return {\n type: 'nested',\n // Literal ${locale} and ${key} — not evaluated here, used in template literals\n template: `${prefix}/\\${locale}/\\${key}.json`,\n locales: Array.from(nestedLocales),\n };\n }\n\n const prefix = mostFrequentPrefix(flatBasePaths);\n return {\n type: 'flat',\n template: `${prefix}/\\${locale}.json`,\n locales: Array.from(flatLocales),\n };\n};\n"],"mappings":";;;;;;;;;;;;;AASA,MAAa,SAAS,OAAO,SAAiB,aAAqB;AACjE,KAAI;AACF,yDAAkB,SAAS,SAAS,CAAC;AACrC,SAAO;SACD;AACN,SAAO;;;;;;AAOX,MAAa,mBAAmB,OAAO,SAAiB,aACtD,yDAAoB,SAAS,SAAS,EAAE,OAAO;;;;AAKjD,MAAa,kBAAkB,OAC7B,SACA,UACA,YACG,0DAAqB,SAAS,SAAS,EAAE,SAAS,OAAO;;;;AAK9D,MAAa,kBAAkB,OAAO,SAAiB,YAAoB;AACzE,KAAI;AACF,wDAAiB,SAAS,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;SAClD;;;;;;;;AAqCV,MAAM,oBAAoB,IAAI,IAAY,OAAO,OAAOA,uCAAY,CAAC;;;;;AAMrE,MAAM,mBAAmB,YACvB,kBAAkB,IAAI,QAAQ;;AAGhC,MAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;AAWF,MAAa,0BAA0B,OACrC,YACsC;CACtC,MAAM,QAAQ,6BAAS,aAAa;EAClC,KAAK;EACL,QAAQC;EACR,UAAU;EACV,WAAW;EACZ,CAAC;CAEF,MAAM,kBAA4B,EAAE;CACpC,MAAM,gBAA0B,EAAE;CAClC,MAAM,gCAAgB,IAAI,KAAa;CACvC,MAAM,8BAAc,IAAI,KAAa;AAErC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,KAAK,MAAM,IAAI;EAC7B,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAE5C,MAAI,uBAAuB,IAAI,SAAS,CAAE;AAG1C,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,YAAY,MAAM,MAAM,SAAS,MAAM;AAC7C,OAAI,gBAAgB,UAAU,EAAE;AAC9B,oBAAgB,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACzD,kBAAc,IAAI,UAAU;;;AAKhC,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,WAAW,SAAS,MAAM,GAAG,GAAG;AACtC,OAAI,gBAAgB,SAAS,EAAE;AAC7B,kBAAc,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACvD,gBAAY,IAAI,SAAS;;;;AAK/B,KAAI,gBAAgB,WAAW,KAAK,cAAc,WAAW,EAC3D,QAAO;;;;;CAOT,MAAM,sBAAsB,UAA4B;EACtD,MAAM,SAAS,MAAM,QAAgC,aAAa,SAAS;AACzE,eAAY,SAAS,YAAY,SAAS,KAAK;AAC/C,UAAO;KACN,EAAE,CAAC;EAEN,MAAM,WADW,OAAO,QAAQ,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,KAC1C,MAAM;AAClC,SAAO,aAAa,MAAM,MAAM,KAAK;;AAGvC,KAAI,gBAAgB,UAAU,cAAc,OAE1C,QAAO;EACL,MAAM;EAEN,UAAU,GAJG,mBAAmB,gBAIb,CAAC;EACpB,SAAS,MAAM,KAAK,cAAc;EACnC;AAIH,QAAO;EACL,MAAM;EACN,UAAU,GAHG,mBAAmB,cAGb,CAAC;EACpB,SAAS,MAAM,KAAK,YAAY;EACjC"}
1
+ {"version":3,"file":"fileSystem.cjs","names":["ALL_LOCALES","EXCLUDED_PATHS","sep"],"sources":["../../../../src/init/utils/fileSystem.ts"],"sourcesContent":["import { access, mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { EXCLUDED_PATHS } from '@intlayer/config/defaultValues';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\n\n/**\n * Helper to check if a file exists\n */\nexport const exists = async (rootDir: string, filePath: string) => {\n try {\n await access(join(rootDir, filePath));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Helper to read a file\n */\nexport const readFileFromRoot = async (rootDir: string, filePath: string) =>\n await readFile(join(rootDir, filePath), 'utf8');\n\n/**\n * Helper to write a file\n */\nexport const writeFileToRoot = async (\n rootDir: string,\n filePath: string,\n content: string\n) => await writeFile(join(rootDir, filePath), content, 'utf8');\n\n/**\n * Helper to ensure a directory exists\n */\nexport const ensureDirectory = async (rootDir: string, dirPath: string) => {\n try {\n await mkdir(join(rootDir, dirPath), { recursive: true });\n } catch {\n // Directory already exists or could not be created\n }\n};\n\n/**\n * Pattern type for locale JSON file organisation.\n * - 'nested': files are at `{base}/{locale}/{key}.json`\n * - 'flat': files are at `{base}/{locale}.json`\n */\nexport type JsonLocalePatternType = 'nested' | 'flat';\n\n/**\n * Detected locale JSON file pattern and the corresponding source template.\n * `template` uses `${locale}` and `${key}` as literal placeholders (not JS\n * expressions) so it can be embedded directly in a template-literal string.\n */\nexport type JsonLocalePattern = {\n type: JsonLocalePatternType;\n /**\n * Source path template for syncJSON `source` option.\n * Example nested: `./locales/${locale}/${key}.json`\n * Example flat: `./locales/${locale}.json`\n */\n template: string;\n /**\n * Detected locales in the directory.\n */\n locales: string[];\n};\n\n/**\n * Set of all known locale string values from the intlayer Locales registry\n * (e.g. `'en'`, `'fr'`, `'zh-TW'`). Keyed by the exact locale string so\n * `.has()` lookups are O(1) and common short directory names (`src`, `lib`,\n * `app`, …) are not mistaken for locales.\n */\nconst ALL_LOCALE_VALUES = new Set<string>(Object.values(ALL_LOCALES));\n\n/**\n * Returns true when `segment` matches a known BCP-47 locale identifier, e.g.\n * `en`, `fr`, `zh-TW`, `pt-BR`, `en-US`.\n */\nconst isLocaleSegment = (segment: string): boolean =>\n ALL_LOCALE_VALUES.has(segment);\n\n/** JSON filenames that are never locale translation files. */\nconst KNOWN_CONFIG_FILENAMES = new Set([\n 'package.json',\n 'tsconfig.json',\n 'jsconfig.json',\n 'biome.json',\n 'turbo.json',\n 'lerna.json',\n 'vercel.json',\n 'netlify.json',\n 'babel.config.json',\n 'jest.config.json',\n 'vitest.config.json',\n '.eslintrc.json',\n '.prettierrc.json',\n]);\n\n/**\n * Scans the project for JSON files and determines whether locale files are\n * organised as `{base}/{locale}/{key}.json` (nested) or `{base}/{locale}.json`\n * (flat). Returns the most likely source template, or `null` when no locale\n * JSON files are found.\n *\n * The returned `template` contains `${locale}` and `${key}` as **literal**\n * placeholder strings so it can be embedded inside a JS template literal.\n */\nexport const detectJsonLocalePattern = async (\n rootDir: string\n): Promise<JsonLocalePattern | null> => {\n const files = await fg('**/*.json', {\n cwd: rootDir,\n ignore: EXCLUDED_PATHS,\n absolute: false,\n onlyFiles: true,\n });\n\n const nestedBasePaths: string[] = [];\n const flatBasePaths: string[] = [];\n const nestedLocales = new Set<string>();\n const flatLocales = new Set<string>();\n\n for (const file of files) {\n const parts = file.split('/');\n const filename = parts[parts.length - 1] ?? '';\n\n if (KNOWN_CONFIG_FILENAMES.has(filename)) continue;\n\n // Nested: …/{locale}/{key}.json — parent directory is a locale code\n if (parts.length >= 3) {\n const localeDir = parts[parts.length - 2] ?? '';\n if (isLocaleSegment(localeDir)) {\n nestedBasePaths.push(parts.slice(0, -2).join('/') || '.');\n nestedLocales.add(localeDir);\n }\n }\n\n // Flat: …/{locale}.json — filename (without extension) is a locale code\n if (parts.length >= 2) {\n const baseName = filename.slice(0, -5); // strip \".json\"\n if (isLocaleSegment(baseName)) {\n flatBasePaths.push(parts.slice(0, -1).join('/') || '.');\n flatLocales.add(baseName);\n }\n }\n }\n\n if (nestedBasePaths.length === 0 && flatBasePaths.length === 0) {\n return null;\n }\n\n /**\n * Returns the path prefix that appears most frequently among the matches,\n * formatted as a relative path suitable for a source template.\n */\n const mostFrequentPrefix = (paths: string[]): string => {\n const counts = paths.reduce<Record<string, number>>((accumulator, path) => {\n accumulator[path] = (accumulator[path] ?? 0) + 1;\n return accumulator;\n }, {});\n const topEntry = Object.entries(counts).sort(([, a], [, b]) => b - a)[0];\n const basePath = topEntry?.[0] ?? '.';\n return basePath === '.' ? '.' : `./${basePath}`;\n };\n\n if (nestedBasePaths.length >= flatBasePaths.length) {\n const prefix = mostFrequentPrefix(nestedBasePaths);\n return {\n type: 'nested',\n // Literal ${locale} and ${key} — not evaluated here, used in template literals\n template: `${prefix}/\\${locale}/\\${key}.json`,\n locales: Array.from(nestedLocales),\n };\n }\n\n const prefix = mostFrequentPrefix(flatBasePaths);\n return {\n type: 'flat',\n template: `${prefix}/\\${locale}.json`,\n locales: Array.from(flatLocales),\n };\n};\n\n/**\n * The messages source template derived from a `next-intl` `i18n/request.ts`\n * file, ready to be used as a `syncJSON` `source` builder.\n */\nexport type NextIntlMessagesPattern = {\n /** `'flat'` (one file per locale) or `'nested'` (per-namespace files). */\n type: JsonLocalePatternType;\n /**\n * Source path template relative to the project root, with `${locale}` (and\n * `${key}` when nested) as literal placeholders, e.g. `./messages/${locale}.json`.\n */\n template: string;\n};\n\n/** Common locations of the `next-intl` request config, relative to the root. */\nconst NEXT_INTL_REQUEST_FILES = [\n 'i18n/request.ts',\n 'i18n/request.tsx',\n 'i18n/request.js',\n 'i18n/request.mjs',\n 'src/i18n/request.ts',\n 'src/i18n/request.tsx',\n 'src/i18n/request.js',\n 'src/i18n/request.mjs',\n 'app/i18n/request.ts',\n 'src/app/i18n/request.ts',\n];\n\n/**\n * Derives the messages source template from a `next-intl` `i18n/request.ts`\n * file, which is the authoritative location of the messages path in a next-intl\n * project (e.g. `messages: (await import(\\`../messages/${locale}.json\\`)).default`).\n *\n * Reading it removes the ambiguity of globbing the file system and yields the\n * exact `source` template for `syncJSON`. When the resulting template has no\n * `${key}` segment (the common single-file-per-locale layout, where top-level\n * keys are namespaces), `syncJSON` `splitKeys` auto-detection turns each\n * top-level key into its own dictionary.\n *\n * Returns `null` when no request file is found, the messages import cannot be\n * parsed, or the path is not project-root-relative (e.g. uses a TS path alias).\n *\n * @param rootDir - Project root directory.\n */\nexport const detectNextIntlMessagesPattern = async (\n rootDir: string\n): Promise<NextIntlMessagesPattern | null> => {\n for (const requestFile of NEXT_INTL_REQUEST_FILES) {\n if (!(await exists(rootDir, requestFile))) continue;\n\n const content = await readFileFromRoot(rootDir, requestFile);\n\n // Capture the template-literal path of the messages dynamic import, e.g.\n // import(`../messages/${locale}.json`) → `../messages/${locale}.json`.\n const importMatch = content.match(\n /import\\(\\s*`([^`]*\\$\\{\\s*locale\\s*\\}[^`]*\\.json)`/\n );\n\n const importPath = importMatch?.[1];\n if (!importPath) continue;\n\n // Only relative imports can be resolved against the file system; path\n // aliases (e.g. `@/messages/...`) are skipped in favour of glob detection.\n if (!importPath.startsWith('.')) continue;\n\n // Resolve the import (relative to the request file) back to a\n // project-root-relative template. The `${locale}` / `${key}` placeholders\n // are kept literal — path utilities treat them as ordinary segments.\n const requestDir = dirname(resolve(rootDir, requestFile));\n const absoluteTemplate = resolve(requestDir, importPath);\n const relativeTemplate = relative(rootDir, absoluteTemplate)\n .split(sep)\n .join('/');\n\n const template = relativeTemplate.startsWith('.')\n ? relativeTemplate\n : `./${relativeTemplate}`;\n\n const type: JsonLocalePatternType =\n template.includes('${key}') || template.includes('${namespace}')\n ? 'nested'\n : 'flat';\n\n return { type, template };\n }\n\n return null;\n};\n"],"mappings":";;;;;;;;;;;;;AASA,MAAa,SAAS,OAAO,SAAiB,aAAqB;AACjE,KAAI;AACF,yDAAkB,SAAS,SAAS,CAAC;AACrC,SAAO;SACD;AACN,SAAO;;;;;;AAOX,MAAa,mBAAmB,OAAO,SAAiB,aACtD,yDAAoB,SAAS,SAAS,EAAE,OAAO;;;;AAKjD,MAAa,kBAAkB,OAC7B,SACA,UACA,YACG,0DAAqB,SAAS,SAAS,EAAE,SAAS,OAAO;;;;AAK9D,MAAa,kBAAkB,OAAO,SAAiB,YAAoB;AACzE,KAAI;AACF,wDAAiB,SAAS,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;SAClD;;;;;;;;AAqCV,MAAM,oBAAoB,IAAI,IAAY,OAAO,OAAOA,uCAAY,CAAC;;;;;AAMrE,MAAM,mBAAmB,YACvB,kBAAkB,IAAI,QAAQ;;AAGhC,MAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;AAWF,MAAa,0BAA0B,OACrC,YACsC;CACtC,MAAM,QAAQ,6BAAS,aAAa;EAClC,KAAK;EACL,QAAQC;EACR,UAAU;EACV,WAAW;EACZ,CAAC;CAEF,MAAM,kBAA4B,EAAE;CACpC,MAAM,gBAA0B,EAAE;CAClC,MAAM,gCAAgB,IAAI,KAAa;CACvC,MAAM,8BAAc,IAAI,KAAa;AAErC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,KAAK,MAAM,IAAI;EAC7B,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAE5C,MAAI,uBAAuB,IAAI,SAAS,CAAE;AAG1C,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,YAAY,MAAM,MAAM,SAAS,MAAM;AAC7C,OAAI,gBAAgB,UAAU,EAAE;AAC9B,oBAAgB,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACzD,kBAAc,IAAI,UAAU;;;AAKhC,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,WAAW,SAAS,MAAM,GAAG,GAAG;AACtC,OAAI,gBAAgB,SAAS,EAAE;AAC7B,kBAAc,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACvD,gBAAY,IAAI,SAAS;;;;AAK/B,KAAI,gBAAgB,WAAW,KAAK,cAAc,WAAW,EAC3D,QAAO;;;;;CAOT,MAAM,sBAAsB,UAA4B;EACtD,MAAM,SAAS,MAAM,QAAgC,aAAa,SAAS;AACzE,eAAY,SAAS,YAAY,SAAS,KAAK;AAC/C,UAAO;KACN,EAAE,CAAC;EAEN,MAAM,WADW,OAAO,QAAQ,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,KAC1C,MAAM;AAClC,SAAO,aAAa,MAAM,MAAM,KAAK;;AAGvC,KAAI,gBAAgB,UAAU,cAAc,OAE1C,QAAO;EACL,MAAM;EAEN,UAAU,GAJG,mBAAmB,gBAIb,CAAC;EACpB,SAAS,MAAM,KAAK,cAAc;EACnC;AAIH,QAAO;EACL,MAAM;EACN,UAAU,GAHG,mBAAmB,cAGb,CAAC;EACpB,SAAS,MAAM,KAAK,YAAY;EACjC;;;AAkBH,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAkBD,MAAa,gCAAgC,OAC3C,YAC4C;AAC5C,MAAK,MAAM,eAAe,yBAAyB;AACjD,MAAI,CAAE,MAAM,OAAO,SAAS,YAAY,CAAG;EAU3C,MAAM,cAJc,MAJE,iBAAiB,SAAS,YAAY,EAIhC,MAC1B,oDAG4B,GAAG;AACjC,MAAI,CAAC,WAAY;AAIjB,MAAI,CAAC,WAAW,WAAW,IAAI,CAAE;EAOjC,MAAM,2CAA4B,8EAFC,SAAS,YAAY,CACb,EAAE,WACc,CAAC,CACzD,MAAMC,cAAI,CACV,KAAK,IAAI;EAEZ,MAAM,WAAW,iBAAiB,WAAW,IAAI,GAC7C,mBACA,KAAK;AAOT,SAAO;GAAE,MAJP,SAAS,SAAS,SAAS,IAAI,SAAS,SAAS,eAAe,GAC5D,WACA;GAES;GAAU;;AAG3B,QAAO"}
@@ -10,6 +10,7 @@ exports.GITHUB_FILL_WORKFLOW_PATH = require_init_utils_githubActions.GITHUB_FILL
10
10
  exports.GITHUB_TEST_WORKFLOW_PATH = require_init_utils_githubActions.GITHUB_TEST_WORKFLOW_PATH;
11
11
  exports.detectJsonLocalePattern = require_init_utils_fileSystem.detectJsonLocalePattern;
12
12
  exports.detectMissingIntlayerPackages = require_init_utils_packageManager.detectMissingIntlayerPackages;
13
+ exports.detectNextIntlMessagesPattern = require_init_utils_fileSystem.detectNextIntlMessagesPattern;
13
14
  exports.detectPackageManager = require_init_utils_packageManager.detectPackageManager;
14
15
  exports.ensureDirectory = require_init_utils_fileSystem.ensureDirectory;
15
16
  exports.exists = require_init_utils_fileSystem.exists;
@@ -57,7 +57,7 @@ const detectMissingIntlayerPackages = (allDependencies) => {
57
57
  addIfMissing("next-intl");
58
58
  compatSyncConfig ??= {
59
59
  format: "icu",
60
- sourceTemplate: "./locales/${locale}/${key}.json"
60
+ sourceTemplate: "./messages/${locale}.json"
61
61
  };
62
62
  }
63
63
  if (isInstalled("next-i18next") || isInstalled("@intlayer/next-i18next")) {
@@ -104,6 +104,18 @@ const detectMissingIntlayerPackages = (allDependencies) => {
104
104
  pluginPackageSource: "@intlayer/vue-i18n/plugin"
105
105
  };
106
106
  }
107
+ if (isInstalled("use-intl") || isInstalled("@intlayer/use-intl")) {
108
+ addIfMissing("@intlayer/use-intl");
109
+ addIfMissing("use-intl");
110
+ compatSyncConfig ??= {
111
+ format: "icu",
112
+ sourceTemplate: "./messages/${locale}.json"
113
+ };
114
+ compatVitePluginConfig ??= {
115
+ pluginFunctionName: "useIntlVitePlugin",
116
+ pluginPackageSource: "@intlayer/use-intl/plugin"
117
+ };
118
+ }
107
119
  if (isInstalled("react-intl") || isInstalled("@intlayer/react-intl")) {
108
120
  addIfMissing("@intlayer/react-intl");
109
121
  addIfMissing("react-intl");
@@ -1 +1 @@
1
- {"version":3,"file":"packageManager.cjs","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\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 /** JSON format matching the compat library's conventions. */\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\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\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 */\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(allDependencies[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 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\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: './locales/${locale}/${key}.json',\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 // 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 // @todo syncJSON format not yet implemented for lingui (uses PO files)\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'linguiVitePlugin',\n pluginPackageSource: '@intlayer/lingui/plugin',\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('@intlayer/sync-json-plugin');\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"],"mappings":";;;;;;;;;;;AAyDA,MAAa,wBAAwB,YAAoC;AACvE,iDACkB,SAAS,WAAW,CAAC,gDACrB,SAAS,YAAY,CAAC,CAEtC,QAAO;AAET,iDAAoB,SAAS,iBAAiB,CAAC,CAC7C,QAAO;AAET,iDAAoB,SAAS,YAAY,CAAC,CACxC,QAAO;AAET,QAAO;;;;;AAMT,MAAM,uBACJ,gBACA,UACA,QAAiB,UACN;CACX,MAAM,cAAc,SAAS,KAAK,IAAI;AACtC,SAAQ,gBAAR;EACE,KAAK,MACH,QAAO,WAAW,QAAQ,QAAQ,KAAK;EACzC,KAAK,OACH,QAAO,YAAY,QAAQ,QAAQ,KAAK;EAC1C,KAAK,OACH,QAAO,YAAY,QAAQ,QAAQ,KAAK;EAC1C,KAAK,MACH,QAAO,eAAe,QAAQ,QAAQ,KAAK;;;;;;;;AASjD,MAAa,iCACX,oBAC4B;CAC5B,MAAM,oBAA8B,EAAE;CACtC,MAAM,uBAAiC,EAAE;CACzC,IAAI;CACJ,IAAI;CAEJ,MAAM,eAAe,gBACnB,QAAQ,gBAAgB,aAAa;CAEvC,MAAM,gBAAgB,gBAA8B;AAClD,MAAI,CAAC,YAAY,YAAY,CAC3B,mBAAkB,KAAK,YAAY;;CAIvC,MAAM,mBAAmB,gBAA8B;AACrD,MAAI,CAAC,YAAY,YAAY,CAC3B,sBAAqB,KAAK,YAAY;;AAK1C,cAAa,WAAW;AAGxB,KAAI,YAAY,OAAO,CACrB,cAAa,gBAAgB;UACpB,YAAY,QAAQ,CAC7B,cAAa,iBAAiB;AAGhC,KAAI,YAAY,SAAS,CACvB,cAAa,kBAAkB;AAGjC,KAAI,YAAY,WAAW,CACzB,cAAa,iBAAiB;AAGhC,KAAI,YAAY,gBAAgB,CAC9B,cAAa,mBAAmB;AAGlC,KAAI,YAAY,MAAM,CACpB,cAAa,eAAe;AAG9B,KAAI,YAAY,OAAO,CACrB,cAAa,gBAAgB;AAe/B,KAAI,YAAY,YAAY,IAAI,YAAY,sBAAsB,EAAE;AAClE,eAAa,sBAAsB;AACnC,eAAa,YAAY;AACzB,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAKH,KAAI,YAAY,eAAe,IAAI,YAAY,yBAAyB,EAAE;AACxE,eAAa,yBAAyB;AACtC,eAAa,eAAe;AAC5B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAKH,KACE,YAAY,iBAAiB,IAC7B,YAAY,2BAA2B,EACvC;AACA,eAAa,2BAA2B;AACxC,eAAa,iBAAiB;AAC9B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAKH,KAAI,YAAY,UAAU,IAAI,YAAY,oBAAoB,EAAE;AAC9D,eAAa,oBAAoB;AAEjC,eAAa,UAAU;AACvB,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAIH,KAAI,YAAY,gBAAgB,IAAI,YAAY,0BAA0B,EAAE;AAC1E,eAAa,0BAA0B;AAEvC,eAAa,gBAAgB;AAC7B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAIH,KAAI,YAAY,WAAW,IAAI,YAAY,qBAAqB,EAAE;AAChE,eAAa,qBAAqB;AAClC,eAAa,WAAW;AACxB,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;AACD,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAIH,KAAI,YAAY,aAAa,IAAI,YAAY,uBAAuB,EAAE;AACpE,eAAa,uBAAuB;AACpC,eAAa,aAAa;AAC1B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;AACD,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAKH,KAAI,YAAY,oBAAoB,IAAI,YAAY,sBAAsB,EAAE;AAC1E,eAAa,sBAAsB;AACnC,eAAa,oBAAoB;AACjC,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAIH,KAAI,YAAY,cAAc,IAAI,YAAY,wBAAwB,EAAE;AACtE,eAAa,wBAAwB;AACrC,eAAa,cAAc;AAC3B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;AACD,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAKH,KAAI,YAAY,gBAAgB,IAAI,YAAY,qBAAqB,EAAE;AACrE,eAAa,qBAAqB;AAClC,eAAa,gBAAgB;AAC7B,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAIH,KAAI,YAAY,eAAe,IAAI,YAAY,wBAAwB,EAAE;AACvE,eAAa,wBAAwB;AACrC,eAAa,eAAe;AAC5B,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;;AAKH,KACE,YAAY,sBAAsB,IAClC,YAAY,0BAA0B,EACtC;AACA,eAAa,0BAA0B;AACvC,eAAa,sBAAsB;AACnC,uBAAqB;GACnB,QAAQ;GACR,gBAAgB;GACjB;AACD,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAKH,KACE,YAAY,eAAe,IAC3B,YAAY,gBAAgB,IAC5B,YAAY,mBAAmB,EAC/B;AACA,eAAa,mBAAmB;AAChC,eAAa,eAAe;AAC5B,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAKH,KAAI,YAAY,UAAU,IAAI,YAAY,oBAAoB,EAAE;AAC9D,eAAa,oBAAoB;AACjC,eAAa,UAAU;AACvB,6BAA2B;GACzB,oBAAoB;GACpB,qBAAqB;GACtB;;AAGH,KAAI,iBACF,iBAAgB,6BAA6B;AAG/C,QAAO;EACL;EACA;EACA;EACA;EACD;;;;;;AAOH,MAAa,mBACX,SACA,UACA,gBACA,QAAiB,UACR;AAET,kCADgB,oBAAoB,gBAAgB,UAAU,MAC9C,EAAE;EAAE,KAAK;EAAS,OAAO;EAAW,CAAC"}
1
+ {"version":3,"file":"packageManager.cjs","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\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 /** JSON format matching the compat library's conventions. */\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\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\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 */\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(allDependencies[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 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 };\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 };\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 // @todo syncJSON format not yet implemented for lingui (uses PO files)\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'linguiVitePlugin',\n pluginPackageSource: '@intlayer/lingui/plugin',\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('@intlayer/sync-json-plugin');\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"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { initConfig } from "../initConfig/index.mjs";
2
2
  import { updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin } from "./utils/configManipulation.mjs";
3
- import { detectJsonLocalePattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./utils/fileSystem.mjs";
3
+ import { detectJsonLocalePattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./utils/fileSystem.mjs";
4
4
  import { getGithubWorkflows } from "./utils/githubActions.mjs";
5
5
  import { parseJSONWithComments } from "./utils/jsonParser.mjs";
6
6
  import { detectMissingIntlayerPackages, detectPackageManager, installPackages } from "./utils/packageManager.mjs";
@@ -225,9 +225,10 @@ const initIntlayer = async (rootDir, options) => {
225
225
  const detectedPattern = await detectJsonLocalePattern(rootDir);
226
226
  await initConfig(format, rootDir, detectedPattern?.locales);
227
227
  if (compatSyncConfig) {
228
- const resolvedSyncConfig = detectedPattern ? {
228
+ const sourceTemplate = (allDeps["next-intl"] || allDeps["@intlayer/next-intl"] || allDeps["use-intl"] || allDeps["@intlayer/use-intl"] ? await detectNextIntlMessagesPattern(rootDir) : null)?.template ?? detectedPattern?.template;
229
+ const resolvedSyncConfig = sourceTemplate ? {
229
230
  ...compatSyncConfig,
230
- sourceTemplate: detectedPattern.template
231
+ sourceTemplate
231
232
  } : compatSyncConfig;
232
233
  for (const configFile of [
233
234
  "intlayer.config.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/init/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\n\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport {\n detectJsonLocalePattern,\n detectMissingIntlayerPackages,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n installPackages,\n parseJSONWithComments,\n readFileFromRoot,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n writeFileToRoot,\n} from './utils';\n\n/**\n * Documentation URL Constants\n */\nconst DocumentationRouter = {\n NextJS: 'https://intlayer.org/doc/environment/nextjs.md',\n NextJS_15: 'https://intlayer.org/doc/environment/nextjs/15.md',\n NextJS_14: 'https://intlayer.org/doc/environment/nextjs/14.md',\n CRA: 'https://intlayer.org/doc/environment/create-react-app.md',\n Astro: 'https://intlayer.org/doc/environment/astro.md',\n ViteAndReact: 'https://intlayer.org/doc/environment/vite-and-react.md',\n ViteAndReact_ReactRouterV7:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7.md',\n ViteAndReact_ReactRouterV7_FSRoutes:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7-fs-routes.md',\n ViteAndVue: 'https://intlayer.org/doc/environment/vite-and-vue.md',\n ViteAndSolid: 'https://intlayer.org/doc/environment/vite-and-solid.md',\n ViteAndSvelte: 'https://intlayer.org/doc/environment/vite-and-svelte.md',\n ViteAndPreact: 'https://intlayer.org/doc/environment/vite-and-preact.md',\n TanStackRouter: 'https://intlayer.org/doc/environment/tanstack.md',\n NuxtAndVue: 'https://intlayer.org/doc/environment/nuxt-and-vue.md',\n Angular: 'https://intlayer.org/doc/environment/angular.md',\n SvelteKit: 'https://intlayer.org/doc/environment/sveltekit.md',\n ReactNativeAndExpo:\n 'https://intlayer.org/doc/environment/react-native-and-expo.md',\n Lynx: 'https://intlayer.org/doc/environment/lynx-and-react.md',\n Express: 'https://intlayer.org/doc/environment/express.md',\n NestJS: 'https://intlayer.org/doc/environment/nestjs.md',\n Fastify: 'https://intlayer.org/doc/environment/fastify.md',\n Default: 'https://intlayer.org/doc/get-started',\n\n // Intlayer Language Server (Go-to-Definition from getter keys to .content files)\n LSP: 'https://intlayer.org/doc/lsp.md',\n\n // Check for competitors libs\n NextIntl: 'https://intlayer.org/blog/intlayer-with-next-intl.md',\n ReactI18Next: 'https://intlayer.org/blog/intlayer-with-react-i18next.md',\n ReactIntl: 'https://intlayer.org/blog/intlayer-with-react-intl.md',\n NextI18Next: 'https://intlayer.org/blog/intlayer-with-next-i18next.md',\n VueI18n: 'https://intlayer.org/blog/intlayer-with-vue-i18n.md',\n};\n\n/**\n * Helper: Detects the environment and returns the doc URL\n */\nconst getDocumentationUrl = (packageJson: any): string => {\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n /**\n * Helper to check if a version string matches a specific major version\n * Matches: \"15\", \"^15.0.0\", \"~15.2\", \"15.0.0-beta\"\n */\n const isVersion = (versionString: string, major: number): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const regex = new RegExp(`^[\\\\^~]?${major}(?:\\\\.|$)`);\n return regex.test(versionString);\n };\n\n // Mobile / Cross-platform\n if (deps['@lynx-js/react'] || deps['@lynx-js/core']) {\n return DocumentationRouter.Lynx;\n }\n if (deps['react-native'] || deps.expo) {\n return DocumentationRouter.ReactNativeAndExpo;\n }\n\n // Meta-frameworks (Next, Nuxt, Astro, SvelteKit)\n if (deps.next) {\n const version = deps.next;\n\n if (isVersion(version, 14)) {\n return DocumentationRouter.NextJS_14;\n }\n\n if (isVersion(version, 15)) {\n return DocumentationRouter.NextJS_15;\n }\n\n return DocumentationRouter.NextJS;\n }\n\n if (deps.nuxt) return DocumentationRouter.NuxtAndVue;\n if (deps.astro) return DocumentationRouter.Astro;\n if (deps['@sveltejs/kit']) return DocumentationRouter.SvelteKit;\n\n // Routers (TanStack & React Router v7)\n if (deps['@tanstack/react-router']) {\n return DocumentationRouter.TanStackRouter;\n }\n\n // Check for React Router v7\n const reactRouterVersion = deps['react-router'];\n if (reactRouterVersion && typeof reactRouterVersion === 'string') {\n // Distinguish between standard v7 and v7 with FS routes\n if (deps['@react-router/fs-routes']) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7_FSRoutes;\n }\n\n // Use Regex to ensure it is v7\n if (isVersion(reactRouterVersion, 7)) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7;\n }\n }\n\n // Vite Ecosystem (General)\n if (deps.vite) {\n if (deps.vue) return DocumentationRouter.ViteAndVue;\n if (deps['solid-js']) return DocumentationRouter.ViteAndSolid;\n if (deps.svelte) return DocumentationRouter.ViteAndSvelte;\n if (deps.preact) return DocumentationRouter.ViteAndPreact;\n\n // Default to React if Vite is present but specific other frameworks aren't found\n return DocumentationRouter.ViteAndReact;\n }\n\n // Other Web Frameworks\n if (deps['react-scripts']) return DocumentationRouter.CRA;\n if (deps['@angular/core']) return DocumentationRouter.Angular;\n\n // Backend\n if (deps['@nestjs/core']) return DocumentationRouter.NestJS;\n if (deps.express) return DocumentationRouter.Express;\n if (deps.fastify) return DocumentationRouter.Fastify;\n\n // Competitor Libs (Migration Guides)\n // We check these last as specific environment setup is usually higher priority,\n // but if no specific framework logic matched (or as a fallback), we guide to migration.\n if (deps['next-intl']) return DocumentationRouter.NextIntl;\n if (deps['react-i18next'] || deps.i18next)\n return DocumentationRouter.ReactI18Next;\n if (deps['react-intl']) return DocumentationRouter.ReactIntl;\n if (deps['next-i18next']) return DocumentationRouter.NextI18Next;\n if (deps['vue-i18n']) return DocumentationRouter.VueI18n;\n\n return DocumentationRouter.Default;\n};\n\n/**\n * OPTIONS\n */\nexport type InitOptions = {\n noGitignore?: boolean;\n /** Skip scaffolding the `fill` and `test` GitHub Actions workflows. */\n noGithubActions?: boolean;\n};\n\n/**\n * MAIN LOGIC\n */\nexport const initIntlayer = async (rootDir: string, options?: InitOptions) => {\n logger(colorize('Checking Intlayer configuration...', ANSIColors.CYAN));\n\n // READ PACKAGE.JSON\n const packageJsonPath = 'package.json';\n if (!(await exists(rootDir, packageJsonPath))) {\n logger(\n `${x} No ${colorizePath('package.json')} found. Please run this script from the project root.`,\n { level: 'error' }\n );\n process.exit(1);\n }\n\n const packageJsonContent = await readFileFromRoot(rootDir, packageJsonPath);\n let packageJson: Record<string, any>;\n try {\n packageJson = JSON.parse(packageJsonContent);\n } catch {\n logger(`${x} Could not parse ${colorizePath('package.json')}.`, {\n level: 'error',\n });\n process.exit(1);\n }\n\n // Determine the correct documentation URL based on dependencies\n const guideUrl = getDocumentationUrl(packageJson);\n\n const allDeps: Record<string, string> = {\n ...(packageJson.dependencies ?? {}),\n ...(packageJson.devDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(allDeps);\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(rootDir, packagesToInstall, packageManager);\n logger(\n `${v} Installed: ${packagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install packages. Please install manually: ${packagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n if (devPackagesToInstall.length > 0) {\n logger(\n colorize(\n 'Installing missing Intlayer dev dependencies...',\n ANSIColors.CYAN\n )\n );\n try {\n installPackages(rootDir, devPackagesToInstall, packageManager, true);\n logger(\n `${v} Installed: ${devPackagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install dev packages. Please install manually: ${devPackagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n // CHECK .GITIGNORE\n const gitignorePath = '.gitignore';\n if (!options?.noGitignore && (await exists(rootDir, gitignorePath))) {\n const gitignoreContent = await readFileFromRoot(rootDir, gitignorePath);\n\n if (!gitignoreContent.includes('intlayer')) {\n const newContent = `${gitignoreContent}\\n# Intlayer\\n.intlayer\\n`;\n await writeFileToRoot(rootDir, gitignorePath, newContent);\n logger(\n `${v} Added ${colorizePath('.intlayer')} to ${colorizePath(gitignorePath)}`\n );\n } else {\n logger(`${v} ${colorizePath(gitignorePath)} already includes .intlayer`);\n }\n }\n\n // SCAFFOLD GITHUB ACTIONS WORKFLOWS (fill + test)\n // Generate two workflows whose commands match the detected package manager:\n // - intlayer-fill.yml: auto-fills missing translations on pull requests\n // - intlayer-test.yml: fails the PR when required locales are missing\n if (!options?.noGithubActions) {\n const workflows = getGithubWorkflows(packageManager);\n\n for (const workflow of workflows) {\n if (await exists(rootDir, workflow.filePath)) {\n logger(`${v} ${colorizePath(workflow.filePath)} already exists`);\n continue;\n }\n\n try {\n await ensureDirectory(rootDir, join('.github', 'workflows'));\n await writeFileToRoot(rootDir, workflow.filePath, workflow.content);\n logger(\n `${v} Added GitHub Actions workflow ${colorizePath(workflow.filePath)}`\n );\n } catch {\n logger(\n `${x} Could not create ${colorizePath(workflow.filePath)}. You may need to add it manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // CHECK VS CODE EXTENSION RECOMMENDATIONS\n const vscodeDir = '.vscode';\n const extensionsJsonPath = join(vscodeDir, 'extensions.json');\n const extensionId = 'intlayer.intlayer-vs-code-extension';\n\n try {\n let extensionsConfig: { recommendations: string[] } = {\n recommendations: [],\n };\n\n if (await exists(rootDir, extensionsJsonPath)) {\n const content = await readFileFromRoot(rootDir, extensionsJsonPath);\n extensionsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n if (!extensionsConfig.recommendations) {\n extensionsConfig.recommendations = [];\n }\n\n if (!extensionsConfig.recommendations.includes(extensionId)) {\n extensionsConfig.recommendations.push(extensionId);\n await writeFileToRoot(\n rootDir,\n extensionsJsonPath,\n JSON.stringify(extensionsConfig, null, 2)\n );\n logger(\n `${v} Added ${colorize(extensionId, ANSIColors.MAGENTA)} to ${colorizePath(extensionsJsonPath)}`\n );\n } else {\n logger(\n `${v} ${colorizePath(extensionsJsonPath)} already includes ${colorize(extensionId, ANSIColors.MAGENTA)}`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(extensionsJsonPath)}. You may need to add ${colorize(extensionId, ANSIColors.MAGENTA)} manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n try {\n let settingsConfig: Record<string, unknown> = {};\n\n if (await exists(rootDir, settingsJsonPath)) {\n const content = await readFileFromRoot(rootDir, settingsJsonPath);\n settingsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n let settingsUpdated = false;\n\n if (!settingsConfig['intlayer.languageServer.command']) {\n settingsConfig['intlayer.languageServer.command'] = 'npx';\n settingsUpdated = true;\n }\n\n if (!settingsConfig['intlayer.languageServer.args']) {\n settingsConfig['intlayer.languageServer.args'] = ['@intlayer/lsp'];\n settingsUpdated = true;\n }\n\n if (settingsUpdated) {\n await writeFileToRoot(\n rootDir,\n settingsJsonPath,\n JSON.stringify(settingsConfig, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(settingsJsonPath)} with LSP configuration`\n );\n } else {\n logger(\n `${v} ${colorizePath(settingsJsonPath)} already includes LSP configuration`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(settingsJsonPath)}. You may need to add the LSP settings manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK TSCONFIGS\n const tsConfigFiles = await findTsConfigFiles(rootDir);\n let hasTsConfig = false;\n\n for (const fileName of tsConfigFiles) {\n if (await exists(rootDir, fileName)) {\n hasTsConfig = true;\n try {\n const fileContent = await readFileFromRoot(rootDir, fileName);\n const config = parseJSONWithComments(fileContent);\n const typeDefinition = '.intlayer/**/*.ts';\n\n let updated = false;\n\n if (!config.include) {\n // Skip if no include array (solution-style)\n } else if (\n Array.isArray(config.include) &&\n !(config.include as string[]).some((pattern: string) =>\n pattern.includes('.intlayer')\n )\n ) {\n config.include.push(typeDefinition);\n updated = true;\n } else if (config.include.includes(typeDefinition)) {\n logger(\n `${v} ${colorizePath(fileName)} already includes intlayer types`\n );\n }\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n fileName,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(fileName)} to include intlayer types`\n );\n }\n } catch {\n logger(\n `${x} Could not parse or update ${colorizePath(fileName)}. You may need to add ${colorizePath('.intlayer/types/**/*.ts')} manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // INITIALIZE CONFIG FILE\n const format = hasTsConfig ? 'intlayer.config.ts' : 'intlayer.config.mjs';\n\n // Detect the locale JSON file pattern already in the project so we can\n // insert the matching locales into the config and produce the most\n // accurate source template for compat libraries.\n const detectedPattern = await detectJsonLocalePattern(rootDir);\n\n await initConfig(format, rootDir, detectedPattern?.locales);\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES\n if (compatSyncConfig) {\n const resolvedSyncConfig = detectedPattern\n ? { ...compatSyncConfig, sourceTemplate: detectedPattern.template }\n : compatSyncConfig;\n\n const intlayerConfigCandidates = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n ];\n\n for (const configFile of intlayerConfigCandidates) {\n if (await exists(rootDir, configFile)) {\n const configContent = await readFileFromRoot(rootDir, configFile);\n\n if (!configContent.includes('@intlayer/sync-json-plugin')) {\n const extension = configFile.split('.').pop()!;\n const updatedConfigContent = updateIntlayerConfigWithSyncPlugin(\n configContent,\n extension,\n resolvedSyncConfig\n );\n await writeFileToRoot(rootDir, configFile, updatedConfigContent);\n logger(\n `${v} Updated ${colorizePath(configFile)} with syncJSON compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes syncJSON plugin`\n );\n }\n break;\n }\n }\n }\n\n let hasAliasConfiguration = false;\n\n // CHECK VITE CONFIG\n const viteConfigs = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];\n\n for (const file of viteConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (compatVitePluginConfig) {\n if (!content.includes(compatVitePluginConfig.pluginPackageSource)) {\n const updatedContent = updateViteConfigForCompatPlugin(\n content,\n extension,\n compatVitePluginConfig\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include ${compatVitePluginConfig.pluginFunctionName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n }\n } else if (!content.includes('vite-intlayer')) {\n const updatedContent = updateViteConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK NEXT CONFIG\n const nextConfigs = ['next.config.js', 'next.config.mjs', 'next.config.ts'];\n let isNextJsProject = false;\n\n for (const file of nextConfigs) {\n if (await exists(rootDir, file)) {\n isNextJsProject = true;\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (allDeps['next-i18next']) {\n if (!content.includes('@intlayer/next-i18next')) {\n const updatedContent = updateNextConfigForNextI18next(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-i18next compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-i18next`\n );\n }\n } else if (allDeps['next-intl']) {\n if (!content.includes('@intlayer/next-intl/plugin')) {\n const updatedContent = updateNextConfigForNextIntl(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-intl compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-intl/plugin`\n );\n }\n } else if (allDeps['next-translate']) {\n if (!content.includes('@intlayer/next-translate')) {\n const updatedContent = updateNextConfigForNextTranslate(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-translate compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-translate`\n );\n }\n } else if (!content.includes('next-intlayer')) {\n const updatedContent = updateNextConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK OTHER FRAMEWORKS CONFIG\n const astroConfigs = [\n 'astro.config.mjs',\n 'astro.config.js',\n 'astro.config.ts',\n 'astro.config.cjs',\n ];\n\n for (const file of astroConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n if (file.startsWith('astro.config.')) {\n const content = await readFileFromRoot(rootDir, file);\n\n if (!content.includes('astro-intlayer')) {\n const extension = file.split('.').pop()!;\n const updatedContent = updateAstroConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer integration`\n );\n }\n }\n break;\n }\n }\n\n const nuxtConfigs = ['nuxt.config.js', 'nuxt.config.ts'];\n for (const file of nuxtConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n const content = await readFileFromRoot(rootDir, file);\n\n if (allDeps['@nuxtjs/i18n']) {\n if (!content.includes('@intlayer/nuxtjs-i18n')) {\n const updatedContent = updateNuxtConfigForNuxtjsI18n(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include @intlayer/nuxtjs-i18n module`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/nuxtjs-i18n`\n );\n }\n } else if (!content.includes('nuxt-intlayer')) {\n const updatedContent = updateNuxtConfig(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer module`);\n }\n break;\n }\n }\n\n // UPDATE PACKAGE.JSON DEV SCRIPT\n // Next.js >= 16 uses a bun-specific wrapper; backend frameworks wrap whatever\n // the existing dev script is. Both use `intlayer watch --with`.\n const isVersionGreaterOrEqual = (\n versionString: string,\n major: number\n ): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const match = versionString.match(/^[^\\d]*(\\d+)/);\n\n if (!match?.[1]) return false;\n\n return parseInt(match[1], 10) >= major;\n };\n\n const backendIntlayerPackages = [\n 'express-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'hono-intlayer',\n ];\n\n const devScript = packageJson.scripts?.dev;\n\n let newDevScript: string | undefined;\n\n if (\n ((isNextJsProject &&\n allDeps.next &&\n isVersionGreaterOrEqual(allDeps.next, 16)) ||\n backendIntlayerPackages.some((pkg) => allDeps[pkg])) &&\n !devScript.includes('intlayer watch')\n ) {\n newDevScript = `intlayer watch --with '${devScript}'`;\n }\n\n if (newDevScript) {\n packageJson.scripts.dev = newDevScript;\n\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath('package.json')} dev script to run intlayer watch`\n );\n }\n\n // CHECK WEBPACK CONFIG\n const webpackConfigs = [\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'webpack.config.cjs',\n ];\n\n for (const file of webpackConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n logger(\n `${v} Found ${colorizePath(\n file\n )}. Make sure to configure aliases manually or use the Intlayer Webpack plugin.`\n );\n break;\n }\n }\n\n const backendConfigPackages = [\n 'express',\n 'fastify',\n '@adonisjs/core',\n 'hono',\n ...backendIntlayerPackages,\n ];\n\n if (backendConfigPackages.some((pkg) => allDeps[pkg])) {\n hasAliasConfiguration = true;\n }\n\n if (!hasAliasConfiguration) {\n const configuration = getConfiguration({ baseDir: rootDir });\n const aliases = getAlias({ configuration });\n\n if (hasTsConfig && tsConfigFiles.length > 0) {\n const tsConfigPath =\n tsConfigFiles.find((file) => file === 'tsconfig.json') ||\n tsConfigFiles[0];\n\n if (tsConfigPath) {\n const tsConfigContent = await readFileFromRoot(rootDir, tsConfigPath);\n const config = parseJSONWithComments(tsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n tsConfigPath,\n JSON.stringify(config, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath(\n tsConfigPath\n )} to include Intlayer aliases`\n );\n }\n }\n } else {\n const jsConfigPath = 'jsconfig.json';\n\n if (await exists(rootDir, jsConfigPath)) {\n const jsConfigContent = await readFileFromRoot(rootDir, jsConfigPath);\n const config = parseJSONWithComments(jsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n jsConfigPath,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n jsConfigPath\n )} to include Intlayer aliases`\n );\n }\n } else {\n packageJson.imports ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n const importAlias = alias.replace('@', '#');\n const importPath = path.startsWith('.') ? path : `./${path}`;\n\n if (!packageJson.imports[importAlias]) {\n packageJson.imports[importAlias] = importPath;\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n packageJsonPath\n )} to include Intlayer imports`\n );\n }\n }\n }\n }\n\n // FINAL SUCCESS MESSAGE\n logger(`${v} ${colorize('Intlayer init setup complete.', ANSIColors.GREEN)}`);\n logger([\n colorize('Next →', ANSIColors.MAGENTA),\n colorize(\n `Follow the instructions in the documentation to complete the setup:`,\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(guideUrl),\n ]);\n\n // INTLAYER LSP — instruction for the AI agent running `intlayer init`.\n // The Intlayer Language Server (`@intlayer/lsp`) provides Go-to-Definition\n // from `useIntlayer` / `getIntlayer` keys to their `.content` files, for both\n // IDEs and AI agents. Setup is editor-specific (VS Code, Cursor, Windsurf,\n // Zed, Neovim, Claude Code, …), so we don't scaffold anything here — instead\n // we point to the doc and ask the agent to confirm the target platform.\n logger([\n colorize('Intlayer LSP →', ANSIColors.MAGENTA),\n colorize(\n 'The Intlayer Language Server is available via the `@intlayer/lsp` package. It lets IDEs and AI agents jump from `useIntlayer`/`getIntlayer` keys to their `.content` files.',\n ANSIColors.GREY_LIGHT\n ),\n colorize(\n 'Ask the user which platform/editor they want to enable it on (VS Code, Cursor, Windsurf, Zed, Neovim, Claude Code, …), then follow the matching setup instructions:',\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(DocumentationRouter.LSP),\n ]);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/init/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\n\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport {\n detectJsonLocalePattern,\n detectMissingIntlayerPackages,\n detectNextIntlMessagesPattern,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n installPackages,\n parseJSONWithComments,\n readFileFromRoot,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n writeFileToRoot,\n} from './utils';\n\n/**\n * Documentation URL Constants\n */\nconst DocumentationRouter = {\n NextJS: 'https://intlayer.org/doc/environment/nextjs.md',\n NextJS_15: 'https://intlayer.org/doc/environment/nextjs/15.md',\n NextJS_14: 'https://intlayer.org/doc/environment/nextjs/14.md',\n CRA: 'https://intlayer.org/doc/environment/create-react-app.md',\n Astro: 'https://intlayer.org/doc/environment/astro.md',\n ViteAndReact: 'https://intlayer.org/doc/environment/vite-and-react.md',\n ViteAndReact_ReactRouterV7:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7.md',\n ViteAndReact_ReactRouterV7_FSRoutes:\n 'https://intlayer.org/doc/environment/vite-and-react/react-router-v7-fs-routes.md',\n ViteAndVue: 'https://intlayer.org/doc/environment/vite-and-vue.md',\n ViteAndSolid: 'https://intlayer.org/doc/environment/vite-and-solid.md',\n ViteAndSvelte: 'https://intlayer.org/doc/environment/vite-and-svelte.md',\n ViteAndPreact: 'https://intlayer.org/doc/environment/vite-and-preact.md',\n TanStackRouter: 'https://intlayer.org/doc/environment/tanstack.md',\n NuxtAndVue: 'https://intlayer.org/doc/environment/nuxt-and-vue.md',\n Angular: 'https://intlayer.org/doc/environment/angular.md',\n SvelteKit: 'https://intlayer.org/doc/environment/sveltekit.md',\n ReactNativeAndExpo:\n 'https://intlayer.org/doc/environment/react-native-and-expo.md',\n Lynx: 'https://intlayer.org/doc/environment/lynx-and-react.md',\n Express: 'https://intlayer.org/doc/environment/express.md',\n NestJS: 'https://intlayer.org/doc/environment/nestjs.md',\n Fastify: 'https://intlayer.org/doc/environment/fastify.md',\n Default: 'https://intlayer.org/doc/get-started',\n\n // Intlayer Language Server (Go-to-Definition from getter keys to .content files)\n LSP: 'https://intlayer.org/doc/lsp.md',\n\n // Check for competitors libs\n NextIntl: 'https://intlayer.org/blog/intlayer-with-next-intl.md',\n ReactI18Next: 'https://intlayer.org/blog/intlayer-with-react-i18next.md',\n ReactIntl: 'https://intlayer.org/blog/intlayer-with-react-intl.md',\n NextI18Next: 'https://intlayer.org/blog/intlayer-with-next-i18next.md',\n VueI18n: 'https://intlayer.org/blog/intlayer-with-vue-i18n.md',\n};\n\n/**\n * Helper: Detects the environment and returns the doc URL\n */\nconst getDocumentationUrl = (packageJson: any): string => {\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n /**\n * Helper to check if a version string matches a specific major version\n * Matches: \"15\", \"^15.0.0\", \"~15.2\", \"15.0.0-beta\"\n */\n const isVersion = (versionString: string, major: number): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const regex = new RegExp(`^[\\\\^~]?${major}(?:\\\\.|$)`);\n return regex.test(versionString);\n };\n\n // Mobile / Cross-platform\n if (deps['@lynx-js/react'] || deps['@lynx-js/core']) {\n return DocumentationRouter.Lynx;\n }\n if (deps['react-native'] || deps.expo) {\n return DocumentationRouter.ReactNativeAndExpo;\n }\n\n // Meta-frameworks (Next, Nuxt, Astro, SvelteKit)\n if (deps.next) {\n const version = deps.next;\n\n if (isVersion(version, 14)) {\n return DocumentationRouter.NextJS_14;\n }\n\n if (isVersion(version, 15)) {\n return DocumentationRouter.NextJS_15;\n }\n\n return DocumentationRouter.NextJS;\n }\n\n if (deps.nuxt) return DocumentationRouter.NuxtAndVue;\n if (deps.astro) return DocumentationRouter.Astro;\n if (deps['@sveltejs/kit']) return DocumentationRouter.SvelteKit;\n\n // Routers (TanStack & React Router v7)\n if (deps['@tanstack/react-router']) {\n return DocumentationRouter.TanStackRouter;\n }\n\n // Check for React Router v7\n const reactRouterVersion = deps['react-router'];\n if (reactRouterVersion && typeof reactRouterVersion === 'string') {\n // Distinguish between standard v7 and v7 with FS routes\n if (deps['@react-router/fs-routes']) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7_FSRoutes;\n }\n\n // Use Regex to ensure it is v7\n if (isVersion(reactRouterVersion, 7)) {\n return DocumentationRouter.ViteAndReact_ReactRouterV7;\n }\n }\n\n // Vite Ecosystem (General)\n if (deps.vite) {\n if (deps.vue) return DocumentationRouter.ViteAndVue;\n if (deps['solid-js']) return DocumentationRouter.ViteAndSolid;\n if (deps.svelte) return DocumentationRouter.ViteAndSvelte;\n if (deps.preact) return DocumentationRouter.ViteAndPreact;\n\n // Default to React if Vite is present but specific other frameworks aren't found\n return DocumentationRouter.ViteAndReact;\n }\n\n // Other Web Frameworks\n if (deps['react-scripts']) return DocumentationRouter.CRA;\n if (deps['@angular/core']) return DocumentationRouter.Angular;\n\n // Backend\n if (deps['@nestjs/core']) return DocumentationRouter.NestJS;\n if (deps.express) return DocumentationRouter.Express;\n if (deps.fastify) return DocumentationRouter.Fastify;\n\n // Competitor Libs (Migration Guides)\n // We check these last as specific environment setup is usually higher priority,\n // but if no specific framework logic matched (or as a fallback), we guide to migration.\n if (deps['next-intl']) return DocumentationRouter.NextIntl;\n if (deps['react-i18next'] || deps.i18next)\n return DocumentationRouter.ReactI18Next;\n if (deps['react-intl']) return DocumentationRouter.ReactIntl;\n if (deps['next-i18next']) return DocumentationRouter.NextI18Next;\n if (deps['vue-i18n']) return DocumentationRouter.VueI18n;\n\n return DocumentationRouter.Default;\n};\n\n/**\n * OPTIONS\n */\nexport type InitOptions = {\n noGitignore?: boolean;\n /** Skip scaffolding the `fill` and `test` GitHub Actions workflows. */\n noGithubActions?: boolean;\n};\n\n/**\n * MAIN LOGIC\n */\nexport const initIntlayer = async (rootDir: string, options?: InitOptions) => {\n logger(colorize('Checking Intlayer configuration...', ANSIColors.CYAN));\n\n // READ PACKAGE.JSON\n const packageJsonPath = 'package.json';\n if (!(await exists(rootDir, packageJsonPath))) {\n logger(\n `${x} No ${colorizePath('package.json')} found. Please run this script from the project root.`,\n { level: 'error' }\n );\n process.exit(1);\n }\n\n const packageJsonContent = await readFileFromRoot(rootDir, packageJsonPath);\n let packageJson: Record<string, any>;\n try {\n packageJson = JSON.parse(packageJsonContent);\n } catch {\n logger(`${x} Could not parse ${colorizePath('package.json')}.`, {\n level: 'error',\n });\n process.exit(1);\n }\n\n // Determine the correct documentation URL based on dependencies\n const guideUrl = getDocumentationUrl(packageJson);\n\n const allDeps: Record<string, string> = {\n ...(packageJson.dependencies ?? {}),\n ...(packageJson.devDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(allDeps);\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(rootDir, packagesToInstall, packageManager);\n logger(\n `${v} Installed: ${packagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install packages. Please install manually: ${packagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n if (devPackagesToInstall.length > 0) {\n logger(\n colorize(\n 'Installing missing Intlayer dev dependencies...',\n ANSIColors.CYAN\n )\n );\n try {\n installPackages(rootDir, devPackagesToInstall, packageManager, true);\n logger(\n `${v} Installed: ${devPackagesToInstall.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to install dev packages. Please install manually: ${devPackagesToInstall.join(' ')}`,\n { level: 'warn' }\n );\n }\n }\n\n // CHECK .GITIGNORE\n const gitignorePath = '.gitignore';\n if (!options?.noGitignore && (await exists(rootDir, gitignorePath))) {\n const gitignoreContent = await readFileFromRoot(rootDir, gitignorePath);\n\n if (!gitignoreContent.includes('intlayer')) {\n const newContent = `${gitignoreContent}\\n# Intlayer\\n.intlayer\\n`;\n await writeFileToRoot(rootDir, gitignorePath, newContent);\n logger(\n `${v} Added ${colorizePath('.intlayer')} to ${colorizePath(gitignorePath)}`\n );\n } else {\n logger(`${v} ${colorizePath(gitignorePath)} already includes .intlayer`);\n }\n }\n\n // SCAFFOLD GITHUB ACTIONS WORKFLOWS (fill + test)\n // Generate two workflows whose commands match the detected package manager:\n // - intlayer-fill.yml: auto-fills missing translations on pull requests\n // - intlayer-test.yml: fails the PR when required locales are missing\n if (!options?.noGithubActions) {\n const workflows = getGithubWorkflows(packageManager);\n\n for (const workflow of workflows) {\n if (await exists(rootDir, workflow.filePath)) {\n logger(`${v} ${colorizePath(workflow.filePath)} already exists`);\n continue;\n }\n\n try {\n await ensureDirectory(rootDir, join('.github', 'workflows'));\n await writeFileToRoot(rootDir, workflow.filePath, workflow.content);\n logger(\n `${v} Added GitHub Actions workflow ${colorizePath(workflow.filePath)}`\n );\n } catch {\n logger(\n `${x} Could not create ${colorizePath(workflow.filePath)}. You may need to add it manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // CHECK VS CODE EXTENSION RECOMMENDATIONS\n const vscodeDir = '.vscode';\n const extensionsJsonPath = join(vscodeDir, 'extensions.json');\n const extensionId = 'intlayer.intlayer-vs-code-extension';\n\n try {\n let extensionsConfig: { recommendations: string[] } = {\n recommendations: [],\n };\n\n if (await exists(rootDir, extensionsJsonPath)) {\n const content = await readFileFromRoot(rootDir, extensionsJsonPath);\n extensionsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n if (!extensionsConfig.recommendations) {\n extensionsConfig.recommendations = [];\n }\n\n if (!extensionsConfig.recommendations.includes(extensionId)) {\n extensionsConfig.recommendations.push(extensionId);\n await writeFileToRoot(\n rootDir,\n extensionsJsonPath,\n JSON.stringify(extensionsConfig, null, 2)\n );\n logger(\n `${v} Added ${colorize(extensionId, ANSIColors.MAGENTA)} to ${colorizePath(extensionsJsonPath)}`\n );\n } else {\n logger(\n `${v} ${colorizePath(extensionsJsonPath)} already includes ${colorize(extensionId, ANSIColors.MAGENTA)}`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(extensionsJsonPath)}. You may need to add ${colorize(extensionId, ANSIColors.MAGENTA)} manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n try {\n let settingsConfig: Record<string, unknown> = {};\n\n if (await exists(rootDir, settingsJsonPath)) {\n const content = await readFileFromRoot(rootDir, settingsJsonPath);\n settingsConfig = parseJSONWithComments(content);\n } else {\n await ensureDirectory(rootDir, vscodeDir);\n }\n\n let settingsUpdated = false;\n\n if (!settingsConfig['intlayer.languageServer.command']) {\n settingsConfig['intlayer.languageServer.command'] = 'npx';\n settingsUpdated = true;\n }\n\n if (!settingsConfig['intlayer.languageServer.args']) {\n settingsConfig['intlayer.languageServer.args'] = ['@intlayer/lsp'];\n settingsUpdated = true;\n }\n\n if (settingsUpdated) {\n await writeFileToRoot(\n rootDir,\n settingsJsonPath,\n JSON.stringify(settingsConfig, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(settingsJsonPath)} with LSP configuration`\n );\n } else {\n logger(\n `${v} ${colorizePath(settingsJsonPath)} already includes LSP configuration`\n );\n }\n } catch {\n logger(\n `${x} Could not update ${colorizePath(settingsJsonPath)}. You may need to add the LSP settings manually.`,\n { level: 'warn' }\n );\n }\n\n // CHECK TSCONFIGS\n const tsConfigFiles = await findTsConfigFiles(rootDir);\n let hasTsConfig = false;\n\n for (const fileName of tsConfigFiles) {\n if (await exists(rootDir, fileName)) {\n hasTsConfig = true;\n try {\n const fileContent = await readFileFromRoot(rootDir, fileName);\n const config = parseJSONWithComments(fileContent);\n const typeDefinition = '.intlayer/**/*.ts';\n\n let updated = false;\n\n if (!config.include) {\n // Skip if no include array (solution-style)\n } else if (\n Array.isArray(config.include) &&\n !(config.include as string[]).some((pattern: string) =>\n pattern.includes('.intlayer')\n )\n ) {\n config.include.push(typeDefinition);\n updated = true;\n } else if (config.include.includes(typeDefinition)) {\n logger(\n `${v} ${colorizePath(fileName)} already includes intlayer types`\n );\n }\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n fileName,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(fileName)} to include intlayer types`\n );\n }\n } catch {\n logger(\n `${x} Could not parse or update ${colorizePath(fileName)}. You may need to add ${colorizePath('.intlayer/types/**/*.ts')} manually.`,\n { level: 'warn' }\n );\n }\n }\n }\n\n // INITIALIZE CONFIG FILE\n const format = hasTsConfig ? 'intlayer.config.ts' : 'intlayer.config.mjs';\n\n // Detect the locale JSON file pattern already in the project so we can\n // insert the matching locales into the config and produce the most\n // accurate source template for compat libraries.\n const detectedPattern = await detectJsonLocalePattern(rootDir);\n\n await initConfig(format, rootDir, detectedPattern?.locales);\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES\n if (compatSyncConfig) {\n // For next-intl / use-intl, the messages path is authoritatively declared\n // in `i18n/request.ts` (e.g. `import(`../messages/${locale}.json`)`), so we\n // read it directly. It usually resolves to a single file per locale (no\n // `${key}` segment), which `syncJSON` splits per top-level namespace key via\n // `splitKeys` auto-detection. Falls back to file-system globbing otherwise.\n const nextIntlMessagesPattern =\n allDeps['next-intl'] ||\n allDeps['@intlayer/next-intl'] ||\n allDeps['use-intl'] ||\n allDeps['@intlayer/use-intl']\n ? await detectNextIntlMessagesPattern(rootDir)\n : null;\n\n const sourceTemplate =\n nextIntlMessagesPattern?.template ?? detectedPattern?.template;\n\n const resolvedSyncConfig = sourceTemplate\n ? { ...compatSyncConfig, sourceTemplate }\n : compatSyncConfig;\n\n const intlayerConfigCandidates = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n ];\n\n for (const configFile of intlayerConfigCandidates) {\n if (await exists(rootDir, configFile)) {\n const configContent = await readFileFromRoot(rootDir, configFile);\n\n if (!configContent.includes('@intlayer/sync-json-plugin')) {\n const extension = configFile.split('.').pop()!;\n const updatedConfigContent = updateIntlayerConfigWithSyncPlugin(\n configContent,\n extension,\n resolvedSyncConfig\n );\n await writeFileToRoot(rootDir, configFile, updatedConfigContent);\n logger(\n `${v} Updated ${colorizePath(configFile)} with syncJSON compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes syncJSON plugin`\n );\n }\n break;\n }\n }\n }\n\n let hasAliasConfiguration = false;\n\n // CHECK VITE CONFIG\n const viteConfigs = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];\n\n for (const file of viteConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (compatVitePluginConfig) {\n if (!content.includes(compatVitePluginConfig.pluginPackageSource)) {\n const updatedContent = updateViteConfigForCompatPlugin(\n content,\n extension,\n compatVitePluginConfig\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include ${compatVitePluginConfig.pluginFunctionName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n }\n } else if (!content.includes('vite-intlayer')) {\n const updatedContent = updateViteConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK NEXT CONFIG\n const nextConfigs = ['next.config.js', 'next.config.mjs', 'next.config.ts'];\n let isNextJsProject = false;\n\n for (const file of nextConfigs) {\n if (await exists(rootDir, file)) {\n isNextJsProject = true;\n hasAliasConfiguration = true;\n const content = await readFileFromRoot(rootDir, file);\n const extension = file.split('.').pop()!;\n\n if (allDeps['next-i18next']) {\n if (!content.includes('@intlayer/next-i18next')) {\n const updatedContent = updateNextConfigForNextI18next(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-i18next compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-i18next`\n );\n }\n } else if (allDeps['next-intl']) {\n if (!content.includes('@intlayer/next-intl/plugin')) {\n const updatedContent = updateNextConfigForNextIntl(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-intl compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-intl/plugin`\n );\n }\n } else if (allDeps['next-translate']) {\n if (!content.includes('@intlayer/next-translate')) {\n const updatedContent = updateNextConfigForNextTranslate(\n content,\n extension\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer next-translate compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/next-translate`\n );\n }\n } else if (!content.includes('next-intlayer')) {\n const updatedContent = updateNextConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer plugin`);\n }\n break;\n }\n }\n\n // CHECK OTHER FRAMEWORKS CONFIG\n const astroConfigs = [\n 'astro.config.mjs',\n 'astro.config.js',\n 'astro.config.ts',\n 'astro.config.cjs',\n ];\n\n for (const file of astroConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n if (file.startsWith('astro.config.')) {\n const content = await readFileFromRoot(rootDir, file);\n\n if (!content.includes('astro-intlayer')) {\n const extension = file.split('.').pop()!;\n const updatedContent = updateAstroConfig(content, extension);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include Intlayer integration`\n );\n }\n }\n break;\n }\n }\n\n const nuxtConfigs = ['nuxt.config.js', 'nuxt.config.ts'];\n for (const file of nuxtConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n\n const content = await readFileFromRoot(rootDir, file);\n\n if (allDeps['@nuxtjs/i18n']) {\n if (!content.includes('@intlayer/nuxtjs-i18n')) {\n const updatedContent = updateNuxtConfigForNuxtjsI18n(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to include @intlayer/nuxtjs-i18n module`\n );\n } else {\n logger(\n `${v} ${colorizePath(file)} already includes @intlayer/nuxtjs-i18n`\n );\n }\n } else if (!content.includes('nuxt-intlayer')) {\n const updatedContent = updateNuxtConfig(content);\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(`${v} Updated ${colorizePath(file)} to include Intlayer module`);\n }\n break;\n }\n }\n\n // UPDATE PACKAGE.JSON DEV SCRIPT\n // Next.js >= 16 uses a bun-specific wrapper; backend frameworks wrap whatever\n // the existing dev script is. Both use `intlayer watch --with`.\n const isVersionGreaterOrEqual = (\n versionString: string,\n major: number\n ): boolean => {\n if (!versionString || typeof versionString !== 'string') return false;\n const match = versionString.match(/^[^\\d]*(\\d+)/);\n\n if (!match?.[1]) return false;\n\n return parseInt(match[1], 10) >= major;\n };\n\n const backendIntlayerPackages = [\n 'express-intlayer',\n 'fastify-intlayer',\n 'adonis-intlayer',\n 'hono-intlayer',\n ];\n\n const devScript = packageJson.scripts?.dev;\n\n let newDevScript: string | undefined;\n\n if (\n ((isNextJsProject &&\n allDeps.next &&\n isVersionGreaterOrEqual(allDeps.next, 16)) ||\n backendIntlayerPackages.some((pkg) => allDeps[pkg])) &&\n !devScript.includes('intlayer watch')\n ) {\n newDevScript = `intlayer watch --with '${devScript}'`;\n }\n\n if (newDevScript) {\n packageJson.scripts.dev = newDevScript;\n\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath('package.json')} dev script to run intlayer watch`\n );\n }\n\n // CHECK WEBPACK CONFIG\n const webpackConfigs = [\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'webpack.config.cjs',\n ];\n\n for (const file of webpackConfigs) {\n if (await exists(rootDir, file)) {\n hasAliasConfiguration = true;\n logger(\n `${v} Found ${colorizePath(\n file\n )}. Make sure to configure aliases manually or use the Intlayer Webpack plugin.`\n );\n break;\n }\n }\n\n const backendConfigPackages = [\n 'express',\n 'fastify',\n '@adonisjs/core',\n 'hono',\n ...backendIntlayerPackages,\n ];\n\n if (backendConfigPackages.some((pkg) => allDeps[pkg])) {\n hasAliasConfiguration = true;\n }\n\n if (!hasAliasConfiguration) {\n const configuration = getConfiguration({ baseDir: rootDir });\n const aliases = getAlias({ configuration });\n\n if (hasTsConfig && tsConfigFiles.length > 0) {\n const tsConfigPath =\n tsConfigFiles.find((file) => file === 'tsconfig.json') ||\n tsConfigFiles[0];\n\n if (tsConfigPath) {\n const tsConfigContent = await readFileFromRoot(rootDir, tsConfigPath);\n const config = parseJSONWithComments(tsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n tsConfigPath,\n JSON.stringify(config, null, 2)\n );\n\n logger(\n `${v} Updated ${colorizePath(\n tsConfigPath\n )} to include Intlayer aliases`\n );\n }\n }\n } else {\n const jsConfigPath = 'jsconfig.json';\n\n if (await exists(rootDir, jsConfigPath)) {\n const jsConfigContent = await readFileFromRoot(rootDir, jsConfigPath);\n const config = parseJSONWithComments(jsConfigContent);\n\n config.compilerOptions ??= {};\n config.compilerOptions.paths ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n if (!config.compilerOptions.paths[alias]) {\n config.compilerOptions.paths[alias] = [path];\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n jsConfigPath,\n JSON.stringify(config, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n jsConfigPath\n )} to include Intlayer aliases`\n );\n }\n } else {\n packageJson.imports ??= {};\n\n let updated = false;\n\n Object.entries(aliases).forEach(([alias, path]) => {\n const importAlias = alias.replace('@', '#');\n const importPath = path.startsWith('.') ? path : `./${path}`;\n\n if (!packageJson.imports[importAlias]) {\n packageJson.imports[importAlias] = importPath;\n updated = true;\n }\n });\n\n if (updated) {\n await writeFileToRoot(\n rootDir,\n packageJsonPath,\n JSON.stringify(packageJson, null, 2)\n );\n logger(\n `${v} Updated ${colorizePath(\n packageJsonPath\n )} to include Intlayer imports`\n );\n }\n }\n }\n }\n\n // FINAL SUCCESS MESSAGE\n logger(`${v} ${colorize('Intlayer init setup complete.', ANSIColors.GREEN)}`);\n logger([\n colorize('Next →', ANSIColors.MAGENTA),\n colorize(\n `Follow the instructions in the documentation to complete the setup:`,\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(guideUrl),\n ]);\n\n // INTLAYER LSP — instruction for the AI agent running `intlayer init`.\n // The Intlayer Language Server (`@intlayer/lsp`) provides Go-to-Definition\n // from `useIntlayer` / `getIntlayer` keys to their `.content` files, for both\n // IDEs and AI agents. Setup is editor-specific (VS Code, Cursor, Windsurf,\n // Zed, Neovim, Claude Code, …), so we don't scaffold anything here — instead\n // we point to the doc and ask the agent to confirm the target platform.\n logger([\n colorize('Intlayer LSP →', ANSIColors.MAGENTA),\n colorize(\n 'The Intlayer Language Server is available via the `@intlayer/lsp` package. It lets IDEs and AI agents jump from `useIntlayer`/`getIntlayer` keys to their `.content` files.',\n ANSIColors.GREY_LIGHT\n ),\n colorize(\n 'Ask the user which platform/editor they want to enable it on (VS Code, Cursor, Windsurf, Zed, Neovim, Claude Code, …), then follow the matching setup instructions:',\n ANSIColors.GREY_LIGHT\n ),\n colorizePath(DocumentationRouter.LSP),\n ]);\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
2
+ import { dirname, join, relative, resolve, sep } from "node:path";
3
3
  import fg from "fast-glob";
4
4
  import { EXCLUDED_PATHS } from "@intlayer/config/defaultValues";
5
5
  import { ALL_LOCALES } from "@intlayer/types/allLocales";
@@ -123,7 +123,51 @@ const detectJsonLocalePattern = async (rootDir) => {
123
123
  locales: Array.from(flatLocales)
124
124
  };
125
125
  };
126
+ /** Common locations of the `next-intl` request config, relative to the root. */
127
+ const NEXT_INTL_REQUEST_FILES = [
128
+ "i18n/request.ts",
129
+ "i18n/request.tsx",
130
+ "i18n/request.js",
131
+ "i18n/request.mjs",
132
+ "src/i18n/request.ts",
133
+ "src/i18n/request.tsx",
134
+ "src/i18n/request.js",
135
+ "src/i18n/request.mjs",
136
+ "app/i18n/request.ts",
137
+ "src/app/i18n/request.ts"
138
+ ];
139
+ /**
140
+ * Derives the messages source template from a `next-intl` `i18n/request.ts`
141
+ * file, which is the authoritative location of the messages path in a next-intl
142
+ * project (e.g. `messages: (await import(\`../messages/${locale}.json\`)).default`).
143
+ *
144
+ * Reading it removes the ambiguity of globbing the file system and yields the
145
+ * exact `source` template for `syncJSON`. When the resulting template has no
146
+ * `${key}` segment (the common single-file-per-locale layout, where top-level
147
+ * keys are namespaces), `syncJSON` `splitKeys` auto-detection turns each
148
+ * top-level key into its own dictionary.
149
+ *
150
+ * Returns `null` when no request file is found, the messages import cannot be
151
+ * parsed, or the path is not project-root-relative (e.g. uses a TS path alias).
152
+ *
153
+ * @param rootDir - Project root directory.
154
+ */
155
+ const detectNextIntlMessagesPattern = async (rootDir) => {
156
+ for (const requestFile of NEXT_INTL_REQUEST_FILES) {
157
+ if (!await exists(rootDir, requestFile)) continue;
158
+ const importPath = (await readFileFromRoot(rootDir, requestFile)).match(/import\(\s*`([^`]*\$\{\s*locale\s*\}[^`]*\.json)`/)?.[1];
159
+ if (!importPath) continue;
160
+ if (!importPath.startsWith(".")) continue;
161
+ const relativeTemplate = relative(rootDir, resolve(dirname(resolve(rootDir, requestFile)), importPath)).split(sep).join("/");
162
+ const template = relativeTemplate.startsWith(".") ? relativeTemplate : `./${relativeTemplate}`;
163
+ return {
164
+ type: template.includes("${key}") || template.includes("${namespace}") ? "nested" : "flat",
165
+ template
166
+ };
167
+ }
168
+ return null;
169
+ };
126
170
 
127
171
  //#endregion
128
- export { detectJsonLocalePattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot };
172
+ export { detectJsonLocalePattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot };
129
173
  //# sourceMappingURL=fileSystem.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileSystem.mjs","names":[],"sources":["../../../../src/init/utils/fileSystem.ts"],"sourcesContent":["import { access, mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { EXCLUDED_PATHS } from '@intlayer/config/defaultValues';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\n\n/**\n * Helper to check if a file exists\n */\nexport const exists = async (rootDir: string, filePath: string) => {\n try {\n await access(join(rootDir, filePath));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Helper to read a file\n */\nexport const readFileFromRoot = async (rootDir: string, filePath: string) =>\n await readFile(join(rootDir, filePath), 'utf8');\n\n/**\n * Helper to write a file\n */\nexport const writeFileToRoot = async (\n rootDir: string,\n filePath: string,\n content: string\n) => await writeFile(join(rootDir, filePath), content, 'utf8');\n\n/**\n * Helper to ensure a directory exists\n */\nexport const ensureDirectory = async (rootDir: string, dirPath: string) => {\n try {\n await mkdir(join(rootDir, dirPath), { recursive: true });\n } catch {\n // Directory already exists or could not be created\n }\n};\n\n/**\n * Pattern type for locale JSON file organisation.\n * - 'nested': files are at `{base}/{locale}/{key}.json`\n * - 'flat': files are at `{base}/{locale}.json`\n */\nexport type JsonLocalePatternType = 'nested' | 'flat';\n\n/**\n * Detected locale JSON file pattern and the corresponding source template.\n * `template` uses `${locale}` and `${key}` as literal placeholders (not JS\n * expressions) so it can be embedded directly in a template-literal string.\n */\nexport type JsonLocalePattern = {\n type: JsonLocalePatternType;\n /**\n * Source path template for syncJSON `source` option.\n * Example nested: `./locales/${locale}/${key}.json`\n * Example flat: `./locales/${locale}.json`\n */\n template: string;\n /**\n * Detected locales in the directory.\n */\n locales: string[];\n};\n\n/**\n * Set of all known locale string values from the intlayer Locales registry\n * (e.g. `'en'`, `'fr'`, `'zh-TW'`). Keyed by the exact locale string so\n * `.has()` lookups are O(1) and common short directory names (`src`, `lib`,\n * `app`, …) are not mistaken for locales.\n */\nconst ALL_LOCALE_VALUES = new Set<string>(Object.values(ALL_LOCALES));\n\n/**\n * Returns true when `segment` matches a known BCP-47 locale identifier, e.g.\n * `en`, `fr`, `zh-TW`, `pt-BR`, `en-US`.\n */\nconst isLocaleSegment = (segment: string): boolean =>\n ALL_LOCALE_VALUES.has(segment);\n\n/** JSON filenames that are never locale translation files. */\nconst KNOWN_CONFIG_FILENAMES = new Set([\n 'package.json',\n 'tsconfig.json',\n 'jsconfig.json',\n 'biome.json',\n 'turbo.json',\n 'lerna.json',\n 'vercel.json',\n 'netlify.json',\n 'babel.config.json',\n 'jest.config.json',\n 'vitest.config.json',\n '.eslintrc.json',\n '.prettierrc.json',\n]);\n\n/**\n * Scans the project for JSON files and determines whether locale files are\n * organised as `{base}/{locale}/{key}.json` (nested) or `{base}/{locale}.json`\n * (flat). Returns the most likely source template, or `null` when no locale\n * JSON files are found.\n *\n * The returned `template` contains `${locale}` and `${key}` as **literal**\n * placeholder strings so it can be embedded inside a JS template literal.\n */\nexport const detectJsonLocalePattern = async (\n rootDir: string\n): Promise<JsonLocalePattern | null> => {\n const files = await fg('**/*.json', {\n cwd: rootDir,\n ignore: EXCLUDED_PATHS,\n absolute: false,\n onlyFiles: true,\n });\n\n const nestedBasePaths: string[] = [];\n const flatBasePaths: string[] = [];\n const nestedLocales = new Set<string>();\n const flatLocales = new Set<string>();\n\n for (const file of files) {\n const parts = file.split('/');\n const filename = parts[parts.length - 1] ?? '';\n\n if (KNOWN_CONFIG_FILENAMES.has(filename)) continue;\n\n // Nested: …/{locale}/{key}.json — parent directory is a locale code\n if (parts.length >= 3) {\n const localeDir = parts[parts.length - 2] ?? '';\n if (isLocaleSegment(localeDir)) {\n nestedBasePaths.push(parts.slice(0, -2).join('/') || '.');\n nestedLocales.add(localeDir);\n }\n }\n\n // Flat: …/{locale}.json — filename (without extension) is a locale code\n if (parts.length >= 2) {\n const baseName = filename.slice(0, -5); // strip \".json\"\n if (isLocaleSegment(baseName)) {\n flatBasePaths.push(parts.slice(0, -1).join('/') || '.');\n flatLocales.add(baseName);\n }\n }\n }\n\n if (nestedBasePaths.length === 0 && flatBasePaths.length === 0) {\n return null;\n }\n\n /**\n * Returns the path prefix that appears most frequently among the matches,\n * formatted as a relative path suitable for a source template.\n */\n const mostFrequentPrefix = (paths: string[]): string => {\n const counts = paths.reduce<Record<string, number>>((accumulator, path) => {\n accumulator[path] = (accumulator[path] ?? 0) + 1;\n return accumulator;\n }, {});\n const topEntry = Object.entries(counts).sort(([, a], [, b]) => b - a)[0];\n const basePath = topEntry?.[0] ?? '.';\n return basePath === '.' ? '.' : `./${basePath}`;\n };\n\n if (nestedBasePaths.length >= flatBasePaths.length) {\n const prefix = mostFrequentPrefix(nestedBasePaths);\n return {\n type: 'nested',\n // Literal ${locale} and ${key} — not evaluated here, used in template literals\n template: `${prefix}/\\${locale}/\\${key}.json`,\n locales: Array.from(nestedLocales),\n };\n }\n\n const prefix = mostFrequentPrefix(flatBasePaths);\n return {\n type: 'flat',\n template: `${prefix}/\\${locale}.json`,\n locales: Array.from(flatLocales),\n };\n};\n"],"mappings":";;;;;;;;;;AASA,MAAa,SAAS,OAAO,SAAiB,aAAqB;AACjE,KAAI;AACF,QAAM,OAAO,KAAK,SAAS,SAAS,CAAC;AACrC,SAAO;SACD;AACN,SAAO;;;;;;AAOX,MAAa,mBAAmB,OAAO,SAAiB,aACtD,MAAM,SAAS,KAAK,SAAS,SAAS,EAAE,OAAO;;;;AAKjD,MAAa,kBAAkB,OAC7B,SACA,UACA,YACG,MAAM,UAAU,KAAK,SAAS,SAAS,EAAE,SAAS,OAAO;;;;AAK9D,MAAa,kBAAkB,OAAO,SAAiB,YAAoB;AACzE,KAAI;AACF,QAAM,MAAM,KAAK,SAAS,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;SAClD;;;;;;;;AAqCV,MAAM,oBAAoB,IAAI,IAAY,OAAO,OAAO,YAAY,CAAC;;;;;AAMrE,MAAM,mBAAmB,YACvB,kBAAkB,IAAI,QAAQ;;AAGhC,MAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;AAWF,MAAa,0BAA0B,OACrC,YACsC;CACtC,MAAM,QAAQ,MAAM,GAAG,aAAa;EAClC,KAAK;EACL,QAAQ;EACR,UAAU;EACV,WAAW;EACZ,CAAC;CAEF,MAAM,kBAA4B,EAAE;CACpC,MAAM,gBAA0B,EAAE;CAClC,MAAM,gCAAgB,IAAI,KAAa;CACvC,MAAM,8BAAc,IAAI,KAAa;AAErC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,KAAK,MAAM,IAAI;EAC7B,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAE5C,MAAI,uBAAuB,IAAI,SAAS,CAAE;AAG1C,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,YAAY,MAAM,MAAM,SAAS,MAAM;AAC7C,OAAI,gBAAgB,UAAU,EAAE;AAC9B,oBAAgB,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACzD,kBAAc,IAAI,UAAU;;;AAKhC,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,WAAW,SAAS,MAAM,GAAG,GAAG;AACtC,OAAI,gBAAgB,SAAS,EAAE;AAC7B,kBAAc,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACvD,gBAAY,IAAI,SAAS;;;;AAK/B,KAAI,gBAAgB,WAAW,KAAK,cAAc,WAAW,EAC3D,QAAO;;;;;CAOT,MAAM,sBAAsB,UAA4B;EACtD,MAAM,SAAS,MAAM,QAAgC,aAAa,SAAS;AACzE,eAAY,SAAS,YAAY,SAAS,KAAK;AAC/C,UAAO;KACN,EAAE,CAAC;EAEN,MAAM,WADW,OAAO,QAAQ,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,KAC1C,MAAM;AAClC,SAAO,aAAa,MAAM,MAAM,KAAK;;AAGvC,KAAI,gBAAgB,UAAU,cAAc,OAE1C,QAAO;EACL,MAAM;EAEN,UAAU,GAJG,mBAAmB,gBAIb,CAAC;EACpB,SAAS,MAAM,KAAK,cAAc;EACnC;AAIH,QAAO;EACL,MAAM;EACN,UAAU,GAHG,mBAAmB,cAGb,CAAC;EACpB,SAAS,MAAM,KAAK,YAAY;EACjC"}
1
+ {"version":3,"file":"fileSystem.mjs","names":[],"sources":["../../../../src/init/utils/fileSystem.ts"],"sourcesContent":["import { access, mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { EXCLUDED_PATHS } from '@intlayer/config/defaultValues';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\n\n/**\n * Helper to check if a file exists\n */\nexport const exists = async (rootDir: string, filePath: string) => {\n try {\n await access(join(rootDir, filePath));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Helper to read a file\n */\nexport const readFileFromRoot = async (rootDir: string, filePath: string) =>\n await readFile(join(rootDir, filePath), 'utf8');\n\n/**\n * Helper to write a file\n */\nexport const writeFileToRoot = async (\n rootDir: string,\n filePath: string,\n content: string\n) => await writeFile(join(rootDir, filePath), content, 'utf8');\n\n/**\n * Helper to ensure a directory exists\n */\nexport const ensureDirectory = async (rootDir: string, dirPath: string) => {\n try {\n await mkdir(join(rootDir, dirPath), { recursive: true });\n } catch {\n // Directory already exists or could not be created\n }\n};\n\n/**\n * Pattern type for locale JSON file organisation.\n * - 'nested': files are at `{base}/{locale}/{key}.json`\n * - 'flat': files are at `{base}/{locale}.json`\n */\nexport type JsonLocalePatternType = 'nested' | 'flat';\n\n/**\n * Detected locale JSON file pattern and the corresponding source template.\n * `template` uses `${locale}` and `${key}` as literal placeholders (not JS\n * expressions) so it can be embedded directly in a template-literal string.\n */\nexport type JsonLocalePattern = {\n type: JsonLocalePatternType;\n /**\n * Source path template for syncJSON `source` option.\n * Example nested: `./locales/${locale}/${key}.json`\n * Example flat: `./locales/${locale}.json`\n */\n template: string;\n /**\n * Detected locales in the directory.\n */\n locales: string[];\n};\n\n/**\n * Set of all known locale string values from the intlayer Locales registry\n * (e.g. `'en'`, `'fr'`, `'zh-TW'`). Keyed by the exact locale string so\n * `.has()` lookups are O(1) and common short directory names (`src`, `lib`,\n * `app`, …) are not mistaken for locales.\n */\nconst ALL_LOCALE_VALUES = new Set<string>(Object.values(ALL_LOCALES));\n\n/**\n * Returns true when `segment` matches a known BCP-47 locale identifier, e.g.\n * `en`, `fr`, `zh-TW`, `pt-BR`, `en-US`.\n */\nconst isLocaleSegment = (segment: string): boolean =>\n ALL_LOCALE_VALUES.has(segment);\n\n/** JSON filenames that are never locale translation files. */\nconst KNOWN_CONFIG_FILENAMES = new Set([\n 'package.json',\n 'tsconfig.json',\n 'jsconfig.json',\n 'biome.json',\n 'turbo.json',\n 'lerna.json',\n 'vercel.json',\n 'netlify.json',\n 'babel.config.json',\n 'jest.config.json',\n 'vitest.config.json',\n '.eslintrc.json',\n '.prettierrc.json',\n]);\n\n/**\n * Scans the project for JSON files and determines whether locale files are\n * organised as `{base}/{locale}/{key}.json` (nested) or `{base}/{locale}.json`\n * (flat). Returns the most likely source template, or `null` when no locale\n * JSON files are found.\n *\n * The returned `template` contains `${locale}` and `${key}` as **literal**\n * placeholder strings so it can be embedded inside a JS template literal.\n */\nexport const detectJsonLocalePattern = async (\n rootDir: string\n): Promise<JsonLocalePattern | null> => {\n const files = await fg('**/*.json', {\n cwd: rootDir,\n ignore: EXCLUDED_PATHS,\n absolute: false,\n onlyFiles: true,\n });\n\n const nestedBasePaths: string[] = [];\n const flatBasePaths: string[] = [];\n const nestedLocales = new Set<string>();\n const flatLocales = new Set<string>();\n\n for (const file of files) {\n const parts = file.split('/');\n const filename = parts[parts.length - 1] ?? '';\n\n if (KNOWN_CONFIG_FILENAMES.has(filename)) continue;\n\n // Nested: …/{locale}/{key}.json — parent directory is a locale code\n if (parts.length >= 3) {\n const localeDir = parts[parts.length - 2] ?? '';\n if (isLocaleSegment(localeDir)) {\n nestedBasePaths.push(parts.slice(0, -2).join('/') || '.');\n nestedLocales.add(localeDir);\n }\n }\n\n // Flat: …/{locale}.json — filename (without extension) is a locale code\n if (parts.length >= 2) {\n const baseName = filename.slice(0, -5); // strip \".json\"\n if (isLocaleSegment(baseName)) {\n flatBasePaths.push(parts.slice(0, -1).join('/') || '.');\n flatLocales.add(baseName);\n }\n }\n }\n\n if (nestedBasePaths.length === 0 && flatBasePaths.length === 0) {\n return null;\n }\n\n /**\n * Returns the path prefix that appears most frequently among the matches,\n * formatted as a relative path suitable for a source template.\n */\n const mostFrequentPrefix = (paths: string[]): string => {\n const counts = paths.reduce<Record<string, number>>((accumulator, path) => {\n accumulator[path] = (accumulator[path] ?? 0) + 1;\n return accumulator;\n }, {});\n const topEntry = Object.entries(counts).sort(([, a], [, b]) => b - a)[0];\n const basePath = topEntry?.[0] ?? '.';\n return basePath === '.' ? '.' : `./${basePath}`;\n };\n\n if (nestedBasePaths.length >= flatBasePaths.length) {\n const prefix = mostFrequentPrefix(nestedBasePaths);\n return {\n type: 'nested',\n // Literal ${locale} and ${key} — not evaluated here, used in template literals\n template: `${prefix}/\\${locale}/\\${key}.json`,\n locales: Array.from(nestedLocales),\n };\n }\n\n const prefix = mostFrequentPrefix(flatBasePaths);\n return {\n type: 'flat',\n template: `${prefix}/\\${locale}.json`,\n locales: Array.from(flatLocales),\n };\n};\n\n/**\n * The messages source template derived from a `next-intl` `i18n/request.ts`\n * file, ready to be used as a `syncJSON` `source` builder.\n */\nexport type NextIntlMessagesPattern = {\n /** `'flat'` (one file per locale) or `'nested'` (per-namespace files). */\n type: JsonLocalePatternType;\n /**\n * Source path template relative to the project root, with `${locale}` (and\n * `${key}` when nested) as literal placeholders, e.g. `./messages/${locale}.json`.\n */\n template: string;\n};\n\n/** Common locations of the `next-intl` request config, relative to the root. */\nconst NEXT_INTL_REQUEST_FILES = [\n 'i18n/request.ts',\n 'i18n/request.tsx',\n 'i18n/request.js',\n 'i18n/request.mjs',\n 'src/i18n/request.ts',\n 'src/i18n/request.tsx',\n 'src/i18n/request.js',\n 'src/i18n/request.mjs',\n 'app/i18n/request.ts',\n 'src/app/i18n/request.ts',\n];\n\n/**\n * Derives the messages source template from a `next-intl` `i18n/request.ts`\n * file, which is the authoritative location of the messages path in a next-intl\n * project (e.g. `messages: (await import(\\`../messages/${locale}.json\\`)).default`).\n *\n * Reading it removes the ambiguity of globbing the file system and yields the\n * exact `source` template for `syncJSON`. When the resulting template has no\n * `${key}` segment (the common single-file-per-locale layout, where top-level\n * keys are namespaces), `syncJSON` `splitKeys` auto-detection turns each\n * top-level key into its own dictionary.\n *\n * Returns `null` when no request file is found, the messages import cannot be\n * parsed, or the path is not project-root-relative (e.g. uses a TS path alias).\n *\n * @param rootDir - Project root directory.\n */\nexport const detectNextIntlMessagesPattern = async (\n rootDir: string\n): Promise<NextIntlMessagesPattern | null> => {\n for (const requestFile of NEXT_INTL_REQUEST_FILES) {\n if (!(await exists(rootDir, requestFile))) continue;\n\n const content = await readFileFromRoot(rootDir, requestFile);\n\n // Capture the template-literal path of the messages dynamic import, e.g.\n // import(`../messages/${locale}.json`) → `../messages/${locale}.json`.\n const importMatch = content.match(\n /import\\(\\s*`([^`]*\\$\\{\\s*locale\\s*\\}[^`]*\\.json)`/\n );\n\n const importPath = importMatch?.[1];\n if (!importPath) continue;\n\n // Only relative imports can be resolved against the file system; path\n // aliases (e.g. `@/messages/...`) are skipped in favour of glob detection.\n if (!importPath.startsWith('.')) continue;\n\n // Resolve the import (relative to the request file) back to a\n // project-root-relative template. The `${locale}` / `${key}` placeholders\n // are kept literal — path utilities treat them as ordinary segments.\n const requestDir = dirname(resolve(rootDir, requestFile));\n const absoluteTemplate = resolve(requestDir, importPath);\n const relativeTemplate = relative(rootDir, absoluteTemplate)\n .split(sep)\n .join('/');\n\n const template = relativeTemplate.startsWith('.')\n ? relativeTemplate\n : `./${relativeTemplate}`;\n\n const type: JsonLocalePatternType =\n template.includes('${key}') || template.includes('${namespace}')\n ? 'nested'\n : 'flat';\n\n return { type, template };\n }\n\n return null;\n};\n"],"mappings":";;;;;;;;;;AASA,MAAa,SAAS,OAAO,SAAiB,aAAqB;AACjE,KAAI;AACF,QAAM,OAAO,KAAK,SAAS,SAAS,CAAC;AACrC,SAAO;SACD;AACN,SAAO;;;;;;AAOX,MAAa,mBAAmB,OAAO,SAAiB,aACtD,MAAM,SAAS,KAAK,SAAS,SAAS,EAAE,OAAO;;;;AAKjD,MAAa,kBAAkB,OAC7B,SACA,UACA,YACG,MAAM,UAAU,KAAK,SAAS,SAAS,EAAE,SAAS,OAAO;;;;AAK9D,MAAa,kBAAkB,OAAO,SAAiB,YAAoB;AACzE,KAAI;AACF,QAAM,MAAM,KAAK,SAAS,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;SAClD;;;;;;;;AAqCV,MAAM,oBAAoB,IAAI,IAAY,OAAO,OAAO,YAAY,CAAC;;;;;AAMrE,MAAM,mBAAmB,YACvB,kBAAkB,IAAI,QAAQ;;AAGhC,MAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;AAWF,MAAa,0BAA0B,OACrC,YACsC;CACtC,MAAM,QAAQ,MAAM,GAAG,aAAa;EAClC,KAAK;EACL,QAAQ;EACR,UAAU;EACV,WAAW;EACZ,CAAC;CAEF,MAAM,kBAA4B,EAAE;CACpC,MAAM,gBAA0B,EAAE;CAClC,MAAM,gCAAgB,IAAI,KAAa;CACvC,MAAM,8BAAc,IAAI,KAAa;AAErC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,KAAK,MAAM,IAAI;EAC7B,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAE5C,MAAI,uBAAuB,IAAI,SAAS,CAAE;AAG1C,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,YAAY,MAAM,MAAM,SAAS,MAAM;AAC7C,OAAI,gBAAgB,UAAU,EAAE;AAC9B,oBAAgB,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACzD,kBAAc,IAAI,UAAU;;;AAKhC,MAAI,MAAM,UAAU,GAAG;GACrB,MAAM,WAAW,SAAS,MAAM,GAAG,GAAG;AACtC,OAAI,gBAAgB,SAAS,EAAE;AAC7B,kBAAc,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI;AACvD,gBAAY,IAAI,SAAS;;;;AAK/B,KAAI,gBAAgB,WAAW,KAAK,cAAc,WAAW,EAC3D,QAAO;;;;;CAOT,MAAM,sBAAsB,UAA4B;EACtD,MAAM,SAAS,MAAM,QAAgC,aAAa,SAAS;AACzE,eAAY,SAAS,YAAY,SAAS,KAAK;AAC/C,UAAO;KACN,EAAE,CAAC;EAEN,MAAM,WADW,OAAO,QAAQ,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,KAC1C,MAAM;AAClC,SAAO,aAAa,MAAM,MAAM,KAAK;;AAGvC,KAAI,gBAAgB,UAAU,cAAc,OAE1C,QAAO;EACL,MAAM;EAEN,UAAU,GAJG,mBAAmB,gBAIb,CAAC;EACpB,SAAS,MAAM,KAAK,cAAc;EACnC;AAIH,QAAO;EACL,MAAM;EACN,UAAU,GAHG,mBAAmB,cAGb,CAAC;EACpB,SAAS,MAAM,KAAK,YAAY;EACjC;;;AAkBH,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAkBD,MAAa,gCAAgC,OAC3C,YAC4C;AAC5C,MAAK,MAAM,eAAe,yBAAyB;AACjD,MAAI,CAAE,MAAM,OAAO,SAAS,YAAY,CAAG;EAU3C,MAAM,cAJc,MAJE,iBAAiB,SAAS,YAAY,EAIhC,MAC1B,oDAG4B,GAAG;AACjC,MAAI,CAAC,WAAY;AAIjB,MAAI,CAAC,WAAW,WAAW,IAAI,CAAE;EAOjC,MAAM,mBAAmB,SAAS,SADT,QADN,QAAQ,QAAQ,SAAS,YAAY,CACb,EAAE,WACc,CAAC,CACzD,MAAM,IAAI,CACV,KAAK,IAAI;EAEZ,MAAM,WAAW,iBAAiB,WAAW,IAAI,GAC7C,mBACA,KAAK;AAOT,SAAO;GAAE,MAJP,SAAS,SAAS,SAAS,IAAI,SAAS,SAAS,eAAe,GAC5D,WACA;GAES;GAAU;;AAG3B,QAAO"}
@@ -1,8 +1,8 @@
1
1
  import { updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.mjs";
2
- import { detectJsonLocalePattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.mjs";
2
+ import { detectJsonLocalePattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.mjs";
3
3
  import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows } from "./githubActions.mjs";
4
4
  import { parseJSONWithComments } from "./jsonParser.mjs";
5
5
  import { detectMissingIntlayerPackages, detectPackageManager, installPackages } from "./packageManager.mjs";
6
6
  import { findTsConfigFiles } from "./tsConfig.mjs";
7
7
 
8
- export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, detectJsonLocalePattern, detectMissingIntlayerPackages, detectPackageManager, ensureDirectory, exists, findTsConfigFiles, getGithubWorkflows, installPackages, parseJSONWithComments, readFileFromRoot, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, writeFileToRoot };
8
+ export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, detectJsonLocalePattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectPackageManager, ensureDirectory, exists, findTsConfigFiles, getGithubWorkflows, installPackages, parseJSONWithComments, readFileFromRoot, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, writeFileToRoot };
@@ -55,7 +55,7 @@ const detectMissingIntlayerPackages = (allDependencies) => {
55
55
  addIfMissing("next-intl");
56
56
  compatSyncConfig ??= {
57
57
  format: "icu",
58
- sourceTemplate: "./locales/${locale}/${key}.json"
58
+ sourceTemplate: "./messages/${locale}.json"
59
59
  };
60
60
  }
61
61
  if (isInstalled("next-i18next") || isInstalled("@intlayer/next-i18next")) {
@@ -102,6 +102,18 @@ const detectMissingIntlayerPackages = (allDependencies) => {
102
102
  pluginPackageSource: "@intlayer/vue-i18n/plugin"
103
103
  };
104
104
  }
105
+ if (isInstalled("use-intl") || isInstalled("@intlayer/use-intl")) {
106
+ addIfMissing("@intlayer/use-intl");
107
+ addIfMissing("use-intl");
108
+ compatSyncConfig ??= {
109
+ format: "icu",
110
+ sourceTemplate: "./messages/${locale}.json"
111
+ };
112
+ compatVitePluginConfig ??= {
113
+ pluginFunctionName: "useIntlVitePlugin",
114
+ pluginPackageSource: "@intlayer/use-intl/plugin"
115
+ };
116
+ }
105
117
  if (isInstalled("react-intl") || isInstalled("@intlayer/react-intl")) {
106
118
  addIfMissing("@intlayer/react-intl");
107
119
  addIfMissing("react-intl");
@@ -1 +1 @@
1
- {"version":3,"file":"packageManager.mjs","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\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 /** JSON format matching the compat library's conventions. */\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\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\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 */\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(allDependencies[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 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\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: './locales/${locale}/${key}.json',\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 // 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 // @todo syncJSON format not yet implemented for lingui (uses PO files)\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'linguiVitePlugin',\n pluginPackageSource: '@intlayer/lingui/plugin',\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('@intlayer/sync-json-plugin');\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"],"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 } from 'node:fs';\nimport { join } from 'node:path';\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 /** JSON format matching the compat library's conventions. */\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\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\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 */\nexport const detectMissingIntlayerPackages = (\n allDependencies: Record<string, string>\n): IntlayerPackageAnalysis => {\n const packagesToInstall: string[] = [];\n const devPackagesToInstall: string[] = [];\n let compatSyncConfig: CompatSyncConfig | undefined;\n let compatVitePluginConfig: CompatVitePluginConfig | undefined;\n\n const isInstalled = (packageName: string): boolean =>\n Boolean(allDependencies[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 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 };\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 };\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 // @todo syncJSON format not yet implemented for lingui (uses PO files)\n if (\n isInstalled('@lingui/core') ||\n isInstalled('@lingui/react') ||\n isInstalled('@intlayer/lingui')\n ) {\n addIfMissing('@intlayer/lingui');\n addIfMissing('@lingui/core');\n compatVitePluginConfig ??= {\n pluginFunctionName: 'linguiVitePlugin',\n pluginPackageSource: '@intlayer/lingui/plugin',\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('@intlayer/sync-json-plugin');\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"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;AA6KA;;KAAY,WAAA;EACV,WAAA,YAEe;EAAf,eAAA;AAAA;;;;cAMW,YAAA,GAAsB,OAAA,UAAiB,OAAA,GAAU,WAAA,KAAW,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;AA8KA;;KAAY,WAAA;EACV,WAAA,YAEe;EAAf,eAAA;AAAA;;;;cAMW,YAAA,GAAsB,OAAA,UAAiB,OAAA,GAAU,WAAA,KAAW,OAAA"}
@@ -49,6 +49,35 @@ type JsonLocalePattern = {
49
49
  * placeholder strings so it can be embedded inside a JS template literal.
50
50
  */
51
51
  declare const detectJsonLocalePattern: (rootDir: string) => Promise<JsonLocalePattern | null>;
52
+ /**
53
+ * The messages source template derived from a `next-intl` `i18n/request.ts`
54
+ * file, ready to be used as a `syncJSON` `source` builder.
55
+ */
56
+ type NextIntlMessagesPattern = {
57
+ /** `'flat'` (one file per locale) or `'nested'` (per-namespace files). */type: JsonLocalePatternType;
58
+ /**
59
+ * Source path template relative to the project root, with `${locale}` (and
60
+ * `${key}` when nested) as literal placeholders, e.g. `./messages/${locale}.json`.
61
+ */
62
+ template: string;
63
+ };
64
+ /**
65
+ * Derives the messages source template from a `next-intl` `i18n/request.ts`
66
+ * file, which is the authoritative location of the messages path in a next-intl
67
+ * project (e.g. `messages: (await import(\`../messages/${locale}.json\`)).default`).
68
+ *
69
+ * Reading it removes the ambiguity of globbing the file system and yields the
70
+ * exact `source` template for `syncJSON`. When the resulting template has no
71
+ * `${key}` segment (the common single-file-per-locale layout, where top-level
72
+ * keys are namespaces), `syncJSON` `splitKeys` auto-detection turns each
73
+ * top-level key into its own dictionary.
74
+ *
75
+ * Returns `null` when no request file is found, the messages import cannot be
76
+ * parsed, or the path is not project-root-relative (e.g. uses a TS path alias).
77
+ *
78
+ * @param rootDir - Project root directory.
79
+ */
80
+ declare const detectNextIntlMessagesPattern: (rootDir: string) => Promise<NextIntlMessagesPattern | null>;
52
81
  //#endregion
53
- export { JsonLocalePattern, JsonLocalePatternType, detectJsonLocalePattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot };
82
+ export { JsonLocalePattern, JsonLocalePatternType, NextIntlMessagesPattern, detectJsonLocalePattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot };
54
83
  //# sourceMappingURL=fileSystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileSystem.d.ts","names":[],"sources":["../../../../src/init/utils/fileSystem.ts"],"mappings":";;AASA;;cAAa,MAAA,GAAgB,OAAA,UAAiB,QAAA,aAAgB,OAAA;;;;cAYjD,gBAAA,GAA0B,OAAA,UAAiB,QAAA,aAAgB,OAAA;;;AAAxE;cAMa,eAAA,GACX,OAAA,UACA,QAAA,UACA,OAAA,aAAe,OAAA;;;;cAMJ,eAAA,GAAyB,OAAA,UAAiB,OAAA,aAAe,OAAA;;;;AATtE;;KAsBY,qBAAA;;;;;;KAOA,iBAAA;EACV,IAAA,EAAM,qBAAA;EArBK;;;;;EA2BX,QAAA;EA3BoE;;;EA+BpE,OAAA;AAAA;;;;AAXF;;;;;;cAuDa,uBAAA,GACX,OAAA,aACC,OAAA,CAAQ,iBAAA"}
1
+ {"version":3,"file":"fileSystem.d.ts","names":[],"sources":["../../../../src/init/utils/fileSystem.ts"],"mappings":";;AASA;;cAAa,MAAA,GAAgB,OAAA,UAAiB,QAAA,aAAgB,OAAA;;;;cAYjD,gBAAA,GAA0B,OAAA,UAAiB,QAAA,aAAgB,OAAA;;;AAAxE;cAMa,eAAA,GACX,OAAA,UACA,QAAA,UACA,OAAA,aAAe,OAAA;;;;cAMJ,eAAA,GAAyB,OAAA,UAAiB,OAAA,aAAe,OAAA;;;;AATtE;;KAsBY,qBAAA;;;;;;KAOA,iBAAA;EACV,IAAA,EAAM,qBAAA;EArBK;;;;;EA2BX,QAAA;EA3BoE;;;EA+BpE,OAAA;AAAA;;;;AAXF;;;;;;cAuDa,uBAAA,GACX,OAAA,aACC,OAAA,CAAQ,iBAAA;;;;AAFX;KAgFY,uBAAA;4EAEV,IAAA,EAAM,qBAAA;EAjFN;;;;EAsFA,QAAA;AAAA;;;;;;;;;AAiCF;;;;;;;;cAAa,6BAAA,GACX,OAAA,aACC,OAAA,CAAQ,uBAAA"}
@@ -1,7 +1,7 @@
1
1
  import { CompatSyncConfig, CompatVitePluginConfig, IntlayerPackageAnalysis, PackageManager, detectMissingIntlayerPackages, detectPackageManager, installPackages } from "./packageManager.js";
2
2
  import { updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.js";
3
- import { JsonLocalePattern, JsonLocalePatternType, detectJsonLocalePattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.js";
3
+ import { JsonLocalePattern, JsonLocalePatternType, NextIntlMessagesPattern, detectJsonLocalePattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.js";
4
4
  import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, getGithubWorkflows } from "./githubActions.js";
5
5
  import { parseJSONWithComments } from "./jsonParser.js";
6
6
  import { findTsConfigFiles } from "./tsConfig.js";
7
- export { CompatSyncConfig, CompatVitePluginConfig, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, PackageManager, detectJsonLocalePattern, detectMissingIntlayerPackages, detectPackageManager, ensureDirectory, exists, findTsConfigFiles, getGithubWorkflows, installPackages, parseJSONWithComments, readFileFromRoot, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, writeFileToRoot };
7
+ export { CompatSyncConfig, CompatVitePluginConfig, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, NextIntlMessagesPattern, PackageManager, detectJsonLocalePattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectPackageManager, ensureDirectory, exists, findTsConfigFiles, getGithubWorkflows, installPackages, parseJSONWithComments, readFileFromRoot, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, writeFileToRoot };
@@ -1 +1 @@
1
- {"version":3,"file":"packageManager.d.ts","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"mappings":";;KAKY,cAAA;;;;;KAMA,gBAAA;EAAgB,6DAE1B,MAAA;EAAA;;AAaF;;EARE,cAAA;AAAA;;AAgBF;;;;KARY,sBAAA;EAYV,kFAVA,kBAAA,UAgBkB;EAdlB,mBAAA;AAAA;;KAIU,uBAAA;EAuBC,mEArBX,iBAAA;EAEA,oBAAA;EAiCD;AA4BD;;;;EAvDE,gBAAA,EAAkB,gBAAA;EAwDlB;;;;AA+PF;EAjTE,sBAAA,EAAwB,sBAAA;AAAA;;;;;cAOb,oBAAA,GAAwB,OAAA,aAAkB,cAAA;;;;;;cA0C1C,6BAAA,GACX,eAAA,EAAiB,MAAA,qBAChB,uBAAA;;;;;cA8PU,eAAA,GACX,OAAA,UACA,QAAA,YACA,cAAA,EAAgB,cAAA,EAChB,KAAA"}
1
+ {"version":3,"file":"packageManager.d.ts","names":[],"sources":["../../../../src/init/utils/packageManager.ts"],"mappings":";;KAKY,cAAA;;;;;KAMA,gBAAA;EAAgB,6DAE1B,MAAA;EAAA;;AAaF;;EARE,cAAA;AAAA;;AAgBF;;;;KARY,sBAAA;EAYV,kFAVA,kBAAA,UAgBkB;EAdlB,mBAAA;AAAA;;KAIU,uBAAA;EAuBC,mEArBX,iBAAA;EAEA,oBAAA;EAiCD;AA4BD;;;;EAvDE,gBAAA,EAAkB,gBAAA;EAwDlB;;;;AAoRF;EAtUE,sBAAA,EAAwB,sBAAA;AAAA;;;;;cAOb,oBAAA,GAAwB,OAAA,aAAkB,cAAA;;;;;;cA0C1C,6BAAA,GACX,eAAA,EAAiB,MAAA,qBAChB,uBAAA;;;;;cAmRU,eAAA,GACX,OAAA,UACA,QAAA,YACA,cAAA,EAAgB,cAAA,EAChB,KAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/chokidar",
3
- "version": "9.0.0-canary.2",
3
+ "version": "9.0.0-canary.3",
4
4
  "private": false,
5
5
  "description": "Scans and builds Intlayer declaration files into dictionaries based on Intlayer configuration.",
6
6
  "keywords": [
@@ -125,13 +125,13 @@
125
125
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
126
126
  },
127
127
  "dependencies": {
128
- "@intlayer/api": "9.0.0-canary.2",
129
- "@intlayer/config": "9.0.0-canary.2",
130
- "@intlayer/core": "9.0.0-canary.2",
131
- "@intlayer/dictionaries-entry": "9.0.0-canary.2",
132
- "@intlayer/remote-dictionaries-entry": "9.0.0-canary.2",
133
- "@intlayer/types": "9.0.0-canary.2",
134
- "@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.2",
128
+ "@intlayer/api": "9.0.0-canary.3",
129
+ "@intlayer/config": "9.0.0-canary.3",
130
+ "@intlayer/core": "9.0.0-canary.3",
131
+ "@intlayer/dictionaries-entry": "9.0.0-canary.3",
132
+ "@intlayer/remote-dictionaries-entry": "9.0.0-canary.3",
133
+ "@intlayer/types": "9.0.0-canary.3",
134
+ "@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.3",
135
135
  "@parcel/watcher": "2.5.6",
136
136
  "defu": "6.1.7",
137
137
  "fast-glob": "3.3.3",