@intlayer/engine 9.0.0-canary.18 → 9.0.0-canary.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/cjs/init/frameworkSetup/nextAppRouter/restructure.cjs +2 -2
  2. package/dist/cjs/init/frameworkSetup/nextAppRouter/restructure.cjs.map +1 -1
  3. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs +2 -2
  4. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
  5. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs +2 -2
  6. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs.map +1 -1
  7. package/dist/cjs/init/utils/configManipulation.cjs +17 -17
  8. package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
  9. package/dist/cjs/utils/babelParser.cjs +30 -0
  10. package/dist/cjs/utils/babelParser.cjs.map +1 -0
  11. package/dist/cjs/writeContentDeclaration/transformJSFile.cjs +2 -2
  12. package/dist/cjs/writeContentDeclaration/transformJSFile.cjs.map +1 -1
  13. package/dist/esm/_virtual/_rolldown/runtime.mjs +8 -0
  14. package/dist/esm/init/frameworkSetup/nextAppRouter/restructure.mjs +1 -1
  15. package/dist/esm/init/frameworkSetup/nextAppRouter/restructure.mjs.map +1 -1
  16. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs +1 -1
  17. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
  18. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs +1 -1
  19. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs.map +1 -1
  20. package/dist/esm/init/utils/configManipulation.mjs +1 -1
  21. package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
  22. package/dist/esm/utils/babelParser.mjs +29 -0
  23. package/dist/esm/utils/babelParser.mjs.map +1 -0
  24. package/dist/esm/writeContentDeclaration/transformJSFile.mjs +1 -1
  25. package/dist/esm/writeContentDeclaration/transformJSFile.mjs.map +1 -1
  26. package/dist/types/utils/babelParser.d.ts +9 -0
  27. package/dist/types/utils/babelParser.d.ts.map +1 -0
  28. package/package.json +9 -9
  29. package/dist/cjs/utils/recastBabelParser.cjs +0 -66
  30. package/dist/cjs/utils/recastBabelParser.cjs.map +0 -1
  31. package/dist/esm/utils/recastBabelParser.mjs +0 -64
  32. package/dist/esm/utils/recastBabelParser.mjs.map +0 -1
  33. package/dist/types/utils/recastBabelParser.d.ts +0 -12
  34. package/dist/types/utils/recastBabelParser.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- const require_utils_recastBabelParser = require('../../../utils/recastBabelParser.cjs');
3
+ const require_utils_babelParser = require('../../../utils/babelParser.cjs');
4
4
  let node_fs_promises = require("node:fs/promises");
5
5
  let node_path = require("node:path");
6
6
  let fast_glob = require("fast-glob");
@@ -76,7 +76,7 @@ const mapTargetPath = (oldTargetAbs, { appDirAbs, localeDirAbs, movedTopLevelNam
76
76
  * are left untouched. Returns the original code unchanged when nothing matched.
77
77
  */
78
78
  const rewriteRelativeImports = (code, oldAbs, newAbs, context) => {
79
- const ast = recast.parse(code, { parser: require_utils_recastBabelParser.babelTsParser });
79
+ const ast = recast.parse(code, { parser: require_utils_babelParser.babelTsParser });
80
80
  let changed = false;
81
81
  const rewriteSource = (sourceNode) => {
82
82
  if (!sourceNode || !n.StringLiteral.check(sourceNode)) return;
@@ -1 +1 @@
1
- {"version":3,"file":"restructure.cjs","names":["sep","babelTsParser"],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/restructure.ts"],"sourcesContent":["import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport fg from 'fast-glob';\nimport * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/recastBabelParser';\n\nconst { namedTypes: n } = recast.types;\n\n/** Source file extensions whose relative imports must be rewritten after a move. */\nconst SCRIPT_GLOB = '**/*.{ts,tsx,js,jsx,mjs,cjs}';\n\n/** Strips a known script extension from a file name, e.g. `page.tsx` -> `page`. */\nconst stripScriptExtension = (fileName: string): string =>\n fileName.replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, '');\n\n/**\n * Detects whether a top-level App Router entry is already a locale segment, in\n * any of the Next.js dynamic-segment forms:\n * - `[locale]` — required segment (prefix every locale),\n * - `[...locale]` / `[[...locale]]` — catch-all / optional catch-all segments.\n *\n * Used to skip the restructure when the project is already locale-aware, so an\n * existing locale segment is never nested under a freshly created `[locale]`.\n */\nexport const isLocaleSegment = (entryName: string): boolean =>\n /^\\[\\[?\\.{0,3}locale\\]\\]?$/.test(entryName);\n\n/**\n * Top-level App Router entries that must stay at the app root and never be\n * moved under `[locale]`:\n * - `api/` route handlers (not locale-prefixed),\n * - global stylesheets,\n * - metadata/asset file conventions (favicon, icon, sitemap, robots, manifest…),\n * - `global-error` and `not-found` boundaries (kept as root fallbacks).\n *\n * Everything else (`page`, `loading`, `error`, `template`, `default`, the root\n * `layout`, and nested route folders) is moved so it becomes locale-aware.\n */\nexport const shouldKeepAppEntryAtRoot = (entryName: string): boolean => {\n if (entryName === 'api') return true;\n if (entryName.toLowerCase().endsWith('.css')) return true;\n if (entryName === 'favicon.ico') return true;\n\n const base = stripScriptExtension(entryName);\n const keepExactBases = new Set([\n 'not-found',\n 'global-error',\n 'sitemap',\n 'robots',\n 'manifest',\n ]);\n if (keepExactBases.has(base)) return true;\n\n // Image metadata conventions: favicon, icon, apple-icon, opengraph-image,\n // twitter-image — optionally suffixed (e.g. `icon1`, `opengraph-image-alt`).\n const imageConventionPrefixes = [\n 'favicon',\n 'icon',\n 'apple-icon',\n 'opengraph-image',\n 'twitter-image',\n ];\n if (imageConventionPrefixes.some((prefix) => base.startsWith(prefix))) {\n return true;\n }\n\n return false;\n};\n\ntype RewriteContext = {\n appDirAbs: string;\n localeDirAbs: string;\n movedTopLevelNames: string[];\n};\n\n/**\n * Maps an import target's pre-move absolute path to its post-move absolute path.\n * Targets that live inside a moved top-level entry are relocated under\n * `[locale]`; targets that stayed at the app root or live outside the app\n * directory are returned unchanged.\n */\nconst mapTargetPath = (\n oldTargetAbs: string,\n { appDirAbs, localeDirAbs, movedTopLevelNames }: RewriteContext\n): string => {\n const relFromApp = relative(appDirAbs, oldTargetAbs);\n\n // Outside the app directory (e.g. `../components/...`) — never moved.\n if (relFromApp.startsWith('..') || isAbsolute(relFromApp)) {\n return oldTargetAbs;\n }\n\n const firstSegment = relFromApp.split(sep)[0] ?? '';\n const isMoved = movedTopLevelNames.some(\n (name) =>\n name === firstSegment || stripScriptExtension(name) === firstSegment\n );\n\n if (!isMoved) return oldTargetAbs;\n\n return join(localeDirAbs, relFromApp);\n};\n\n/**\n * Rewrites relative import/export/`import()`/`require()` specifiers in a file\n * that has moved from `oldAbs` to `newAbs`, so they keep resolving to the same\n * modules after the move. Non-relative specifiers (bare packages, `@/` aliases)\n * are left untouched. Returns the original code unchanged when nothing matched.\n */\nexport const rewriteRelativeImports = (\n code: string,\n oldAbs: string,\n newAbs: string,\n context: RewriteContext\n): string => {\n // babel-ts handles TypeScript *and* JSX (App Router files are `.tsx`).\n const ast = recast.parse(code, { parser: babelTsParser });\n\n let changed = false;\n\n const rewriteSource = (sourceNode: any): void => {\n if (!sourceNode || !n.StringLiteral.check(sourceNode)) return;\n const specifier = sourceNode.value;\n if (typeof specifier !== 'string' || !specifier.startsWith('.')) return;\n\n const oldTargetAbs = resolve(dirname(oldAbs), specifier);\n const newTargetAbs = mapTargetPath(oldTargetAbs, context);\n\n let newSpecifier = relative(dirname(newAbs), newTargetAbs)\n .split(sep)\n .join('/');\n if (!newSpecifier.startsWith('.')) {\n newSpecifier = `./${newSpecifier}`;\n }\n\n if (newSpecifier !== specifier) {\n sourceNode.value = newSpecifier;\n changed = true;\n }\n };\n\n recast.visit(ast, {\n visitImportDeclaration(path) {\n rewriteSource(path.node.source);\n return false;\n },\n visitExportAllDeclaration(path) {\n rewriteSource(path.node.source);\n return false;\n },\n visitExportNamedDeclaration(path) {\n if (path.node.source) rewriteSource(path.node.source);\n return false;\n },\n visitCallExpression(path) {\n const { callee, arguments: args } = path.node;\n const isDynamicImport = callee.type === 'Import';\n const isRequire = n.Identifier.check(callee) && callee.name === 'require';\n if ((isDynamicImport || isRequire) && args.length > 0) {\n rewriteSource(args[0]);\n }\n this.traverse(path);\n },\n });\n\n if (!changed) return code;\n return recast.print(ast).code;\n};\n\n/** Outcome of an attempted `[locale]` restructure. */\nexport type RestructureResult =\n | { status: 'already-structured'; localeSegment: string }\n | { status: 'nothing-to-move' }\n | { status: 'moved'; movedEntries: string[] };\n\n/**\n * Moves the routable App Router entries of `appDir` under a new `[locale]`\n * segment and rewrites relative imports in the moved files. Idempotent: it is a\n * no-op when the app is already locale-aware in any prefix mode (see\n * {@link isLocaleSegment}), which is reported via `localeSegment`. Root-only\n * files (see {@link shouldKeepAppEntryAtRoot}) are left in place.\n */\nexport const restructureAppIntoLocale = async (\n rootDir: string,\n appDir: string\n): Promise<RestructureResult> => {\n const appDirAbs = join(rootDir, appDir);\n const localeDirAbs = join(appDirAbs, '[locale]');\n\n const entries = await readdir(appDirAbs, { withFileTypes: true });\n\n // Skip when the app is already locale-aware in any prefix mode — a fresh\n // `[locale]`, or an existing `[...locale]` / `[[...locale]]` catch-all segment.\n const existingLocaleSegment = entries.find((entry) =>\n isLocaleSegment(entry.name)\n );\n if (existingLocaleSegment) {\n return {\n status: 'already-structured',\n localeSegment: existingLocaleSegment.name,\n };\n }\n\n const movedTopLevelNames = entries\n .map((entry) => entry.name)\n .filter((name) => !shouldKeepAppEntryAtRoot(name));\n\n if (movedTopLevelNames.length === 0) {\n return { status: 'nothing-to-move' };\n }\n\n await mkdir(localeDirAbs, { recursive: true });\n\n for (const name of movedTopLevelNames) {\n await rename(join(appDirAbs, name), join(localeDirAbs, name));\n }\n\n const movedFiles = await fg(SCRIPT_GLOB, {\n cwd: localeDirAbs,\n absolute: true,\n onlyFiles: true,\n });\n\n const rewriteContext: RewriteContext = {\n appDirAbs,\n localeDirAbs,\n movedTopLevelNames,\n };\n\n for (const newAbs of movedFiles) {\n const relFromLocale = relative(localeDirAbs, newAbs);\n const oldAbs = join(appDirAbs, relFromLocale);\n const code = await readFile(newAbs, 'utf8');\n const rewritten = rewriteRelativeImports(\n code,\n oldAbs,\n newAbs,\n rewriteContext\n );\n if (rewritten !== code) {\n await writeFile(newAbs, rewritten, 'utf8');\n }\n }\n\n return { status: 'moved', movedEntries: movedTopLevelNames };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"restructure.cjs","names":["sep","babelTsParser"],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/restructure.ts"],"sourcesContent":["import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport fg from 'fast-glob';\nimport * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/babelParser';\n\nconst { namedTypes: n } = recast.types;\n\n/** Source file extensions whose relative imports must be rewritten after a move. */\nconst SCRIPT_GLOB = '**/*.{ts,tsx,js,jsx,mjs,cjs}';\n\n/** Strips a known script extension from a file name, e.g. `page.tsx` -> `page`. */\nconst stripScriptExtension = (fileName: string): string =>\n fileName.replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, '');\n\n/**\n * Detects whether a top-level App Router entry is already a locale segment, in\n * any of the Next.js dynamic-segment forms:\n * - `[locale]` — required segment (prefix every locale),\n * - `[...locale]` / `[[...locale]]` — catch-all / optional catch-all segments.\n *\n * Used to skip the restructure when the project is already locale-aware, so an\n * existing locale segment is never nested under a freshly created `[locale]`.\n */\nexport const isLocaleSegment = (entryName: string): boolean =>\n /^\\[\\[?\\.{0,3}locale\\]\\]?$/.test(entryName);\n\n/**\n * Top-level App Router entries that must stay at the app root and never be\n * moved under `[locale]`:\n * - `api/` route handlers (not locale-prefixed),\n * - global stylesheets,\n * - metadata/asset file conventions (favicon, icon, sitemap, robots, manifest…),\n * - `global-error` and `not-found` boundaries (kept as root fallbacks).\n *\n * Everything else (`page`, `loading`, `error`, `template`, `default`, the root\n * `layout`, and nested route folders) is moved so it becomes locale-aware.\n */\nexport const shouldKeepAppEntryAtRoot = (entryName: string): boolean => {\n if (entryName === 'api') return true;\n if (entryName.toLowerCase().endsWith('.css')) return true;\n if (entryName === 'favicon.ico') return true;\n\n const base = stripScriptExtension(entryName);\n const keepExactBases = new Set([\n 'not-found',\n 'global-error',\n 'sitemap',\n 'robots',\n 'manifest',\n ]);\n if (keepExactBases.has(base)) return true;\n\n // Image metadata conventions: favicon, icon, apple-icon, opengraph-image,\n // twitter-image — optionally suffixed (e.g. `icon1`, `opengraph-image-alt`).\n const imageConventionPrefixes = [\n 'favicon',\n 'icon',\n 'apple-icon',\n 'opengraph-image',\n 'twitter-image',\n ];\n if (imageConventionPrefixes.some((prefix) => base.startsWith(prefix))) {\n return true;\n }\n\n return false;\n};\n\ntype RewriteContext = {\n appDirAbs: string;\n localeDirAbs: string;\n movedTopLevelNames: string[];\n};\n\n/**\n * Maps an import target's pre-move absolute path to its post-move absolute path.\n * Targets that live inside a moved top-level entry are relocated under\n * `[locale]`; targets that stayed at the app root or live outside the app\n * directory are returned unchanged.\n */\nconst mapTargetPath = (\n oldTargetAbs: string,\n { appDirAbs, localeDirAbs, movedTopLevelNames }: RewriteContext\n): string => {\n const relFromApp = relative(appDirAbs, oldTargetAbs);\n\n // Outside the app directory (e.g. `../components/...`) — never moved.\n if (relFromApp.startsWith('..') || isAbsolute(relFromApp)) {\n return oldTargetAbs;\n }\n\n const firstSegment = relFromApp.split(sep)[0] ?? '';\n const isMoved = movedTopLevelNames.some(\n (name) =>\n name === firstSegment || stripScriptExtension(name) === firstSegment\n );\n\n if (!isMoved) return oldTargetAbs;\n\n return join(localeDirAbs, relFromApp);\n};\n\n/**\n * Rewrites relative import/export/`import()`/`require()` specifiers in a file\n * that has moved from `oldAbs` to `newAbs`, so they keep resolving to the same\n * modules after the move. Non-relative specifiers (bare packages, `@/` aliases)\n * are left untouched. Returns the original code unchanged when nothing matched.\n */\nexport const rewriteRelativeImports = (\n code: string,\n oldAbs: string,\n newAbs: string,\n context: RewriteContext\n): string => {\n // babel-ts handles TypeScript *and* JSX (App Router files are `.tsx`).\n const ast = recast.parse(code, { parser: babelTsParser });\n\n let changed = false;\n\n const rewriteSource = (sourceNode: any): void => {\n if (!sourceNode || !n.StringLiteral.check(sourceNode)) return;\n const specifier = sourceNode.value;\n if (typeof specifier !== 'string' || !specifier.startsWith('.')) return;\n\n const oldTargetAbs = resolve(dirname(oldAbs), specifier);\n const newTargetAbs = mapTargetPath(oldTargetAbs, context);\n\n let newSpecifier = relative(dirname(newAbs), newTargetAbs)\n .split(sep)\n .join('/');\n if (!newSpecifier.startsWith('.')) {\n newSpecifier = `./${newSpecifier}`;\n }\n\n if (newSpecifier !== specifier) {\n sourceNode.value = newSpecifier;\n changed = true;\n }\n };\n\n recast.visit(ast, {\n visitImportDeclaration(path) {\n rewriteSource(path.node.source);\n return false;\n },\n visitExportAllDeclaration(path) {\n rewriteSource(path.node.source);\n return false;\n },\n visitExportNamedDeclaration(path) {\n if (path.node.source) rewriteSource(path.node.source);\n return false;\n },\n visitCallExpression(path) {\n const { callee, arguments: args } = path.node;\n const isDynamicImport = callee.type === 'Import';\n const isRequire = n.Identifier.check(callee) && callee.name === 'require';\n if ((isDynamicImport || isRequire) && args.length > 0) {\n rewriteSource(args[0]);\n }\n this.traverse(path);\n },\n });\n\n if (!changed) return code;\n return recast.print(ast).code;\n};\n\n/** Outcome of an attempted `[locale]` restructure. */\nexport type RestructureResult =\n | { status: 'already-structured'; localeSegment: string }\n | { status: 'nothing-to-move' }\n | { status: 'moved'; movedEntries: string[] };\n\n/**\n * Moves the routable App Router entries of `appDir` under a new `[locale]`\n * segment and rewrites relative imports in the moved files. Idempotent: it is a\n * no-op when the app is already locale-aware in any prefix mode (see\n * {@link isLocaleSegment}), which is reported via `localeSegment`. Root-only\n * files (see {@link shouldKeepAppEntryAtRoot}) are left in place.\n */\nexport const restructureAppIntoLocale = async (\n rootDir: string,\n appDir: string\n): Promise<RestructureResult> => {\n const appDirAbs = join(rootDir, appDir);\n const localeDirAbs = join(appDirAbs, '[locale]');\n\n const entries = await readdir(appDirAbs, { withFileTypes: true });\n\n // Skip when the app is already locale-aware in any prefix mode — a fresh\n // `[locale]`, or an existing `[...locale]` / `[[...locale]]` catch-all segment.\n const existingLocaleSegment = entries.find((entry) =>\n isLocaleSegment(entry.name)\n );\n if (existingLocaleSegment) {\n return {\n status: 'already-structured',\n localeSegment: existingLocaleSegment.name,\n };\n }\n\n const movedTopLevelNames = entries\n .map((entry) => entry.name)\n .filter((name) => !shouldKeepAppEntryAtRoot(name));\n\n if (movedTopLevelNames.length === 0) {\n return { status: 'nothing-to-move' };\n }\n\n await mkdir(localeDirAbs, { recursive: true });\n\n for (const name of movedTopLevelNames) {\n await rename(join(appDirAbs, name), join(localeDirAbs, name));\n }\n\n const movedFiles = await fg(SCRIPT_GLOB, {\n cwd: localeDirAbs,\n absolute: true,\n onlyFiles: true,\n });\n\n const rewriteContext: RewriteContext = {\n appDirAbs,\n localeDirAbs,\n movedTopLevelNames,\n };\n\n for (const newAbs of movedFiles) {\n const relFromLocale = relative(localeDirAbs, newAbs);\n const oldAbs = join(appDirAbs, relFromLocale);\n const code = await readFile(newAbs, 'utf8');\n const rewritten = rewriteRelativeImports(\n code,\n oldAbs,\n newAbs,\n rewriteContext\n );\n if (rewritten !== code) {\n await writeFile(newAbs, rewritten, 'utf8');\n }\n }\n\n return { status: 'moved', movedEntries: movedTopLevelNames };\n};\n"],"mappings":";;;;;;;;;;;AAMA,MAAM,EAAE,YAAY,MAAM,OAAO;;AAGjC,MAAM,cAAc;;AAGpB,MAAM,wBAAwB,aAC5B,SAAS,QAAQ,8BAA8B,EAAE;;;;;;;;;;AAWnD,MAAa,mBAAmB,cAC9B,4BAA4B,KAAK,SAAS;;;;;;;;;;;;AAa5C,MAAa,4BAA4B,cAA+B;CACtE,IAAI,cAAc,OAAO,OAAO;CAChC,IAAI,UAAU,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO;CACrD,IAAI,cAAc,eAAe,OAAO;CAExC,MAAM,OAAO,qBAAqB,SAAS;CAQ3C,qBAAI,IAPuB,IAAI;EAC7B;EACA;EACA;EACA;EACA;CACF,CACiB,EAAC,CAAC,IAAI,IAAI,GAAG,OAAO;CAWrC,IAAI;EANF;EACA;EACA;EACA;EACA;CAEwB,CAAC,CAAC,MAAM,WAAW,KAAK,WAAW,MAAM,CAAC,GAClE,OAAO;CAGT,OAAO;AACT;;;;;;;AAcA,MAAM,iBACJ,cACA,EAAE,WAAW,cAAc,yBAChB;CACX,MAAM,qCAAsB,WAAW,YAAY;CAGnD,IAAI,WAAW,WAAW,IAAI,+BAAgB,UAAU,GACtD,OAAO;CAGT,MAAM,eAAe,WAAW,MAAMA,aAAG,CAAC,CAAC,MAAM;CAMjD,IAAI,CALY,mBAAmB,MAChC,SACC,SAAS,gBAAgB,qBAAqB,IAAI,MAAM,YAGjD,GAAG,OAAO;CAErB,2BAAY,cAAc,UAAU;AACtC;;;;;;;AAQA,MAAa,0BACX,MACA,QACA,QACA,YACW;CAEX,MAAM,MAAM,OAAO,MAAM,MAAM,EAAE,QAAQC,wCAAc,CAAC;CAExD,IAAI,UAAU;CAEd,MAAM,iBAAiB,eAA0B;EAC/C,IAAI,CAAC,cAAc,CAAC,EAAE,cAAc,MAAM,UAAU,GAAG;EACvD,MAAM,YAAY,WAAW;EAC7B,IAAI,OAAO,cAAc,YAAY,CAAC,UAAU,WAAW,GAAG,GAAG;EAEjE,MAAM,6DAA+B,MAAM,GAAG,SAAS;EACvD,MAAM,eAAe,cAAc,cAAc,OAAO;EAExD,IAAI,8DAAgC,MAAM,GAAG,YAAY,CAAC,CACvD,MAAMD,aAAG,CAAC,CACV,KAAK,GAAG;EACX,IAAI,CAAC,aAAa,WAAW,GAAG,GAC9B,eAAe,KAAK;EAGtB,IAAI,iBAAiB,WAAW;GAC9B,WAAW,QAAQ;GACnB,UAAU;EACZ;CACF;CAEA,OAAO,MAAM,KAAK;EAChB,uBAAuB,MAAM;GAC3B,cAAc,KAAK,KAAK,MAAM;GAC9B,OAAO;EACT;EACA,0BAA0B,MAAM;GAC9B,cAAc,KAAK,KAAK,MAAM;GAC9B,OAAO;EACT;EACA,4BAA4B,MAAM;GAChC,IAAI,KAAK,KAAK,QAAQ,cAAc,KAAK,KAAK,MAAM;GACpD,OAAO;EACT;EACA,oBAAoB,MAAM;GACxB,MAAM,EAAE,QAAQ,WAAW,SAAS,KAAK;GACzC,MAAM,kBAAkB,OAAO,SAAS;GACxC,MAAM,YAAY,EAAE,WAAW,MAAM,MAAM,KAAK,OAAO,SAAS;GAChE,KAAK,mBAAmB,cAAc,KAAK,SAAS,GAClD,cAAc,KAAK,EAAE;GAEvB,KAAK,SAAS,IAAI;EACpB;CACF,CAAC;CAED,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;AAC3B;;;;;;;;AAeA,MAAa,2BAA2B,OACtC,SACA,WAC+B;CAC/B,MAAM,gCAAiB,SAAS,MAAM;CACtC,MAAM,mCAAoB,WAAW,UAAU;CAE/C,MAAM,UAAU,oCAAc,WAAW,EAAE,eAAe,KAAK,CAAC;CAIhE,MAAM,wBAAwB,QAAQ,MAAM,UAC1C,gBAAgB,MAAM,IAAI,CAC5B;CACA,IAAI,uBACF,OAAO;EACL,QAAQ;EACR,eAAe,sBAAsB;CACvC;CAGF,MAAM,qBAAqB,QACxB,KAAK,UAAU,MAAM,IAAI,CAAC,CAC1B,QAAQ,SAAS,CAAC,yBAAyB,IAAI,CAAC;CAEnD,IAAI,mBAAmB,WAAW,GAChC,OAAO,EAAE,QAAQ,kBAAkB;CAGrC,kCAAY,cAAc,EAAE,WAAW,KAAK,CAAC;CAE7C,KAAK,MAAM,QAAQ,oBACjB,uDAAkB,WAAW,IAAI,uBAAQ,cAAc,IAAI,CAAC;CAG9D,MAAM,aAAa,6BAAS,aAAa;EACvC,KAAK;EACL,UAAU;EACV,WAAW;CACb,CAAC;CAED,MAAM,iBAAiC;EACrC;EACA;EACA;CACF;CAEA,KAAK,MAAM,UAAU,YAAY;EAE/B,MAAM,6BAAc,mCADW,cAAc,MACF,CAAC;EAC5C,MAAM,OAAO,qCAAe,QAAQ,MAAM;EAC1C,MAAM,YAAY,uBAChB,MACA,QACA,QACA,cACF;EACA,IAAI,cAAc,MAChB,sCAAgB,QAAQ,WAAW,MAAM;CAE7C;CAEA,OAAO;EAAE,QAAQ;EAAS,cAAc;CAAmB;AAC7D"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- const require_utils_recastBabelParser = require('../../../utils/recastBabelParser.cjs');
3
+ const require_utils_babelParser = require('../../../utils/babelParser.cjs');
4
4
  const require_init_utils_astImports = require('../../utils/astImports.cjs');
5
5
  let recast = require("recast");
6
6
  recast = require_runtime.__toESM(recast);
@@ -8,7 +8,7 @@ recast = require_runtime.__toESM(recast);
8
8
  //#region src/init/frameworkSetup/nextAppRouter/transforms.ts
9
9
  const { builders: b } = recast.types;
10
10
  /** babel-ts parser handles TypeScript *and* JSX (the `typescript` parser does not). */
11
- const parseTsx = (code) => recast.parse(code, { parser: require_utils_recastBabelParser.babelTsParser });
11
+ const parseTsx = (code) => recast.parse(code, { parser: require_utils_babelParser.babelTsParser });
12
12
  /** Detects a top-level `'use client'` directive (client components can't be async server providers). */
13
13
  const isClientComponent = (ast) => {
14
14
  if ((ast.program.directives ?? []).some((directive) => directive.value?.value === "use client")) return true;
@@ -1 +1 @@
1
- {"version":3,"file":"transforms.cjs","names":["babelTsParser","firstInsertIndex"],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/recastBabelParser';\nimport { ensureNamedImport, firstInsertIndex } from '../../utils/astImports';\n\nconst { builders: b } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX (the `typescript` parser does not). */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped-client' | 'skipped';\n};\n\n/** Detects a top-level `'use client'` directive (client components can't be async server providers). */\nconst isClientComponent = (ast: any): boolean => {\n const directives = ast.program.directives ?? [];\n if (\n directives.some((directive: any) => directive.value?.value === 'use client')\n ) {\n return true;\n }\n return ast.program.body.some(\n (stmt: any) =>\n stmt.type === 'ExpressionStatement' &&\n stmt.expression?.type === 'StringLiteral' &&\n stmt.expression.value === 'use client'\n );\n};\n\n/** Finds the function node behind `export default`, following an identifier reference if needed. */\nconst findDefaultExportFunction = (ast: any): any => {\n const body = ast.program.body;\n\n const asFunction = (node: any): any =>\n node &&\n (node.type === 'ArrowFunctionExpression' ||\n node.type === 'FunctionExpression' ||\n node.type === 'FunctionDeclaration')\n ? node\n : null;\n\n for (const stmt of body) {\n if (stmt.type !== 'ExportDefaultDeclaration') continue;\n\n const direct = asFunction(stmt.declaration);\n if (direct) return direct;\n\n if (stmt.declaration?.type === 'Identifier') {\n const name = stmt.declaration.name;\n for (const candidate of body) {\n if (candidate.type === 'VariableDeclaration') {\n for (const declarator of candidate.declarations) {\n if (\n declarator.id?.type === 'Identifier' &&\n declarator.id.name === name\n ) {\n const fn = asFunction(declarator.init);\n if (fn) return fn;\n }\n }\n }\n if (\n candidate.type === 'FunctionDeclaration' &&\n candidate.id?.name === name\n ) {\n return candidate;\n }\n }\n }\n }\n\n return null;\n};\n\n/** Ensures `export { exportedName } from source`, skipping when already declared/re-exported. */\nconst ensureExportFrom = (\n ast: any,\n exportedName: string,\n source: string\n): void => {\n const body = ast.program.body;\n\n const alreadyPresent = body.some((stmt: any) => {\n if (\n stmt.type === 'ExportNamedDeclaration' &&\n stmt.source?.value === source\n ) {\n return stmt.specifiers.some(\n (spec: any) => spec.exported?.name === exportedName\n );\n }\n // Locally declared `export const/function generateStaticParams`\n if (stmt.type === 'ExportNamedDeclaration' && stmt.declaration) {\n const decl = stmt.declaration;\n if (decl.type === 'FunctionDeclaration' && decl.id?.name === exportedName)\n return true;\n if (decl.type === 'VariableDeclaration') {\n return decl.declarations.some(\n (d: any) => d.id?.type === 'Identifier' && d.id.name === exportedName\n );\n }\n }\n return false;\n });\n\n if (alreadyPresent) return;\n\n const exportNode = parseTsx(`export { ${exportedName} } from \"${source}\";`)\n .program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, exportNode);\n};\n\n/** Makes the function async and inserts `const locale = await getLocale();` once, at the top of its body. */\nconst ensureAwaitedLocale = (funcNode: any): void => {\n funcNode.async = true;\n\n if (funcNode.body.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const hasLocale = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some(\n (d: any) =>\n // const locale = ...\n (d.id?.type === 'Identifier' && d.id.name === 'locale') ||\n // const { locale } = ... or const { locale: locale } = ...\n (d.id?.type === 'ObjectPattern' &&\n d.id.properties?.some(\n (prop: any) =>\n prop.value?.type === 'Identifier' &&\n prop.value?.name === 'locale'\n ))\n )\n );\n\n if (!hasLocale) {\n const localeStatement = parseTsx('const locale = await getLocale();')\n .program.body[0];\n funcNode.body.body.unshift(localeStatement);\n }\n};\n\n/** Builds `<providerName locale={locale}>{child}</providerName>` around an existing JSX child node. */\nconst buildProviderElement = (providerName: string, childNode: any): any => {\n const template = parseTsx(\n `const __wrap = <${providerName} locale={locale}>{__child__}</${providerName}>;`\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [childNode];\n return providerElement;\n};\n\n/** Sets `lang={locale}` on the first `<html>` element, if present. */\nconst setHtmlLang = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n const langAttr = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === 'lang'\n ) as any;\n const localeExpression = b.jsxExpressionContainer(\n b.identifier('locale')\n );\n if (langAttr) {\n langAttr.value = localeExpression;\n } else {\n node.attributes.push(\n b.jsxAttribute(b.jsxIdentifier('lang'), localeExpression)\n );\n }\n return false;\n }\n this.traverse(path);\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a Next.js App Router **layout** with\n * `IntlayerClientProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails (returns the original code) for client components, when no\n * `{children}` placeholder is found, or when there is no default export.\n */\nexport const wrapLayoutWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerClientProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n path.replace(buildProviderElement('IntlayerClientProvider', path.node));\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerClientProvider', 'next-intlayer');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureExportFrom(ast, 'generateStaticParams', 'next-intlayer');\n ensureAwaitedLocale(funcNode);\n setHtmlLang(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n\n/** Returns the single top-level JSX return of a function, or the JSX of an expression-bodied arrow. */\nconst findSingleJsxReturn = (\n funcNode: any\n): { kind: 'return'; node: any } | { kind: 'arrow'; node: any } | null => {\n if (\n funcNode.type === 'ArrowFunctionExpression' &&\n funcNode.body.type !== 'BlockStatement'\n ) {\n const body =\n funcNode.body.type === 'JSXElement' ||\n funcNode.body.type === 'JSXFragment'\n ? funcNode.body\n : null;\n return body ? { kind: 'arrow', node: funcNode } : null;\n }\n\n if (funcNode.body.type !== 'BlockStatement') return null;\n\n // Collect every JSX-returning `return` inside this function, but do not\n // descend into nested function scopes (e.g. an inner component defined in the\n // same file). More than one top-level JSX return is ambiguous — bail.\n const jsxReturns: any[] = [];\n let functionDepth = 0;\n recast.visit(funcNode, {\n visitFunction(path) {\n functionDepth++;\n if (functionDepth === 1) {\n this.traverse(path);\n }\n functionDepth--;\n return false;\n },\n visitReturnStatement(path) {\n const argument = path.node.argument;\n if (argument?.type === 'JSXElement' || argument?.type === 'JSXFragment') {\n jsxReturns.push(path.node);\n }\n this.traverse(path);\n },\n });\n\n if (jsxReturns.length !== 1) return null;\n return { kind: 'return', node: jsxReturns[0] };\n};\n\n/**\n * Wraps the returned JSX of a Next.js App Router **page** with\n * `IntlayerServerProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails for client components, when the page has no single\n * top-level JSX return, or when there is no default export.\n */\nexport const wrapPageWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerServerProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n const jsxReturn = findSingleJsxReturn(funcNode);\n if (!jsxReturn) return { code, status: 'skipped' };\n\n if (jsxReturn.kind === 'return') {\n jsxReturn.node.argument = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.argument\n );\n } else {\n jsxReturn.node.body = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.body\n );\n }\n\n ensureNamedImport(ast, 'IntlayerServerProvider', 'next-intlayer/server');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureAwaitedLocale(funcNode);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transforms.cjs","names":["babelTsParser","firstInsertIndex"],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/babelParser';\nimport { ensureNamedImport, firstInsertIndex } from '../../utils/astImports';\n\nconst { builders: b } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX (the `typescript` parser does not). */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped-client' | 'skipped';\n};\n\n/** Detects a top-level `'use client'` directive (client components can't be async server providers). */\nconst isClientComponent = (ast: any): boolean => {\n const directives = ast.program.directives ?? [];\n if (\n directives.some((directive: any) => directive.value?.value === 'use client')\n ) {\n return true;\n }\n return ast.program.body.some(\n (stmt: any) =>\n stmt.type === 'ExpressionStatement' &&\n stmt.expression?.type === 'StringLiteral' &&\n stmt.expression.value === 'use client'\n );\n};\n\n/** Finds the function node behind `export default`, following an identifier reference if needed. */\nconst findDefaultExportFunction = (ast: any): any => {\n const body = ast.program.body;\n\n const asFunction = (node: any): any =>\n node &&\n (node.type === 'ArrowFunctionExpression' ||\n node.type === 'FunctionExpression' ||\n node.type === 'FunctionDeclaration')\n ? node\n : null;\n\n for (const stmt of body) {\n if (stmt.type !== 'ExportDefaultDeclaration') continue;\n\n const direct = asFunction(stmt.declaration);\n if (direct) return direct;\n\n if (stmt.declaration?.type === 'Identifier') {\n const name = stmt.declaration.name;\n for (const candidate of body) {\n if (candidate.type === 'VariableDeclaration') {\n for (const declarator of candidate.declarations) {\n if (\n declarator.id?.type === 'Identifier' &&\n declarator.id.name === name\n ) {\n const fn = asFunction(declarator.init);\n if (fn) return fn;\n }\n }\n }\n if (\n candidate.type === 'FunctionDeclaration' &&\n candidate.id?.name === name\n ) {\n return candidate;\n }\n }\n }\n }\n\n return null;\n};\n\n/** Ensures `export { exportedName } from source`, skipping when already declared/re-exported. */\nconst ensureExportFrom = (\n ast: any,\n exportedName: string,\n source: string\n): void => {\n const body = ast.program.body;\n\n const alreadyPresent = body.some((stmt: any) => {\n if (\n stmt.type === 'ExportNamedDeclaration' &&\n stmt.source?.value === source\n ) {\n return stmt.specifiers.some(\n (spec: any) => spec.exported?.name === exportedName\n );\n }\n // Locally declared `export const/function generateStaticParams`\n if (stmt.type === 'ExportNamedDeclaration' && stmt.declaration) {\n const decl = stmt.declaration;\n if (decl.type === 'FunctionDeclaration' && decl.id?.name === exportedName)\n return true;\n if (decl.type === 'VariableDeclaration') {\n return decl.declarations.some(\n (d: any) => d.id?.type === 'Identifier' && d.id.name === exportedName\n );\n }\n }\n return false;\n });\n\n if (alreadyPresent) return;\n\n const exportNode = parseTsx(`export { ${exportedName} } from \"${source}\";`)\n .program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, exportNode);\n};\n\n/** Makes the function async and inserts `const locale = await getLocale();` once, at the top of its body. */\nconst ensureAwaitedLocale = (funcNode: any): void => {\n funcNode.async = true;\n\n if (funcNode.body.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const hasLocale = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some(\n (d: any) =>\n // const locale = ...\n (d.id?.type === 'Identifier' && d.id.name === 'locale') ||\n // const { locale } = ... or const { locale: locale } = ...\n (d.id?.type === 'ObjectPattern' &&\n d.id.properties?.some(\n (prop: any) =>\n prop.value?.type === 'Identifier' &&\n prop.value?.name === 'locale'\n ))\n )\n );\n\n if (!hasLocale) {\n const localeStatement = parseTsx('const locale = await getLocale();')\n .program.body[0];\n funcNode.body.body.unshift(localeStatement);\n }\n};\n\n/** Builds `<providerName locale={locale}>{child}</providerName>` around an existing JSX child node. */\nconst buildProviderElement = (providerName: string, childNode: any): any => {\n const template = parseTsx(\n `const __wrap = <${providerName} locale={locale}>{__child__}</${providerName}>;`\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [childNode];\n return providerElement;\n};\n\n/** Sets `lang={locale}` on the first `<html>` element, if present. */\nconst setHtmlLang = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n const langAttr = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === 'lang'\n ) as any;\n const localeExpression = b.jsxExpressionContainer(\n b.identifier('locale')\n );\n if (langAttr) {\n langAttr.value = localeExpression;\n } else {\n node.attributes.push(\n b.jsxAttribute(b.jsxIdentifier('lang'), localeExpression)\n );\n }\n return false;\n }\n this.traverse(path);\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a Next.js App Router **layout** with\n * `IntlayerClientProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails (returns the original code) for client components, when no\n * `{children}` placeholder is found, or when there is no default export.\n */\nexport const wrapLayoutWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerClientProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n path.replace(buildProviderElement('IntlayerClientProvider', path.node));\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerClientProvider', 'next-intlayer');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureExportFrom(ast, 'generateStaticParams', 'next-intlayer');\n ensureAwaitedLocale(funcNode);\n setHtmlLang(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n\n/** Returns the single top-level JSX return of a function, or the JSX of an expression-bodied arrow. */\nconst findSingleJsxReturn = (\n funcNode: any\n): { kind: 'return'; node: any } | { kind: 'arrow'; node: any } | null => {\n if (\n funcNode.type === 'ArrowFunctionExpression' &&\n funcNode.body.type !== 'BlockStatement'\n ) {\n const body =\n funcNode.body.type === 'JSXElement' ||\n funcNode.body.type === 'JSXFragment'\n ? funcNode.body\n : null;\n return body ? { kind: 'arrow', node: funcNode } : null;\n }\n\n if (funcNode.body.type !== 'BlockStatement') return null;\n\n // Collect every JSX-returning `return` inside this function, but do not\n // descend into nested function scopes (e.g. an inner component defined in the\n // same file). More than one top-level JSX return is ambiguous — bail.\n const jsxReturns: any[] = [];\n let functionDepth = 0;\n recast.visit(funcNode, {\n visitFunction(path) {\n functionDepth++;\n if (functionDepth === 1) {\n this.traverse(path);\n }\n functionDepth--;\n return false;\n },\n visitReturnStatement(path) {\n const argument = path.node.argument;\n if (argument?.type === 'JSXElement' || argument?.type === 'JSXFragment') {\n jsxReturns.push(path.node);\n }\n this.traverse(path);\n },\n });\n\n if (jsxReturns.length !== 1) return null;\n return { kind: 'return', node: jsxReturns[0] };\n};\n\n/**\n * Wraps the returned JSX of a Next.js App Router **page** with\n * `IntlayerServerProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails for client components, when the page has no single\n * top-level JSX return, or when there is no default export.\n */\nexport const wrapPageWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerServerProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n const jsxReturn = findSingleJsxReturn(funcNode);\n if (!jsxReturn) return { code, status: 'skipped' };\n\n if (jsxReturn.kind === 'return') {\n jsxReturn.node.argument = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.argument\n );\n } else {\n jsxReturn.node.body = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.body\n );\n }\n\n ensureNamedImport(ast, 'IntlayerServerProvider', 'next-intlayer/server');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureAwaitedLocale(funcNode);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- const require_utils_recastBabelParser = require('../../../utils/recastBabelParser.cjs');
3
+ const require_utils_babelParser = require('../../../utils/babelParser.cjs');
4
4
  const require_init_utils_astImports = require('../../utils/astImports.cjs');
5
5
  let recast = require("recast");
6
6
  recast = require_runtime.__toESM(recast);
@@ -8,7 +8,7 @@ recast = require_runtime.__toESM(recast);
8
8
  //#region src/init/frameworkSetup/tanstackStart/transforms.ts
9
9
  const { builders: b, namedTypes: n } = recast.types;
10
10
  /** babel-ts parser handles TypeScript *and* JSX. */
11
- const parseTsx = (code) => recast.parse(code, { parser: require_utils_recastBabelParser.babelTsParser });
11
+ const parseTsx = (code) => recast.parse(code, { parser: require_utils_babelParser.babelTsParser });
12
12
  /**
13
13
  * Finds the single function that returns the `<html>` document element. Returns
14
14
  * `null` when there is no such function, or more than one (ambiguous).
@@ -1 +1 @@
1
- {"version":3,"file":"transforms.cjs","names":["babelTsParser"],"sources":["../../../../../src/init/frameworkSetup/tanstackStart/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/recastBabelParser';\nimport { ensureNamedImport } from '../../utils/astImports';\n\nconst { builders: b, namedTypes: n } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX. */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped';\n};\n\n/**\n * Finds the single function that returns the `<html>` document element. Returns\n * `null` when there is no such function, or more than one (ambiguous).\n */\nconst findHtmlDocumentFunction = (ast: any): any => {\n const found = new Set<any>();\n\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n // Walk up to the nearest enclosing function node.\n let current = path.parentPath;\n while (current) {\n const value = current.value;\n if (\n value &&\n (n.FunctionDeclaration.check(value) ||\n n.FunctionExpression.check(value) ||\n n.ArrowFunctionExpression.check(value))\n ) {\n found.add(value);\n break;\n }\n current = current.parentPath;\n }\n }\n this.traverse(path);\n },\n });\n\n return found.size === 1 ? [...found][0] : null;\n};\n\n/**\n * Whether the binding pattern `node` introduces a variable named `name`.\n * Recurses through destructuring patterns so all of `const locale`,\n * `const { locale } = …`, `const { locale = fallback } = …`,\n * `const { foo: locale } = …`, `const [locale] = …` and `...locale` are\n * detected — not just a bare identifier.\n */\nconst patternBindsName = (node: any, name: string): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === name;\n case 'AssignmentPattern':\n // `locale = fallback`\n return patternBindsName(node.left, name);\n case 'RestElement':\n // `...locale`\n return patternBindsName(node.argument, name);\n case 'ArrayPattern':\n return node.elements.some((element: any) =>\n patternBindsName(element, name)\n );\n case 'ObjectPattern':\n return node.properties.some((property: any) =>\n property.type === 'RestElement'\n ? patternBindsName(property.argument, name)\n : // The *value* is the binding target (`{ foo: locale }` binds `locale`).\n patternBindsName(property.value, name)\n );\n default:\n return false;\n }\n};\n\n/**\n * Inserts `const locale = …` once, at the top of the function body. A single\n * self-contained statement is used (rather than an intermediate `params` const)\n * so it can never collide with a `params` variable the document already\n * declares. Expression-bodied arrow functions are first converted to a block so\n * the declaration has somewhere to live.\n *\n * No-ops when `locale` is already bound in the function — whether as a simple\n * identifier, through a destructuring pattern (e.g.\n * `const { locale = defaultLocale } = useLoaderData()`), or as a function\n * parameter — so the injected declaration never collides with one the document\n * already provides (which would produce an\n * `Identifier 'locale' has already been declared` parse error).\n */\nconst ensureLocaleFromParams = (funcNode: any): void => {\n if (funcNode.body?.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const declaredInBody = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some((d: any) => patternBindsName(d.id, 'locale'))\n );\n const declaredInParams = (funcNode.params ?? []).some((param: any) =>\n patternBindsName(param, 'locale')\n );\n if (declaredInBody || declaredInParams) return;\n\n const statement = parseTsx(\n 'const locale = useParams({ strict: false }).locale ?? defaultLocale;'\n ).program.body[0];\n funcNode.body.body.unshift(statement);\n};\n\n/** Sets `lang={locale}` and `dir={getHTMLTextDir(locale)}` on the first `<html>` element. */\nconst setHtmlLangAndDir = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type !== 'JSXIdentifier' || node.name.name !== 'html') {\n this.traverse(path);\n return;\n }\n\n const upsertAttribute = (name: string, value: any): void => {\n const existing = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === name\n ) as any;\n if (existing) {\n existing.value = value;\n } else {\n node.attributes.push(b.jsxAttribute(b.jsxIdentifier(name), value));\n }\n };\n\n upsertAttribute('lang', b.jsxExpressionContainer(b.identifier('locale')));\n upsertAttribute(\n 'dir',\n b.jsxExpressionContainer(\n b.callExpression(b.identifier('getHTMLTextDir'), [\n b.identifier('locale'),\n ])\n )\n );\n return false;\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a TanStack Start root document with\n * `IntlayerProvider`, deriving the locale from the `{-$locale}` route param.\n * Safe and idempotent: bails (returns the original code) when the provider is\n * already present, when no `<html>` document function is found, or when there is\n * no `{children}` placeholder to wrap.\n */\nexport const wrapRootWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (code.includes('IntlayerProvider')) return { code, status: 'already' };\n\n const funcNode = findHtmlDocumentFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n const template = parseTsx(\n 'const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;'\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [path.node];\n path.replace(providerElement);\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerProvider', 'react-intlayer');\n ensureNamedImport(ast, 'useParams', '@tanstack/react-router');\n ensureNamedImport(ast, 'defaultLocale', 'intlayer');\n ensureNamedImport(ast, 'getHTMLTextDir', 'intlayer');\n ensureLocaleFromParams(funcNode);\n setHtmlLangAndDir(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transforms.cjs","names":["babelTsParser"],"sources":["../../../../../src/init/frameworkSetup/tanstackStart/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/babelParser';\nimport { ensureNamedImport } from '../../utils/astImports';\n\nconst { builders: b, namedTypes: n } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX. */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped';\n};\n\n/**\n * Finds the single function that returns the `<html>` document element. Returns\n * `null` when there is no such function, or more than one (ambiguous).\n */\nconst findHtmlDocumentFunction = (ast: any): any => {\n const found = new Set<any>();\n\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n // Walk up to the nearest enclosing function node.\n let current = path.parentPath;\n while (current) {\n const value = current.value;\n if (\n value &&\n (n.FunctionDeclaration.check(value) ||\n n.FunctionExpression.check(value) ||\n n.ArrowFunctionExpression.check(value))\n ) {\n found.add(value);\n break;\n }\n current = current.parentPath;\n }\n }\n this.traverse(path);\n },\n });\n\n return found.size === 1 ? [...found][0] : null;\n};\n\n/**\n * Whether the binding pattern `node` introduces a variable named `name`.\n * Recurses through destructuring patterns so all of `const locale`,\n * `const { locale } = …`, `const { locale = fallback } = …`,\n * `const { foo: locale } = …`, `const [locale] = …` and `...locale` are\n * detected — not just a bare identifier.\n */\nconst patternBindsName = (node: any, name: string): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === name;\n case 'AssignmentPattern':\n // `locale = fallback`\n return patternBindsName(node.left, name);\n case 'RestElement':\n // `...locale`\n return patternBindsName(node.argument, name);\n case 'ArrayPattern':\n return node.elements.some((element: any) =>\n patternBindsName(element, name)\n );\n case 'ObjectPattern':\n return node.properties.some((property: any) =>\n property.type === 'RestElement'\n ? patternBindsName(property.argument, name)\n : // The *value* is the binding target (`{ foo: locale }` binds `locale`).\n patternBindsName(property.value, name)\n );\n default:\n return false;\n }\n};\n\n/**\n * Inserts `const locale = …` once, at the top of the function body. A single\n * self-contained statement is used (rather than an intermediate `params` const)\n * so it can never collide with a `params` variable the document already\n * declares. Expression-bodied arrow functions are first converted to a block so\n * the declaration has somewhere to live.\n *\n * No-ops when `locale` is already bound in the function — whether as a simple\n * identifier, through a destructuring pattern (e.g.\n * `const { locale = defaultLocale } = useLoaderData()`), or as a function\n * parameter — so the injected declaration never collides with one the document\n * already provides (which would produce an\n * `Identifier 'locale' has already been declared` parse error).\n */\nconst ensureLocaleFromParams = (funcNode: any): void => {\n if (funcNode.body?.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const declaredInBody = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some((d: any) => patternBindsName(d.id, 'locale'))\n );\n const declaredInParams = (funcNode.params ?? []).some((param: any) =>\n patternBindsName(param, 'locale')\n );\n if (declaredInBody || declaredInParams) return;\n\n const statement = parseTsx(\n 'const locale = useParams({ strict: false }).locale ?? defaultLocale;'\n ).program.body[0];\n funcNode.body.body.unshift(statement);\n};\n\n/** Sets `lang={locale}` and `dir={getHTMLTextDir(locale)}` on the first `<html>` element. */\nconst setHtmlLangAndDir = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type !== 'JSXIdentifier' || node.name.name !== 'html') {\n this.traverse(path);\n return;\n }\n\n const upsertAttribute = (name: string, value: any): void => {\n const existing = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === name\n ) as any;\n if (existing) {\n existing.value = value;\n } else {\n node.attributes.push(b.jsxAttribute(b.jsxIdentifier(name), value));\n }\n };\n\n upsertAttribute('lang', b.jsxExpressionContainer(b.identifier('locale')));\n upsertAttribute(\n 'dir',\n b.jsxExpressionContainer(\n b.callExpression(b.identifier('getHTMLTextDir'), [\n b.identifier('locale'),\n ])\n )\n );\n return false;\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a TanStack Start root document with\n * `IntlayerProvider`, deriving the locale from the `{-$locale}` route param.\n * Safe and idempotent: bails (returns the original code) when the provider is\n * already present, when no `<html>` document function is found, or when there is\n * no `{children}` placeholder to wrap.\n */\nexport const wrapRootWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (code.includes('IntlayerProvider')) return { code, status: 'already' };\n\n const funcNode = findHtmlDocumentFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n const template = parseTsx(\n 'const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;'\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [path.node];\n path.replace(providerElement);\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerProvider', 'react-intlayer');\n ensureNamedImport(ast, 'useParams', '@tanstack/react-router');\n ensureNamedImport(ast, 'defaultLocale', 'intlayer');\n ensureNamedImport(ast, 'getHTMLTextDir', 'intlayer');\n ensureLocaleFromParams(funcNode);\n setHtmlLangAndDir(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
3
- const require_utils_recastBabelParser = require('../../utils/recastBabelParser.cjs');
3
+ const require_utils_babelParser = require('../../utils/babelParser.cjs');
4
4
  const require_init_utils_astImports = require('./astImports.cjs');
5
5
  let recast = require("recast");
6
6
  recast = require_runtime.__toESM(recast);
@@ -61,7 +61,7 @@ const addEnvReferenceProperty = (objExpr, key, envVar) => {
61
61
  */
62
62
  const setIntlayerConfigRoutingMode = (content, extension, mode) => {
63
63
  if (extension === "json") return content.replace(/("mode"\s*:\s*)"(?:prefix-no-default|prefix-all|no-prefix|search-params)"/, `$1"${mode}"`);
64
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
64
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
65
65
  genericRecastVisit(ast, (objExpr) => {
66
66
  if (!isObjectExpression(objExpr)) return;
67
67
  const routingProperty = ensureObjectProperty(objExpr, "routing", b.objectExpression([]));
@@ -87,7 +87,7 @@ const setIntlayerConfigCompilerOutput = (content, extension, outputTemplate) =>
87
87
  };
88
88
  return JSON.stringify(parsed, null, 2);
89
89
  }
90
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
90
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
91
91
  genericRecastVisit(ast, (objExpr) => {
92
92
  if (!isObjectExpression(objExpr)) return;
93
93
  const compilerProperty = ensureObjectProperty(objExpr, "compiler", b.objectExpression([]));
@@ -105,7 +105,7 @@ const setIntlayerConfigCompilerOutput = (content, extension, outputTemplate) =>
105
105
  * (JSON cannot reference `process.env`).
106
106
  */
107
107
  const enableIntlayerEditorConfig = (content) => {
108
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
108
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
109
109
  genericRecastVisit(ast, (objExpr) => {
110
110
  if (!isObjectExpression(objExpr)) return;
111
111
  const editorProperty = ensureObjectProperty(objExpr, "editor", b.objectExpression([]));
@@ -189,21 +189,21 @@ const genericRecastVisit = (ast, updateConfigObject, callNames = ["defineConfig"
189
189
  */
190
190
  const hasIntlayerVitePlugin = (content) => content.includes("vite-intlayer") || /@intlayer\/[^'"]+\/plugin/.test(content);
191
191
  const updateViteConfig = (content, extension) => {
192
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
192
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
193
193
  const isCJSFile = extension === "cjs" || content.includes("module.exports") && !content.includes("import ");
194
194
  injectImport(ast, isCJSFile, "intlayer", "vite-intlayer");
195
195
  genericRecastVisit(ast, (obj) => updatePluginArray(obj, "plugins", "intlayer"));
196
196
  return recast.print(ast).code;
197
197
  };
198
198
  const updateAstroConfig = (content, extension) => {
199
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
199
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
200
200
  const isCJSFile = extension === "cjs" || content.includes("module.exports") && !content.includes("import ");
201
201
  injectImport(ast, isCJSFile, "intlayer", "astro-intlayer");
202
202
  genericRecastVisit(ast, (obj) => updatePluginArray(obj, "integrations", "intlayer"));
203
203
  return recast.print(ast).code;
204
204
  };
205
205
  const updateNextConfig = (content, extension) => {
206
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
206
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
207
207
  const isCJSFile = extension === "cjs" || content.includes("module.exports");
208
208
  injectImport(ast, isCJSFile, "withIntlayer", "next-intlayer/server");
209
209
  recast.visit(ast, {
@@ -240,7 +240,7 @@ const isImmediatelyInvokedFunction = (node) => n.CallExpression.check(node) && (
240
240
  */
241
241
  const updateMetroConfig = (content, extension) => {
242
242
  if (content.includes("react-native-intlayer")) return content;
243
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
243
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
244
244
  const isCJSFile = extension === "cjs" || content.includes("module.exports") && !content.includes("import ");
245
245
  const wrapperName = "configMetroIntlayerSync";
246
246
  const isWrappable = (node) => n.Expression.check(node) && !isImmediatelyInvokedFunction(node) && !(n.CallExpression.check(node) && n.Identifier.check(node.callee) && node.callee.name === wrapperName);
@@ -285,7 +285,7 @@ module.exports = (async () => {
285
285
  `;
286
286
  };
287
287
  const updateNuxtConfig = (content) => {
288
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
288
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
289
289
  const updateConfigObject = (objExpr) => {
290
290
  if (!objExpr || objExpr.type !== "ObjectExpression" && !n.ObjectExpression.check(objExpr)) return;
291
291
  let modulesProp = objExpr.properties.find((p) => {
@@ -312,7 +312,7 @@ const updateNuxtConfig = (content) => {
312
312
  * `@intlayer/vue-i18n/plugin` into the plugins array.
313
313
  */
314
314
  const updateViteConfigForVueI18n = (content, extension) => {
315
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
315
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
316
316
  const isCJSFile = extension === "cjs" || content.includes("module.exports") && !content.includes("import ");
317
317
  injectImport(ast, isCJSFile, "vueI18nVitePlugin", "@intlayer/vue-i18n/plugin");
318
318
  genericRecastVisit(ast, (obj) => updatePluginArray(obj, "plugins", "vueI18nVitePlugin"));
@@ -324,7 +324,7 @@ const updateViteConfigForVueI18n = (content, extension) => {
324
324
  * call to the `plugins` array.
325
325
  */
326
326
  const updateViteConfigForCompatPlugin = (content, extension, pluginConfig) => {
327
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
327
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
328
328
  const isCJSFile = extension === "cjs" || content.includes("module.exports") && !content.includes("import ");
329
329
  injectImport(ast, isCJSFile, pluginConfig.pluginFunctionName, pluginConfig.pluginPackageSource);
330
330
  genericRecastVisit(ast, (obj) => updatePluginArray(obj, "plugins", pluginConfig.pluginFunctionName));
@@ -340,7 +340,7 @@ const updateViteConfigForCompatPlugin = (content, extension, pluginConfig) => {
340
340
  * is found.
341
341
  */
342
342
  const replaceViteConfigPluginImportSource = (content, importName, fromPackageSource, toPackageSource) => {
343
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
343
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
344
344
  let changed = false;
345
345
  recast.visit(ast, { visitImportDeclaration(path) {
346
346
  const { source, specifiers } = path.node;
@@ -359,7 +359,7 @@ const replaceViteConfigPluginImportSource = (content, importName, fromPackageSou
359
359
  * wraps the default export / `module.exports` with a HOC call.
360
360
  */
361
361
  const wrapNextConfigWithHoc = (content, extension, hocFunctionName, pluginPackageSource) => {
362
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
362
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
363
363
  const isCJSFile = extension === "cjs" || content.includes("module.exports");
364
364
  injectImport(ast, isCJSFile, hocFunctionName, pluginPackageSource);
365
365
  recast.visit(ast, {
@@ -386,7 +386,7 @@ const updateNextConfigForNextTranslate = (content, extension) => wrapNextConfigW
386
386
  * to the `modules` array.
387
387
  */
388
388
  const updateNuxtConfigForNuxtjsI18n = (content) => {
389
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
389
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
390
390
  const updateConfigObject = (objExpr) => {
391
391
  if (!objExpr || objExpr.type !== "ObjectExpression" && !n.ObjectExpression.check(objExpr)) return;
392
392
  let modulesProp = objExpr.properties.find((p) => {
@@ -420,7 +420,7 @@ const updateNextConfigForNextI18next = (content, extension) => wrapNextConfigWit
420
420
  * import is present.
421
421
  */
422
422
  const updateNextConfigForNextIntl = (content, extension) => {
423
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
423
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
424
424
  const isCJSFile = extension === "cjs" || content.includes("module.exports");
425
425
  let replacedExistingSource = false;
426
426
  recast.visit(ast, { visitImportDeclaration(path) {
@@ -482,7 +482,7 @@ const buildSyncCallNode = (syncConfig) => {
482
482
  const { functionName } = getSyncPluginInfo(syncConfig);
483
483
  const sourceProperty = `source: (${!syncConfig.sourceTemplate.includes("${key}") ? "{ locale }" : syncConfig.format === "icu" || syncConfig.plugin === "po" ? "{ key, locale }" : "{ locale, key }"}) => \`${syncConfig.sourceTemplate}\``;
484
484
  const parseSnippet = (snippet) => {
485
- return recast.parse(snippet, { parser: require_utils_recastBabelParser.typescriptParser }).program.body[0].expression;
485
+ return recast.parse(snippet, { parser: require_utils_babelParser.typescriptParser }).program.body[0].expression;
486
486
  };
487
487
  if (syncConfig.plugin === "po") return parseSnippet(`${functionName}({ ${sourceProperty} })`);
488
488
  const splitKeys = Boolean(syncConfig.splitKeys);
@@ -533,7 +533,7 @@ const injectDictionaryFormat = (objExpr, format) => {
533
533
  * config file. Idempotent: skips when the plugin call is already present.
534
534
  */
535
535
  const updateIntlayerConfigWithSyncPlugin = (content, extension, syncConfig) => {
536
- const ast = recast.parse(content, { parser: require_utils_recastBabelParser.typescriptParser });
536
+ const ast = recast.parse(content, { parser: require_utils_babelParser.typescriptParser });
537
537
  const isCJSFile = extension === "cjs" || content.includes("module.exports");
538
538
  const { functionName, packageSource } = getSyncPluginInfo(syncConfig);
539
539
  injectImport(ast, isCJSFile, functionName, packageSource);