@translation-cms/sync 1.2.28 → 1.2.29
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.
- package/dist/api.d.ts +105 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +208 -0
- package/dist/api.js.map +1 -0
- package/dist/bin.d.ts +25 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +208 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +107 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +10 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +35 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +15 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +62 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +131 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/watch.d.ts +18 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +71 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/config-internals/args.d.ts +11 -0
- package/dist/config/config-internals/args.d.ts.map +1 -0
- package/dist/config/config-internals/args.js +22 -0
- package/dist/config/config-internals/args.js.map +1 -0
- package/dist/config/config-internals/env.d.ts +10 -0
- package/dist/config/config-internals/env.d.ts.map +1 -0
- package/dist/config/config-internals/env.js +35 -0
- package/dist/config/config-internals/env.js.map +1 -0
- package/dist/config/config-internals/file.d.ts +11 -0
- package/dist/config/config-internals/file.d.ts.map +1 -0
- package/dist/config/config-internals/file.js +28 -0
- package/dist/config/config-internals/file.js.map +1 -0
- package/dist/config/config-internals/resolve.d.ts +21 -0
- package/dist/config/config-internals/resolve.d.ts.map +1 -0
- package/dist/config/config-internals/resolve.js +73 -0
- package/dist/config/config-internals/resolve.js.map +1 -0
- package/dist/config/config-internals/root.d.ts +9 -0
- package/dist/config/config-internals/root.d.ts.map +1 -0
- package/dist/config/config-internals/root.js +22 -0
- package/dist/config/config-internals/root.js.map +1 -0
- package/dist/config/config-internals/types.d.ts +91 -0
- package/dist/config/config-internals/types.d.ts.map +1 -0
- package/dist/config/config-internals/types.js +9 -0
- package/dist/config/config-internals/types.js.map +1 -0
- package/dist/config/resolve-config.d.ts +11 -0
- package/dist/config/resolve-config.d.ts.map +1 -0
- package/dist/config/resolve-config.js +10 -0
- package/dist/config/resolve-config.js.map +1 -0
- package/dist/core/api-internals/helpers.d.ts +9 -0
- package/dist/core/api-internals/helpers.d.ts.map +1 -0
- package/dist/core/api-internals/helpers.js +14 -0
- package/dist/core/api-internals/helpers.js.map +1 -0
- package/dist/core/api-internals/pull.d.ts +19 -0
- package/dist/core/api-internals/pull.d.ts.map +1 -0
- package/dist/core/api-internals/pull.js +269 -0
- package/dist/core/api-internals/pull.js.map +1 -0
- package/dist/core/api-internals/route-config.d.ts +13 -0
- package/dist/core/api-internals/route-config.d.ts.map +1 -0
- package/dist/core/api-internals/route-config.js +34 -0
- package/dist/core/api-internals/route-config.js.map +1 -0
- package/dist/core/api-internals/sync.d.ts +19 -0
- package/dist/core/api-internals/sync.d.ts.map +1 -0
- package/dist/core/api-internals/sync.js +139 -0
- package/dist/core/api-internals/sync.js.map +1 -0
- package/dist/core/api-internals/types.d.ts +33 -0
- package/dist/core/api-internals/types.d.ts.map +1 -0
- package/dist/core/api-internals/types.js +5 -0
- package/dist/core/api-internals/types.js.map +1 -0
- package/dist/core/api.d.ts +11 -0
- package/dist/core/api.d.ts.map +1 -0
- package/dist/core/api.js +11 -0
- package/dist/core/api.js.map +1 -0
- package/dist/core/cache-internals/format.d.ts +20 -0
- package/dist/core/cache-internals/format.d.ts.map +1 -0
- package/dist/core/cache-internals/format.js +33 -0
- package/dist/core/cache-internals/format.js.map +1 -0
- package/dist/core/cache-internals/params.d.ts +33 -0
- package/dist/core/cache-internals/params.d.ts.map +1 -0
- package/dist/core/cache-internals/params.js +155 -0
- package/dist/core/cache-internals/params.js.map +1 -0
- package/dist/core/cache-internals/pull.d.ts +17 -0
- package/dist/core/cache-internals/pull.d.ts.map +1 -0
- package/dist/core/cache-internals/pull.js +34 -0
- package/dist/core/cache-internals/pull.js.map +1 -0
- package/dist/core/cache-internals/sync.d.ts +29 -0
- package/dist/core/cache-internals/sync.d.ts.map +1 -0
- package/dist/core/cache-internals/sync.js +104 -0
- package/dist/core/cache-internals/sync.js.map +1 -0
- package/dist/core/cache-internals/types.d.ts +48 -0
- package/dist/core/cache-internals/types.d.ts.map +1 -0
- package/dist/core/cache-internals/types.js +2 -0
- package/dist/core/cache-internals/types.js.map +1 -0
- package/dist/core/cache.d.ts +13 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +33 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/scanner-internals/ast.d.ts +40 -0
- package/dist/core/scanner-internals/ast.d.ts.map +1 -0
- package/dist/core/scanner-internals/ast.js +100 -0
- package/dist/core/scanner-internals/ast.js.map +1 -0
- package/dist/core/scanner-internals/file-walker.d.ts +10 -0
- package/dist/core/scanner-internals/file-walker.d.ts.map +1 -0
- package/dist/core/scanner-internals/file-walker.js +23 -0
- package/dist/core/scanner-internals/file-walker.js.map +1 -0
- package/dist/core/scanner-internals/import-resolver.d.ts +21 -0
- package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -0
- package/dist/core/scanner-internals/import-resolver.js +119 -0
- package/dist/core/scanner-internals/import-resolver.js.map +1 -0
- package/dist/core/scanner-internals/key-extractor.d.ts +20 -0
- package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -0
- package/dist/core/scanner-internals/key-extractor.js +274 -0
- package/dist/core/scanner-internals/key-extractor.js.map +1 -0
- package/dist/core/scanner-internals/nav-config-scanner.d.ts +30 -0
- package/dist/core/scanner-internals/nav-config-scanner.d.ts.map +1 -0
- package/dist/core/scanner-internals/nav-config-scanner.js +170 -0
- package/dist/core/scanner-internals/nav-config-scanner.js.map +1 -0
- package/dist/core/scanner-internals/route-detector.d.ts +27 -0
- package/dist/core/scanner-internals/route-detector.d.ts.map +1 -0
- package/dist/core/scanner-internals/route-detector.js +78 -0
- package/dist/core/scanner-internals/route-detector.js.map +1 -0
- package/dist/core/scanner-internals/types.d.ts +60 -0
- package/dist/core/scanner-internals/types.d.ts.map +1 -0
- package/dist/core/scanner-internals/types.js +29 -0
- package/dist/core/scanner-internals/types.js.map +1 -0
- package/dist/core/scanner.d.ts +21 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +162 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/next.d.ts +33 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +110 -0
- package/dist/next.js.map +1 -0
- package/dist/preview/index.d.ts +39 -0
- package/dist/preview/index.d.ts.map +1 -0
- package/dist/preview/index.js +123 -0
- package/dist/preview/index.js.map +1 -0
- package/dist/preview/internals/highlight.d.ts +31 -0
- package/dist/preview/internals/highlight.d.ts.map +1 -0
- package/dist/preview/internals/highlight.js +184 -0
- package/dist/preview/internals/highlight.js.map +1 -0
- package/dist/preview/internals/interactions.d.ts +15 -0
- package/dist/preview/internals/interactions.d.ts.map +1 -0
- package/dist/preview/internals/interactions.js +38 -0
- package/dist/preview/internals/interactions.js.map +1 -0
- package/dist/preview/internals/interactive.d.ts +14 -0
- package/dist/preview/internals/interactive.d.ts.map +1 -0
- package/dist/preview/internals/interactive.js +122 -0
- package/dist/preview/internals/interactive.js.map +1 -0
- package/dist/preview/internals/locales.d.ts +9 -0
- package/dist/preview/internals/locales.d.ts.map +1 -0
- package/dist/preview/internals/locales.js +24 -0
- package/dist/preview/internals/locales.js.map +1 -0
- package/dist/preview/internals/state.d.ts +37 -0
- package/dist/preview/internals/state.d.ts.map +1 -0
- package/dist/preview/internals/state.js +74 -0
- package/dist/preview/internals/state.js.map +1 -0
- package/dist/preview/internals/styles.d.ts +8 -0
- package/dist/preview/internals/styles.d.ts.map +1 -0
- package/dist/preview/internals/styles.js +28 -0
- package/dist/preview/internals/styles.js.map +1 -0
- package/dist/preview/internals/types.d.ts +74 -0
- package/dist/preview/internals/types.d.ts.map +1 -0
- package/dist/preview/internals/types.js +5 -0
- package/dist/preview/internals/types.js.map +1 -0
- package/dist/preview/internals/ui-indicators.d.ts +15 -0
- package/dist/preview/internals/ui-indicators.d.ts.map +1 -0
- package/dist/preview/internals/ui-indicators.js +92 -0
- package/dist/preview/internals/ui-indicators.js.map +1 -0
- package/dist/scaffold/index.d.ts +3 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +3 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/intenrals/scaffold.d.ts +24 -0
- package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -0
- package/dist/scaffold/intenrals/scaffold.js +53 -0
- package/dist/scaffold/intenrals/scaffold.js.map +1 -0
- package/dist/scaffold/intenrals/templates.d.ts +10 -0
- package/dist/scaffold/intenrals/templates.d.ts.map +1 -0
- package/dist/scaffold/intenrals/templates.js +344 -0
- package/dist/scaffold/intenrals/templates.js.map +1 -0
- package/dist/scaffold/intenrals/types.d.ts +14 -0
- package/dist/scaffold/intenrals/types.d.ts.map +1 -0
- package/dist/scaffold/intenrals/types.js +5 -0
- package/dist/scaffold/intenrals/types.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation config scanner.
|
|
3
|
+
* Extracts href values from navigation configuration files and returns them
|
|
4
|
+
* as preview routes that can be merged into the translation key map.
|
|
5
|
+
*
|
|
6
|
+
* Looks for patterns like:
|
|
7
|
+
* href: `/projects/${id}/settings`
|
|
8
|
+
* href: '/admin/users'
|
|
9
|
+
* href: `/o/${orgId}/projects`
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { parseSource, walk } from './ast.js';
|
|
14
|
+
/**
|
|
15
|
+
* Finds navigation config files in the project.
|
|
16
|
+
* Matches files with patterns like:
|
|
17
|
+
* - **/navigation.config.ts(x)
|
|
18
|
+
* - **/navigation*.ts(x) in config/ directories
|
|
19
|
+
* - **/routes.config.ts(x)
|
|
20
|
+
* - **/app-routes.ts(x)
|
|
21
|
+
*/
|
|
22
|
+
export function findNavConfigFiles(root, sourceExtensions) {
|
|
23
|
+
const navFiles = [];
|
|
24
|
+
const navPatterns = [
|
|
25
|
+
/navigation.*config\.[jt]sx?$/i,
|
|
26
|
+
/routes\.config\.[jt]sx?$/i,
|
|
27
|
+
];
|
|
28
|
+
function walk(dir) {
|
|
29
|
+
try {
|
|
30
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const fullPath = path.join(dir, entry.name);
|
|
33
|
+
if (entry.isDirectory()) {
|
|
34
|
+
// Skip excluded directories
|
|
35
|
+
if ([
|
|
36
|
+
'node_modules',
|
|
37
|
+
'.next',
|
|
38
|
+
'dist',
|
|
39
|
+
'.git',
|
|
40
|
+
'out',
|
|
41
|
+
].includes(entry.name)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
walk(fullPath);
|
|
45
|
+
}
|
|
46
|
+
else if (entry.isFile()) {
|
|
47
|
+
const ext = path.extname(entry.name);
|
|
48
|
+
if (!sourceExtensions.has(ext))
|
|
49
|
+
continue;
|
|
50
|
+
// Check if filename matches expected patterns
|
|
51
|
+
if (navPatterns.some(p => p.test(entry.name))) {
|
|
52
|
+
navFiles.push(fullPath);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Silently skip unreadable directories
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
walk(root);
|
|
62
|
+
return navFiles;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Extract href values from a navigation config file.
|
|
66
|
+
* Returns an array of href strings/routes found in the config.
|
|
67
|
+
*/
|
|
68
|
+
export function extractNavRoutes(filePath) {
|
|
69
|
+
try {
|
|
70
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
71
|
+
const ast = parseSource(content, filePath);
|
|
72
|
+
const routes = new Set();
|
|
73
|
+
// Walk the AST looking for ObjectProperty nodes with key "href" or "path"
|
|
74
|
+
walk(ast, (node) => {
|
|
75
|
+
if (!node || node.type !== 'ObjectProperty')
|
|
76
|
+
return;
|
|
77
|
+
const objProp = node;
|
|
78
|
+
const key = objProp.key;
|
|
79
|
+
const keyName = key?.name ?? '';
|
|
80
|
+
if (keyName === 'href' || keyName === 'path') {
|
|
81
|
+
const value = objProp.value;
|
|
82
|
+
if (!value)
|
|
83
|
+
return;
|
|
84
|
+
// String literal: href: "/path"
|
|
85
|
+
if (value.type === 'StringLiteral') {
|
|
86
|
+
const route = value.value;
|
|
87
|
+
if (route && route.startsWith('/')) {
|
|
88
|
+
routes.add(route);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Template literal: href: `/path/${id}`
|
|
92
|
+
else if (value.type === 'TemplateLiteral') {
|
|
93
|
+
const route = reconstructTemplatePath(value);
|
|
94
|
+
if (route && route.startsWith('/')) {
|
|
95
|
+
routes.add(route);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return Array.from(routes);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.warn(`[nav-config] Failed to parse ${path.basename(filePath)}: ${err instanceof Error ? err.message : 'unknown error'}`);
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Reconstruct a template path by replacing expressions with parameter placeholders.
|
|
109
|
+
* Example: `${orgId}/projects/${projectId}` → `/[orgId]/projects/[projectId]`
|
|
110
|
+
*/
|
|
111
|
+
function reconstructTemplatePath(node) {
|
|
112
|
+
if (node.type !== 'TemplateLiteral')
|
|
113
|
+
return '';
|
|
114
|
+
let result = '';
|
|
115
|
+
const quasis = node.quasis ?? [];
|
|
116
|
+
const expressions = node.expressions ?? [];
|
|
117
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
118
|
+
const quasi = quasis[i];
|
|
119
|
+
const value = quasi.value;
|
|
120
|
+
const cooked = value?.cooked ?? '';
|
|
121
|
+
result += cooked;
|
|
122
|
+
if (i < expressions.length) {
|
|
123
|
+
const expr = expressions[i];
|
|
124
|
+
const varName = extractVariableName(expr);
|
|
125
|
+
if (varName) {
|
|
126
|
+
result += `[${varName}]`;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
result += '[param]';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Extract the variable name from an expression node.
|
|
137
|
+
* Handles simple identifiers like `orgId`, `projectId`, etc.
|
|
138
|
+
*/
|
|
139
|
+
function extractVariableName(node) {
|
|
140
|
+
if (!node)
|
|
141
|
+
return null;
|
|
142
|
+
const expr = node;
|
|
143
|
+
if (expr.type === 'Identifier')
|
|
144
|
+
return expr.name;
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Scan navigation config files and return preview routes for all hrefs found.
|
|
149
|
+
* Returns a map of route patterns to their string arrays.
|
|
150
|
+
*/
|
|
151
|
+
export function scanNavConfig(root, sourceExtensions) {
|
|
152
|
+
const navFiles = findNavConfigFiles(root, sourceExtensions);
|
|
153
|
+
if (navFiles.length === 0) {
|
|
154
|
+
return {};
|
|
155
|
+
}
|
|
156
|
+
console.log(`[nav-config] Found ${navFiles.length} navigation config file(s)`);
|
|
157
|
+
const allRoutes = new Map();
|
|
158
|
+
for (const filePath of navFiles) {
|
|
159
|
+
const routes = extractNavRoutes(filePath);
|
|
160
|
+
console.log(`[nav-config] ${path.relative(root, filePath)}: extracted ${routes.length} route(s)`);
|
|
161
|
+
routes.forEach(r => allRoutes.set(r, true));
|
|
162
|
+
}
|
|
163
|
+
// Convert to the format expected: route → routes array
|
|
164
|
+
const result = {};
|
|
165
|
+
if (allRoutes.size > 0) {
|
|
166
|
+
result['__NAV_CONFIG__'] = Array.from(allRoutes.keys());
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=nav-config-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav-config-scanner.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/nav-config-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route detection from Next.js file paths.
|
|
3
|
+
* Maps source files (page.tsx, layout.tsx) to their corresponding route strings.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
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.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isRedirectOnlyPage(filePath: string): boolean;
|
|
12
|
+
/**
|
|
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]']
|
|
25
|
+
*/
|
|
26
|
+
export declare function filePathToRoute(root: string, filePath: string): string[];
|
|
27
|
+
//# sourceMappingURL=route-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route detection from Next.js file paths.
|
|
3
|
+
* Maps source files (page.tsx, layout.tsx) to their corresponding route strings.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { parseSource, walk } from './ast.js';
|
|
8
|
+
/**
|
|
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.
|
|
13
|
+
*/
|
|
14
|
+
export function isRedirectOnlyPage(filePath) {
|
|
15
|
+
let ast;
|
|
16
|
+
try {
|
|
17
|
+
// Single try/catch covers both file read and parse
|
|
18
|
+
ast = parseSource(filePath, fs.readFileSync(filePath, 'utf-8'));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
let hasRedirect = false;
|
|
24
|
+
let hasJsxReturn = false;
|
|
25
|
+
walk(ast, node => {
|
|
26
|
+
// Detect redirect() calls
|
|
27
|
+
if (node.type === 'CallExpression') {
|
|
28
|
+
const callee = node.callee;
|
|
29
|
+
if (callee.type === 'Identifier' && callee.name === 'redirect')
|
|
30
|
+
hasRedirect = true;
|
|
31
|
+
return;
|
|
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;
|
|
45
|
+
});
|
|
46
|
+
return hasRedirect && !hasJsxReturn;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
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]']
|
|
61
|
+
*/
|
|
62
|
+
export function filePathToRoute(root, filePath) {
|
|
63
|
+
// Only page files map to routes; layouts, components, hooks, etc. do not
|
|
64
|
+
if (path.basename(filePath, path.extname(filePath)) !== 'page')
|
|
65
|
+
return [];
|
|
66
|
+
// Skip redirect-only pages — no UI to preview
|
|
67
|
+
if (isRedirectOnlyPage(filePath))
|
|
68
|
+
return [];
|
|
69
|
+
const rel = path.relative(root, filePath).replace(/\\/g, '/');
|
|
70
|
+
const appMatch = rel.match(/^(?:src\/)?app\/(.*?)page\.[jt]sx?$/);
|
|
71
|
+
if (!appMatch)
|
|
72
|
+
return [];
|
|
73
|
+
let routePath = appMatch[1] ?? '';
|
|
74
|
+
routePath = routePath.replace(/\([^)]+\)\//g, ''); // strip (routeGroup)/ segments
|
|
75
|
+
routePath = routePath.replace(/\/$/, ''); // strip trailing slash
|
|
76
|
+
return ['/' + routePath];
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=route-detector.js.map
|
|
@@ -0,0 +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;;;;;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,CAAC,uBAAuB;IAEjE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types and constants used throughout the scanner module.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_EXCLUDED_DIRS: Set<string>;
|
|
5
|
+
export declare const DEFAULT_SOURCE_EXTENSIONS: Set<string>;
|
|
6
|
+
/** Options that control the file-system scan behaviour. */
|
|
7
|
+
export interface ScanOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Extra directories to exclude on top of the built-in defaults.
|
|
10
|
+
* @example ["e2e", "fixtures"]
|
|
11
|
+
*/
|
|
12
|
+
excludedDirs?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Override the full set of file extensions to scan.
|
|
15
|
+
* When omitted the defaults (.ts .tsx .js .jsx) are used.
|
|
16
|
+
*/
|
|
17
|
+
sourceExtensions?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* External preview routes from database or config (namespace:key → routes[])
|
|
20
|
+
* These are applied in Pass 3.
|
|
21
|
+
* Keys are route patterns, values are mock params for dynamic segments.
|
|
22
|
+
* @example
|
|
23
|
+
* {
|
|
24
|
+
* "/[locale]/blog/[slug]": { "slug": "first-post" },
|
|
25
|
+
* "/[locale]/products/[slug]": { "slug": "product-a" }
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
routeParams?: Record<string, Record<string, string>>;
|
|
29
|
+
/**
|
|
30
|
+
* TypeScript path mappings from tsconfig.json (for resolving aliased imports).
|
|
31
|
+
* @example { "@/*": ["./src/*"] }
|
|
32
|
+
*/
|
|
33
|
+
pathMappings?: Record<string, string[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Project root directory (used for resolving path aliases).
|
|
36
|
+
* Defaults to the root directory passed to scanProject.
|
|
37
|
+
*/
|
|
38
|
+
projectRoot?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Include navigation config files when scanning for preview routes.
|
|
41
|
+
* When enabled, hrefs from navigation.config.ts files are automatically
|
|
42
|
+
* discovered and added as preview routes.
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
includeNavRoutes?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** A preview route — either a plain path string or an object with per-route params. */
|
|
48
|
+
export type PreviewRoute = string | {
|
|
49
|
+
route: string;
|
|
50
|
+
params?: Record<string, string>;
|
|
51
|
+
};
|
|
52
|
+
/** namespace → (key → previewRoutes[]) */
|
|
53
|
+
export type NamespaceMap = Record<string, Map<string, PreviewRoute[]>>;
|
|
54
|
+
/** Return the route string key used for deduplication. */
|
|
55
|
+
export declare function routeKey(r: PreviewRoute): string;
|
|
56
|
+
/** AST node type for type-safe walking. */
|
|
57
|
+
export type AstNode = {
|
|
58
|
+
type: string;
|
|
59
|
+
} & Record<string, unknown>;
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,qBAAqB,aAWhC,CAAC;AAEH,eAAO,MAAM,yBAAyB,aAKpC,CAAC;AAMH,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAClB,MAAM,GACN;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEzD,0CAA0C;AAC1C,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAEvE,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAEhD;AAED,2CAA2C;AAC3C,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types and constants used throughout the scanner module.
|
|
3
|
+
*/
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Constants
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
export const DEFAULT_EXCLUDED_DIRS = new Set([
|
|
8
|
+
'node_modules',
|
|
9
|
+
'.next',
|
|
10
|
+
'dist',
|
|
11
|
+
'.git',
|
|
12
|
+
'out',
|
|
13
|
+
'.turbo',
|
|
14
|
+
'scripts',
|
|
15
|
+
'packages',
|
|
16
|
+
'.storybook',
|
|
17
|
+
'coverage',
|
|
18
|
+
]);
|
|
19
|
+
export const DEFAULT_SOURCE_EXTENSIONS = new Set([
|
|
20
|
+
'.ts',
|
|
21
|
+
'.tsx',
|
|
22
|
+
'.js',
|
|
23
|
+
'.jsx',
|
|
24
|
+
]);
|
|
25
|
+
/** Return the route string key used for deduplication. */
|
|
26
|
+
export function routeKey(r) {
|
|
27
|
+
return typeof r === 'string' ? r : r.route;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACzC,cAAc;IACd,OAAO;IACP,MAAM;IACN,MAAM;IACN,KAAK;IACL,QAAQ;IACR,SAAS;IACT,UAAU;IACV,YAAY;IACZ,UAAU;CACb,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IAC7C,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;CACT,CAAC,CAAC;AAwDH,0DAA0D;AAC1D,MAAM,UAAU,QAAQ,CAAC,CAAe;IACpC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main scanner orchestration.
|
|
3
|
+
* Coordinates the multi-pass scanning process for translation keys.
|
|
4
|
+
* Re-exports public types and functions for backward compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export { DEFAULT_EXCLUDED_DIRS, DEFAULT_SOURCE_EXTENSIONS, type ScanOptions, type PreviewRoute, type NamespaceMap, routeKey, } from './scanner-internals/types.js';
|
|
7
|
+
export { walkFiles } from './scanner-internals/file-walker.js';
|
|
8
|
+
export { isRedirectOnlyPage, filePathToRoute, } from './scanner-internals/route-detector.js';
|
|
9
|
+
export { extractKeysFromFile } from './scanner-internals/key-extractor.js';
|
|
10
|
+
import { type ScanOptions, type NamespaceMap } from './scanner-internals/types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Scans the project for translation keys and optionally merges external preview routes.
|
|
13
|
+
*
|
|
14
|
+
* Pass 1: Scan all files, extracting keys and associating them with page/layout routes.
|
|
15
|
+
* Pass 2: For each page/layout, walk its import tree to assign keys in deeply-nested
|
|
16
|
+
* components to the correct preview route.
|
|
17
|
+
* Pass 3a: Optionally scan navigation config files and merge their routes (if includeNavRoutes is true).
|
|
18
|
+
* Pass 3b: Merge external preview routes from database or config (routeParams).
|
|
19
|
+
*/
|
|
20
|
+
export declare function scanProject(root: string, opts?: ScanOptions): NamespaceMap;
|
|
21
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +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;AA0CtC;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,CAmI1E"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main scanner orchestration.
|
|
3
|
+
* Coordinates the multi-pass scanning process for translation keys.
|
|
4
|
+
* Re-exports public types and functions for backward compatibility.
|
|
5
|
+
*/
|
|
6
|
+
import path from 'path';
|
|
7
|
+
// Re-export types and constants
|
|
8
|
+
export { DEFAULT_EXCLUDED_DIRS, DEFAULT_SOURCE_EXTENSIONS, routeKey, } from './scanner-internals/types.js';
|
|
9
|
+
// Re-export public functions from submodules
|
|
10
|
+
export { walkFiles } from './scanner-internals/file-walker.js';
|
|
11
|
+
export { isRedirectOnlyPage, filePathToRoute, } from './scanner-internals/route-detector.js';
|
|
12
|
+
export { extractKeysFromFile } from './scanner-internals/key-extractor.js';
|
|
13
|
+
// Import utilities needed for orchestration
|
|
14
|
+
import { DEFAULT_EXCLUDED_DIRS, DEFAULT_SOURCE_EXTENSIONS, routeKey, } from './scanner-internals/types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Returns true for component files that require user interaction to appear
|
|
17
|
+
* (dialogs, modals, drawers, menus, …). Keys in these files are synced to the
|
|
18
|
+
* CMS but get no previewRoutes because simply navigating to a route won't show them.
|
|
19
|
+
*
|
|
20
|
+
* Conservative matching: only flags files whose name ENDS with an overlay keyword
|
|
21
|
+
* (before extension), and files inside overlay-specific directories.
|
|
22
|
+
* Files like "MenuNavigation.tsx" are NOT matched — only "UserMenu.tsx".
|
|
23
|
+
*/
|
|
24
|
+
function isInteractiveOverlay(filePath) {
|
|
25
|
+
const lower = filePath.toLowerCase();
|
|
26
|
+
// File whose name ENDS with an overlay keyword (e.g. UserMenu.tsx, ConfirmDialog.tsx)
|
|
27
|
+
if (/[\\/][^/\\]*(dialog|modal|drawer|sheet|popover|dropdown|menu|combobox|tooltip)\.[jt]sx?$/i.test(lower))
|
|
28
|
+
return true;
|
|
29
|
+
// File inside a dedicated overlay directory (dialogs/, modals/, etc.)
|
|
30
|
+
if (/[\\/](dialogs|modals|drawers|sheets|popovers|dropdowns|menus|comboboxes|tooltips)(\/|\\)/.test(lower))
|
|
31
|
+
return true;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
import { walkFiles } from './scanner-internals/file-walker.js';
|
|
35
|
+
import { filePathToRoute } from './scanner-internals/route-detector.js';
|
|
36
|
+
import { extractKeysFromFile } from './scanner-internals/key-extractor.js';
|
|
37
|
+
import { extractLocalImports, getLayoutChain, } from './scanner-internals/import-resolver.js';
|
|
38
|
+
import { scanNavConfig } from './scanner-internals/nav-config-scanner.js';
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Project scan
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Scans the project for translation keys and optionally merges external preview routes.
|
|
44
|
+
*
|
|
45
|
+
* Pass 1: Scan all files, extracting keys and associating them with page/layout routes.
|
|
46
|
+
* Pass 2: For each page/layout, walk its import tree to assign keys in deeply-nested
|
|
47
|
+
* components to the correct preview route.
|
|
48
|
+
* Pass 3a: Optionally scan navigation config files and merge their routes (if includeNavRoutes is true).
|
|
49
|
+
* Pass 3b: Merge external preview routes from database or config (routeParams).
|
|
50
|
+
*/
|
|
51
|
+
export function scanProject(root, opts) {
|
|
52
|
+
const excludedDirs = new Set([
|
|
53
|
+
...DEFAULT_EXCLUDED_DIRS,
|
|
54
|
+
...(opts?.excludedDirs ?? []),
|
|
55
|
+
]);
|
|
56
|
+
const sourceExtensions = opts?.sourceExtensions
|
|
57
|
+
? new Set(opts.sourceExtensions)
|
|
58
|
+
: DEFAULT_SOURCE_EXTENSIONS;
|
|
59
|
+
const routeParams = opts?.routeParams;
|
|
60
|
+
const pathMappings = opts?.pathMappings;
|
|
61
|
+
const projectRoot = opts?.projectRoot ?? root;
|
|
62
|
+
const result = {};
|
|
63
|
+
let fileCount = 0;
|
|
64
|
+
// Pass 1: scan all files normally
|
|
65
|
+
const routeByFile = new Map();
|
|
66
|
+
for (const file of walkFiles(root, excludedDirs, sourceExtensions)) {
|
|
67
|
+
const routes = filePathToRoute(root, file);
|
|
68
|
+
routeByFile.set(file, routes);
|
|
69
|
+
extractKeysFromFile(file, routes, result);
|
|
70
|
+
fileCount++;
|
|
71
|
+
}
|
|
72
|
+
// Pass 2: for each page/layout file, transitively walk its import tree and
|
|
73
|
+
// re-scan every non-page/layout component with the same routes. This ensures
|
|
74
|
+
// keys used in deeply-nested components (e.g. layout → Nav → NavItem) are
|
|
75
|
+
// associated with the correct preview routes.
|
|
76
|
+
const scannedWithRoute = new Set(); // "file::route" pairs already done
|
|
77
|
+
for (const [file, routes] of routeByFile) {
|
|
78
|
+
if (routes.length === 0)
|
|
79
|
+
continue;
|
|
80
|
+
const isPage = path.basename(file).startsWith('page.');
|
|
81
|
+
const layoutChain = isPage
|
|
82
|
+
? getLayoutChain(root, file, sourceExtensions)
|
|
83
|
+
: [];
|
|
84
|
+
for (const layout of layoutChain) {
|
|
85
|
+
const layoutKey = `${layout}::${routes.join('|')}`;
|
|
86
|
+
if (!scannedWithRoute.has(layoutKey)) {
|
|
87
|
+
scannedWithRoute.add(layoutKey);
|
|
88
|
+
extractKeysFromFile(layout, routes, result);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Queue carries the effective routes that each file was scanned with, so that
|
|
92
|
+
// sub-imports of overlays (dialogs, menus, …) inherit [] routes rather than
|
|
93
|
+
// the page routes from the outer loop.
|
|
94
|
+
const queue = [
|
|
95
|
+
{ file, currentRoutes: routes },
|
|
96
|
+
...layoutChain.map(l => ({ file: l, currentRoutes: routes })),
|
|
97
|
+
];
|
|
98
|
+
while (queue.length > 0) {
|
|
99
|
+
const { file: current, currentRoutes } = queue.shift();
|
|
100
|
+
const imports = extractLocalImports(current, sourceExtensions, projectRoot, pathMappings);
|
|
101
|
+
if (imports.length > 0) {
|
|
102
|
+
console.log(`[Pass 2] ${path.relative(root, current)} (${currentRoutes.join(', ') || 'overlay'}) imports: ${imports.map(i => path.relative(root, i)).join(', ')}`);
|
|
103
|
+
}
|
|
104
|
+
for (const imported of imports) {
|
|
105
|
+
const key = `${imported}::${currentRoutes.join('|')}`;
|
|
106
|
+
if (scannedWithRoute.has(key))
|
|
107
|
+
continue;
|
|
108
|
+
scannedWithRoute.add(key);
|
|
109
|
+
if (!routeByFile.has(imported)) {
|
|
110
|
+
console.log(`[Pass 2] Skipping ${path.relative(root, imported)} — not in walk result`);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (routeByFile.get(imported).length > 0)
|
|
114
|
+
continue;
|
|
115
|
+
// Don't propagate routes into components that need user interaction to appear.
|
|
116
|
+
// Also: if the parent was already an overlay (currentRoutes = []), keep [] so
|
|
117
|
+
// that all transitive imports of an overlay stay route-free.
|
|
118
|
+
const effectiveRoutes = isInteractiveOverlay(imported)
|
|
119
|
+
? []
|
|
120
|
+
: currentRoutes;
|
|
121
|
+
console.log(`[Pass 2] Re-scanning ${path.relative(root, imported)} with routes: ${effectiveRoutes.join(', ') || '(none — interactive overlay)'}`);
|
|
122
|
+
extractKeysFromFile(imported, effectiveRoutes, result);
|
|
123
|
+
queue.push({ file: imported, currentRoutes: effectiveRoutes });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Pass 3a: Scan navigation config files and merge their routes if enabled
|
|
128
|
+
if (opts?.includeNavRoutes) {
|
|
129
|
+
const navRoutes = scanNavConfig(root, sourceExtensions);
|
|
130
|
+
if (navRoutes['__NAV_CONFIG__']) {
|
|
131
|
+
const navRoutesArray = navRoutes['__NAV_CONFIG__'];
|
|
132
|
+
console.log(`[Pass 3a] Merged ${navRoutesArray.length} navigation route(s)`);
|
|
133
|
+
// Add nav routes to all keys that don't have routes yet (accessibility fallback)
|
|
134
|
+
for (const [, keyMap] of Object.entries(result)) {
|
|
135
|
+
for (const [key, routes] of keyMap.entries()) {
|
|
136
|
+
if (routes.length === 0) {
|
|
137
|
+
keyMap.set(key, navRoutesArray);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Pass 3b: upgrade plain dynamic routes to { route, params } objects using routeParams
|
|
144
|
+
if (routeParams) {
|
|
145
|
+
for (const [, keyMap] of Object.entries(result)) {
|
|
146
|
+
for (const [key, routes] of keyMap.entries()) {
|
|
147
|
+
const upgraded = routes.map(r => {
|
|
148
|
+
const rk = routeKey(r);
|
|
149
|
+
const params = routeParams[rk];
|
|
150
|
+
if (params && typeof r === 'string') {
|
|
151
|
+
return { route: rk, params };
|
|
152
|
+
}
|
|
153
|
+
return r;
|
|
154
|
+
});
|
|
155
|
+
keyMap.set(key, upgraded);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
console.log(`Scanned ${fileCount} files.`);
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,sBAAsB,GAC9B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,OAAO,EACH,mBAAmB,EACnB,sBAAsB,GAEzB,MAAM,oBAAoB,CAAC"}
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js Plugin for automatic translation sync
|
|
3
|
+
*
|
|
4
|
+
* Usage in next.config.ts:
|
|
5
|
+
* import withTranslationsCMS from '@translation-cms/sync/next';
|
|
6
|
+
*
|
|
7
|
+
* export default withTranslationsCMS(nextConfig, {
|
|
8
|
+
* pullOnBuild: true, // default
|
|
9
|
+
* pullOnDev: true, // default
|
|
10
|
+
* });
|
|
11
|
+
*/
|
|
12
|
+
import type { NextConfig } from './next';
|
|
13
|
+
export interface TranslationsCMSPluginOptions {
|
|
14
|
+
/** Automatically pull translations on `next build` (default: true) */
|
|
15
|
+
pullOnBuild?: boolean;
|
|
16
|
+
/** Automatically pull translations on `next dev` (default: true) */
|
|
17
|
+
pullOnDev?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* How often (in ms) to poll the CMS for new translations in dev mode.
|
|
20
|
+
* Set to 0 to disable. Default: 10000 (10 seconds).
|
|
21
|
+
*/
|
|
22
|
+
watchInterval?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Higher-order function that wraps your Next.js config with automatic translation syncing.
|
|
26
|
+
*
|
|
27
|
+
* @param userConfig - Your existing next.config.ts configuration
|
|
28
|
+
* @param pluginOptions - Plugin-specific options
|
|
29
|
+
* @returns Enhanced Next.js configuration with sync hooks
|
|
30
|
+
*/
|
|
31
|
+
export declare function withTranslationsCMS(userConfig: NextConfig | undefined, pluginOptions?: TranslationsCMSPluginOptions): NextConfig;
|
|
32
|
+
export default withTranslationsCMS;
|
|
33
|
+
//# sourceMappingURL=next.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAWvC,MAAM,WAAW,4BAA4B;IACzC,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,aAAa,GAAE,4BAAiC,GACjD,UAAU,CAiEZ;AAgDD,eAAe,mBAAmB,CAAC"}
|