@translation-cms/sync 1.2.9 → 1.2.12

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 (116) hide show
  1. package/README.md +304 -151
  2. package/dist/api.d.ts +79 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +151 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/bin.js +51 -17
  7. package/dist/bin.js.map +1 -1
  8. package/dist/commands/init.d.ts +8 -0
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +18 -0
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/pull.d.ts +7 -0
  13. package/dist/commands/pull.d.ts.map +1 -1
  14. package/dist/commands/pull.js +15 -2
  15. package/dist/commands/pull.js.map +1 -1
  16. package/dist/commands/status.d.ts +12 -0
  17. package/dist/commands/status.d.ts.map +1 -1
  18. package/dist/commands/status.js +16 -0
  19. package/dist/commands/status.js.map +1 -1
  20. package/dist/commands/sync.d.ts +10 -0
  21. package/dist/commands/sync.d.ts.map +1 -1
  22. package/dist/commands/sync.js +23 -4
  23. package/dist/commands/sync.js.map +1 -1
  24. package/dist/commands/watch.d.ts +14 -0
  25. package/dist/commands/watch.d.ts.map +1 -1
  26. package/dist/commands/watch.js +23 -3
  27. package/dist/commands/watch.js.map +1 -1
  28. package/dist/config/config-internals/args.d.ts +11 -0
  29. package/dist/config/config-internals/args.d.ts.map +1 -0
  30. package/dist/config/config-internals/args.js +22 -0
  31. package/dist/config/config-internals/args.js.map +1 -0
  32. package/dist/config/config-internals/env.d.ts +10 -0
  33. package/dist/config/config-internals/env.d.ts.map +1 -0
  34. package/dist/config/config-internals/env.js +35 -0
  35. package/dist/config/config-internals/env.js.map +1 -0
  36. package/dist/config/config-internals/file.d.ts +11 -0
  37. package/dist/config/config-internals/file.d.ts.map +1 -0
  38. package/dist/config/config-internals/file.js +28 -0
  39. package/dist/config/config-internals/file.js.map +1 -0
  40. package/dist/config/config-internals/resolve.d.ts +21 -0
  41. package/dist/config/config-internals/resolve.d.ts.map +1 -0
  42. package/dist/config/config-internals/resolve.js +73 -0
  43. package/dist/config/config-internals/resolve.js.map +1 -0
  44. package/dist/config/config-internals/root.d.ts +9 -0
  45. package/dist/config/config-internals/root.d.ts.map +1 -0
  46. package/dist/config/config-internals/root.js +22 -0
  47. package/dist/config/config-internals/root.js.map +1 -0
  48. package/dist/config/config-internals/types.d.ts +83 -0
  49. package/dist/config/config-internals/types.d.ts.map +1 -0
  50. package/dist/config/config-internals/types.js +9 -0
  51. package/dist/config/config-internals/types.js.map +1 -0
  52. package/dist/config/resolve-config.d.ts +9 -90
  53. package/dist/config/resolve-config.d.ts.map +1 -1
  54. package/dist/config/resolve-config.js +7 -123
  55. package/dist/config/resolve-config.js.map +1 -1
  56. package/dist/core/api-internals/pull.d.ts +9 -1
  57. package/dist/core/api-internals/pull.d.ts.map +1 -1
  58. package/dist/core/api-internals/pull.js +41 -28
  59. package/dist/core/api-internals/pull.js.map +1 -1
  60. package/dist/core/api-internals/sync.d.ts +9 -2
  61. package/dist/core/api-internals/sync.d.ts.map +1 -1
  62. package/dist/core/api-internals/sync.js +18 -2
  63. package/dist/core/api-internals/sync.js.map +1 -1
  64. package/dist/core/cache-internals/format.d.ts +16 -0
  65. package/dist/core/cache-internals/format.d.ts.map +1 -1
  66. package/dist/core/cache-internals/format.js +17 -0
  67. package/dist/core/cache-internals/format.js.map +1 -1
  68. package/dist/core/cache-internals/params.d.ts.map +1 -1
  69. package/dist/core/cache-internals/params.js +24 -24
  70. package/dist/core/cache-internals/params.js.map +1 -1
  71. package/dist/core/cache-internals/pull.d.ts +12 -0
  72. package/dist/core/cache-internals/pull.d.ts.map +1 -1
  73. package/dist/core/cache-internals/pull.js +13 -0
  74. package/dist/core/cache-internals/pull.js.map +1 -1
  75. package/dist/core/cache-internals/sync.d.ts +23 -0
  76. package/dist/core/cache-internals/sync.d.ts.map +1 -1
  77. package/dist/core/cache-internals/sync.js +33 -0
  78. package/dist/core/cache-internals/sync.js.map +1 -1
  79. package/dist/core/cache-internals/types.d.ts +20 -0
  80. package/dist/core/cache-internals/types.d.ts.map +1 -1
  81. package/dist/core/scanner-internals/ast.d.ts +23 -5
  82. package/dist/core/scanner-internals/ast.d.ts.map +1 -1
  83. package/dist/core/scanner-internals/ast.js +25 -5
  84. package/dist/core/scanner-internals/ast.js.map +1 -1
  85. package/dist/core/scanner-internals/file-walker.d.ts +3 -2
  86. package/dist/core/scanner-internals/file-walker.d.ts.map +1 -1
  87. package/dist/core/scanner-internals/file-walker.js +10 -12
  88. package/dist/core/scanner-internals/file-walker.js.map +1 -1
  89. package/dist/core/scanner-internals/import-resolver.d.ts +9 -1
  90. package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -1
  91. package/dist/core/scanner-internals/import-resolver.js +58 -63
  92. package/dist/core/scanner-internals/import-resolver.js.map +1 -1
  93. package/dist/core/scanner-internals/key-extractor.d.ts +12 -8
  94. package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -1
  95. package/dist/core/scanner-internals/key-extractor.js +125 -97
  96. package/dist/core/scanner-internals/key-extractor.js.map +1 -1
  97. package/dist/core/scanner-internals/route-detector.d.ts +16 -8
  98. package/dist/core/scanner-internals/route-detector.d.ts.map +1 -1
  99. package/dist/core/scanner-internals/route-detector.js +37 -33
  100. package/dist/core/scanner-internals/route-detector.js.map +1 -1
  101. package/dist/core/scanner.d.ts.map +1 -1
  102. package/dist/core/scanner.js +25 -8
  103. package/dist/core/scanner.js.map +1 -1
  104. package/dist/next.d.ts +28 -0
  105. package/dist/next.d.ts.map +1 -0
  106. package/dist/next.js +65 -0
  107. package/dist/next.js.map +1 -0
  108. package/dist/preview/internals/highlight.d.ts +16 -7
  109. package/dist/preview/internals/highlight.d.ts.map +1 -1
  110. package/dist/preview/internals/highlight.js +71 -60
  111. package/dist/preview/internals/highlight.js.map +1 -1
  112. package/dist/scaffold/intenrals/scaffold.d.ts +17 -0
  113. package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -1
  114. package/dist/scaffold/intenrals/scaffold.js +19 -0
  115. package/dist/scaffold/intenrals/scaffold.js.map +1 -1
  116. package/package.json +16 -3
@@ -1,57 +1,113 @@
1
1
  /**
2
2
  * Extraction of translation keys from source files.
3
- * Finds t('key') calls, useTranslation() bindings, and Trans components.
3
+ *
4
+ * Five passes over the AST per file:
5
+ * 1. Collect `t`-binding declarations (useTranslation / getTranslation / getTranslations)
6
+ * 2. Extract keys from `t('namespace:key')` call expressions
7
+ * 3. Extract keys from `<Trans i18nKey="namespace:key">` JSX elements
8
+ * 4. Extract keys from `I18nKey`-typed string literals in config/data files
9
+ * 5. Extract keys from object properties whose name ends with `Key`
4
10
  */
5
11
  import fs from 'fs';
6
12
  import path from 'path';
7
13
  import { parseSource, walk, stringValue, namespacesFromArg } from './ast.js';
14
+ // ---------------------------------------------------------------------------
15
+ // Small helpers
16
+ // ---------------------------------------------------------------------------
8
17
  /**
9
18
  * Add a key to the namespace map with its associated routes.
10
- * Skips keys that look like paths or are suspiciously short/numeric.
19
+ * Skips keys that look like URL paths or are purely numeric (not translation keys).
20
+ * Merges routes with any previously registered set for the same key.
11
21
  */
12
22
  function addKey(map, namespace, key, routes) {
13
- // Skip keys that look like URL paths or are suspiciously short/numeric
14
23
  if (key.startsWith('/') || key.startsWith('.') || /^\d+$/.test(key))
15
24
  return;
16
25
  if (!map[namespace])
17
26
  map[namespace] = new Map();
18
27
  const existing = map[namespace].get(key) ?? [];
19
28
  if (routes.length > 0) {
29
+ // Union the new routes with whatever was already stored
20
30
  const merged = new Set(existing);
21
31
  for (const route of routes)
22
32
  merged.add(route);
23
33
  map[namespace].set(key, Array.from(merged));
24
34
  }
25
35
  else if (existing.length === 0) {
36
+ // Key seen with no routes yet — register it so it appears in the map
26
37
  map[namespace].set(key, []);
27
38
  }
28
39
  }
29
40
  /**
30
- * Extract translation keys from a source file.
31
- * Handles:
32
- * - const { t } = useTranslation('ns') / getTranslation('ns')
33
- * - const { t: myT } = useTranslation(...)
34
- * - const t = await client.getTranslations(locale, 'ns')
35
- * - t('namespace:key') calls
36
- * - <Trans i18nKey="namespace:key"> components
41
+ * Split a `"namespace:key"` string into its two parts.
42
+ * Returns null when the colon is absent or at position 0 (invalid).
37
43
  */
38
- export function extractKeysFromFile(filePath, routes, result) {
39
- let source;
40
- try {
41
- source = fs.readFileSync(filePath, 'utf-8');
42
- }
43
- catch {
44
- return;
44
+ function splitI18nKey(keyStr) {
45
+ const colonIdx = keyStr.indexOf(':');
46
+ if (colonIdx <= 0)
47
+ return null;
48
+ return [keyStr.slice(0, colonIdx), keyStr.slice(colonIdx + 1)];
49
+ }
50
+ /**
51
+ * Extract the string value of a JSX attribute value node.
52
+ * Handles plain string literals (`i18nKey="ns:key"`) and expression containers
53
+ * (`i18nKey={"ns:key"}`). Returns null for dynamic expressions.
54
+ */
55
+ function jsxAttrStringValue(value) {
56
+ if (!value)
57
+ return null;
58
+ if (value.type === 'StringLiteral')
59
+ return value.value;
60
+ if (value.type === 'JSXExpressionContainer')
61
+ return stringValue(value.expression);
62
+ return null;
63
+ }
64
+ /**
65
+ * Bind translation function aliases from a destructuring pattern.
66
+ *
67
+ * Handles both direct binding and renaming:
68
+ * `const { t } = useTranslation()` → binds `t`
69
+ * `const { t: myT } = useTranslation()` → binds `myT`
70
+ * `const { tDynamic } = getTranslation()` → binds `tDynamic`
71
+ *
72
+ * Only the standard accessor names (`t`, `tDynamic`) are recognised as
73
+ * source keys; any other destructured property is ignored.
74
+ */
75
+ function bindFromObjectPattern(id, namespaces, tBindings) {
76
+ for (const prop of id.properties) {
77
+ if (prop.type !== 'ObjectProperty')
78
+ continue;
79
+ const keyNode = prop.key;
80
+ const origName = keyNode.type === 'Identifier' ? keyNode.name : null;
81
+ if (!origName || (origName !== 't' && origName !== 'tDynamic'))
82
+ continue;
83
+ // Use the aliased name if present: `{ t: myT }` → bind `myT`
84
+ const valNode = prop.value;
85
+ const boundName = valNode.type === 'Identifier' ? valNode.name : origName;
86
+ tBindings.set(boundName, namespaces);
45
87
  }
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Main export
91
+ // ---------------------------------------------------------------------------
92
+ /**
93
+ * Extract all translation keys from `filePath` and merge them into `result`.
94
+ *
95
+ * @param filePath Absolute path to the source file to scan.
96
+ * @param routes Preview routes associated with this file ([] for overlays).
97
+ * @param result Accumulator map updated in place.
98
+ */
99
+ export function extractKeysFromFile(filePath, routes, result) {
46
100
  let ast;
47
101
  try {
48
- ast = parseSource(filePath, source);
102
+ // Single try/catch covers both the file read and the parse step
103
+ ast = parseSource(filePath, fs.readFileSync(filePath, 'utf-8'));
49
104
  }
50
105
  catch {
51
106
  return;
52
107
  }
53
108
  // --- Step 1: collect namespace bindings ---
54
- // Maps the local variable name (e.g. 't') the namespace(s) it's bound to.
109
+ // Maps each local variable name (e.g. `t`) to the namespace(s) it is bound to
110
+ // so that call-expression extraction in Step 2 can resolve the correct namespace.
55
111
  const tBindings = new Map();
56
112
  walk(ast, node => {
57
113
  if (node.type !== 'VariableDeclaration')
@@ -60,7 +116,7 @@ export function extractKeysFromFile(filePath, routes, result) {
60
116
  const init = decl.init;
61
117
  if (!init)
62
118
  continue;
63
- // Unwrap await
119
+ // Unwrap `await` so `const t = await client.getTranslations(...)` works
64
120
  const call = init.type === 'AwaitExpression'
65
121
  ? init.argument
66
122
  : init;
@@ -70,17 +126,15 @@ export function extractKeysFromFile(filePath, routes, result) {
70
126
  const args = call.arguments;
71
127
  // useTranslation('ns') / getTranslation('ns')
72
128
  const isHook = callee.type === 'Identifier' &&
73
- (callee.name === 'useTranslation' ||
74
- callee.name === 'getTranslation');
129
+ (callee.name === 'useTranslation' || callee.name === 'getTranslation');
75
130
  // client.getTranslations(locale, 'ns') / client.getT(locale, 'ns')
76
131
  const isCmsStyle = callee.type === 'MemberExpression' &&
77
132
  callee.property.type === 'Identifier' &&
78
133
  /^getTranslations(?:WithFallback)?$|^getT$/.test(callee.property.name);
79
134
  if (!isHook && !isCmsStyle)
80
135
  continue;
81
- const namespaces = isHook
82
- ? namespacesFromArg(args[0])
83
- : namespacesFromArg(args[1]); // CMS style: getTranslations(locale, ns)
136
+ // Namespace arg position differs: hook uses args[0], CMS style uses args[1]
137
+ const namespaces = isHook ? namespacesFromArg(args[0]) : namespacesFromArg(args[1]);
84
138
  if (!namespaces.length)
85
139
  continue;
86
140
  const id = decl.id;
@@ -89,28 +143,14 @@ export function extractKeysFromFile(filePath, routes, result) {
89
143
  tBindings.set(id.name, namespaces);
90
144
  }
91
145
  else if (id.type === 'ObjectPattern') {
92
- // const { t } = useTranslation(...) or const { t: myT } = useTranslation(...)
93
- for (const prop of id.properties) {
94
- if (prop.type !== 'ObjectProperty')
95
- continue;
96
- const keyNode = prop.key;
97
- const valNode = prop.value;
98
- const origName = keyNode.type === 'Identifier'
99
- ? keyNode.name
100
- : null;
101
- if (!origName ||
102
- (origName !== 't' && origName !== 'tDynamic'))
103
- continue;
104
- const boundName = valNode.type === 'Identifier'
105
- ? valNode.name
106
- : origName;
107
- tBindings.set(boundName, namespaces);
108
- }
146
+ // const { t } = useTranslation(...) or const { t: myT } = ...
147
+ bindFromObjectPattern(id, namespaces, tBindings);
109
148
  }
110
149
  }
111
150
  });
112
- // --- Step 2: extract keys from t('...') call expressions ---
113
- // Only extract from variables that are explicitly bound to translation functions.
151
+ // --- Step 2: extract keys from t('') call expressions ---
152
+ // Only variables explicitly bound in Step 1 are processed; unknown callee
153
+ // names are silently skipped to avoid false positives.
114
154
  walk(ast, node => {
115
155
  if (node.type !== 'CallExpression')
116
156
  return;
@@ -118,27 +158,27 @@ export function extractKeysFromFile(filePath, routes, result) {
118
158
  if (callee.type !== 'Identifier')
119
159
  return;
120
160
  const varName = callee.name;
121
- // Only process if this variable is bound to a translation function
122
161
  if (!tBindings.has(varName))
123
162
  return;
124
- const args = node.arguments;
125
- const keyStr = stringValue(args[0]);
163
+ const keyStr = stringValue(node.arguments[0]);
126
164
  if (!keyStr)
127
165
  return;
128
- const colonIdx = keyStr.indexOf(':');
129
- if (colonIdx > 0) {
130
- // Explicit namespace: t('namespace:key')
131
- addKey(result, keyStr.slice(0, colonIdx), keyStr.slice(colonIdx + 1), routes);
166
+ const parts = splitI18nKey(keyStr);
167
+ if (parts) {
168
+ // t('namespace:key') — namespace is explicit in the key string
169
+ addKey(result, parts[0], parts[1], routes);
132
170
  }
133
171
  else {
134
- // Bare key: t('key') with a known namespace binding warn and register
135
- const namespaces = tBindings.get(varName);
136
- console.warn(`[WARN] Bare key in ${path.relative(process.cwd(), filePath)}: ${varName}('${keyStr}') — use ${varName}('namespace:${keyStr}') instead`);
137
- for (const ns of namespaces)
172
+ // Bare key: t('key') namespace comes from the binding; emit a warning
173
+ console.warn(`[WARN] Bare key in ${path.relative(process.cwd(), filePath)}: ` +
174
+ `${varName}('${keyStr}') — use ${varName}('namespace:${keyStr}') instead`);
175
+ for (const ns of tBindings.get(varName))
138
176
  addKey(result, ns, keyStr, routes);
139
177
  }
140
178
  });
141
179
  // --- Step 3: <Trans i18nKey="namespace:key"> ---
180
+ // The Trans component is the JSX equivalent of t(); only fully-qualified
181
+ // "namespace:key" values are accepted (bare keys cannot be resolved here).
142
182
  walk(ast, node => {
143
183
  if (node.type !== 'JSXOpeningElement')
144
184
  return;
@@ -149,50 +189,37 @@ export function extractKeysFromFile(filePath, routes, result) {
149
189
  if (attr.type !== 'JSXAttribute')
150
190
  continue;
151
191
  const attrName = attr.name;
152
- if (attrName.type !== 'JSXIdentifier' ||
153
- attrName.name !== 'i18nKey')
192
+ if (attrName.type !== 'JSXIdentifier' || attrName.name !== 'i18nKey')
154
193
  continue;
155
- const value = attr.value;
156
- let keyStr = null;
157
- if (value?.type === 'StringLiteral') {
158
- keyStr = value.value;
159
- }
160
- else if (value?.type === 'JSXExpressionContainer') {
161
- keyStr = stringValue(value.expression);
162
- }
194
+ const keyStr = jsxAttrStringValue(attr.value);
163
195
  if (!keyStr)
164
196
  continue;
165
- const colonIdx = keyStr.indexOf(':');
166
- if (colonIdx <= 0)
167
- continue;
168
- addKey(result, keyStr.slice(0, colonIdx), keyStr.slice(colonIdx + 1), routes);
197
+ const parts = splitI18nKey(keyStr);
198
+ if (parts)
199
+ addKey(result, parts[0], parts[1], routes);
169
200
  }
170
201
  });
171
202
  // --- Step 4: I18nKey string literals in config/data files ---
172
- // If the file imports the `I18nKey` type, scan all string literals matching
173
- // the "namespace:key" pattern. This catches translation keys used in typed
174
- // config objects (e.g. nav configs with `label: 'sidebar:settings'`).
175
- const importsI18nKey = hasI18nKeyImport(ast);
176
- if (importsI18nKey) {
203
+ // When a file imports the `I18nKey` type it likely contains typed config
204
+ // objects (e.g. nav items with `label: 'sidebar:settings'`). Scan every
205
+ // string literal that matches "namespace:key" to catch these.
206
+ if (hasI18nKeyImport(ast)) {
177
207
  walk(ast, node => {
178
208
  if (node.type !== 'StringLiteral')
179
209
  return;
180
- const val = node.value;
181
- const colonIdx = val.indexOf(':');
182
- if (colonIdx <= 0)
210
+ const parts = splitI18nKey(node.value);
211
+ if (!parts)
183
212
  return;
184
- const ns = val.slice(0, colonIdx);
185
- const key = val.slice(colonIdx + 1);
186
- // Namespace and key must look like identifiers/dot-paths (no spaces, slashes, etc.)
187
- if (!/^\w[\w-]*$/.test(ns) || !/^\w[\w.-]*$/.test(key))
213
+ // Namespace and key must look like identifiers/dot-paths (no spaces, slashes…)
214
+ if (!/^\w[\w-]*$/.test(parts[0]) || !/^\w[\w.-]*$/.test(parts[1]))
188
215
  return;
189
- addKey(result, ns, key, routes);
216
+ addKey(result, parts[0], parts[1], routes);
190
217
  });
191
218
  }
192
219
  // --- Step 5: *Key object property string literals ---
193
- // Catches translation keys passed as props/config values where the property
220
+ // Catches translation keys passed as prop/config values where the property
194
221
  // name ends with "Key" (e.g. `titleKey: 'subscription:expired'`).
195
- // No import sentinel needed the property name convention is the signal.
222
+ // The naming convention is the only signal needed no import sentinel required.
196
223
  walk(ast, node => {
197
224
  if (node.type !== 'ObjectProperty' && node.type !== 'Property')
198
225
  return;
@@ -207,29 +234,30 @@ export function extractKeysFromFile(filePath, routes, result) {
207
234
  const val = stringValue(node.value);
208
235
  if (!val)
209
236
  return;
210
- const colonIdx = val.indexOf(':');
211
- if (colonIdx <= 0)
237
+ const parts = splitI18nKey(val);
238
+ if (!parts)
212
239
  return;
213
- const ns = val.slice(0, colonIdx);
214
- const key = val.slice(colonIdx + 1);
215
- if (!/^\w[\w-]*$/.test(ns) || !/^\w[\w.-]*$/.test(key))
240
+ if (!/^\w[\w-]*$/.test(parts[0]) || !/^\w[\w.-]*$/.test(parts[1]))
216
241
  return;
217
- addKey(result, ns, key, routes);
242
+ addKey(result, parts[0], parts[1], routes);
218
243
  });
219
244
  }
245
+ // ---------------------------------------------------------------------------
246
+ // Internal helpers
247
+ // ---------------------------------------------------------------------------
220
248
  /**
221
- * Returns true if the AST contains an import of the `I18nKey` type,
222
- * indicating this file uses typed translation keys.
249
+ * Returns true if the AST contains an import of the `I18nKey` type.
250
+ * Used as a cheap sentinel to decide whether Step 4 should run for a file.
251
+ *
252
+ * The `found` flag pattern is necessary because `walk()` does not support
253
+ * early termination — we skip further work as soon as the import is spotted.
223
254
  */
224
255
  function hasI18nKeyImport(ast) {
225
256
  let found = false;
226
257
  walk(ast, node => {
227
- if (found)
228
- return;
229
- if (node.type !== 'ImportDeclaration')
258
+ if (found || node.type !== 'ImportDeclaration')
230
259
  return;
231
- const specifiers = node.specifiers;
232
- for (const spec of specifiers) {
260
+ for (const spec of node.specifiers) {
233
261
  if (spec.type === 'ImportSpecifier' &&
234
262
  spec.imported?.name === 'I18nKey') {
235
263
  found = true;
@@ -1 +1 @@
1
- {"version":3,"file":"key-extractor.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/key-extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"key-extractor.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/key-extractor.ts"],"names":[],"mappings":"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"}
@@ -3,17 +3,25 @@
3
3
  * Maps source files (page.tsx, layout.tsx) to their corresponding route strings.
4
4
  */
5
5
  /**
6
- * Returns true when a page file only calls redirect() without rendering any JSX.
7
- * Such pages are skipped from the preview route list because they have no UI to preview.
6
+ * Returns true when a page file only calls `redirect()` without rendering any JSX.
7
+ *
8
+ * Such pages have no visible UI, so they are excluded from the preview route list —
9
+ * there is nothing for a translator to preview.
8
10
  */
9
11
  export declare function isRedirectOnlyPage(filePath: string): boolean;
10
12
  /**
11
- * Maps a source file path to Next.js route string(s).
12
- * - page.tsx → the route template it represents (e.g. /blog/[slug], /[locale]/about)
13
- * - layout.tsx → the route template of its directory
14
- * - Dynamic segments are kept as-is resolved at preview time via project preview_params
15
- * - Redirect-only pages (no JSX, just redirect()) []
16
- * - All other files (components, hooks, …) []
13
+ * Map a source file path to the Next.js route string(s) it represents.
14
+ *
15
+ * Rules:
16
+ * - Only `page.[jt]sx?` files produce a route; all other files return `[]`.
17
+ * - Pages that only call `redirect()` (no JSX) return `[]` — no UI to preview.
18
+ * - Route groups `(groupName)/` are stripped from the route path.
19
+ * - Dynamic segments `[param]` are kept as-is; they are filled in at preview
20
+ * time using the project's `preview_params` configuration.
21
+ *
22
+ * @example
23
+ * filePathToRoute(root, 'src/app/[locale]/blog/[slug]/page.tsx')
24
+ * // → ['/[locale]/blog/[slug]']
17
25
  */
18
26
  export declare function filePathToRoute(root: string, filePath: string): string[];
19
27
  //# sourceMappingURL=route-detector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-detector.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/route-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuC5D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBxE"}
1
+ {"version":3,"file":"route-detector.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/route-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoC5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBxE"}
@@ -6,20 +6,16 @@ import fs from 'fs';
6
6
  import path from 'path';
7
7
  import { parseSource, walk } from './ast.js';
8
8
  /**
9
- * Returns true when a page file only calls redirect() without rendering any JSX.
10
- * Such pages are skipped from the preview route list because they have no UI to preview.
9
+ * Returns true when a page file only calls `redirect()` without rendering any JSX.
10
+ *
11
+ * Such pages have no visible UI, so they are excluded from the preview route list —
12
+ * there is nothing for a translator to preview.
11
13
  */
12
14
  export function isRedirectOnlyPage(filePath) {
13
- let source;
14
- try {
15
- source = fs.readFileSync(filePath, 'utf-8');
16
- }
17
- catch {
18
- return false;
19
- }
20
15
  let ast;
21
16
  try {
22
- ast = parseSource(filePath, source);
17
+ // Single try/catch covers both file read and parse
18
+ ast = parseSource(filePath, fs.readFileSync(filePath, 'utf-8'));
23
19
  }
24
20
  catch {
25
21
  return false;
@@ -27,39 +23,47 @@ export function isRedirectOnlyPage(filePath) {
27
23
  let hasRedirect = false;
28
24
  let hasJsxReturn = false;
29
25
  walk(ast, node => {
26
+ // Detect redirect() calls
30
27
  if (node.type === 'CallExpression') {
31
28
  const callee = node.callee;
32
- if (callee.type === 'Identifier' && callee.name === 'redirect') {
29
+ if (callee.type === 'Identifier' && callee.name === 'redirect')
33
30
  hasRedirect = true;
34
- }
35
- }
36
- if (node.type === 'ReturnStatement') {
37
- const arg = node.argument;
38
- if (!arg)
39
- return;
40
- const expr = arg.type === 'ParenthesizedExpression'
41
- ? arg.expression
42
- : arg;
43
- if (expr?.type === 'JSXElement' || expr?.type === 'JSXFragment') {
44
- hasJsxReturn = true;
45
- }
31
+ return;
46
32
  }
33
+ // Detect return statements that yield JSX (page has visible UI)
34
+ if (node.type !== 'ReturnStatement')
35
+ return;
36
+ const arg = node.argument;
37
+ if (!arg)
38
+ return;
39
+ // Unwrap parenthesised expressions: return (<div>…</div>)
40
+ const expr = arg.type === 'ParenthesizedExpression'
41
+ ? arg.expression
42
+ : arg;
43
+ if (expr?.type === 'JSXElement' || expr?.type === 'JSXFragment')
44
+ hasJsxReturn = true;
47
45
  });
48
46
  return hasRedirect && !hasJsxReturn;
49
47
  }
50
48
  /**
51
- * Maps a source file path to Next.js route string(s).
52
- * - page.tsx → the route template it represents (e.g. /blog/[slug], /[locale]/about)
53
- * - layout.tsx → the route template of its directory
54
- * - Dynamic segments are kept as-is resolved at preview time via project preview_params
55
- * - Redirect-only pages (no JSX, just redirect()) []
56
- * - All other files (components, hooks, …) []
49
+ * Map a source file path to the Next.js route string(s) it represents.
50
+ *
51
+ * Rules:
52
+ * - Only `page.[jt]sx?` files produce a route; all other files return `[]`.
53
+ * - Pages that only call `redirect()` (no JSX) return `[]` — no UI to preview.
54
+ * - Route groups `(groupName)/` are stripped from the route path.
55
+ * - Dynamic segments `[param]` are kept as-is; they are filled in at preview
56
+ * time using the project's `preview_params` configuration.
57
+ *
58
+ * @example
59
+ * filePathToRoute(root, 'src/app/[locale]/blog/[slug]/page.tsx')
60
+ * // → ['/[locale]/blog/[slug]']
57
61
  */
58
62
  export function filePathToRoute(root, filePath) {
59
- const base = path.basename(filePath, path.extname(filePath));
60
- if (base !== 'page')
63
+ // Only page files map to routes; layouts, components, hooks, etc. do not
64
+ if (path.basename(filePath, path.extname(filePath)) !== 'page')
61
65
  return [];
62
- // Skip pages that only redirect — no UI to preview
66
+ // Skip redirect-only pages — no UI to preview
63
67
  if (isRedirectOnlyPage(filePath))
64
68
  return [];
65
69
  const rel = path.relative(root, filePath).replace(/\\/g, '/');
@@ -67,7 +71,7 @@ export function filePathToRoute(root, filePath) {
67
71
  if (!appMatch)
68
72
  return [];
69
73
  let routePath = appMatch[1] ?? '';
70
- routePath = routePath.replace(/\([^)]+\)\//g, ''); // strip route groups
74
+ routePath = routePath.replace(/\([^)]+\)\//g, ''); // strip (routeGroup)/ segments
71
75
  routePath = routePath.replace(/\/$/, ''); // strip trailing slash
72
76
  return ['/' + routePath];
73
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-detector.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/route-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG7C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IAC/C,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACD,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACD,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;QACb,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAiB,CAAC;YACtC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC7D,WAAW,GAAG,IAAI,CAAC;YACvB,CAAC;QACL,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAsC,CAAC;YACxD,IAAI,CAAC,GAAG;gBAAE,OAAO;YACjB,MAAM,IAAI,GACN,GAAG,CAAC,IAAI,KAAK,yBAAyB;gBAClC,CAAC,CAAE,GAAG,CAAC,UAAsB;gBAC7B,CAAC,CAAC,GAAG,CAAC;YACd,IAAI,IAAI,EAAE,IAAI,KAAK,YAAY,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC9D,YAAY,GAAG,IAAI,CAAC;YACxB,CAAC;QACL,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,IAAI,CAAC,YAAY,CAAC;AACxC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7D,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAE/B,mDAAmD;IACnD,IAAI,kBAAkB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzB,IAAI,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,qBAAqB;IACxE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB;IAEjE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"route-detector.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/route-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IAC/C,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACD,mDAAmD;QACnD,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;QACb,0BAA0B;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAiB,CAAC;YACtC,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;gBAC1D,WAAW,GAAG,IAAI,CAAC;YACvB,OAAO;QACX,CAAC;QAED,gEAAgE;QAChE,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAsC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,0DAA0D;QAC1D,MAAM,IAAI,GACN,GAAG,CAAC,IAAI,KAAK,yBAAyB;YAClC,CAAC,CAAE,GAAG,CAAC,UAAsB;YAC7B,CAAC,CAAC,GAAG,CAAC;QACd,IAAI,IAAI,EAAE,IAAI,KAAK,YAAY,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa;YAC3D,YAAY,GAAG,IAAI,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,IAAI,CAAC,YAAY,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC1D,yEAAyE;IACzE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAE1E,8CAA8C;IAC9C,IAAI,kBAAkB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzB,IAAI,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,+BAA+B;IAClF,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAW,uBAAuB;IAE3E,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;AAC7B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,QAAQ,GACX,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EACH,kBAAkB,EAClB,eAAe,GAClB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAG3E,OAAO,EAGH,KAAK,WAAW,EAChB,KAAK,YAAY,EAEpB,MAAM,8BAA8B,CAAC;AAyBtC;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,CAwG1E"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,QAAQ,GACX,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EACH,kBAAkB,EAClB,eAAe,GAClB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAG3E,OAAO,EAGH,KAAK,WAAW,EAChB,KAAK,YAAY,EAEpB,MAAM,8BAA8B,CAAC;AAwCtC;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,CAgH1E"}
@@ -16,10 +16,19 @@ import { DEFAULT_EXCLUDED_DIRS, DEFAULT_SOURCE_EXTENSIONS, routeKey, } from './s
16
16
  * Returns true for component files that require user interaction to appear
17
17
  * (dialogs, modals, drawers, menus, …). Keys in these files are synced to the
18
18
  * CMS but get no previewRoutes because simply navigating to a route won't show them.
19
+ *
20
+ * Matches any file whose name *contains* an overlay keyword (prefix, suffix, or middle),
21
+ * and any file inside a directory named after an overlay pattern (e.g. dialogs/, modals/).
19
22
  */
20
23
  function isInteractiveOverlay(filePath) {
21
24
  const lower = filePath.toLowerCase();
22
- return /[\\/](dialog|modal|drawer|sheet|popover|dropdown|menu|combobox|tooltip)[^\\/]*\.[jt]sx?$/.test(lower);
25
+ // File whose name contains an overlay keyword
26
+ if (/[\\/][^\\/]*(dialog|modal|drawer|sheet|popover|dropdown|menu|combobox|tooltip)[^\\/]*\.[jt]sx?$/.test(lower))
27
+ return true;
28
+ // File inside a directory named after an overlay pattern (dialogs/, modals/, menus/, …)
29
+ if (/[\\/](dialogs?|modals?|drawers?|sheets?|popovers?|dropdowns?|menus?|comboboxes?|tooltips?)[\\/]/.test(lower))
30
+ return true;
31
+ return false;
23
32
  }
24
33
  import { walkFiles } from './scanner-internals/file-walker.js';
25
34
  import { filePathToRoute } from './scanner-internals/route-detector.js';
@@ -76,15 +85,21 @@ export function scanProject(root, opts) {
76
85
  extractKeysFromFile(layout, routes, result);
77
86
  }
78
87
  }
79
- const queue = [file, ...layoutChain];
88
+ // Queue carries the effective routes that each file was scanned with, so that
89
+ // sub-imports of overlays (dialogs, menus, …) inherit [] routes rather than
90
+ // the page routes from the outer loop.
91
+ const queue = [
92
+ { file, currentRoutes: routes },
93
+ ...layoutChain.map(l => ({ file: l, currentRoutes: routes })),
94
+ ];
80
95
  while (queue.length > 0) {
81
- const current = queue.shift();
96
+ const { file: current, currentRoutes } = queue.shift();
82
97
  const imports = extractLocalImports(current, sourceExtensions, projectRoot, pathMappings);
83
98
  if (imports.length > 0) {
84
- console.log(`[Pass 2] ${path.relative(root, current)} (${routes.join(', ')}) imports: ${imports.map(i => path.relative(root, i)).join(', ')}`);
99
+ console.log(`[Pass 2] ${path.relative(root, current)} (${currentRoutes.join(', ') || 'overlay'}) imports: ${imports.map(i => path.relative(root, i)).join(', ')}`);
85
100
  }
86
101
  for (const imported of imports) {
87
- const key = `${imported}::${routes.join('|')}`;
102
+ const key = `${imported}::${currentRoutes.join('|')}`;
88
103
  if (scannedWithRoute.has(key))
89
104
  continue;
90
105
  scannedWithRoute.add(key);
@@ -94,13 +109,15 @@ export function scanProject(root, opts) {
94
109
  }
95
110
  if (routeByFile.get(imported).length > 0)
96
111
  continue;
97
- // Don't propagate routes into components that need user interaction to appear
112
+ // Don't propagate routes into components that need user interaction to appear.
113
+ // Also: if the parent was already an overlay (currentRoutes = []), keep [] so
114
+ // that all transitive imports of an overlay stay route-free.
98
115
  const effectiveRoutes = isInteractiveOverlay(imported)
99
116
  ? []
100
- : routes;
117
+ : currentRoutes;
101
118
  console.log(`[Pass 2] Re-scanning ${path.relative(root, imported)} with routes: ${effectiveRoutes.join(', ') || '(none — interactive overlay)'}`);
102
119
  extractKeysFromFile(imported, effectiveRoutes, result);
103
- queue.push(imported);
120
+ queue.push({ file: imported, currentRoutes: effectiveRoutes });
104
121
  }
105
122
  }
106
123
  }