@intlayer/babel 9.4.4 → 9.5.1

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 (93) hide show
  1. package/README.md +0 -2
  2. package/dist/cjs/analyzeContentUsage.cjs +301 -0
  3. package/dist/cjs/analyzeContentUsage.cjs.map +1 -0
  4. package/dist/cjs/babel-plugin-intlayer-field-rename.cjs +5 -4
  5. package/dist/cjs/babel-plugin-intlayer-field-rename.cjs.map +1 -1
  6. package/dist/cjs/babel-plugin-intlayer-optimize.cjs +171 -282
  7. package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
  8. package/dist/cjs/babel-plugin-intlayer-purge.cjs +4 -3
  9. package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
  10. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +49 -699
  11. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
  12. package/dist/cjs/compat/namespaceResolution.cjs +124 -0
  13. package/dist/cjs/compat/namespaceResolution.cjs.map +1 -0
  14. package/dist/cjs/compat/optimizePass.cjs +144 -0
  15. package/dist/cjs/compat/optimizePass.cjs.map +1 -0
  16. package/dist/cjs/compat/usageAnalysis.cjs +195 -0
  17. package/dist/cjs/compat/usageAnalysis.cjs.map +1 -0
  18. package/dist/cjs/dictionaryImports.cjs +40 -0
  19. package/dist/cjs/dictionaryImports.cjs.map +1 -0
  20. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +1 -1
  21. package/dist/cjs/getExtractPluginOptions.cjs +1 -1
  22. package/dist/cjs/getOptimizePluginOptions.cjs +2 -6
  23. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  24. package/dist/cjs/getPurgePluginOptions.cjs +1 -1
  25. package/dist/cjs/index.cjs +9 -5
  26. package/dist/cjs/nativeCallers.cjs +41 -0
  27. package/dist/cjs/nativeCallers.cjs.map +1 -0
  28. package/dist/cjs/pruneContext.cjs +79 -0
  29. package/dist/cjs/pruneContext.cjs.map +1 -0
  30. package/dist/cjs/staticAstReaders.cjs +140 -0
  31. package/dist/cjs/staticAstReaders.cjs.map +1 -0
  32. package/dist/cjs/transformers.cjs +2 -1
  33. package/dist/cjs/transformers.cjs.map +1 -1
  34. package/dist/esm/analyzeContentUsage.mjs +300 -0
  35. package/dist/esm/analyzeContentUsage.mjs.map +1 -0
  36. package/dist/esm/babel-plugin-intlayer-field-rename.mjs +3 -2
  37. package/dist/esm/babel-plugin-intlayer-field-rename.mjs.map +1 -1
  38. package/dist/esm/babel-plugin-intlayer-optimize.mjs +171 -282
  39. package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
  40. package/dist/esm/babel-plugin-intlayer-purge.mjs +3 -2
  41. package/dist/esm/babel-plugin-intlayer-purge.mjs.map +1 -1
  42. package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs +43 -694
  43. package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs.map +1 -1
  44. package/dist/esm/compat/namespaceResolution.mjs +120 -0
  45. package/dist/esm/compat/namespaceResolution.mjs.map +1 -0
  46. package/dist/esm/compat/optimizePass.mjs +143 -0
  47. package/dist/esm/compat/optimizePass.mjs.map +1 -0
  48. package/dist/esm/compat/usageAnalysis.mjs +193 -0
  49. package/dist/esm/compat/usageAnalysis.mjs.map +1 -0
  50. package/dist/esm/dictionaryImports.mjs +38 -0
  51. package/dist/esm/dictionaryImports.mjs.map +1 -0
  52. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +1 -1
  53. package/dist/esm/getExtractPluginOptions.mjs +1 -1
  54. package/dist/esm/getOptimizePluginOptions.mjs +2 -6
  55. package/dist/esm/getOptimizePluginOptions.mjs.map +1 -1
  56. package/dist/esm/getPurgePluginOptions.mjs +1 -1
  57. package/dist/esm/index.mjs +5 -2
  58. package/dist/esm/nativeCallers.mjs +38 -0
  59. package/dist/esm/nativeCallers.mjs.map +1 -0
  60. package/dist/esm/pruneContext.mjs +76 -0
  61. package/dist/esm/pruneContext.mjs.map +1 -0
  62. package/dist/esm/staticAstReaders.mjs +129 -0
  63. package/dist/esm/staticAstReaders.mjs.map +1 -0
  64. package/dist/esm/transformers.mjs +2 -1
  65. package/dist/esm/transformers.mjs.map +1 -1
  66. package/dist/types/analyzeContentUsage.d.ts +18 -0
  67. package/dist/types/analyzeContentUsage.d.ts.map +1 -0
  68. package/dist/types/babel-plugin-intlayer-field-rename.d.ts +2 -1
  69. package/dist/types/babel-plugin-intlayer-field-rename.d.ts.map +1 -1
  70. package/dist/types/babel-plugin-intlayer-optimize.d.ts +9 -15
  71. package/dist/types/babel-plugin-intlayer-optimize.d.ts.map +1 -1
  72. package/dist/types/babel-plugin-intlayer-purge.d.ts +3 -2
  73. package/dist/types/babel-plugin-intlayer-purge.d.ts.map +1 -1
  74. package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +20 -187
  75. package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts.map +1 -1
  76. package/dist/types/compat/namespaceResolution.d.ts +66 -0
  77. package/dist/types/compat/namespaceResolution.d.ts.map +1 -0
  78. package/dist/types/compat/optimizePass.d.ts +58 -0
  79. package/dist/types/compat/optimizePass.d.ts.map +1 -0
  80. package/dist/types/compat/usageAnalysis.d.ts +75 -0
  81. package/dist/types/compat/usageAnalysis.d.ts.map +1 -0
  82. package/dist/types/dictionaryImports.d.ts +46 -0
  83. package/dist/types/dictionaryImports.d.ts.map +1 -0
  84. package/dist/types/index.d.ts +5 -2
  85. package/dist/types/nativeCallers.d.ts +33 -0
  86. package/dist/types/nativeCallers.d.ts.map +1 -0
  87. package/dist/types/pruneContext.d.ts +152 -0
  88. package/dist/types/pruneContext.d.ts.map +1 -0
  89. package/dist/types/staticAstReaders.d.ts +84 -0
  90. package/dist/types/staticAstReaders.d.ts.map +1 -0
  91. package/dist/types/transformers.d.ts +2 -1
  92. package/dist/types/transformers.d.ts.map +1 -1
  93. package/package.json +10 -10
@@ -0,0 +1,58 @@
1
+ import { DictionaryImportRegistry, ImportMode } from "../dictionaryImports.js";
2
+ import * as BabelTypes from "@babel/types";
3
+ import { CallerDescriptor } from "@intlayer/config/callers";
4
+ //#region src/compat/optimizePass.d.ts
5
+ /**
6
+ * Compat half of the optimize pass.
7
+ *
8
+ * Every adapter-specific behaviour of the build-time rewrite lives here:
9
+ * matching a compat caller's import, resolving its namespace, and re-pointing
10
+ * the import specifier at the dictionary-accepting helper.
11
+ *
12
+ * The pass works on plain AST nodes rather than `NodePath`s: the optimize
13
+ * plugin collects the call sites in its single traversal and hands them over,
14
+ * so nothing here walks the tree.
15
+ *
16
+ * It is created only when compat descriptors were injected by a compat
17
+ * package's bundler plugin, so a plain intlayer build never allocates it —
18
+ * {@link createCompatOptimizePass} returns `null` for an empty registry.
19
+ */
20
+ export type CompatOptimizePass = {
21
+ /**
22
+ * Whether `importSource` exports at least one rewritable compat caller, so
23
+ * the optimize plugin knows the import is worth inspecting even though it is
24
+ * not a native intlayer package.
25
+ */
26
+ ownsImportSource: (importSource: string) => boolean;
27
+ /** Records the local alias one import specifier introduces. */
28
+ noteImport: (importSource: string, importedName: string, localName: string) => void;
29
+ /** Whether `localName` was bound to a compat caller by an import. */
30
+ ownsLocalName: (localName: string) => boolean;
31
+ /** Whether the file imported any compat caller at all. */
32
+ hasCallers: () => boolean;
33
+ /**
34
+ * Resolves the namespace of every collected call, dropping the callers that
35
+ * cannot be rewritten and deciding the file-level helper family. Must run
36
+ * after every import was noted and before any rewrite.
37
+ */
38
+ analyzeCalls: (callNodes: readonly BabelTypes.CallExpression[]) => void;
39
+ /** Rewrites one compat call site, if its caller survived {@link analyzeCalls}. */
40
+ rewriteCall: (callNode: BabelTypes.CallExpression) => void;
41
+ /** Re-points the compat specifiers of one import declaration. */
42
+ rewriteImportSpecifiers: (importNode: BabelTypes.ImportDeclaration) => void;
43
+ };
44
+ /**
45
+ * Builds the compat optimize pass for one source file, or `null` when no
46
+ * compat caller was injected.
47
+ *
48
+ * @param babelTypes - Babel's type helpers.
49
+ * @param compatCallers - Descriptors injected by the compat packages' plugins.
50
+ * @param imports - Shared dictionary-import registry for the file.
51
+ * @param buildModes - The file's global import mode and per-dictionary overrides.
52
+ */
53
+ export declare const createCompatOptimizePass: (babelTypes: typeof BabelTypes, compatCallers: readonly CallerDescriptor[], imports: DictionaryImportRegistry, buildModes: {
54
+ importMode: ImportMode | undefined;
55
+ dictionaryModeMap?: Record<string, ImportMode | undefined>;
56
+ }) => CompatOptimizePass | null;
57
+ //#endregion
58
+ //# sourceMappingURL=optimizePass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimizePass.d.ts","names":[],"sources":["../../../src/compat/optimizePass.ts"],"mappings":";;;;;;;;;;;;;;;;;;;YA2BY;;;;;;EAMV,mBAAmB;;EAEnB,aACE,sBACA,sBACA;;EAGF,gBAAgB;;EAEhB;;;;;;EAMA,eAAe,oBAAoB,WAAW;;EAE9C,cAAc,UAAU,WAAW;;EAEnC,0BAA0B,YAAY,WAAW;;;;;;;;;;;qBA4EtC,2BAAwB,mBAChB,YAAU,wBACL,oBAAkB,SACjC,0BAAwB;EAE/B,YAAY;EACZ,oBAAoB,eAAe;MAEpC"}
@@ -0,0 +1,75 @@
1
+ import { PruneContext } from "../pruneContext.js";
2
+ import { NodePath } from "@babel/core";
3
+ import * as BabelTypes from "@babel/types";
4
+ import { CallerDescriptor } from "@intlayer/config/callers";
5
+ //#region src/compat/usageAnalysis.d.ts
6
+ /**
7
+ * Analyses how the translation function produced by a compat namespace caller
8
+ * (`useTranslation`, `useTranslations`, `getTranslations`, `getFixedT`,
9
+ * `useI18n`) is consumed, then records the accessed top-level dictionary fields
10
+ * into `pruneContext`.
11
+ *
12
+ * Dictionaries consumed this way are always added to
13
+ * `dictionariesSkippingFieldRename`: the field accesses are string-literal
14
+ * dot-paths inside `t()` calls, which the field-rename plugin cannot rewrite,
15
+ * so renaming the compiled JSON keys would break runtime lookups. Pruning
16
+ * (top-level field removal) remains safe because it preserves field names.
17
+ */
18
+ export declare const analyzeNamespaceCallerUsage: (babelTypes: typeof BabelTypes, pruneContext: PruneContext, callArguments: BabelTypes.CallExpression['arguments'], callerConfig: CallerDescriptor, isSfcFile: boolean,
19
+ /** Absolute path of the analysed file (for untracked-binding reporting). */
20
+ currentSourceFilePath: string,
21
+ /**
22
+ * The call-expression path, when the caller was matched as a call. Omitted
23
+ * for JSX-element matches (`<FormattedMessage id>`), where only the static
24
+ * `'self'` / `'all'` analysis paths apply — the binding-based
25
+ * `'destructured-t'` / `'return-value'` paths require a call site.
26
+ */
27
+ callExpressionPath?: NodePath<BabelTypes.CallExpression>,
28
+ /**
29
+ * Pre-resolved namespace bypassing `namespaceSources`, e.g. the `ns`
30
+ * attribute of react-i18next's `<Trans ns="home" i18nKey="title" />`.
31
+ */
32
+ namespaceOverride?: string) => void;
33
+ /**
34
+ * Compat half of the usage analyser, kept behind one object so the native
35
+ * plugin body contains no adapter-specific branching.
36
+ *
37
+ * The analyser is created only when compat callers were injected, so a plain
38
+ * intlayer build never allocates it and never pays for its lookups —
39
+ * {@link createCompatUsageAnalyzer} returns `null` for an empty registry.
40
+ */
41
+ export type CompatUsageAnalyzer = {
42
+ /**
43
+ * Records the local aliases one import declaration introduces. Called for
44
+ * every import of the file, before any call site is inspected.
45
+ */
46
+ noteImport: (importSource: string, importedName: string, localName: string) => void;
47
+ /**
48
+ * Whether any compat caller can match in this file — either an imported
49
+ * alias was recorded, or a method-matched caller is active. Checked after
50
+ * every import was noted, so the plugin can skip the call traversal.
51
+ */
52
+ hasMatchableCallers: () => boolean;
53
+ /**
54
+ * Analyses one call site. Returns `true` when the call belonged to a compat
55
+ * caller and was handled, `false` when the native path should look at it.
56
+ */
57
+ analyzeCall: (callExpressionPath: NodePath<BabelTypes.CallExpression>, localCallerName: string, isMethodCall: boolean) => boolean;
58
+ /** Analyses one JSX element, e.g. `<Trans i18nKey="…" />`. */
59
+ analyzeJsxElement: (jsxOpeningElementPath: NodePath<BabelTypes.JSXOpeningElement>) => void;
60
+ };
61
+ /**
62
+ * Builds the compat analyser for one source file, or `null` when no compat
63
+ * caller was injected — the base intlayer pipeline then runs untouched.
64
+ *
65
+ * @param babelTypes - Babel's type helpers.
66
+ * @param pruneContext - Shared analysis state to write into.
67
+ * @param compatCallers - Descriptors injected by the compat packages' plugins.
68
+ * @param fileContext - Path of the analysed file and whether it is an SFC.
69
+ */
70
+ export declare const createCompatUsageAnalyzer: (babelTypes: typeof BabelTypes, pruneContext: PruneContext, compatCallers: readonly CallerDescriptor[], fileContext: {
71
+ sourceFilePath: string;
72
+ isSfcFile: boolean;
73
+ }) => CompatUsageAnalyzer | null;
74
+ //#endregion
75
+ //# sourceMappingURL=usageAnalysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usageAnalysis.d.ts","names":[],"sources":["../../../src/compat/usageAnalysis.ts"],"mappings":";;;;;;;;;;;;;;;;;qBAgCa,8BAA2B,mBACnB,YAAU,cACf,cAAY,eACX,WAAW,6BAA2B,cACvC,kBAAgB,oBAGP;;AAAA,+BAOF;;;;;;;AAAA,qBAAA,SAAS,WAAW,iBAKrB;;;;;AAAA;;;;;;;;;YAgRV;;;;;EAKV,aACE,sBACA,sBACA;;;;;;EAOF;;;;;EAKA,cACE,oBAAoB,SAAS,WAAW,iBACxC,yBACA;;EAGF,oBACE,uBAAuB,SAAS,WAAW;;;;;;;;;;;qBAalC,4BAAyB,mBACjB,YAAU,cACf,cAAY,wBACF,oBAAkB;EAC3B;EAAwB;MACtC"}
@@ -0,0 +1,46 @@
1
+ import * as BabelTypes from "@babel/types";
2
+ //#region src/dictionaryImports.d.ts
3
+ /**
4
+ * How a dictionary reaches a call site.
5
+ *
6
+ * - `static` — the compiled JSON is imported directly.
7
+ * - `dynamic` — a generated per-locale loader is imported and resolved at
8
+ * runtime (Suspense).
9
+ * - `fetch` — same as `dynamic`, but the loader fetches remote content.
10
+ */
11
+ export type ImportMode = 'static' | 'dynamic' | 'fetch';
12
+ /**
13
+ * Builds the generated identifier for a dictionary key.
14
+ *
15
+ * Replicates the xxHash64 → Base-62 algorithm used by the SWC version and
16
+ * prefixes an underscore so the generated identifiers never collide with
17
+ * user-defined ones.
18
+ */
19
+ export declare const makeDictionaryIdent: (babelTypes: typeof BabelTypes, key: string, mode: ImportMode) => BabelTypes.Identifier;
20
+ /**
21
+ * The dictionary imports one file needs, accumulated while its call sites are
22
+ * rewritten and injected in one pass at the end.
23
+ *
24
+ * Both the native and the compat rewrites write here, so a dictionary read
25
+ * through `useIntlayer('about')` and through `useTranslation('about')` in the
26
+ * same file shares a single import.
27
+ *
28
+ * `dynamic` and `fetch` share one map because they occupy the same import
29
+ * slot, distinguished only by their identifier suffix — mirroring
30
+ * `InjectedImports` in the SWC plugin.
31
+ */
32
+ export type DictionaryImportRegistry = {
33
+ /** Dictionary key → identifier of the static JSON (or nested companion) import. */
34
+ readonly staticImports: Map<string, BabelTypes.Identifier>;
35
+ /** Dictionary key → identifier of the dynamic / fetch loader import. */
36
+ readonly dynamicImports: Map<string, BabelTypes.Identifier>;
37
+ /**
38
+ * Returns the identifier for `key` in `mode`, creating and registering it on
39
+ * first use.
40
+ */
41
+ identFor: (key: string, mode: ImportMode) => BabelTypes.Identifier;
42
+ };
43
+ /** Creates an empty registry for one source file. */
44
+ export declare const createDictionaryImportRegistry: (babelTypes: typeof BabelTypes) => DictionaryImportRegistry;
45
+ //#endregion
46
+ //# sourceMappingURL=dictionaryImports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionaryImports.d.ts","names":[],"sources":["../../src/dictionaryImports.ts"],"mappings":";;;;;;;;;;YAWY;;;;;;;;qBAgBC,sBAAmB,mBACX,YAAU,aAClB,MACL,eACL,WAAW;;;;;;;;;;;;;YAeF;;WAED,eAAe,YAAY,WAAW;;WAEtC,gBAAgB,YAAY,WAAW;;;;;EAKhD,WAAW,aAAa,MAAM,eAAe,WAAW;;;qBAI7C,iCAA8B,mBACtB,eAClB"}
@@ -1,6 +1,9 @@
1
+ import { DictionaryFieldUsage, NestedRenameEntry, NestedRenameMap, OpaqueFieldOccurrence, PruneContext, createPruneContext, preserveNestedDictionaryFields } from "./pruneContext.js";
1
2
  import { PackageName, SERVER_CAPABLE_PACKAGES, packageList } from "./extractContent/utils/constants.js";
2
3
  import { ExtractPluginOptions, ExtractResult, intlayerExtractBabelPlugin } from "./babel-plugin-intlayer-extract.js";
3
- import { CHAINABLE_RUNTIME_METHOD_NAMES, CallerDescriptor, CallerResultShape, CallerValueSource, CompatCallerConfig, DEFAULT_COMPAT_CALLERS, DictionaryFieldUsage, INTLAYER_CALLER_NAMES, IntlayerCallerName, NestedRenameEntry, NestedRenameMap, OpaqueFieldOccurrence, PruneContext, createPruneContext, makeUsageAnalyzerBabelPlugin, preserveNestedDictionaryFields, unwrapAwait } from "./babel-plugin-intlayer-usage-analyzer.js";
4
+ import { CHAINABLE_RUNTIME_METHOD_NAMES, INTLAYER_CALLER_NAMES, IntlayerCallerName, NATIVE_CALLER_NAME_SET } from "./nativeCallers.js";
5
+ import { unwrapAwait } from "./staticAstReaders.js";
6
+ import { CallerDescriptor, CallerResultShape, CallerValueSource, CompatCallerConfig, DEFAULT_COMPAT_CALLERS, makeUsageAnalyzerBabelPlugin } from "./babel-plugin-intlayer-usage-analyzer.js";
4
7
  import { SerializedFieldRenameEntry, SerializedFieldRenameMap, buildNestedRenameMapFromContent, generateShortFieldName, getNestedRenameEntryAtPath, makeFieldRenameBabelPlugin, renameIntlayerFieldAccesses, serializeFieldRenameMap } from "./babel-plugin-intlayer-field-rename.js";
5
8
  import { MinifyPluginOptions, intlayerMinifyBabelPlugin } from "./babel-plugin-intlayer-minify.js";
6
9
  import { OptimizePluginOptions, intlayerOptimizeBabelPlugin } from "./babel-plugin-intlayer-optimize.js";
@@ -18,4 +21,4 @@ import { CompilerMode, getExtractPluginOptions } from "./getExtractPluginOptions
18
21
  import { getOptimizePluginOptions } from "./getOptimizePluginOptions.js";
19
22
  import { getMinifyPluginOptions, getPurgePluginOptions } from "./getPurgePluginOptions.js";
20
23
  import { BABEL_PARSER_OPTIONS, INTLAYER_USAGE_REGEX, SOURCE_FILE_REGEX, analyzeFieldUsageInFile, buildUsageCheckRegex, getUsageCheckRegex, optimizeSourceFile, renameFieldsInCode, renameFieldsInSourceFile } from "./transformers.js";
21
- export { BABEL_PARSER_OPTIONS, CHAINABLE_RUNTIME_METHOD_NAMES, type CallerDescriptor, type CallerResultShape, type CallerValueSource, CompatCallerConfig, CompilerMode, DEFAULT_COMPAT_CALLERS, DictionaryFieldUsage, ExtractDictionaryInfoOptions, ExtractIntlayerOptions, ExtractPluginOptions, ExtractResult, INTLAYER_CALLER_NAMES, INTLAYER_USAGE_REGEX, IntlayerCallerName, MinifyPluginOptions, NestedRenameEntry, NestedRenameMap, OpaqueFieldOccurrence, OptimizePluginOptions, PackageName, PruneContext, PurgePluginOptions, ResolveContentFilePaths, SERVER_CAPABLE_PACKAGES, SOURCE_FILE_REGEX, ScriptBlock, SerializedFieldRenameEntry, SerializedFieldRenameMap, analyzeFieldUsageInFile, buildNestedRenameMapFromContent, buildUsageCheckRegex, createPruneContext, detectPackageName, extractContent, extractContentSync, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, extractScriptBlocks, generateKey, generateShortFieldName, getComponentName, getExtractPluginOptions, getMinifyPluginOptions, getNestedRenameEntryAtPath, getOptimizePluginOptions, getOutput, getPurgePluginOptions, getSharedPruneContext, getUsageCheckRegex, injectScriptBlocks, intlayerExtractBabelPlugin, intlayerMinifyBabelPlugin, intlayerOptimizeBabelPlugin, intlayerPurgeBabelPlugin, makeFieldRenameBabelPlugin, makeUsageAnalyzerBabelPlugin, mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, optimizeSourceFile, packageList, preserveNestedDictionaryFields, renameFieldsInCode, renameFieldsInSourceFile, renameIntlayerFieldAccesses, resolveContentFilePaths, runIntlayerPurgePipeline, serializeFieldRenameMap, unwrapAwait, writeContentHelper };
24
+ export { BABEL_PARSER_OPTIONS, CHAINABLE_RUNTIME_METHOD_NAMES, type CallerDescriptor, type CallerResultShape, type CallerValueSource, CompatCallerConfig, CompilerMode, DEFAULT_COMPAT_CALLERS, type DictionaryFieldUsage, ExtractDictionaryInfoOptions, ExtractIntlayerOptions, ExtractPluginOptions, ExtractResult, INTLAYER_CALLER_NAMES, INTLAYER_USAGE_REGEX, type IntlayerCallerName, MinifyPluginOptions, NATIVE_CALLER_NAME_SET, type NestedRenameEntry, type NestedRenameMap, type OpaqueFieldOccurrence, OptimizePluginOptions, PackageName, type PruneContext, PurgePluginOptions, ResolveContentFilePaths, SERVER_CAPABLE_PACKAGES, SOURCE_FILE_REGEX, ScriptBlock, SerializedFieldRenameEntry, SerializedFieldRenameMap, analyzeFieldUsageInFile, buildNestedRenameMapFromContent, buildUsageCheckRegex, createPruneContext, detectPackageName, extractContent, extractContentSync, extractDictionaryInfo, extractDictionaryKey, extractDictionaryKeyFromPath, extractScriptBlocks, generateKey, generateShortFieldName, getComponentName, getExtractPluginOptions, getMinifyPluginOptions, getNestedRenameEntryAtPath, getOptimizePluginOptions, getOutput, getPurgePluginOptions, getSharedPruneContext, getUsageCheckRegex, injectScriptBlocks, intlayerExtractBabelPlugin, intlayerMinifyBabelPlugin, intlayerOptimizeBabelPlugin, intlayerPurgeBabelPlugin, makeFieldRenameBabelPlugin, makeUsageAnalyzerBabelPlugin, mergeWithExistingMultilingualDictionary, mergeWithExistingPerLocaleDictionary, optimizeSourceFile, packageList, preserveNestedDictionaryFields, renameFieldsInCode, renameFieldsInSourceFile, renameIntlayerFieldAccesses, resolveContentFilePaths, runIntlayerPurgePipeline, serializeFieldRenameMap, unwrapAwait, writeContentHelper };
@@ -0,0 +1,33 @@
1
+ //#region src/nativeCallers.d.ts
2
+ /**
3
+ * The intlayer getters the build pipeline recognises without any adapter, and
4
+ * the runtime methods their result carries.
5
+ *
6
+ * Kept apart from the compat registry (`@intlayer/config/callers`) so the
7
+ * native passes never have to reason about adapter descriptors.
8
+ */
9
+ /** Canonical intlayer caller names that trigger usage analysis. */
10
+ export declare const INTLAYER_CALLER_NAMES: readonly ['useIntlayer', 'getIntlayer', 'getIntlayerAsync'];
11
+ export type IntlayerCallerName = (typeof INTLAYER_CALLER_NAMES)[number];
12
+ /**
13
+ * {@link INTLAYER_CALLER_NAMES} as a set — the import scan tests every
14
+ * specifier of every file against it, so membership must not be a linear scan.
15
+ */
16
+ export declare const NATIVE_CALLER_NAME_SET: ReadonlySet<string>;
17
+ /**
18
+ * Methods the runtime attaches to a resolved content object rather than fields
19
+ * declared in a `.content` file.
20
+ *
21
+ * `vanilla-intlayer`'s `useIntlayer` / `useDictionary` assign `onChange` onto
22
+ * the content they return, so `useIntlayer('app').onChange(cb)` is a
23
+ * subscription — not a read of a field named `onChange`. Without this list the
24
+ * analyser records `onChange` as the only consumed field and the purge pass
25
+ * strips every real field from the compiled dictionary.
26
+ *
27
+ * The analyser looks *through* these calls: the callback parameter is analysed
28
+ * as a fresh content root, and the call result is analysed again because the
29
+ * helpers return the content object for chaining.
30
+ */
31
+ export declare const CHAINABLE_RUNTIME_METHOD_NAMES: Set<string>;
32
+ //#endregion
33
+ //# sourceMappingURL=nativeCallers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeCallers.d.ts","names":[],"sources":["../../src/nativeCallers.ts"],"mappings":";;;;;;;;;qBASa;YAMD,6BAA6B;;;;;qBAM5B,wBAAwB;;;;;;;;;;;;;;;qBAkBxB,gCAA8B"}
@@ -0,0 +1,152 @@
1
+ import { NestedFieldReferences } from "@intlayer/core/dictionaryManipulator";
2
+ //#region src/pruneContext.d.ts
3
+ /**
4
+ * Dictionary field usage result for a single dictionary key.
5
+ *
6
+ * 'all' → could not determine statically which fields are used;
7
+ * keep every field (no pruning possible).
8
+ * Set<string> → the exact top-level content field names that were accessed.
9
+ */
10
+ export type DictionaryFieldUsage = Set<string> | 'all';
11
+ /**
12
+ * One node in the nested field-rename tree.
13
+ *
14
+ * shortName – the compact alias assigned to this field name.
15
+ * children – rename table for the next level of user-defined keys inside
16
+ * this field's value (empty when the value is a leaf / primitive).
17
+ */
18
+ export type NestedRenameEntry = {
19
+ shortName: string;
20
+ children: NestedRenameMap;
21
+ };
22
+ /** A level of the field-rename tree, mapping original field names to entries. */
23
+ export type NestedRenameMap = Map<string, NestedRenameEntry>;
24
+ /**
25
+ * One opaque consumption of a dictionary content value: the value at
26
+ * `fieldPath` escapes static analysis (passed as-is to a child component or a
27
+ * function argument), so its children must keep their original key names in
28
+ * the compiled JSON.
29
+ */
30
+ export type OpaqueFieldOccurrence = {
31
+ /**
32
+ * Original (pre-rename) user-defined field names from the content root to
33
+ * the escaping value, e.g. `['sections', 'hero']` for
34
+ * `<Card data={content.sections.hero} />`.
35
+ */
36
+ fieldPath: string[];
37
+ /** Source locations (`filePath:line`) where the value escapes. */
38
+ locations: string[];
39
+ };
40
+ /**
41
+ * Shared mutable state created once by the vite plugin and passed by reference
42
+ * to the usage-analyzer (writer) and the prune/minify plugins (readers).
43
+ *
44
+ * All mutations happen during the usage-analysis `buildStart` phase; readers
45
+ * only access this state during the subsequent `transform` phase.
46
+ */
47
+ export type PruneContext = {
48
+ /**
49
+ * Maps every dictionary key seen in source files to the set of top-level
50
+ * content fields statically accessed, or `'all'` when the access pattern
51
+ * could not be determined.
52
+ */
53
+ dictionaryKeyToFieldUsageMap: Map<string, DictionaryFieldUsage>;
54
+ /**
55
+ * Dictionary keys for which the prune/minify step must be skipped entirely
56
+ * because an edge case was detected during analysis or structure recognition.
57
+ */
58
+ dictionariesWithEdgeCases: Set<string>;
59
+ /**
60
+ * True if at least one source file failed to parse during the analysis phase.
61
+ * The prune plugin uses this flag conservatively: any dictionary key without
62
+ * a usage entry might have been referenced by the unparsable file.
63
+ */
64
+ hasUnparsableSourceFiles: boolean;
65
+ /**
66
+ * Maps dictionary keys to the source file paths where the result of
67
+ * `useIntlayer` / `getIntlayer` was assigned to a plain variable, making
68
+ * static field analysis impossible.
69
+ */
70
+ dictionaryKeysWithUntrackedBindings: Map<string, string[]>;
71
+ /**
72
+ * Maps each dictionary key to a nested field-rename tree built after the
73
+ * usage analysis phase (only populated when `build.minify` is active and
74
+ * the field usage for that dictionary is a finite `Set<string>`).
75
+ */
76
+ dictionaryKeyToFieldRenameMap: Map<string, NestedRenameMap>;
77
+ /**
78
+ * Maps each dictionary key to the content field paths whose values are
79
+ * consumed "opaquely" (passed as-is to a child component or function
80
+ * argument). When an opaque value has nested user-defined structure, its
81
+ * children must not be renamed.
82
+ *
83
+ * The inner map is keyed by the dot-joined field path for de-duplication
84
+ * only; the authoritative path is {@link OpaqueFieldOccurrence.fieldPath}.
85
+ *
86
+ * Structure: dictionaryKey → joinedFieldPath → { fieldPath, locations }
87
+ */
88
+ dictionaryKeysWithOpaqueFields: Map<string, Map<string, OpaqueFieldOccurrence>>;
89
+ /**
90
+ * Dictionary keys for which field-key renaming must be skipped even if a
91
+ * finite field-usage set was determined.
92
+ *
93
+ * Populated for dictionaries whose plain-variable bindings were resolved by
94
+ * the framework-specific extractor (Vue / Svelte SFCs), because the Babel
95
+ * rename plugin cannot update the source-code property accesses for those
96
+ * indirect patterns (Vue `.value.field` / Svelte `$store.field`).
97
+ *
98
+ * Pruning and basic minification still apply; only field-key renaming is
99
+ * suppressed.
100
+ */
101
+ dictionariesSkippingFieldRename: Set<string>;
102
+ /**
103
+ * Plain variable bindings that require a framework-specific secondary pass.
104
+ *
105
+ * Populated during the Babel analysis phase for `.vue` and `.svelte` source
106
+ * files where direct field access is not visible to Babel scope analysis:
107
+ * - Vue: `content.value.fieldName` – the `.value` ref-accessor is hidden
108
+ * - Svelte: `$varName.fieldName` – the `$` prefix creates a new identifier
109
+ *
110
+ * Structure: filePath → [{variableName, dictionaryKey}, …]
111
+ */
112
+ pendingFrameworkAnalysis: Map<string, {
113
+ variableName: string;
114
+ dictionaryKey: string;
115
+ }[]>;
116
+ };
117
+ export declare const createPruneContext: () => PruneContext;
118
+ /**
119
+ * Records `nest()` references in a prune context so nest targets stay
120
+ * resolvable — and no larger than they need to be — after purge and minify.
121
+ *
122
+ * A nested node stores the ORIGINAL dot path of the field it reads
123
+ * (`nest('common', 'period')` → `'period'`) and `getNesting` resolves it at
124
+ * runtime against the compiled JSON. That drives three adjustments:
125
+ *
126
+ * - Nest targets never take part in field renaming, since the stored path
127
+ * would no longer match the renamed keys.
128
+ * - A target already consumed by a call site keeps its analysed fields plus
129
+ * the nested ones, so neither consumer loses content.
130
+ * - A target reached *only* through `nest()` is given a usage entry holding
131
+ * exactly the nested fields. Without one, the purge pass leaves the whole
132
+ * dictionary untouched; with one, it trims the dictionary down to what the
133
+ * nest references actually read. This matters most for `dynamic` / `fetch`
134
+ * dictionaries, whose full static snapshot would otherwise be pulled into
135
+ * the eager bundle just to satisfy a single nested field.
136
+ *
137
+ * Seeding is skipped when a source file failed to parse: that file could
138
+ * reference the dictionary in a way the analysis never saw, which is the same
139
+ * guard the purge pass applies to keys with no usage entry.
140
+ *
141
+ * @param pruneContext - Shared analysis state to update in place.
142
+ * @param nestedDictionaryReferences - Nest-target key → referenced top-level
143
+ * fields, as returned by `getNestedDictionaryReferences`.
144
+ */
145
+ export declare const preserveNestedDictionaryFields: (pruneContext: PruneContext, nestedDictionaryReferences: Map<string, NestedFieldReferences>) => void;
146
+ /**
147
+ * Records the usage of a specific dictionary key's fields into `pruneContext`.
148
+ * Merges with any previously recorded usage for the same key.
149
+ */
150
+ export declare const recordFieldUsage: (pruneContext: PruneContext, dictionaryKey: string, fieldUsage: DictionaryFieldUsage) => void;
151
+ //#endregion
152
+ //# sourceMappingURL=pruneContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruneContext.d.ts","names":[],"sources":["../../src/pruneContext.ts"],"mappings":";;;;;;;;;YASY,uBAAuB;;;;;;;;YASvB;EACV;EACA,UAAU;;;YAIA,kBAAkB,YAAY;;;;;;;YAQ9B;;;;;;EAMV;;EAGA;;;;;;;;;YAUU;;;;;;EAMV,8BAA8B,YAAY;;;;;EAM1C,2BAA2B;;;;;;EAO3B;;;;;;EAOA,qCAAqC;;;;;;EAOrC,+BAA+B,YAAY;;;;;;;;;;;;EAa3C,gCAAgC,YAE9B,YAAY;;;;;;;;;;;;;EAed,iCAAiC;;;;;;;;;;;EAYjC,0BAA0B;IAEtB;IAAsB;;;qBAIf,0BAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAyCzB,iCAA8B,cAC3B,cAAY,4BACE,YAAY;;;;;qBAyC7B,mBAAgB,cACb,cAAY,uBACL,YACT"}
@@ -0,0 +1,84 @@
1
+ import { NodePath } from "@babel/core";
2
+ import * as BabelTypes from "@babel/types";
3
+ //#region src/staticAstReaders.d.ts
4
+ /**
5
+ * Static-value readers shared by every pass that has to decide, at build time,
6
+ * which dictionary a call site reads.
7
+ *
8
+ * They were previously duplicated — with small behavioural drifts — between
9
+ * `babel-plugin-intlayer-optimize` and `babel-plugin-intlayer-usage-analyzer`.
10
+ * Both now read through this module so a call site the analyser can attribute
11
+ * is exactly the one the optimizer can rewrite.
12
+ */
13
+ /**
14
+ * Reads a fully-static string from an AST node. Returns `undefined` for
15
+ * dynamic values (identifiers, expressions, template literals with
16
+ * interpolations, …).
17
+ */
18
+ export declare const readStaticString: (babelTypes: typeof BabelTypes, node: BabelTypes.Node | null | undefined) => string | undefined;
19
+ /** Returns the first dot-path segment of a key, e.g. `'a.b.c'` → `'a'`. */
20
+ export declare const firstPathSegment: (path: string) => string;
21
+ /**
22
+ * Reads the static first dot-path segment from a message-id node.
23
+ *
24
+ * t('counter.label') → 'counter'
25
+ * t(`counter.${x}`) → 'counter' (static prefix before the first dot)
26
+ * t(`${x}.label`) → undefined (dynamic first segment)
27
+ * t(someVariable) → undefined
28
+ */
29
+ export declare const readStaticFirstSegment: (babelTypes: typeof BabelTypes, node: BabelTypes.Node | null | undefined) => string | undefined;
30
+ /** Whether an object-property key (identifier or string literal) reads as `name`. */
31
+ export declare const propertyKeyMatches: (babelTypes: typeof BabelTypes, property: BabelTypes.ObjectProperty, name: string) => boolean;
32
+ /**
33
+ * Returns the `ObjectProperty` named `propertyName`, or `undefined` when the
34
+ * object has no such property. Callers that need to mutate the property in
35
+ * place (rewriting or deleting it) use this rather than a value reader.
36
+ */
37
+ export declare const findObjectProperty: (babelTypes: typeof BabelTypes, objectExpression: BabelTypes.ObjectExpression, propertyName: string) => BabelTypes.ObjectProperty | undefined;
38
+ /**
39
+ * Marker returned by the reader helpers when the requested property or
40
+ * argument is simply absent — distinct from present-but-dynamic, which the
41
+ * callers must treat conservatively.
42
+ */
43
+ export declare const ABSENT_VALUE: '__default__';
44
+ /** Either a statically-known value, {@link ABSENT_VALUE}, or `undefined` (dynamic). */
45
+ export type StaticOrAbsent<T> = T | typeof ABSENT_VALUE | undefined;
46
+ /**
47
+ * Reads a static string property from an object expression. Returns
48
+ * {@link ABSENT_VALUE} when the property is absent and `undefined` when
49
+ * present but dynamic.
50
+ */
51
+ export declare const readObjectProperty: (babelTypes: typeof BabelTypes, objectExpression: BabelTypes.ObjectExpression, propertyName: string) => StaticOrAbsent<string>;
52
+ /**
53
+ * Returns the value *node* of a named property, so callers can apply their own
54
+ * reader to it (a full static string, or just its leading path segment).
55
+ * Returns {@link ABSENT_VALUE} when the property is absent.
56
+ */
57
+ export declare const readObjectPropertyNode: (babelTypes: typeof BabelTypes, objectExpression: BabelTypes.ObjectExpression, propertyName: string) => StaticOrAbsent<BabelTypes.Node>;
58
+ /**
59
+ * Reads a named JSX attribute as a static string and returns it wrapped in a
60
+ * `StringLiteral` node so the result can be fed to the same namespace resolver
61
+ * as a call argument. Handles both `id="home.title"` and `id={'home.title'}`.
62
+ * Returns `undefined` when the attribute is absent or dynamic (`id={expr}`).
63
+ */
64
+ export declare const readJsxAttributeString: (babelTypes: typeof BabelTypes, openingElement: BabelTypes.JSXOpeningElement, attributeName: string) => BabelTypes.StringLiteral | undefined;
65
+ /**
66
+ * Splits a compat namespace at the first `.` to separate the dictionary key
67
+ * from an optional key prefix, mirroring the SWC plugin's `split_namespace`.
68
+ *
69
+ * `'about'` → `{ dictionaryKey: 'about', keyPrefix: '' }`
70
+ * `'about.counter'` → `{ dictionaryKey: 'about', keyPrefix: 'counter' }`
71
+ */
72
+ export declare const splitNamespace: (namespace: string) => {
73
+ dictionaryKey: string;
74
+ keyPrefix: string;
75
+ };
76
+ /**
77
+ * Climbs past an enclosing `await` expression so that
78
+ * `const t = await getTranslations('ns')` — or `await getIntlayerAsync('key')`
79
+ * — is resolved to its variable declarator the same way the synchronous form
80
+ * is.
81
+ */
82
+ export declare const unwrapAwait: (babelTypes: typeof BabelTypes, path: NodePath<BabelTypes.Node>) => NodePath<BabelTypes.Node>;
83
+ //#endregion
84
+ //# sourceMappingURL=staticAstReaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staticAstReaders.d.ts","names":[],"sources":["../../src/staticAstReaders.ts"],"mappings":";;;;;;;;;;;;;;;;;qBAkBa,mBAAgB,mBACR,YAAU,MACvB,WAAW;;qBAeN,mBAAgB;;;;;;;;;qBAWhB,yBAAsB,mBACd,YAAU,MACvB,WAAW;;qBAkBN,qBAAkB,mBACV,YAAU,UACnB,WAAW,gBAAc;;;;;;qBAWxB,qBAAkB,mBACV,YAAU,kBACX,WAAW,kBAAgB,yBAE5C,WAAW;;;;;;qBAaD;;YAGD,eAAe,KAAK,WAAW;;;;;;qBAO9B,qBAAkB,mBACV,YAAU,kBACX,WAAW,kBAAgB,yBAE5C;;;;;;qBAeU,yBAAsB,mBACd,YAAU,kBACX,WAAW,kBAAgB,yBAE5C,eAAe,WAAW;;;;;;;qBAgBhB,yBAAsB,mBACd,YAAU,gBACb,WAAW,mBAAiB,0BAE3C,WAAW;;;;;;;;qBAgCD,iBAAc;EAEtB;EAAuB;;;;;;;;qBAef,cAAW,mBACH,YAAU,MACvB,SAAS,WAAW,UACzB,SAAS,WAAW"}
@@ -1,4 +1,5 @@
1
- import { CompatCallerConfig, PruneContext } from "./babel-plugin-intlayer-usage-analyzer.js";
1
+ import { PruneContext } from "./pruneContext.js";
2
+ import { CompatCallerConfig } from "./babel-plugin-intlayer-usage-analyzer.js";
2
3
  import { OptimizePluginOptions } from "./babel-plugin-intlayer-optimize.js";
3
4
  import { ParserOptions } from "@babel/parser";
4
5
  //#region src/transformers.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"transformers.d.ts","names":[],"sources":["../../src/transformers.ts"],"mappings":";;;;;;;;qBA0Ba,sBAAsB;;;;;;;;;;;;;;;;;;;;qBAsCtB,uBAAoB,gCAAkC;;;;;;qBAWtD,sBAAoB;;;;;;qBAgBpB,qBAAkB,yBACJ,yBACxB;;;;;;qBAoBU,mBAAiB;;;;;;;;;;;;;qBAqCjB,0BAAuB,wBACZ,cACV,cACE,cAAY,gBACV,yBACf;;;;;;;qBAyBU,qBAAkB,cACjB,wBACU,cACR,iBACb;;;;;;;;qBAqBU,2BAAwB,wBACb,cACV,cACE,iBACb;;;;;;;;;qBA8CU,qBAAkB,cACjB,wBACU,SACb,0BACR;EACD;EACA"}
1
+ {"version":3,"file":"transformers.d.ts","names":[],"sources":["../../src/transformers.ts"],"mappings":";;;;;;;;;qBA0Ba,sBAAsB;;;;;;;;;;;;;;;;;;;;qBAsCtB,uBAAoB,gCAAkC;;;;;;qBAWtD,sBAAoB;;;;;;qBAgBpB,qBAAkB,yBACJ,yBACxB;;;;;;qBAoBU,mBAAiB;;;;;;;;;;;;;qBAqCjB,0BAAuB,wBACZ,cACV,cACE,cAAY,gBACV,yBACf;;;;;;;qBAyBU,qBAAkB,cACjB,wBACU,cACR,iBACb;;;;;;;;qBAqBU,2BAAwB,wBACb,cACV,cACE,iBACb;;;;;;;;;qBA8CU,qBAAkB,cACjB,wBACU,SACb,0BACR;EACD;EACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/babel",
3
- "version": "9.4.4",
3
+ "version": "9.5.1",
4
4
  "private": false,
5
5
  "description": "A Babel plugin for Intlayer that transforms declaration files and provides internationalization features during the build process according to the Intlayer configuration.",
6
6
  "keywords": [
@@ -89,19 +89,19 @@
89
89
  "@babel/plugin-syntax-jsx": "8.0.1",
90
90
  "@babel/traverse": "8.0.4",
91
91
  "@babel/types": "8.0.4",
92
- "@intlayer/config": "9.4.4",
93
- "@intlayer/core": "9.4.4",
94
- "@intlayer/dictionaries-entry": "9.4.4",
95
- "@intlayer/engine": "9.4.4",
96
- "@intlayer/types": "9.4.4",
97
- "@intlayer/unmerged-dictionaries-entry": "9.4.4"
92
+ "@intlayer/config": "9.5.1",
93
+ "@intlayer/core": "9.5.1",
94
+ "@intlayer/dictionaries-entry": "9.5.1",
95
+ "@intlayer/engine": "9.5.1",
96
+ "@intlayer/types": "9.5.1",
97
+ "@intlayer/unmerged-dictionaries-entry": "9.5.1"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@babel/plugin-syntax-jsx": "8.0.1",
101
101
  "@types/babel__core": "7.20.5",
102
102
  "@types/babel__generator": "7.27.0",
103
103
  "@types/babel__traverse": "7.28.0",
104
- "@types/node": "26.4.1",
104
+ "@types/node": "26.5.0",
105
105
  "@utils/ts-config": "1.0.4",
106
106
  "@utils/ts-config-types": "1.0.4",
107
107
  "@utils/tsdown-config": "1.0.4",
@@ -112,8 +112,8 @@
112
112
  "vitest": "5.0.0"
113
113
  },
114
114
  "peerDependencies": {
115
- "@intlayer/svelte-compiler": "9.4.4",
116
- "@intlayer/vue-compiler": "9.4.4"
115
+ "@intlayer/svelte-compiler": "9.5.1",
116
+ "@intlayer/vue-compiler": "9.5.1"
117
117
  },
118
118
  "peerDependenciesMeta": {
119
119
  "@intlayer/svelte-compiler": {