@intlayer/engine 9.0.0-canary.15 โ†’ 9.0.0-canary.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"githubActions.cjs","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"sourcesContent":["import type { PackageManager } from './packageManager';\n\n/** A GitHub Actions workflow file to be written to the project. */\nexport type GithubWorkflowFile = {\n /** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */\n filePath: string;\n /** Full YAML content of the workflow file. */\n content: string;\n};\n\n/**\n * Package-manager-specific snippets used to assemble the CI workflows.\n * - `setupSteps`: YAML steps (already indented for the `steps:` list) that\n * install the package manager and Node.js, including dependency caching.\n * - `installCommand`: command that installs the project dependencies.\n * - `execCommand`: prefix used to run the locally installed `intlayer` binary.\n */\ntype PackageManagerCIConfig = {\n setupSteps: string;\n installCommand: string;\n execCommand: string;\n};\n\n/**\n * Returns the package-manager-specific steps and commands used to build the\n * GitHub Actions workflows. Each package manager needs a slightly different\n * setup action and a different way to run the local `intlayer` binary.\n */\nconst getPackageManagerCIConfig = (\n packageManager: PackageManager\n): PackageManagerCIConfig => {\n const setupNodeStep = (\n cache: PackageManager | undefined\n ): string => ` - name: ๐ŸŸข Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: 20${cache ? `\\n cache: ${cache}` : ''}`;\n\n switch (packageManager) {\n case 'bun':\n return {\n setupSteps: ` - name: ๐ŸฅŸ Setup Bun\n uses: oven-sh/setup-bun@v2`,\n installCommand: 'bun install --frozen-lockfile',\n execCommand: 'bunx intlayer',\n };\n case 'pnpm':\n return {\n setupSteps: ` - name: ๐Ÿ“ฆ Setup pnpm\n uses: pnpm/action-setup@v4\n${setupNodeStep('pnpm')}`,\n installCommand: 'pnpm install --frozen-lockfile',\n execCommand: 'pnpm exec intlayer',\n };\n case 'yarn':\n return {\n setupSteps: setupNodeStep('yarn'),\n installCommand: 'yarn install --frozen-lockfile',\n execCommand: 'yarn intlayer',\n };\n case 'npm':\n return {\n setupSteps: setupNodeStep('npm'),\n installCommand: 'npm ci',\n execCommand: 'npx intlayer',\n };\n }\n};\n\n/**\n * Builds the `intlayer fill` workflow. Runs on pull requests, regenerates the\n * missing translations for the changed dictionaries (`--git-diff`) using AI,\n * then commits the result back to the PR branch.\n *\n * AI access is required for `fill`. The workflow exposes both options:\n * - a provider API key (`AI_API_KEY` secret), forwarded via CLI flags, or\n * - Intlayer CMS access keys (`INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`).\n */\nconst generateFillWorkflow = (packageManager: PackageManager): string => {\n const { setupSteps, installCommand, execCommand } =\n getPackageManagerCIConfig(packageManager);\n\n return `name: Intlayer Fill\n# Auto-fill missing translations on every pull request.\non:\n pull_request:\n branches:\n - main\n\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n group: intlayer-fill-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n fill:\n runs-on: ubuntu-latest\n env:\n # AI access is required to generate translations.\n # Add the secret in: Settings โ†’ Secrets and variables โ†’ Actions.\n #\n # Option 1 โ€” Use your own AI provider key (forwarded below via CLI flags):\n AI_PROVIDER: openai\n AI_MODEL: gpt-5-mini\n AI_API_KEY: \\${{ secrets.AI_API_KEY }}\n #\n # Option 2 โ€” Use Intlayer CMS access keys instead of your own AI key.\n # Wire them in your intlayer.config and uncomment the lines below:\n # INTLAYER_CLIENT_ID: \\${{ secrets.INTLAYER_CLIENT_ID }}\n # INTLAYER_CLIENT_SECRET: \\${{ secrets.INTLAYER_CLIENT_SECRET }}\n steps:\n - name: โฌ‡๏ธ Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: true # Keep credentials to push back to the PR\n fetch-depth: 0 # Full history so --git-diff can compare refs\n${setupSteps}\n - name: ๐Ÿ“ฆ Install dependencies\n run: ${installCommand}\n - name: โš™๏ธ Build dictionaries\n run: ${execCommand} build\n - name: ๐Ÿค– Fill missing translations\n # Skip when no AI credentials are configured, so the workflow stays green\n # until an \\`AI_API_KEY\\` (or Intlayer CMS access keys) secret is added.\n if: \\${{ env.AI_API_KEY != '' || env.INTLAYER_CLIENT_ID != '' }}\n run: ${execCommand} fill --git-diff --mode complete --provider $AI_PROVIDER --model $AI_MODEL --api-key $AI_API_KEY\n - name: ๐Ÿ“ค Commit and push changes\n run: |\n git config --local user.email \"github-actions[bot]@users.noreply.github.com\"\n git config --local user.name \"github-actions[bot]\"\n if [ -n \"$(git status --porcelain)\" ]; then\n git add .\n git commit -m \"chore(intlayer): fill missing translations [skip ci]\"\n git push origin HEAD:\\${{ github.head_ref }}\n else\n echo \"No missing translations to fill.\"\n fi\n`;\n};\n\n/**\n * Builds the `intlayer test` workflow. Runs on pull requests and fails the\n * check when required locales are missing translations. No AI access needed.\n */\nconst generateTestWorkflow = (packageManager: PackageManager): string => {\n const { setupSteps, installCommand, execCommand } =\n getPackageManagerCIConfig(packageManager);\n\n return `name: Intlayer Test\n# Fail the pull request when required locales are missing translations.\non:\n pull_request:\n branches:\n - main\n\nconcurrency:\n group: intlayer-test-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - name: โฌ‡๏ธ Checkout repository\n uses: actions/checkout@v4\n${setupSteps}\n - name: ๐Ÿ“ฆ Install dependencies\n run: ${installCommand}\n - name: โš™๏ธ Build dictionaries\n run: ${execCommand} build\n - name: ๐Ÿงช Test for missing translations\n run: ${execCommand} test\n`;\n};\n\n/** Workflow file path constants, relative to the project root. */\nexport const GITHUB_FILL_WORKFLOW_PATH = '.github/workflows/intlayer-fill.yml';\nexport const GITHUB_TEST_WORKFLOW_PATH = '.github/workflows/intlayer-test.yml';\n\n/**\n * Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),\n * generated with commands matching the detected package manager.\n */\nexport const getGithubWorkflows = (\n packageManager: PackageManager\n): GithubWorkflowFile[] => [\n {\n filePath: GITHUB_FILL_WORKFLOW_PATH,\n content: generateFillWorkflow(packageManager),\n },\n {\n filePath: GITHUB_TEST_WORKFLOW_PATH,\n content: generateTestWorkflow(packageManager),\n },\n];\n"],"mappings":";;;;;;;;AA4BA,MAAM,6BACJ,mBAC2B;CAC3B,MAAM,iBACJ,UACW;;;4BAGa,QAAQ,sBAAsB,UAAU;AAElE,SAAQ,gBAAR;EACE,KAAK,MACH,QAAO;GACL,YAAY;;GAEZ,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY;;EAElB,cAAc,OAAO;GACf,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY,cAAc,OAAO;GACjC,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,MACH,QAAO;GACL,YAAY,cAAc,MAAM;GAChC,gBAAgB;GAChB,aAAa;GACd;;;;;;;;;;;;AAaP,MAAM,wBAAwB,mBAA2C;CACvE,MAAM,EAAE,YAAY,gBAAgB,gBAClC,0BAA0B,eAAe;AAE3C,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCP,WAAW;;eAEE,eAAe;;eAEf,YAAY;;;;;eAKZ,YAAY;;;;;;;;;;;;;;;;;;AAmB3B,MAAM,wBAAwB,mBAA2C;CACvE,MAAM,EAAE,YAAY,gBAAgB,gBAClC,0BAA0B,eAAe;AAE3C,QAAO;;;;;;;;;;;;;;;;;EAiBP,WAAW;;eAEE,eAAe;;eAEf,YAAY;;eAEZ,YAAY;;;;AAK3B,MAAa,4BAA4B;AACzC,MAAa,4BAA4B;;;;;AAMzC,MAAa,sBACX,mBACyB,CACzB;CACE,UAAU;CACV,SAAS,qBAAqB,eAAe;CAC9C,EACD;CACE,UAAU;CACV,SAAS,qBAAqB,eAAe;CAC9C,CACF"}
1
+ {"version":3,"file":"githubActions.cjs","names":["getGitRootDir","listProjects","detectPackageManager","sep"],"sources":["../../../../src/init/utils/githubActions.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, relative, resolve, sep } from 'node:path';\nimport { getGitRootDir, listProjects } from '../../listProjects';\nimport { detectPackageManager, type PackageManager } from './packageManager';\n\n/** A GitHub Actions workflow file to be written to the project. */\nexport type GithubWorkflowFile = {\n /** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */\n filePath: string;\n /** Full YAML content of the workflow file. */\n content: string;\n};\n\n/** Options controlling how the CI workflows are generated. */\nexport type GithubWorkflowsOptions = {\n /**\n * Route the intlayer commands through `intlayer ci` instead of calling them\n * directly. The `ci` command discovers every Intlayer project of the\n * repository (via `listProjects`) and runs the given command inside each of\n * them, injecting per-project credentials from the\n * `INTLAYER_PROJECT_CREDENTIALS` secret when provided. Required for\n * monorepos where a single workflow must cover several projects.\n */\n useCiCommand?: boolean;\n /**\n * Repository-relative directory (posix separators) the workflow commands run\n * in. Set when the Intlayer project lives in a subdirectory of the\n * repository and the repository root has no workspace manifest to install\n * dependencies from. Undefined = repository root.\n */\n workingDirectory?: string;\n};\n\n/**\n * Resolved placement and generation parameters for the CI workflows.\n * See {@link resolveGithubWorkflowsContext}.\n */\nexport type GithubWorkflowsContext = {\n /**\n * Directory the workflow files must be written to. GitHub only triggers\n * workflows stored in `.github/workflows` at the repository root, so this is\n * the git root whenever the project lives inside a git repository.\n */\n workflowsRootDir: string;\n /** Package manager whose commands are baked into the workflows. */\n packageManager: PackageManager;\n /** Generation options forwarded to {@link getGithubWorkflows}. */\n options: GithubWorkflowsOptions;\n};\n\n/**\n * Returns true when the repository root hosts a workspace manifest\n * (a `package.json` `workspaces` field or a `pnpm-workspace.yaml`), meaning a\n * single install at the root covers every package of the monorepo.\n */\nconst hasWorkspaceManifest = (repositoryRootDir: string): boolean => {\n if (existsSync(join(repositoryRootDir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n\n try {\n const packageJsonPath = join(repositoryRootDir, 'package.json');\n if (!existsSync(packageJsonPath)) return false;\n const { workspaces } = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return Boolean(workspaces);\n } catch {\n return false;\n }\n};\n\n/**\n * Resolves where the CI workflows must be written and how their commands must\n * be generated, based on the repository layout around `rootDir` (the Intlayer\n * project being initialized):\n *\n * - Project at the repository root: workflows are written in place. When the\n * repository is a monorepo (workspace manifest, or several Intlayer projects\n * discovered by `listProjects`), the commands go through `intlayer ci` so\n * every project is covered.\n * - Project nested in a repository whose root has a `package.json`\n * (workspace-managed monorepo): workflows are written at the git root โ€”\n * GitHub ignores `.github/workflows` in subdirectories โ€” dependencies are\n * installed at the root with the root's package manager, and the commands go\n * through `intlayer ci` to iterate every Intlayer project.\n * - Project nested in a repository without a root `package.json`: workflows\n * are written at the git root but run inside the project directory\n * (`working-directory`), keeping the project's own package manager.\n */\nexport const resolveGithubWorkflowsContext = async (\n rootDir: string,\n projectPackageManager: PackageManager\n): Promise<GithubWorkflowsContext> => {\n const projectRootDir = resolve(rootDir);\n\n let repositoryRootDir = projectRootDir;\n try {\n const gitRootDir = await getGitRootDir(projectRootDir);\n if (gitRootDir) repositoryRootDir = resolve(gitRootDir);\n } catch {\n // Not a git repository โ€” keep the project root as the workflow root.\n }\n\n // Discover every Intlayer project of the repository. `listProjects` scans\n // for configuration files, so a fresh project whose config is created later\n // in the init flow may not be counted yet โ€” the workspace manifest check\n // below still catches that monorepo case.\n let repositoryProjectCount = 0;\n try {\n const { projectsPath } = await listProjects({\n baseDir: repositoryRootDir,\n });\n repositoryProjectCount = projectsPath.length;\n } catch {\n repositoryProjectCount = 0;\n }\n\n const isNestedProject = repositoryRootDir !== projectRootDir;\n const isWorkspaceRepository = hasWorkspaceManifest(repositoryRootDir);\n const hasRootPackageJson = existsSync(\n join(repositoryRootDir, 'package.json')\n );\n\n if (!isNestedProject) {\n return {\n workflowsRootDir: projectRootDir,\n packageManager: projectPackageManager,\n options: {\n useCiCommand: isWorkspaceRepository || repositoryProjectCount > 1,\n },\n };\n }\n\n if (hasRootPackageJson) {\n return {\n workflowsRootDir: repositoryRootDir,\n packageManager: detectPackageManager(repositoryRootDir),\n options: { useCiCommand: true },\n };\n }\n\n // Nested project without a root manifest: install and run everything inside\n // the project directory itself.\n return {\n workflowsRootDir: repositoryRootDir,\n packageManager: projectPackageManager,\n options: {\n workingDirectory: relative(repositoryRootDir, projectRootDir)\n .split(sep)\n .join('/'),\n },\n };\n};\n\n/**\n * Package-manager-specific snippets used to assemble the CI workflows.\n * - `setupSteps`: YAML steps (already indented for the `steps:` list) that\n * install the package manager and Node.js, including dependency caching.\n * - `installCommand`: command that installs the project dependencies.\n * - `execCommand`: prefix used to run the locally installed `intlayer` binary.\n */\ntype PackageManagerCIConfig = {\n setupSteps: string;\n installCommand: string;\n execCommand: string;\n};\n\n/** Dependency lock file of each package manager, used for cache invalidation. */\nconst LOCK_FILE_BY_PACKAGE_MANAGER: Record<PackageManager, string> = {\n bun: 'bun.lock',\n pnpm: 'pnpm-lock.yaml',\n yarn: 'yarn.lock',\n npm: 'package-lock.json',\n};\n\n/**\n * Returns the package-manager-specific steps and commands used to build the\n * GitHub Actions workflows. Each package manager needs a slightly different\n * setup action and a different way to run the local `intlayer` binary.\n *\n * `workingDirectory` is the repository-relative directory holding the lock\n * file when the project is nested: `actions/setup-node` looks for the lock\n * file at the repository root by default and fails the cache setup otherwise.\n */\nconst getPackageManagerCIConfig = (\n packageManager: PackageManager,\n workingDirectory?: string\n): PackageManagerCIConfig => {\n const setupNodeStep = (cache: PackageManager | undefined): string => {\n const cacheDependencyPath =\n cache && workingDirectory\n ? `\\n cache-dependency-path: ${workingDirectory}/${LOCK_FILE_BY_PACKAGE_MANAGER[cache]}`\n : '';\n\n return ` - name: ๐ŸŸข Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: 20${cache ? `\\n cache: ${cache}` : ''}${cacheDependencyPath}`;\n };\n\n switch (packageManager) {\n case 'bun':\n return {\n setupSteps: ` - name: ๐ŸฅŸ Setup Bun\n uses: oven-sh/setup-bun@v2`,\n installCommand: 'bun install --frozen-lockfile',\n execCommand: 'bunx intlayer',\n };\n case 'pnpm':\n return {\n setupSteps: ` - name: ๐Ÿ“ฆ Setup pnpm\n uses: pnpm/action-setup@v4\n${setupNodeStep('pnpm')}`,\n installCommand: 'pnpm install --frozen-lockfile',\n execCommand: 'pnpm exec intlayer',\n };\n case 'yarn':\n return {\n setupSteps: setupNodeStep('yarn'),\n installCommand: 'yarn install --frozen-lockfile',\n execCommand: 'yarn intlayer',\n };\n case 'npm':\n return {\n setupSteps: setupNodeStep('npm'),\n installCommand: 'npm ci',\n execCommand: 'npx intlayer',\n };\n }\n};\n\n/**\n * Renders the `defaults.run.working-directory` block for jobs that must run\n * inside a nested project directory. Empty when the commands run at the\n * repository root.\n */\nconst getWorkingDirectoryBlock = (workingDirectory?: string): string =>\n workingDirectory\n ? `\n defaults:\n run:\n working-directory: ${workingDirectory}`\n : '';\n\n/**\n * Renders the env comment + optional wiring for per-project credentials in\n * monorepo (`intlayer ci`) mode. The `ci` command matches each entry of the\n * `INTLAYER_PROJECT_CREDENTIALS` JSON map to a discovered project path and\n * injects its access keys before running the command in that project.\n */\nconst getMonorepoCredentialsBlock = (useCiCommand?: boolean): string =>\n useCiCommand\n ? `\n #\n # Monorepo โ€” per-project CMS credentials, as a JSON map of project path\n # (relative to the repository root) to access keys, e.g.\n # {\"apps/web\":{\"clientId\":\"...\",\"clientSecret\":\"...\"}}:\n # INTLAYER_PROJECT_CREDENTIALS: \\${{ secrets.INTLAYER_PROJECT_CREDENTIALS }}`\n : '';\n\n/**\n * Builds the `intlayer fill` workflow. Runs on pull requests, regenerates the\n * missing translations for the changed dictionaries (`--git-diff`) using AI,\n * then commits the result back to the PR branch.\n *\n * AI access is required for `fill`. The workflow exposes both options:\n * - a provider API key (`AI_API_KEY` secret), forwarded via CLI flags, or\n * - Intlayer CMS access keys (`INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`).\n */\nconst generateFillWorkflow = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions\n): string => {\n const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(\n packageManager,\n options.workingDirectory\n );\n\n // In monorepo mode `intlayer ci <command>` discovers every Intlayer project\n // of the repository and runs the command inside each of them.\n const intlayerCommand = options.useCiCommand\n ? `${execCommand} ci`\n : execCommand;\n\n return `name: Intlayer Fill\n# Auto-fill missing translations on every pull request.\non:\n pull_request:\n branches:\n - main\n\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n group: intlayer-fill-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n fill:\n runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}\n env:\n # AI access is required to generate translations.\n # Add the secret in: Settings โ†’ Secrets and variables โ†’ Actions.\n #\n # Option 1 โ€” Use your own AI provider key (forwarded below via CLI flags):\n AI_PROVIDER: openai\n AI_MODEL: gpt-5-mini\n AI_API_KEY: \\${{ secrets.AI_API_KEY }}\n #\n # Option 2 โ€” Use Intlayer CMS access keys instead of your own AI key.\n # Wire them in your intlayer.config and uncomment the lines below:\n # INTLAYER_CLIENT_ID: \\${{ secrets.INTLAYER_CLIENT_ID }}\n # INTLAYER_CLIENT_SECRET: \\${{ secrets.INTLAYER_CLIENT_SECRET }}${getMonorepoCredentialsBlock(options.useCiCommand)}\n steps:\n - name: โฌ‡๏ธ Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: true # Keep credentials to push back to the PR\n fetch-depth: 0 # Full history so --git-diff can compare refs\n${setupSteps}\n - name: ๐Ÿ“ฆ Install dependencies\n run: ${installCommand}\n - name: โš™๏ธ Build dictionaries\n run: ${intlayerCommand} build\n - name: ๐Ÿค– Fill missing translations\n # Skip when no AI credentials are configured, so the workflow stays green\n # until an \\`AI_API_KEY\\` (or Intlayer CMS access keys) secret is added.\n if: \\${{ env.AI_API_KEY != '' || env.INTLAYER_CLIENT_ID != '' }}\n run: ${intlayerCommand} fill --git-diff --mode complete --provider $AI_PROVIDER --model $AI_MODEL --api-key $AI_API_KEY\n - name: ๐Ÿ“ค Commit and push changes\n run: |\n git config --local user.email \"github-actions[bot]@users.noreply.github.com\"\n git config --local user.name \"github-actions[bot]\"\n if [ -n \"$(git status --porcelain)\" ]; then\n git add .\n git commit -m \"chore(intlayer): fill missing translations [skip ci]\"\n git push origin HEAD:\\${{ github.head_ref }}\n else\n echo \"No missing translations to fill.\"\n fi\n`;\n};\n\n/**\n * Builds the `intlayer test` workflow. Runs on pull requests and fails the\n * check when required locales are missing translations. No AI access needed.\n */\nconst generateTestWorkflow = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions\n): string => {\n const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(\n packageManager,\n options.workingDirectory\n );\n\n // In monorepo mode `intlayer ci <command>` discovers every Intlayer project\n // of the repository and runs the command inside each of them.\n const intlayerCommand = options.useCiCommand\n ? `${execCommand} ci`\n : execCommand;\n\n return `name: Intlayer Test\n# Fail the pull request when required locales are missing translations.\non:\n pull_request:\n branches:\n - main\n\nconcurrency:\n group: intlayer-test-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n test:\n runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}\n steps:\n - name: โฌ‡๏ธ Checkout repository\n uses: actions/checkout@v4\n${setupSteps}\n - name: ๐Ÿ“ฆ Install dependencies\n run: ${installCommand}\n - name: โš™๏ธ Build dictionaries\n run: ${intlayerCommand} build\n - name: ๐Ÿงช Test for missing translations\n run: ${intlayerCommand} test\n`;\n};\n\n/** Workflow file path constants, relative to the project root. */\nexport const GITHUB_FILL_WORKFLOW_PATH = '.github/workflows/intlayer-fill.yml';\nexport const GITHUB_TEST_WORKFLOW_PATH = '.github/workflows/intlayer-test.yml';\n\n/**\n * Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),\n * generated with commands matching the detected package manager and the\n * repository layout (see {@link GithubWorkflowsOptions} for the monorepo and\n * nested-project variants).\n */\nexport const getGithubWorkflows = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions = {}\n): GithubWorkflowFile[] => [\n {\n filePath: GITHUB_FILL_WORKFLOW_PATH,\n content: generateFillWorkflow(packageManager, options),\n },\n {\n filePath: GITHUB_TEST_WORKFLOW_PATH,\n content: generateTestWorkflow(packageManager, options),\n },\n];\n"],"mappings":"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"}
@@ -3,9 +3,9 @@ const require_init_utils_astImports = require('./astImports.cjs');
3
3
  const require_init_utils_configManipulation = require('./configManipulation.cjs');
4
4
  const require_init_utils_fileSystem = require('./fileSystem.cjs');
5
5
  const require_init_utils_version = require('./version.cjs');
6
+ const require_init_utils_packageManager = require('./packageManager.cjs');
6
7
  const require_init_utils_githubActions = require('./githubActions.cjs');
7
8
  const require_init_utils_jsonParser = require('./jsonParser.cjs');
8
- const require_init_utils_packageManager = require('./packageManager.cjs');
9
9
  const require_init_utils_nextCompilerBabel = require('./nextCompilerBabel.cjs');
10
10
  const require_init_utils_tsConfig = require('./tsConfig.cjs');
11
11
 
@@ -36,6 +36,7 @@ exports.normalizeVersion = require_init_utils_packageManager.normalizeVersion;
36
36
  exports.parseJSONWithComments = require_init_utils_jsonParser.parseJSONWithComments;
37
37
  exports.readFileFromRoot = require_init_utils_fileSystem.readFileFromRoot;
38
38
  exports.replaceViteConfigPluginImportSource = require_init_utils_configManipulation.replaceViteConfigPluginImportSource;
39
+ exports.resolveGithubWorkflowsContext = require_init_utils_githubActions.resolveGithubWorkflowsContext;
39
40
  exports.setIntlayerConfigCompilerOutput = require_init_utils_configManipulation.setIntlayerConfigCompilerOutput;
40
41
  exports.setIntlayerConfigRoutingMode = require_init_utils_configManipulation.setIntlayerConfigRoutingMode;
41
42
  exports.setupNextCompilerBabelConfig = require_init_utils_nextCompilerBabel.setupNextCompilerBabelConfig;
@@ -9,7 +9,8 @@ simple_git = require_runtime.__toESM(simple_git);
9
9
 
10
10
  //#region src/listProjects.ts
11
11
  /**
12
- * Get the git root directory
12
+ * Returns the git repository root directory, or `null` when the given
13
+ * directory is not inside a git repository.
13
14
  */
14
15
  const getGitRootDir = async (cwd) => {
15
16
  try {
@@ -44,5 +45,6 @@ const listProjects = async (options) => {
44
45
  };
45
46
 
46
47
  //#endregion
48
+ exports.getGitRootDir = getGitRootDir;
47
49
  exports.listProjects = listProjects;
48
50
  //# sourceMappingURL=listProjects.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"listProjects.cjs","names":["configurationFilesCandidates"],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n * Get the git root directory\n */\nconst getGitRootDir = async (cwd?: string): Promise<string | null> => {\n try {\n const git = cwd ? simpleGit(cwd) : simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (_error) {\n return null;\n }\n};\n\n/**\n * List all Intlayer projects by searching for configuration files\n *\n * @param options - Options for listing projects\n * @returns Array of absolute paths to project directories containing Intlayer config\n */\nexport const listProjects = async (\n options?: ListProjectsOptions\n): Promise<{ searchDir: string; projectsPath: string[] }> => {\n let searchDir = options?.baseDir ?? process.cwd();\n\n // If gitRoot option is enabled, try to get the git root directory\n if (options?.gitRoot) {\n const gitRootDir = await getGitRootDir(searchDir);\n if (gitRootDir) {\n searchDir = gitRootDir;\n }\n }\n\n // Build glob patterns for all config file candidates\n const configPatterns = configurationFilesCandidates.map(\n (fileName) => `**/${fileName}`\n );\n\n // Search for all config files\n const configFiles = await fg(configPatterns, {\n cwd: searchDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.git/**'],\n dot: true, // Include dot files like .intlayerrc\n });\n\n // Extract unique directory paths from config files\n const projectDirs = [...new Set(configFiles.map((file) => dirname(file)))];\n\n // Sort alphabetically for consistent output\n return { searchDir, projectsPath: projectDirs.sort() };\n};\n"],"mappings":";;;;;;;;;;;;;AAqBA,MAAM,gBAAgB,OAAO,QAAyC;AACpE,KAAI;AAGF,UAAO,OAFK,8BAAgB,IAAI,4BAAc,EACpB,SAAS,CAAC,kBAAkB,CAAC,EACxC,MAAM;UACd,QAAQ;AACf,SAAO;;;;;;;;;AAUX,MAAa,eAAe,OAC1B,YAC2D;CAC3D,IAAI,YAAY,SAAS,WAAW,QAAQ,KAAK;AAGjD,KAAI,SAAS,SAAS;EACpB,MAAM,aAAa,MAAM,cAAc,UAAU;AACjD,MAAI,WACF,aAAY;;CAUhB,MAAM,cAAc,6BALGA,mDAA6B,KACjD,aAAa,MAAM,WAIqB,EAAE;EAC3C,KAAK;EACL,UAAU;EACV,QAAQ,CAAC,sBAAsB,aAAa;EAC5C,KAAK;EACN,CAAC;CAGF,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,KAAK,gCAAiB,KAAK,CAAC,CAAC,CAAC;AAG1E,QAAO;EAAE;EAAW,cAAc,YAAY,MAAM;EAAE"}
1
+ {"version":3,"file":"listProjects.cjs","names":["configurationFilesCandidates"],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n * Returns the git repository root directory, or `null` when the given\n * directory is not inside a git repository.\n */\nexport const getGitRootDir = async (cwd?: string): Promise<string | null> => {\n try {\n const git = cwd ? simpleGit(cwd) : simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (_error) {\n return null;\n }\n};\n\n/**\n * List all Intlayer projects by searching for configuration files\n *\n * @param options - Options for listing projects\n * @returns Array of absolute paths to project directories containing Intlayer config\n */\nexport const listProjects = async (\n options?: ListProjectsOptions\n): Promise<{ searchDir: string; projectsPath: string[] }> => {\n let searchDir = options?.baseDir ?? process.cwd();\n\n // If gitRoot option is enabled, try to get the git root directory\n if (options?.gitRoot) {\n const gitRootDir = await getGitRootDir(searchDir);\n if (gitRootDir) {\n searchDir = gitRootDir;\n }\n }\n\n // Build glob patterns for all config file candidates\n const configPatterns = configurationFilesCandidates.map(\n (fileName) => `**/${fileName}`\n );\n\n // Search for all config files\n const configFiles = await fg(configPatterns, {\n cwd: searchDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.git/**'],\n dot: true, // Include dot files like .intlayerrc\n });\n\n // Extract unique directory paths from config files\n const projectDirs = [...new Set(configFiles.map((file) => dirname(file)))];\n\n // Sort alphabetically for consistent output\n return { searchDir, projectsPath: projectDirs.sort() };\n};\n"],"mappings":";;;;;;;;;;;;;;AAsBA,MAAa,gBAAgB,OAAO,QAAyC;AAC3E,KAAI;AAGF,UAAO,OAFK,8BAAgB,IAAI,4BAAc,EACpB,SAAS,CAAC,kBAAkB,CAAC,EACxC,MAAM;UACd,QAAQ;AACf,SAAO;;;;;;;;;AAUX,MAAa,eAAe,OAC1B,YAC2D;CAC3D,IAAI,YAAY,SAAS,WAAW,QAAQ,KAAK;AAGjD,KAAI,SAAS,SAAS;EACpB,MAAM,aAAa,MAAM,cAAc,UAAU;AACjD,MAAI,WACF,aAAY;;CAUhB,MAAM,cAAc,6BALGA,mDAA6B,KACjD,aAAa,MAAM,WAIqB,EAAE;EAC3C,KAAK;EACL,UAAU;EACV,QAAQ,CAAC,sBAAsB,aAAa;EAC5C,KAAK;EACN,CAAC;CAGF,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,KAAK,gCAAiB,KAAK,CAAC,CAAC,CAAC;AAG1E,QAAO;EAAE;EAAW,cAAc,YAAY,MAAM;EAAE"}
@@ -2,11 +2,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  //#region src/writeConfiguration/generateConfigurationContent.ts
4
4
  const generateConfigurationContent = (configuration, format) => {
5
- const { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler } = configuration;
5
+ const { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler } = configuration;
6
6
  let fileContent = "";
7
7
  fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\n`;
8
8
  fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\n`;
9
9
  fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\n`;
10
+ fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\n`;
10
11
  fileContent += `const log = ${JSON.stringify(log, null, 2)};\n`;
11
12
  fileContent += `const system = ${JSON.stringify(system, null, 2)};\n`;
12
13
  fileContent += `const content = ${JSON.stringify(content, null, 2)};\n`;
@@ -14,11 +15,12 @@ const generateConfigurationContent = (configuration, format) => {
14
15
  fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\n`;
15
16
  fileContent += `const build = ${JSON.stringify(build, null, 2)};\n`;
16
17
  fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\n`;
17
- if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\n`;
18
+ if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\n`;
18
19
  else {
19
20
  fileContent += `\nmodule.exports.internationalization = internationalization;\n`;
20
21
  fileContent += `module.exports.routing = routing;\n`;
21
22
  fileContent += `module.exports.editor = editor;\n`;
23
+ fileContent += `module.exports.analytics = analytics;\n`;
22
24
  fileContent += `module.exports.log = log;\n`;
23
25
  fileContent += `module.exports.system = system;\n`;
24
26
  fileContent += `module.exports.content = content;\n`;
@@ -1 +1 @@
1
- {"version":3,"file":"generateConfigurationContent.cjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";;;AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
1
+ {"version":3,"file":"generateConfigurationContent.cjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n analytics,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.analytics = analytics;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";;;AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,WACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,qBAAqB,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC;AACvE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
package/dist/esm/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { listProjects } from "./listProjects.mjs";
1
+ import { getGitRootDir, listProjects } from "./listProjects.mjs";
2
2
  import { installLSP } from "./installLSP.mjs";
3
3
  import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.mjs";
4
4
  import { prepareIntlayer } from "./prepareIntlayer.mjs";
@@ -17,4 +17,4 @@ import { installMCP } from "./installMCP/installMCP.mjs";
17
17
  import { listGitFiles, listGitLines } from "./listGitFiles.mjs";
18
18
  import { logConfigDetails } from "./logConfigDetails.mjs";
19
19
 
20
- export { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
20
+ export { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getGitRootDir, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
@@ -4,9 +4,9 @@ import { setCompilerOutputInConfig, setRoutingModeInConfig } from "./cms.mjs";
4
4
  import { initConfig } from "../initConfig/index.mjs";
5
5
  import { isVersionAtLeast } from "./utils/version.mjs";
6
6
  import { setupFramework } from "./frameworkSetup/index.mjs";
7
- import { getGithubWorkflows } from "./utils/githubActions.mjs";
8
- import { parseJSONWithComments } from "./utils/jsonParser.mjs";
9
7
  import { detectMissingIntlayerPackages, detectOutdatedIntlayerPackages, detectPackageManager, installPackages, upgradePackages } from "./utils/packageManager.mjs";
8
+ import { getGithubWorkflows, resolveGithubWorkflowsContext } from "./utils/githubActions.mjs";
9
+ import { parseJSONWithComments } from "./utils/jsonParser.mjs";
10
10
  import { setupNextCompilerBabelConfig } from "./utils/nextCompilerBabel.mjs";
11
11
  import { findTsConfigFiles } from "./utils/tsConfig.mjs";
12
12
  import { join } from "node:path";
@@ -196,15 +196,16 @@ const initIntlayer = async (rootDir, options) => {
196
196
  } else logger(`${v} ${colorizePath(gitignorePath)} already includes .intlayer`);
197
197
  }
198
198
  if (!options?.noGithubActions) {
199
- const workflows = getGithubWorkflows(packageManager);
199
+ const workflowsContext = await resolveGithubWorkflowsContext(rootDir, packageManager);
200
+ const workflows = getGithubWorkflows(workflowsContext.packageManager, workflowsContext.options);
200
201
  for (const workflow of workflows) {
201
- if (await exists(rootDir, workflow.filePath)) {
202
+ if (await exists(workflowsContext.workflowsRootDir, workflow.filePath)) {
202
203
  logger(`${v} ${colorizePath(workflow.filePath)} already exists`);
203
204
  continue;
204
205
  }
205
206
  try {
206
- await ensureDirectory(rootDir, join(".github", "workflows"));
207
- await writeFileToRoot(rootDir, workflow.filePath, workflow.content);
207
+ await ensureDirectory(workflowsContext.workflowsRootDir, join(".github", "workflows"));
208
+ await writeFileToRoot(workflowsContext.workflowsRootDir, workflow.filePath, workflow.content);
208
209
  logger(`${v} Added GitHub Actions workflow ${colorizePath(workflow.filePath)}`);
209
210
  } catch {
210
211
  logger(`${x} Could not create ${colorizePath(workflow.filePath)}. You may need to add it manually.`, { level: "warn" });
@@ -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';\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport { setCompilerOutputInConfig, setRoutingModeInConfig } from './cms';\nimport { setupFramework } from './frameworkSetup';\nimport type { CompatSyncConfig, RoutingMode } from './utils';\nimport {\n detectJsonLocalePattern,\n detectLinguiCatalogPattern,\n detectMissingIntlayerPackages,\n detectNextIntlMessagesPattern,\n detectOutdatedIntlayerPackages,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n getMetroConfigTemplate,\n hasIntlayerVitePlugin,\n installPackages,\n isVersionAtLeast,\n parseJSONWithComments,\n readFileFromRoot,\n replaceViteConfigPluginImportSource,\n setupNextCompilerBabelConfig,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateMetroConfig,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n upgradePackages,\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 * Resolves the default dev-server URL of the detected framework, used as the\n * `editor.applicationURL` of the generated configuration file. Frameworks that\n * embed Vite (Astro, SvelteKit, โ€ฆ) are checked before the bare Vite fallback so\n * their own dev port wins.\n */\nexport const getDefaultApplicationURL = (\n dependencies: Record<string, string>\n): string => {\n if (dependencies.next) return 'http://localhost:3000';\n if (dependencies.astro) return 'http://localhost:4321';\n if (dependencies['@angular/core']) return 'http://localhost:4200';\n if (dependencies.nuxt) return 'http://localhost:3000';\n if (dependencies['@sveltejs/kit']) return 'http://localhost:5173';\n if (dependencies['react-scripts']) return 'http://localhost:3000';\n if (dependencies.vite) return 'http://localhost:5173';\n\n return 'http://localhost:3000';\n};\n\n/**\n * How the interactive init organizes autogenerated content (compiler output /\n * autofill):\n * - `per-component` โ€” multilingual `.content` files co-located with components\n * (the configuration template default).\n * - `centralized` โ€” per-locale JSON dictionaries under `/locales/{locale}/`.\n * - `json-namespaces` โ€” plain per-locale JSON namespace files kept in sync\n * through `@intlayer/sync-json-plugin`.\n */\nexport type ContentStrategy =\n | 'per-component'\n | 'centralized'\n | 'json-namespaces';\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 * Skip installing missing Intlayer dependencies and upgrading outdated ones.\n */\n noInstallPackages?: boolean;\n /** Skip adding the Intlayer extension to `.vscode/extensions.json`. */\n noVscodeExtension?: boolean;\n /** Skip writing the Intlayer LSP configuration to `.vscode/settings.json`. */\n noLsp?: boolean;\n /**\n * Skip framework-specific scaffolding (middleware/proxy, providers in\n * layout/page, example content). Defaults to enabled.\n */\n noFrameworkSetup?: boolean;\n /**\n * Version that outdated Intlayer packages should be upgraded to (typically the\n * running CLI version). When omitted, installed packages are left untouched and\n * only missing ones are installed.\n */\n upgradeToVersion?: string;\n /**\n * Locale routing strategy to write to `routing.mode` in the generated/existing\n * Intlayer configuration file. When omitted, the configuration default\n * (`prefix-no-default`) is kept.\n */\n routingMode?: RoutingMode;\n /**\n * Extra packages hinted by the interactive init prompt (compat i18n library\n * selections made before those libraries are actually installed). These are\n * merged into the dependency map used by {@link detectMissingIntlayerPackages}\n * so the correct sync plugin and compat adapter are always scheduled.\n */\n hintDependencies?: Record<string, string>;\n /**\n * Content organization strategy chosen by the interactive init prompt. Drives\n * the `compiler.output` template (`centralized`) or the injection of the\n * syncJSON plugin (`json-namespaces`). When omitted (or `per-component`), the\n * configuration template default is kept.\n */\n contentStrategy?: ContentStrategy;\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 // Effective deps = real deps + interactive hint-deps (compat library selections\n // from the interactive init prompt that haven't been installed yet).\n const effectiveAllDeps: Record<string, string> = {\n ...allDeps,\n ...(options?.hintDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n\n // lingui keeps its catalogs as `.po` (default) or `.json`. Detect which so the\n // matching sync plugin (`syncPO` / `syncJSON`) + dev dependency are chosen.\n // Also respect the `__lingui_json__` sentinel injected by the interactive init\n // prompt when the user explicitly selected \"Lingui (.json catalogs)\".\n const linguiPresent = Boolean(\n effectiveAllDeps['@lingui/core'] ||\n effectiveAllDeps['@lingui/react'] ||\n effectiveAllDeps['@intlayer/lingui']\n );\n\n // Determine format: prefer filesystem scan, then the interactive sentinel.\n const linguiCatalog = linguiPresent\n ? await detectLinguiCatalogPattern(rootDir)\n : null;\n\n const hintLinguiJson = Boolean(\n options?.hintDependencies?.['__lingui_json__']\n );\n // `linguiCatalogFormat` resolution:\n // 1. Filesystem scan result (authoritative when catalogs already exist)\n // 2. Interactive sentinel `__lingui_json__` โ†’ 'json'\n // 3. Fallback: 'po' (lingui's default) when lingui is selected but no\n // catalogs have been generated yet and no sentinel was injected.\n const linguiCatalogFormat: 'po' | 'json' | null =\n linguiCatalog?.format ??\n (linguiPresent ? (hintLinguiJson ? 'json' : 'po') : null);\n\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(effectiveAllDeps, {\n linguiCatalogFormat,\n });\n\n // The `json-namespaces` content strategy uses the same syncJSON pipeline as\n // the compat libraries: plain per-locale JSON namespace files synced through\n // `@intlayer/sync-json-plugin`. A detected compat library keeps precedence โ€”\n // its own catalog format/template is authoritative.\n const wantsJsonNamespaces =\n options?.contentStrategy === 'json-namespaces' && !compatSyncConfig;\n\n if (\n wantsJsonNamespaces &&\n !effectiveAllDeps['@intlayer/sync-json-plugin'] &&\n !devPackagesToInstall.includes('@intlayer/sync-json-plugin')\n ) {\n devPackagesToInstall.push('@intlayer/sync-json-plugin');\n }\n\n if (!options?.noInstallPackages) {\n const withVersion = (packages: string[]): string[] =>\n options?.upgradeToVersion\n ? packages.map((pkg) => `${pkg}@${options.upgradeToVersion}`)\n : packages;\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(\n rootDir,\n withVersion(packagesToInstall),\n packageManager\n );\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(\n rootDir,\n withVersion(devPackagesToInstall),\n packageManager,\n true\n );\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 // UPGRADE OUTDATED INTLAYER DEPENDENCIES\n // Only runs when a target version is provided (typically the running CLI\n // version). Already up-to-date packages are skipped. Prod and dev\n // dependencies are upgraded separately so their dependency type is kept.\n if (options?.upgradeToVersion) {\n const outdatedDependencies = detectOutdatedIntlayerPackages(\n rootDir,\n packageJson.dependencies ?? {},\n options.upgradeToVersion\n );\n const outdatedDevDependencies = detectOutdatedIntlayerPackages(\n rootDir,\n packageJson.devDependencies ?? {},\n options.upgradeToVersion\n );\n\n const allOutdated = [...outdatedDependencies, ...outdatedDevDependencies];\n\n if (allOutdated.length > 0) {\n logger(\n colorize(\n `Upgrading outdated Intlayer dependencies to ${options.upgradeToVersion}...`,\n ANSIColors.CYAN\n )\n );\n try {\n upgradePackages(\n rootDir,\n outdatedDependencies,\n packageManager,\n options.upgradeToVersion\n );\n upgradePackages(\n rootDir,\n outdatedDevDependencies,\n packageManager,\n options.upgradeToVersion,\n true\n );\n logger(\n `${v} Upgraded: ${allOutdated.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to upgrade packages. Please upgrade manually: ${allOutdated.join(' ')}`,\n { level: 'warn' }\n );\n }\n } else {\n logger(`${v} Intlayer dependencies are up to date`);\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 if (!options?.noVscodeExtension) {\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\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n if (!options?.noLsp) {\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\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, {\n locales: detectedPattern?.locales,\n applicationURL: getDefaultApplicationURL(allDeps),\n });\n\n // APPLY CONTENT STRATEGY โ€” CENTRALIZED\n // Point `compiler.output` at per-locale JSON dictionaries under `/locales/`\n // instead of the per-component template default.\n if (options?.contentStrategy === 'centralized') {\n await setCompilerOutputInConfig(\n rootDir,\n '/locales/{{locale}}/{{key}}.content.json'\n );\n }\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES / JSON-NAMESPACES STRATEGY\n const syncConfigToInject: CompatSyncConfig | undefined =\n compatSyncConfig ??\n (wantsJsonNamespaces\n ? {\n format: 'i18next',\n sourceTemplate:\n detectedPattern?.template ?? './locales/${locale}/${key}.json',\n }\n : undefined);\n\n if (syncConfigToInject) {\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), whose first-level keys are namespaces โ€” so the compat\n // config carries `splitKeys: true` to emit one dictionary per namespace.\n // 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 // lingui authoritatively resolves to `โ€ฆ/{locale}/messages.{po,json}`, where\n // the `messages` filename becomes the dictionary key. Prefer it so a `.po`\n // project gets `syncPO` (the generic JSON glob only sees `.json`).\n const sourceTemplate =\n linguiCatalog?.template ??\n nextIntlMessagesPattern?.template ??\n detectedPattern?.template;\n\n const resolvedSyncConfig = {\n ...syncConfigToInject,\n ...(sourceTemplate ? { sourceTemplate } : {}),\n };\n\n const syncPluginPackage =\n resolvedSyncConfig.plugin === 'po'\n ? '@intlayer/sync-po-plugin'\n : '@intlayer/sync-json-plugin';\n const syncPluginName =\n resolvedSyncConfig.plugin === 'po' ? 'syncPO' : 'syncJSON';\n\n // `splitKeys` only makes sense for a single file holding several namespaces.\n // If the resolved template addresses one namespace per file (`${key}`\n // segment), each file is already a single namespace โ€” drop the flag so\n // syncJSON keeps one dictionary per file.\n if (\n resolvedSyncConfig.splitKeys &&\n resolvedSyncConfig.sourceTemplate.includes('${key}')\n ) {\n resolvedSyncConfig.splitKeys = false;\n }\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(syncPluginPackage)) {\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 ${syncPluginName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes ${syncPluginName} plugin`\n );\n }\n break;\n }\n }\n }\n\n // APPLY ROUTING MODE\n // When a routing strategy was chosen (interactive init), write it to\n // `routing.mode` in the configuration file. Idempotent and comment-preserving.\n if (options?.routingMode) {\n await setRoutingModeInConfig(rootDir, options.routingMode);\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 const { replacesVitePlugin } = compatVitePluginConfig;\n\n if (content.includes(compatVitePluginConfig.pluginPackageSource)) {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n } else if (\n replacesVitePlugin &&\n content.includes(replacesVitePlugin.fromPackageSource)\n ) {\n // Drop-in replacement: rewrite the original i18n vite plugin's import\n // source, keeping its binding and call site (e.g. lingui).\n const updatedContent = replaceViteConfigPluginImportSource(\n content,\n replacesVitePlugin.importName,\n replacesVitePlugin.fromPackageSource,\n compatVitePluginConfig.pluginPackageSource\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to import ${replacesVitePlugin.importName} from ${compatVitePluginConfig.pluginPackageSource}`\n );\n } else {\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 }\n } else if (hasIntlayerVitePlugin(content)) {\n // A compat adapter plugin (e.g. `reactI18nextVitePlugin`) already wraps\n // `intlayer()` internally, so skip adding a redundant standalone plugin.\n logger(\n `${v} ${colorizePath(file)} already includes an Intlayer plugin`\n );\n } else {\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 NEXT.JS COMPILER (BABEL)\n // When a Next.js project already uses Babel, install @intlayer/babel and print\n // the compiler + build-optimization plugins (extract, purge, minify, optimize)\n // to add. SWC projects need no setup: withIntlayer injects @intlayer/swc.\n if (isNextJsProject) {\n await setupNextCompilerBabelConfig({\n rootDir,\n packageManager,\n allDeps,\n skipInstall: Boolean(options?.noInstallPackages),\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 // CHECK METRO CONFIG (React Native / Expo)\n // Metro is the React Native bundler. The Intlayer Metro plugin\n // (`react-native-intlayer/metro`) handles dictionary aliasing and building.\n // When no config exists we scaffold one; when one exists we safely wrap its\n // exported config with `configMetroIntlayerSync`, leaving custom async\n // (IIFE) configs untouched so existing setups are never broken.\n const isReactNativeProject = Boolean(allDeps['react-native'] || allDeps.expo);\n\n if (isReactNativeProject) {\n // Metro resolves Intlayer aliases itself, so skip the alias fallback below.\n hasAliasConfiguration = true;\n\n const metroConfigs = [\n 'metro.config.js',\n 'metro.config.cjs',\n 'metro.config.mjs',\n 'metro.config.ts',\n ];\n\n let metroConfigFile: string | undefined;\n\n for (const file of metroConfigs) {\n if (await exists(rootDir, file)) {\n metroConfigFile = file;\n break;\n }\n }\n\n if (metroConfigFile) {\n const content = await readFileFromRoot(rootDir, metroConfigFile);\n\n if (content.includes('react-native-intlayer')) {\n logger(\n `${v} ${colorizePath(metroConfigFile)} already includes the Intlayer Metro plugin`\n );\n } else {\n const extension = metroConfigFile.split('.').pop()!;\n const updatedContent = updateMetroConfig(content, extension);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, metroConfigFile, updatedContent);\n logger(\n `${v} Updated ${colorizePath(metroConfigFile)} to include the Intlayer Metro plugin`\n );\n } else {\n logger(\n `${x} Could not automatically update ${colorizePath(metroConfigFile)}. Wrap your exported config with ${colorize('configMetroIntlayer', ANSIColors.MAGENTA)}: ${colorizePath(DocumentationRouter.ReactNativeAndExpo)}`,\n { level: 'warn' }\n );\n }\n }\n } else {\n const newMetroConfigFile = 'metro.config.js';\n await writeFileToRoot(\n rootDir,\n newMetroConfigFile,\n getMetroConfigTemplate(Boolean(allDeps.expo))\n );\n logger(\n `${v} Created ${colorizePath(newMetroConfigFile)} with the Intlayer Metro plugin`\n );\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 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 devScript &&\n ((isNextJsProject && allDeps.next && isVersionAtLeast(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 // FRAMEWORK-SPECIFIC SCAFFOLDING\n // Sets up middleware/proxy and wraps the layout/page with the Intlayer\n // providers for the detected framework (Next.js App Router today). Idempotent\n // and non-destructive: it never overwrites user code it cannot safely\n // transform, skipping with guidance instead.\n //\n // Skipped entirely when a compat i18n library drives the app (i18next,\n // next-intl, vue-i18n, โ€ฆ): the app already owns its routing, providers and\n // layouts, and Intlayer only syncs its catalogs โ€” restructuring routes or\n // injecting providers would break the existing setup.\n const hasCompatLibrary = Boolean(compatSyncConfig || compatVitePluginConfig);\n\n if (!options?.noFrameworkSetup && hasCompatLibrary) {\n logger(\n `${v} Compat i18n library detected โ€” keeping the app structure untouched (no route restructure, no provider injection)`\n );\n }\n\n if (!options?.noFrameworkSetup && !hasCompatLibrary) {\n try {\n // Prefer the user's interactive choice, else the configured routing mode\n // (which itself defaults to `prefix-no-default`). Drives whether the\n // locale path segment is required (`prefix-all`) or optional.\n const routingMode =\n options?.routingMode ??\n getConfiguration({ baseDir: rootDir }).routing.mode;\n\n await setupFramework({\n rootDir,\n allDeps,\n packageManager,\n useTypeScript: hasTsConfig,\n routingMode,\n });\n } catch {\n logger(\n `${x} Framework-specific scaffolding failed. Your existing files were left untouched; follow the documentation to finish the setup.`,\n { level: 'warn' }\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';\nimport { getAlias } from '@intlayer/config/utils';\nimport { initConfig } from '../initConfig';\nimport { setCompilerOutputInConfig, setRoutingModeInConfig } from './cms';\nimport { setupFramework } from './frameworkSetup';\nimport type { CompatSyncConfig, RoutingMode } from './utils';\nimport {\n detectJsonLocalePattern,\n detectLinguiCatalogPattern,\n detectMissingIntlayerPackages,\n detectNextIntlMessagesPattern,\n detectOutdatedIntlayerPackages,\n detectPackageManager,\n ensureDirectory,\n exists,\n findTsConfigFiles,\n getGithubWorkflows,\n getMetroConfigTemplate,\n hasIntlayerVitePlugin,\n installPackages,\n isVersionAtLeast,\n parseJSONWithComments,\n readFileFromRoot,\n replaceViteConfigPluginImportSource,\n resolveGithubWorkflowsContext,\n setupNextCompilerBabelConfig,\n updateAstroConfig,\n updateIntlayerConfigWithSyncPlugin,\n updateMetroConfig,\n updateNextConfig,\n updateNextConfigForNextI18next,\n updateNextConfigForNextIntl,\n updateNextConfigForNextTranslate,\n updateNuxtConfig,\n updateNuxtConfigForNuxtjsI18n,\n updateViteConfig,\n updateViteConfigForCompatPlugin,\n upgradePackages,\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 * Resolves the default dev-server URL of the detected framework, used as the\n * `editor.applicationURL` of the generated configuration file. Frameworks that\n * embed Vite (Astro, SvelteKit, โ€ฆ) are checked before the bare Vite fallback so\n * their own dev port wins.\n */\nexport const getDefaultApplicationURL = (\n dependencies: Record<string, string>\n): string => {\n if (dependencies.next) return 'http://localhost:3000';\n if (dependencies.astro) return 'http://localhost:4321';\n if (dependencies['@angular/core']) return 'http://localhost:4200';\n if (dependencies.nuxt) return 'http://localhost:3000';\n if (dependencies['@sveltejs/kit']) return 'http://localhost:5173';\n if (dependencies['react-scripts']) return 'http://localhost:3000';\n if (dependencies.vite) return 'http://localhost:5173';\n\n return 'http://localhost:3000';\n};\n\n/**\n * How the interactive init organizes autogenerated content (compiler output /\n * autofill):\n * - `per-component` โ€” multilingual `.content` files co-located with components\n * (the configuration template default).\n * - `centralized` โ€” per-locale JSON dictionaries under `/locales/{locale}/`.\n * - `json-namespaces` โ€” plain per-locale JSON namespace files kept in sync\n * through `@intlayer/sync-json-plugin`.\n */\nexport type ContentStrategy =\n | 'per-component'\n | 'centralized'\n | 'json-namespaces';\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 * Skip installing missing Intlayer dependencies and upgrading outdated ones.\n */\n noInstallPackages?: boolean;\n /** Skip adding the Intlayer extension to `.vscode/extensions.json`. */\n noVscodeExtension?: boolean;\n /** Skip writing the Intlayer LSP configuration to `.vscode/settings.json`. */\n noLsp?: boolean;\n /**\n * Skip framework-specific scaffolding (middleware/proxy, providers in\n * layout/page, example content). Defaults to enabled.\n */\n noFrameworkSetup?: boolean;\n /**\n * Version that outdated Intlayer packages should be upgraded to (typically the\n * running CLI version). When omitted, installed packages are left untouched and\n * only missing ones are installed.\n */\n upgradeToVersion?: string;\n /**\n * Locale routing strategy to write to `routing.mode` in the generated/existing\n * Intlayer configuration file. When omitted, the configuration default\n * (`prefix-no-default`) is kept.\n */\n routingMode?: RoutingMode;\n /**\n * Extra packages hinted by the interactive init prompt (compat i18n library\n * selections made before those libraries are actually installed). These are\n * merged into the dependency map used by {@link detectMissingIntlayerPackages}\n * so the correct sync plugin and compat adapter are always scheduled.\n */\n hintDependencies?: Record<string, string>;\n /**\n * Content organization strategy chosen by the interactive init prompt. Drives\n * the `compiler.output` template (`centralized`) or the injection of the\n * syncJSON plugin (`json-namespaces`). When omitted (or `per-component`), the\n * configuration template default is kept.\n */\n contentStrategy?: ContentStrategy;\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 // Effective deps = real deps + interactive hint-deps (compat library selections\n // from the interactive init prompt that haven't been installed yet).\n const effectiveAllDeps: Record<string, string> = {\n ...allDeps,\n ...(options?.hintDependencies ?? {}),\n };\n\n // INSTALL MISSING INTLAYER DEPENDENCIES\n const packageManager = detectPackageManager(rootDir);\n\n // lingui keeps its catalogs as `.po` (default) or `.json`. Detect which so the\n // matching sync plugin (`syncPO` / `syncJSON`) + dev dependency are chosen.\n // Also respect the `__lingui_json__` sentinel injected by the interactive init\n // prompt when the user explicitly selected \"Lingui (.json catalogs)\".\n const linguiPresent = Boolean(\n effectiveAllDeps['@lingui/core'] ||\n effectiveAllDeps['@lingui/react'] ||\n effectiveAllDeps['@intlayer/lingui']\n );\n\n // Determine format: prefer filesystem scan, then the interactive sentinel.\n const linguiCatalog = linguiPresent\n ? await detectLinguiCatalogPattern(rootDir)\n : null;\n\n const hintLinguiJson = Boolean(\n options?.hintDependencies?.['__lingui_json__']\n );\n // `linguiCatalogFormat` resolution:\n // 1. Filesystem scan result (authoritative when catalogs already exist)\n // 2. Interactive sentinel `__lingui_json__` โ†’ 'json'\n // 3. Fallback: 'po' (lingui's default) when lingui is selected but no\n // catalogs have been generated yet and no sentinel was injected.\n const linguiCatalogFormat: 'po' | 'json' | null =\n linguiCatalog?.format ??\n (linguiPresent ? (hintLinguiJson ? 'json' : 'po') : null);\n\n const {\n packagesToInstall,\n devPackagesToInstall,\n compatSyncConfig,\n compatVitePluginConfig,\n } = detectMissingIntlayerPackages(effectiveAllDeps, {\n linguiCatalogFormat,\n });\n\n // The `json-namespaces` content strategy uses the same syncJSON pipeline as\n // the compat libraries: plain per-locale JSON namespace files synced through\n // `@intlayer/sync-json-plugin`. A detected compat library keeps precedence โ€”\n // its own catalog format/template is authoritative.\n const wantsJsonNamespaces =\n options?.contentStrategy === 'json-namespaces' && !compatSyncConfig;\n\n if (\n wantsJsonNamespaces &&\n !effectiveAllDeps['@intlayer/sync-json-plugin'] &&\n !devPackagesToInstall.includes('@intlayer/sync-json-plugin')\n ) {\n devPackagesToInstall.push('@intlayer/sync-json-plugin');\n }\n\n if (!options?.noInstallPackages) {\n const withVersion = (packages: string[]): string[] =>\n options?.upgradeToVersion\n ? packages.map((pkg) => `${pkg}@${options.upgradeToVersion}`)\n : packages;\n\n if (packagesToInstall.length > 0) {\n logger(\n colorize('Installing missing Intlayer dependencies...', ANSIColors.CYAN)\n );\n try {\n installPackages(\n rootDir,\n withVersion(packagesToInstall),\n packageManager\n );\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(\n rootDir,\n withVersion(devPackagesToInstall),\n packageManager,\n true\n );\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 // UPGRADE OUTDATED INTLAYER DEPENDENCIES\n // Only runs when a target version is provided (typically the running CLI\n // version). Already up-to-date packages are skipped. Prod and dev\n // dependencies are upgraded separately so their dependency type is kept.\n if (options?.upgradeToVersion) {\n const outdatedDependencies = detectOutdatedIntlayerPackages(\n rootDir,\n packageJson.dependencies ?? {},\n options.upgradeToVersion\n );\n const outdatedDevDependencies = detectOutdatedIntlayerPackages(\n rootDir,\n packageJson.devDependencies ?? {},\n options.upgradeToVersion\n );\n\n const allOutdated = [...outdatedDependencies, ...outdatedDevDependencies];\n\n if (allOutdated.length > 0) {\n logger(\n colorize(\n `Upgrading outdated Intlayer dependencies to ${options.upgradeToVersion}...`,\n ANSIColors.CYAN\n )\n );\n try {\n upgradePackages(\n rootDir,\n outdatedDependencies,\n packageManager,\n options.upgradeToVersion\n );\n upgradePackages(\n rootDir,\n outdatedDevDependencies,\n packageManager,\n options.upgradeToVersion,\n true\n );\n logger(\n `${v} Upgraded: ${allOutdated.map((pkg) => colorize(pkg, ANSIColors.MAGENTA)).join(', ')}`\n );\n } catch {\n logger(\n `${x} Failed to upgrade packages. Please upgrade manually: ${allOutdated.join(' ')}`,\n { level: 'warn' }\n );\n }\n } else {\n logger(`${v} Intlayer dependencies are up to date`);\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 // GitHub only triggers workflows stored at the repository root, so in a\n // monorepo the files are written to the git root and the commands go through\n // `intlayer ci`, which iterates over every Intlayer project of the\n // repository (see resolveGithubWorkflowsContext).\n if (!options?.noGithubActions) {\n const workflowsContext = await resolveGithubWorkflowsContext(\n rootDir,\n packageManager\n );\n const workflows = getGithubWorkflows(\n workflowsContext.packageManager,\n workflowsContext.options\n );\n\n for (const workflow of workflows) {\n if (await exists(workflowsContext.workflowsRootDir, workflow.filePath)) {\n logger(`${v} ${colorizePath(workflow.filePath)} already exists`);\n continue;\n }\n\n try {\n await ensureDirectory(\n workflowsContext.workflowsRootDir,\n join('.github', 'workflows')\n );\n await writeFileToRoot(\n workflowsContext.workflowsRootDir,\n workflow.filePath,\n workflow.content\n );\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 if (!options?.noVscodeExtension) {\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\n // CHECK VS CODE LSP SETTINGS\n const settingsJsonPath = join(vscodeDir, 'settings.json');\n\n if (!options?.noLsp) {\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\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, {\n locales: detectedPattern?.locales,\n applicationURL: getDefaultApplicationURL(allDeps),\n });\n\n // APPLY CONTENT STRATEGY โ€” CENTRALIZED\n // Point `compiler.output` at per-locale JSON dictionaries under `/locales/`\n // instead of the per-component template default.\n if (options?.contentStrategy === 'centralized') {\n await setCompilerOutputInConfig(\n rootDir,\n '/locales/{{locale}}/{{key}}.content.json'\n );\n }\n\n // INJECT SYNC-JSON PLUGIN FOR COMPAT LIBRARIES / JSON-NAMESPACES STRATEGY\n const syncConfigToInject: CompatSyncConfig | undefined =\n compatSyncConfig ??\n (wantsJsonNamespaces\n ? {\n format: 'i18next',\n sourceTemplate:\n detectedPattern?.template ?? './locales/${locale}/${key}.json',\n }\n : undefined);\n\n if (syncConfigToInject) {\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), whose first-level keys are namespaces โ€” so the compat\n // config carries `splitKeys: true` to emit one dictionary per namespace.\n // 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 // lingui authoritatively resolves to `โ€ฆ/{locale}/messages.{po,json}`, where\n // the `messages` filename becomes the dictionary key. Prefer it so a `.po`\n // project gets `syncPO` (the generic JSON glob only sees `.json`).\n const sourceTemplate =\n linguiCatalog?.template ??\n nextIntlMessagesPattern?.template ??\n detectedPattern?.template;\n\n const resolvedSyncConfig = {\n ...syncConfigToInject,\n ...(sourceTemplate ? { sourceTemplate } : {}),\n };\n\n const syncPluginPackage =\n resolvedSyncConfig.plugin === 'po'\n ? '@intlayer/sync-po-plugin'\n : '@intlayer/sync-json-plugin';\n const syncPluginName =\n resolvedSyncConfig.plugin === 'po' ? 'syncPO' : 'syncJSON';\n\n // `splitKeys` only makes sense for a single file holding several namespaces.\n // If the resolved template addresses one namespace per file (`${key}`\n // segment), each file is already a single namespace โ€” drop the flag so\n // syncJSON keeps one dictionary per file.\n if (\n resolvedSyncConfig.splitKeys &&\n resolvedSyncConfig.sourceTemplate.includes('${key}')\n ) {\n resolvedSyncConfig.splitKeys = false;\n }\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(syncPluginPackage)) {\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 ${syncPluginName} compat plugin`\n );\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already includes ${syncPluginName} plugin`\n );\n }\n break;\n }\n }\n }\n\n // APPLY ROUTING MODE\n // When a routing strategy was chosen (interactive init), write it to\n // `routing.mode` in the configuration file. Idempotent and comment-preserving.\n if (options?.routingMode) {\n await setRoutingModeInConfig(rootDir, options.routingMode);\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 const { replacesVitePlugin } = compatVitePluginConfig;\n\n if (content.includes(compatVitePluginConfig.pluginPackageSource)) {\n logger(\n `${v} ${colorizePath(file)} already includes ${compatVitePluginConfig.pluginPackageSource}`\n );\n } else if (\n replacesVitePlugin &&\n content.includes(replacesVitePlugin.fromPackageSource)\n ) {\n // Drop-in replacement: rewrite the original i18n vite plugin's import\n // source, keeping its binding and call site (e.g. lingui).\n const updatedContent = replaceViteConfigPluginImportSource(\n content,\n replacesVitePlugin.importName,\n replacesVitePlugin.fromPackageSource,\n compatVitePluginConfig.pluginPackageSource\n );\n await writeFileToRoot(rootDir, file, updatedContent);\n logger(\n `${v} Updated ${colorizePath(file)} to import ${replacesVitePlugin.importName} from ${compatVitePluginConfig.pluginPackageSource}`\n );\n } else {\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 }\n } else if (hasIntlayerVitePlugin(content)) {\n // A compat adapter plugin (e.g. `reactI18nextVitePlugin`) already wraps\n // `intlayer()` internally, so skip adding a redundant standalone plugin.\n logger(\n `${v} ${colorizePath(file)} already includes an Intlayer plugin`\n );\n } else {\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 NEXT.JS COMPILER (BABEL)\n // When a Next.js project already uses Babel, install @intlayer/babel and print\n // the compiler + build-optimization plugins (extract, purge, minify, optimize)\n // to add. SWC projects need no setup: withIntlayer injects @intlayer/swc.\n if (isNextJsProject) {\n await setupNextCompilerBabelConfig({\n rootDir,\n packageManager,\n allDeps,\n skipInstall: Boolean(options?.noInstallPackages),\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 // CHECK METRO CONFIG (React Native / Expo)\n // Metro is the React Native bundler. The Intlayer Metro plugin\n // (`react-native-intlayer/metro`) handles dictionary aliasing and building.\n // When no config exists we scaffold one; when one exists we safely wrap its\n // exported config with `configMetroIntlayerSync`, leaving custom async\n // (IIFE) configs untouched so existing setups are never broken.\n const isReactNativeProject = Boolean(allDeps['react-native'] || allDeps.expo);\n\n if (isReactNativeProject) {\n // Metro resolves Intlayer aliases itself, so skip the alias fallback below.\n hasAliasConfiguration = true;\n\n const metroConfigs = [\n 'metro.config.js',\n 'metro.config.cjs',\n 'metro.config.mjs',\n 'metro.config.ts',\n ];\n\n let metroConfigFile: string | undefined;\n\n for (const file of metroConfigs) {\n if (await exists(rootDir, file)) {\n metroConfigFile = file;\n break;\n }\n }\n\n if (metroConfigFile) {\n const content = await readFileFromRoot(rootDir, metroConfigFile);\n\n if (content.includes('react-native-intlayer')) {\n logger(\n `${v} ${colorizePath(metroConfigFile)} already includes the Intlayer Metro plugin`\n );\n } else {\n const extension = metroConfigFile.split('.').pop()!;\n const updatedContent = updateMetroConfig(content, extension);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, metroConfigFile, updatedContent);\n logger(\n `${v} Updated ${colorizePath(metroConfigFile)} to include the Intlayer Metro plugin`\n );\n } else {\n logger(\n `${x} Could not automatically update ${colorizePath(metroConfigFile)}. Wrap your exported config with ${colorize('configMetroIntlayer', ANSIColors.MAGENTA)}: ${colorizePath(DocumentationRouter.ReactNativeAndExpo)}`,\n { level: 'warn' }\n );\n }\n }\n } else {\n const newMetroConfigFile = 'metro.config.js';\n await writeFileToRoot(\n rootDir,\n newMetroConfigFile,\n getMetroConfigTemplate(Boolean(allDeps.expo))\n );\n logger(\n `${v} Created ${colorizePath(newMetroConfigFile)} with the Intlayer Metro plugin`\n );\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 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 devScript &&\n ((isNextJsProject && allDeps.next && isVersionAtLeast(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 // FRAMEWORK-SPECIFIC SCAFFOLDING\n // Sets up middleware/proxy and wraps the layout/page with the Intlayer\n // providers for the detected framework (Next.js App Router today). Idempotent\n // and non-destructive: it never overwrites user code it cannot safely\n // transform, skipping with guidance instead.\n //\n // Skipped entirely when a compat i18n library drives the app (i18next,\n // next-intl, vue-i18n, โ€ฆ): the app already owns its routing, providers and\n // layouts, and Intlayer only syncs its catalogs โ€” restructuring routes or\n // injecting providers would break the existing setup.\n const hasCompatLibrary = Boolean(compatSyncConfig || compatVitePluginConfig);\n\n if (!options?.noFrameworkSetup && hasCompatLibrary) {\n logger(\n `${v} Compat i18n library detected โ€” keeping the app structure untouched (no route restructure, no provider injection)`\n );\n }\n\n if (!options?.noFrameworkSetup && !hasCompatLibrary) {\n try {\n // Prefer the user's interactive choice, else the configured routing mode\n // (which itself defaults to `prefix-no-default`). Drives whether the\n // locale path segment is required (`prefix-all`) or optional.\n const routingMode =\n options?.routingMode ??\n getConfiguration({ baseDir: rootDir }).routing.mode;\n\n await setupFramework({\n rootDir,\n allDeps,\n packageManager,\n useTypeScript: hasTsConfig,\n routingMode,\n });\n } catch {\n logger(\n `${x} Framework-specific scaffolding failed. Your existing files were left untouched; follow the documentation to finish the setup.`,\n { level: 'warn' }\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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"}