@translation-cms/sync 1.2.1 → 1.2.4
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/bin.d.ts +25 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +173 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +68 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +22 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +46 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +10 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +20 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/watch.d.ts +4 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +51 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/{load-config.d.ts → config/resolve-config.d.ts} +13 -10
- package/dist/config/resolve-config.d.ts.map +1 -0
- package/dist/{resolve-config.js → config/resolve-config.js} +21 -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 +11 -0
- package/dist/core/api-internals/pull.d.ts.map +1 -0
- package/dist/core/api-internals/pull.js +124 -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 +12 -0
- package/dist/core/api-internals/sync.d.ts.map +1 -0
- package/dist/core/api-internals/sync.js +95 -0
- package/dist/core/api-internals/sync.js.map +1 -0
- package/dist/core/api-internals/types.d.ts +25 -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/{sync.d.ts → core/cache.d.ts} +5 -33
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +143 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/scanner-internals/ast.d.ts +22 -0
- package/dist/core/scanner-internals/ast.d.ts.map +1 -0
- package/dist/core/scanner-internals/ast.js +80 -0
- package/dist/core/scanner-internals/ast.js.map +1 -0
- package/dist/core/scanner-internals/file-walker.d.ts +9 -0
- package/dist/core/scanner-internals/file-walker.d.ts.map +1 -0
- package/dist/core/scanner-internals/file-walker.js +25 -0
- package/dist/core/scanner-internals/file-walker.js.map +1 -0
- package/dist/core/scanner-internals/import-resolver.d.ts +13 -0
- package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -0
- package/dist/core/scanner-internals/import-resolver.js +124 -0
- package/dist/core/scanner-internals/import-resolver.js.map +1 -0
- package/dist/core/scanner-internals/key-extractor.d.ts +16 -0
- package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -0
- package/dist/core/scanner-internals/key-extractor.js +172 -0
- package/dist/core/scanner-internals/key-extractor.js.map +1 -0
- package/dist/core/scanner-internals/route-detector.d.ts +19 -0
- package/dist/core/scanner-internals/route-detector.d.ts.map +1 -0
- package/dist/core/scanner-internals/route-detector.js +74 -0
- package/dist/core/scanner-internals/route-detector.js.map +1 -0
- package/dist/core/scanner-internals/types.d.ts +53 -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 +20 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +113 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/preview/index.d.ts +38 -0
- package/dist/preview/index.d.ts.map +1 -0
- package/dist/preview/index.js +114 -0
- package/dist/preview/index.js.map +1 -0
- package/dist/preview/internals/highlight.d.ts +22 -0
- package/dist/preview/internals/highlight.d.ts.map +1 -0
- package/dist/preview/internals/highlight.js +153 -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/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 +35 -0
- package/dist/preview/internals/state.d.ts.map +1 -0
- package/dist/preview/internals/state.js +65 -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 +49 -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/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 +7 -0
- package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -0
- package/dist/scaffold/intenrals/scaffold.js +34 -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.js → scaffold/intenrals/templates.js} +10 -38
- package/dist/scaffold/intenrals/templates.js.map +1 -0
- package/dist/{scaffold.d.ts → scaffold/intenrals/types.d.ts} +4 -2
- 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 +7 -7
- package/schema.json +64 -0
- package/dist/cli-entry.d.ts +0 -3
- package/dist/cli-entry.d.ts.map +0 -1
- package/dist/cli-entry.js +0 -390
- package/dist/cli-entry.js.map +0 -1
- package/dist/cli.d.ts +0 -16
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -16
- package/dist/cli.js.map +0 -1
- package/dist/load-config.d.ts.map +0 -1
- package/dist/load-config.js +0 -24
- package/dist/load-config.js.map +0 -1
- package/dist/preview.d.ts +0 -88
- package/dist/preview.d.ts.map +0 -1
- package/dist/preview.js +0 -461
- package/dist/preview.js.map +0 -1
- package/dist/resolve-config.d.ts +0 -15
- package/dist/resolve-config.d.ts.map +0 -1
- package/dist/resolve-config.js.map +0 -1
- package/dist/scaffold.d.ts.map +0 -1
- package/dist/scaffold.js.map +0 -1
- package/dist/scanner.d.ts +0 -77
- package/dist/scanner.d.ts.map +0 -1
- package/dist/scanner.js +0 -555
- package/dist/scanner.js.map +0 -1
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js +0 -383
- package/dist/sync.js.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST parsing and traversal utilities.
|
|
3
|
+
*/
|
|
4
|
+
import { parse } from '@babel/parser';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* Walk an AST tree depth-first, calling visit() for each node.
|
|
8
|
+
*/
|
|
9
|
+
export function walk(node, visit) {
|
|
10
|
+
if (!node || typeof node !== 'object')
|
|
11
|
+
return;
|
|
12
|
+
if (Array.isArray(node)) {
|
|
13
|
+
for (const item of node)
|
|
14
|
+
walk(item, visit);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const n = node;
|
|
18
|
+
if (typeof n.type === 'string')
|
|
19
|
+
visit(n);
|
|
20
|
+
for (const value of Object.values(n)) {
|
|
21
|
+
if (value && typeof value === 'object')
|
|
22
|
+
walk(value, visit);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse source code using Babel with appropriate plugins based on file extension.
|
|
27
|
+
*/
|
|
28
|
+
export function parseSource(filePath, source) {
|
|
29
|
+
const ext = path.extname(filePath);
|
|
30
|
+
const plugins = [];
|
|
31
|
+
if (ext === '.ts' || ext === '.tsx')
|
|
32
|
+
plugins.push('typescript');
|
|
33
|
+
if (ext !== '.ts')
|
|
34
|
+
plugins.push('jsx'); // .tsx, .jsx, .js
|
|
35
|
+
return parse(source, {
|
|
36
|
+
sourceType: 'module',
|
|
37
|
+
plugins,
|
|
38
|
+
errorRecovery: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns the string value of a StringLiteral or no-expression TemplateLiteral node.
|
|
43
|
+
*/
|
|
44
|
+
export function stringValue(node) {
|
|
45
|
+
if (!node || typeof node !== 'object')
|
|
46
|
+
return null;
|
|
47
|
+
const n = node;
|
|
48
|
+
if (n.type === 'StringLiteral' && typeof n.value === 'string')
|
|
49
|
+
return n.value;
|
|
50
|
+
if (n.type === 'TemplateLiteral') {
|
|
51
|
+
const exprs = n.expressions;
|
|
52
|
+
const quasis = n.quasis;
|
|
53
|
+
if (exprs.length === 0 && quasis.length === 1) {
|
|
54
|
+
const quasi = quasis[0];
|
|
55
|
+
if (quasi?.value) {
|
|
56
|
+
return quasi.value.cooked ?? null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Extracts namespace string(s) from a useTranslation/getTranslation argument.
|
|
64
|
+
* Handles both single strings and arrays of strings.
|
|
65
|
+
*/
|
|
66
|
+
export function namespacesFromArg(node) {
|
|
67
|
+
const single = stringValue(node);
|
|
68
|
+
if (single)
|
|
69
|
+
return [single];
|
|
70
|
+
if (!node || typeof node !== 'object')
|
|
71
|
+
return [];
|
|
72
|
+
const n = node;
|
|
73
|
+
if (n.type === 'ArrayExpression') {
|
|
74
|
+
return n.elements
|
|
75
|
+
.map(stringValue)
|
|
76
|
+
.filter((s) => s !== null);
|
|
77
|
+
}
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File system traversal utilities.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Recursively walk through files in a directory, yielding file paths that match
|
|
6
|
+
* the source extensions and are not in excluded directories.
|
|
7
|
+
*/
|
|
8
|
+
export declare function walkFiles(dir: string, excludedDirs: Set<string>, sourceExtensions: Set<string>): Generator<string>;
|
|
9
|
+
//# sourceMappingURL=file-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-walker.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/file-walker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,wBAAiB,SAAS,CACtB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC9B,SAAS,CAAC,MAAM,CAAC,CAgBnB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File system traversal utilities.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* Recursively walk through files in a directory, yielding file paths that match
|
|
8
|
+
* the source extensions and are not in excluded directories.
|
|
9
|
+
*/
|
|
10
|
+
export function* walkFiles(dir, excludedDirs, sourceExtensions) {
|
|
11
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
12
|
+
for (const entry of entries) {
|
|
13
|
+
if (entry.isDirectory()) {
|
|
14
|
+
if (excludedDirs.has(entry.name))
|
|
15
|
+
continue;
|
|
16
|
+
yield* walkFiles(path.join(dir, entry.name), excludedDirs, sourceExtensions);
|
|
17
|
+
}
|
|
18
|
+
else if (entry.isFile()) {
|
|
19
|
+
if (sourceExtensions.has(path.extname(entry.name))) {
|
|
20
|
+
yield path.join(dir, entry.name);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=file-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-walker.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/file-walker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,SAAS,CAAC,CAAC,SAAS,CACtB,GAAW,EACX,YAAyB,EACzB,gBAA6B;IAE7B,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC3C,KAAK,CAAC,CAAC,SAAS,CACZ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAC1B,YAAY,EACZ,gBAAgB,CACnB,CAAC;QACN,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxB,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import path resolution and traversal.
|
|
3
|
+
* Handles aliased imports (@/path), relative imports (../path), and layout chains.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Extract all local imports (relative and aliased) from a source file via AST.
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractLocalImports(filePath: string, sourceExtensions: Set<string>, root?: string, pathMappings?: Record<string, string[]>): string[];
|
|
9
|
+
/**
|
|
10
|
+
* For a given page file, find all wrapping layout files up to the app root.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getLayoutChain(root: string, pageFile: string, sourceExtensions: Set<string>): string[];
|
|
13
|
+
//# sourceMappingURL=import-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-resolver.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/import-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4EH;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACxC,MAAM,EAAE,CAoDV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC9B,MAAM,EAAE,CAeV"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import path resolution and traversal.
|
|
3
|
+
* Handles aliased imports (@/path), relative imports (../path), and layout chains.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { parseSource, walk } from './ast.js';
|
|
8
|
+
/**
|
|
9
|
+
* Resolve an aliased import path (e.g., @/components/button) to an absolute file path.
|
|
10
|
+
* Uses tsconfig path mappings if provided.
|
|
11
|
+
*/
|
|
12
|
+
function resolveAliasedImport(importPath, root, sourceExtensions, pathMappings) {
|
|
13
|
+
if (!pathMappings)
|
|
14
|
+
return null;
|
|
15
|
+
for (const [alias, targets] of Object.entries(pathMappings)) {
|
|
16
|
+
const pattern = alias.replace(/\*/g, '(.*)');
|
|
17
|
+
const regex = new RegExp(`^${pattern}$`);
|
|
18
|
+
const match = importPath.match(regex);
|
|
19
|
+
if (match) {
|
|
20
|
+
const captured = match[1] ?? '';
|
|
21
|
+
for (const target of targets) {
|
|
22
|
+
const resolved = target.replace(/\*/g, captured);
|
|
23
|
+
const fullPath = path.join(root, resolved);
|
|
24
|
+
if (sourceExtensions.has(path.extname(fullPath))) {
|
|
25
|
+
if (fs.existsSync(fullPath))
|
|
26
|
+
return fullPath;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
for (const ext of sourceExtensions) {
|
|
30
|
+
const candidate = fullPath + ext;
|
|
31
|
+
if (fs.existsSync(candidate))
|
|
32
|
+
return candidate;
|
|
33
|
+
}
|
|
34
|
+
for (const ext of sourceExtensions) {
|
|
35
|
+
const candidate = path.join(fullPath, 'index' + ext);
|
|
36
|
+
if (fs.existsSync(candidate))
|
|
37
|
+
return candidate;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a relative import path to an absolute file path.
|
|
47
|
+
*/
|
|
48
|
+
function resolveLocalImport(fromDir, importPath, sourceExtensions) {
|
|
49
|
+
const joined = path.join(fromDir, importPath);
|
|
50
|
+
if (sourceExtensions.has(path.extname(joined))) {
|
|
51
|
+
return fs.existsSync(joined) ? joined : null;
|
|
52
|
+
}
|
|
53
|
+
for (const ext of sourceExtensions) {
|
|
54
|
+
const candidate = joined + ext;
|
|
55
|
+
if (fs.existsSync(candidate))
|
|
56
|
+
return candidate;
|
|
57
|
+
}
|
|
58
|
+
for (const ext of sourceExtensions) {
|
|
59
|
+
const candidate = path.join(joined, 'index' + ext);
|
|
60
|
+
if (fs.existsSync(candidate))
|
|
61
|
+
return candidate;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Extract all local imports (relative and aliased) from a source file via AST.
|
|
67
|
+
*/
|
|
68
|
+
export function extractLocalImports(filePath, sourceExtensions, root, pathMappings) {
|
|
69
|
+
let source;
|
|
70
|
+
try {
|
|
71
|
+
source = fs.readFileSync(filePath, 'utf-8');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
let ast;
|
|
77
|
+
try {
|
|
78
|
+
ast = parseSource(filePath, source);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const fromDir = path.dirname(filePath);
|
|
84
|
+
const results = [];
|
|
85
|
+
walk(ast, node => {
|
|
86
|
+
if (node.type !== 'ImportDeclaration' &&
|
|
87
|
+
node.type !== 'ExportNamedDeclaration' &&
|
|
88
|
+
node.type !== 'ExportAllDeclaration')
|
|
89
|
+
return;
|
|
90
|
+
const src = node.source;
|
|
91
|
+
if (!src || typeof src.value !== 'string')
|
|
92
|
+
return;
|
|
93
|
+
const importPath = src.value;
|
|
94
|
+
let resolved = null;
|
|
95
|
+
if (importPath.startsWith('.')) {
|
|
96
|
+
resolved = resolveLocalImport(fromDir, importPath, sourceExtensions);
|
|
97
|
+
}
|
|
98
|
+
else if (root && pathMappings) {
|
|
99
|
+
resolved = resolveAliasedImport(importPath, root, sourceExtensions, pathMappings);
|
|
100
|
+
}
|
|
101
|
+
if (resolved && !results.includes(resolved)) {
|
|
102
|
+
results.push(resolved);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* For a given page file, find all wrapping layout files up to the app root.
|
|
109
|
+
*/
|
|
110
|
+
export function getLayoutChain(root, pageFile, sourceExtensions) {
|
|
111
|
+
const layouts = [];
|
|
112
|
+
let dir = path.dirname(pageFile);
|
|
113
|
+
while (dir.startsWith(root)) {
|
|
114
|
+
for (const ext of sourceExtensions) {
|
|
115
|
+
const candidate = path.join(dir, `layout${ext}`);
|
|
116
|
+
if (fs.existsSync(candidate)) {
|
|
117
|
+
layouts.push(candidate);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
dir = path.dirname(dir);
|
|
121
|
+
}
|
|
122
|
+
return layouts;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=import-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/import-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extraction of translation keys from source files.
|
|
3
|
+
* Finds t('key') calls, useTranslation() bindings, and Trans components.
|
|
4
|
+
*/
|
|
5
|
+
import type { NamespaceMap } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Extract translation keys from a source file.
|
|
8
|
+
* Handles:
|
|
9
|
+
* - const { t } = useTranslation('ns') / getTranslation('ns')
|
|
10
|
+
* - const { t: myT } = useTranslation(...)
|
|
11
|
+
* - const t = await client.getTranslations(locale, 'ns')
|
|
12
|
+
* - t('namespace:key') calls
|
|
13
|
+
* - <Trans i18nKey="namespace:key"> components
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractKeysFromFile(filePath: string, routes: string[], result: NamespaceMap): void;
|
|
16
|
+
//# sourceMappingURL=key-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-extractor.d.ts","sourceRoot":"","sources":["../../../src/core/scanner-internals/key-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAW,YAAY,EAAE,MAAM,YAAY,CAAC;AA0BxD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,YAAY,GACrB,IAAI,CA2JN"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extraction of translation keys from source files.
|
|
3
|
+
* Finds t('key') calls, useTranslation() bindings, and Trans components.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { parseSource, walk, stringValue, namespacesFromArg } from './ast.js';
|
|
8
|
+
/**
|
|
9
|
+
* Add a key to the namespace map with its associated routes.
|
|
10
|
+
* Skips keys that look like paths or are suspiciously short/numeric.
|
|
11
|
+
*/
|
|
12
|
+
function addKey(map, namespace, key, routes) {
|
|
13
|
+
// Skip keys that look like URL paths or are suspiciously short/numeric
|
|
14
|
+
if (key.startsWith('/') || key.startsWith('.') || /^\d+$/.test(key))
|
|
15
|
+
return;
|
|
16
|
+
if (!map[namespace])
|
|
17
|
+
map[namespace] = new Map();
|
|
18
|
+
const existing = map[namespace].get(key) ?? [];
|
|
19
|
+
if (routes.length > 0) {
|
|
20
|
+
const merged = new Set(existing);
|
|
21
|
+
for (const route of routes)
|
|
22
|
+
merged.add(route);
|
|
23
|
+
map[namespace].set(key, Array.from(merged));
|
|
24
|
+
}
|
|
25
|
+
else if (existing.length === 0) {
|
|
26
|
+
map[namespace].set(key, []);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
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
|
|
37
|
+
*/
|
|
38
|
+
export function extractKeysFromFile(filePath, routes, result) {
|
|
39
|
+
let source;
|
|
40
|
+
try {
|
|
41
|
+
source = fs.readFileSync(filePath, 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let ast;
|
|
47
|
+
try {
|
|
48
|
+
ast = parseSource(filePath, source);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// --- Step 1: collect namespace bindings ---
|
|
54
|
+
// Maps the local variable name (e.g. 't') → the namespace(s) it's bound to.
|
|
55
|
+
const tBindings = new Map();
|
|
56
|
+
walk(ast, node => {
|
|
57
|
+
if (node.type !== 'VariableDeclaration')
|
|
58
|
+
return;
|
|
59
|
+
for (const decl of node.declarations) {
|
|
60
|
+
const init = decl.init;
|
|
61
|
+
if (!init)
|
|
62
|
+
continue;
|
|
63
|
+
// Unwrap await
|
|
64
|
+
const call = init.type === 'AwaitExpression'
|
|
65
|
+
? init.argument
|
|
66
|
+
: init;
|
|
67
|
+
if (!call || call.type !== 'CallExpression')
|
|
68
|
+
continue;
|
|
69
|
+
const callee = call.callee;
|
|
70
|
+
const args = call.arguments;
|
|
71
|
+
// useTranslation('ns') / getTranslation('ns')
|
|
72
|
+
const isHook = callee.type === 'Identifier' &&
|
|
73
|
+
(callee.name === 'useTranslation' ||
|
|
74
|
+
callee.name === 'getTranslation');
|
|
75
|
+
// client.getTranslations(locale, 'ns') / client.getT(locale, 'ns')
|
|
76
|
+
const isCmsStyle = callee.type === 'MemberExpression' &&
|
|
77
|
+
callee.property.type === 'Identifier' &&
|
|
78
|
+
/^getTranslations(?:WithFallback)?$|^getT$/.test(callee.property.name);
|
|
79
|
+
if (!isHook && !isCmsStyle)
|
|
80
|
+
continue;
|
|
81
|
+
const namespaces = isHook
|
|
82
|
+
? namespacesFromArg(args[0])
|
|
83
|
+
: namespacesFromArg(args[1]); // CMS style: getTranslations(locale, ns)
|
|
84
|
+
if (!namespaces.length)
|
|
85
|
+
continue;
|
|
86
|
+
const id = decl.id;
|
|
87
|
+
if (id.type === 'Identifier') {
|
|
88
|
+
// const t = useTranslation(...)
|
|
89
|
+
tBindings.set(id.name, namespaces);
|
|
90
|
+
}
|
|
91
|
+
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
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
// --- Step 2: extract keys from t('...') call expressions ---
|
|
113
|
+
// Only extract from variables that are explicitly bound to translation functions.
|
|
114
|
+
walk(ast, node => {
|
|
115
|
+
if (node.type !== 'CallExpression')
|
|
116
|
+
return;
|
|
117
|
+
const callee = node.callee;
|
|
118
|
+
if (callee.type !== 'Identifier')
|
|
119
|
+
return;
|
|
120
|
+
const varName = callee.name;
|
|
121
|
+
// Only process if this variable is bound to a translation function
|
|
122
|
+
if (!tBindings.has(varName))
|
|
123
|
+
return;
|
|
124
|
+
const args = node.arguments;
|
|
125
|
+
const keyStr = stringValue(args[0]);
|
|
126
|
+
if (!keyStr)
|
|
127
|
+
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);
|
|
132
|
+
}
|
|
133
|
+
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)
|
|
138
|
+
addKey(result, ns, keyStr, routes);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
// --- Step 3: <Trans i18nKey="namespace:key"> ---
|
|
142
|
+
walk(ast, node => {
|
|
143
|
+
if (node.type !== 'JSXOpeningElement')
|
|
144
|
+
return;
|
|
145
|
+
const name = node.name;
|
|
146
|
+
if (name.type !== 'JSXIdentifier' || name.name !== 'Trans')
|
|
147
|
+
return;
|
|
148
|
+
for (const attr of node.attributes) {
|
|
149
|
+
if (attr.type !== 'JSXAttribute')
|
|
150
|
+
continue;
|
|
151
|
+
const attrName = attr.name;
|
|
152
|
+
if (attrName.type !== 'JSXIdentifier' ||
|
|
153
|
+
attrName.name !== 'i18nKey')
|
|
154
|
+
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
|
+
}
|
|
163
|
+
if (!keyStr)
|
|
164
|
+
continue;
|
|
165
|
+
const colonIdx = keyStr.indexOf(':');
|
|
166
|
+
if (colonIdx <= 0)
|
|
167
|
+
continue;
|
|
168
|
+
addKey(result, keyStr.slice(0, colonIdx), keyStr.slice(colonIdx + 1), routes);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=key-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-extractor.js","sourceRoot":"","sources":["../../../src/core/scanner-internals/key-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
* Such pages are skipped from the preview route list because they have no UI to preview.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isRedirectOnlyPage(filePath: string): boolean;
|
|
10
|
+
/**
|
|
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, …) → []
|
|
17
|
+
*/
|
|
18
|
+
export declare function filePathToRoute(root: string, filePath: string): string[];
|
|
19
|
+
//# 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;;;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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
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
|
+
* Such pages are skipped from the preview route list because they have no UI to preview.
|
|
11
|
+
*/
|
|
12
|
+
export function isRedirectOnlyPage(filePath) {
|
|
13
|
+
let source;
|
|
14
|
+
try {
|
|
15
|
+
source = fs.readFileSync(filePath, 'utf-8');
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
let ast;
|
|
21
|
+
try {
|
|
22
|
+
ast = parseSource(filePath, source);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
let hasRedirect = false;
|
|
28
|
+
let hasJsxReturn = false;
|
|
29
|
+
walk(ast, node => {
|
|
30
|
+
if (node.type === 'CallExpression') {
|
|
31
|
+
const callee = node.callee;
|
|
32
|
+
if (callee.type === 'Identifier' && callee.name === 'redirect') {
|
|
33
|
+
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
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return hasRedirect && !hasJsxReturn;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
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, …) → []
|
|
57
|
+
*/
|
|
58
|
+
export function filePathToRoute(root, filePath) {
|
|
59
|
+
const base = path.basename(filePath, path.extname(filePath));
|
|
60
|
+
if (base !== 'page')
|
|
61
|
+
return [];
|
|
62
|
+
// Skip pages that only redirect — no UI to preview
|
|
63
|
+
if (isRedirectOnlyPage(filePath))
|
|
64
|
+
return [];
|
|
65
|
+
const rel = path.relative(root, filePath).replace(/\\/g, '/');
|
|
66
|
+
const appMatch = rel.match(/^(?:src\/)?app\/(.*?)page\.[jt]sx?$/);
|
|
67
|
+
if (!appMatch)
|
|
68
|
+
return [];
|
|
69
|
+
let routePath = appMatch[1] ?? '';
|
|
70
|
+
routePath = routePath.replace(/\([^)]+\)\//g, ''); // strip route groups
|
|
71
|
+
routePath = routePath.replace(/\/$/, ''); // strip trailing slash
|
|
72
|
+
return ['/' + routePath];
|
|
73
|
+
}
|
|
74
|
+
//# 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;;;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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
/** A preview route — either a plain path string or an object with per-route params. */
|
|
41
|
+
export type PreviewRoute = string | {
|
|
42
|
+
route: string;
|
|
43
|
+
params?: Record<string, string>;
|
|
44
|
+
};
|
|
45
|
+
/** namespace → (key → previewRoutes[]) */
|
|
46
|
+
export type NamespaceMap = Record<string, Map<string, PreviewRoute[]>>;
|
|
47
|
+
/** Return the route string key used for deduplication. */
|
|
48
|
+
export declare function routeKey(r: PreviewRoute): string;
|
|
49
|
+
/** AST node type for type-safe walking. */
|
|
50
|
+
export type AstNode = {
|
|
51
|
+
type: string;
|
|
52
|
+
} & Record<string, unknown>;
|
|
53
|
+
//# 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;CACxB;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"}
|