ai-localize-scanner 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +24 -24
- package/dist/index.mjs +4 -4
- package/package.json +3 -3
- package/src/asset-scanner.ts +2 -2
- package/src/ast-scanner.ts +2 -2
- package/src/incremental-scanner.ts +2 -2
- package/src/project-scanner.ts +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DetectedText, AssetReference, LegacyCdnUrl, LocalizationConfig, ScanResult } from '
|
|
1
|
+
import { DetectedText, AssetReference, LegacyCdnUrl, LocalizationConfig, ScanResult } from 'ai-localize-shared';
|
|
2
2
|
|
|
3
3
|
interface AstScanOptions {
|
|
4
4
|
filePath: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DetectedText, AssetReference, LegacyCdnUrl, LocalizationConfig, ScanResult } from '
|
|
1
|
+
import { DetectedText, AssetReference, LegacyCdnUrl, LocalizationConfig, ScanResult } from 'ai-localize-shared';
|
|
2
2
|
|
|
3
3
|
interface AstScanOptions {
|
|
4
4
|
filePath: string;
|
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
42
42
|
var parser = __toESM(require("@babel/parser"));
|
|
43
43
|
var import_traverse = __toESM(require("@babel/traverse"));
|
|
44
44
|
var t = __toESM(require("@babel/types"));
|
|
45
|
-
var
|
|
45
|
+
var import_ai_localize_shared = require("ai-localize-shared");
|
|
46
46
|
var TRANSLATION_IMPORT_SOURCES = /* @__PURE__ */ new Set([
|
|
47
47
|
"react-i18next",
|
|
48
48
|
"i18next",
|
|
@@ -80,8 +80,8 @@ var AstScanner = class {
|
|
|
80
80
|
this.collectTranslationImports(ast);
|
|
81
81
|
(0, import_traverse.default)(ast, {
|
|
82
82
|
JSXText: (nodePath) => {
|
|
83
|
-
const text = (0,
|
|
84
|
-
if (!(0,
|
|
83
|
+
const text = (0, import_ai_localize_shared.normalizeText)(nodePath.node.value);
|
|
84
|
+
if (!(0, import_ai_localize_shared.isHumanReadableText)(text)) return;
|
|
85
85
|
if (this.isInsideTranslationCall(nodePath)) return;
|
|
86
86
|
this.addDetected(
|
|
87
87
|
text,
|
|
@@ -93,11 +93,11 @@ var AstScanner = class {
|
|
|
93
93
|
},
|
|
94
94
|
JSXAttribute: (nodePath) => {
|
|
95
95
|
const attrName = t.isJSXIdentifier(nodePath.node.name) ? nodePath.node.name.name : "";
|
|
96
|
-
if (!
|
|
96
|
+
if (!import_ai_localize_shared.TEXT_ATTRIBUTE_NAMES.has(attrName.toLowerCase())) return;
|
|
97
97
|
const valueNode = nodePath.node.value;
|
|
98
98
|
if (!t.isStringLiteral(valueNode)) return;
|
|
99
|
-
const text = (0,
|
|
100
|
-
if (!(0,
|
|
99
|
+
const text = (0, import_ai_localize_shared.normalizeText)(valueNode.value);
|
|
100
|
+
if (!(0, import_ai_localize_shared.isHumanReadableText)(text)) return;
|
|
101
101
|
if (this.isInsideTranslationCall(nodePath)) return;
|
|
102
102
|
const context = this.mapAttrToContext(attrName);
|
|
103
103
|
this.addDetected(
|
|
@@ -114,8 +114,8 @@ var AstScanner = class {
|
|
|
114
114
|
if (t.isJSXAttribute(nodePath.parent)) return;
|
|
115
115
|
if (this.isInsideTranslationCall(nodePath)) return;
|
|
116
116
|
if (/^[a-z][a-z0-9_.]+$/.test(nodePath.node.value)) return;
|
|
117
|
-
const text = (0,
|
|
118
|
-
if (!(0,
|
|
117
|
+
const text = (0, import_ai_localize_shared.normalizeText)(nodePath.node.value);
|
|
118
|
+
if (!(0, import_ai_localize_shared.isHumanReadableText)(text)) return;
|
|
119
119
|
this.addDetected(
|
|
120
120
|
text,
|
|
121
121
|
nodePath.node.loc?.start.line ?? 0,
|
|
@@ -127,8 +127,8 @@ var AstScanner = class {
|
|
|
127
127
|
TemplateLiteral: (nodePath) => {
|
|
128
128
|
if (nodePath.node.expressions.length > 0) return;
|
|
129
129
|
if (this.isInsideTranslationCall(nodePath)) return;
|
|
130
|
-
const text = (0,
|
|
131
|
-
if (!(0,
|
|
130
|
+
const text = (0, import_ai_localize_shared.normalizeText)(nodePath.node.quasis[0]?.value.cooked ?? "");
|
|
131
|
+
if (!(0, import_ai_localize_shared.isHumanReadableText)(text)) return;
|
|
132
132
|
this.addDetected(
|
|
133
133
|
text,
|
|
134
134
|
nodePath.node.loc?.start.line ?? 0,
|
|
@@ -170,7 +170,7 @@ var AstScanner = class {
|
|
|
170
170
|
return false;
|
|
171
171
|
}
|
|
172
172
|
addDetected(text, line, column, context, nodeType) {
|
|
173
|
-
const key = (0,
|
|
173
|
+
const key = (0, import_ai_localize_shared.generateLocaleKey)(
|
|
174
174
|
this.options.filePath,
|
|
175
175
|
text,
|
|
176
176
|
this.options.sourceRoot || "src"
|
|
@@ -202,9 +202,9 @@ var AstScanner = class {
|
|
|
202
202
|
let m;
|
|
203
203
|
jsxTextRegex.lastIndex = 0;
|
|
204
204
|
while ((m = jsxTextRegex.exec(line)) !== null) {
|
|
205
|
-
const text = (0,
|
|
206
|
-
if (!(0,
|
|
207
|
-
const key = (0,
|
|
205
|
+
const text = (0, import_ai_localize_shared.normalizeText)(m[1]);
|
|
206
|
+
if (!(0, import_ai_localize_shared.isHumanReadableText)(text)) continue;
|
|
207
|
+
const key = (0, import_ai_localize_shared.generateLocaleKey)(this.options.filePath, text, this.options.sourceRoot || "src");
|
|
208
208
|
results.push({
|
|
209
209
|
filePath: this.options.filePath,
|
|
210
210
|
line: idx + 1,
|
|
@@ -224,7 +224,7 @@ var AstScanner = class {
|
|
|
224
224
|
// src/asset-scanner.ts
|
|
225
225
|
var fs = __toESM(require("fs"));
|
|
226
226
|
var path = __toESM(require("path"));
|
|
227
|
-
var
|
|
227
|
+
var import_ai_localize_shared2 = require("ai-localize-shared");
|
|
228
228
|
var CDN_URL_PATTERN = /https?:\/\/[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,}\/[^\s"'`\)\]>]+/g;
|
|
229
229
|
var CSS_URL_PATTERN = /url\(['"\s]?([^'")]+)['"\s]?\)/g;
|
|
230
230
|
var IMPORT_ASSET_PATTERN = /import\s+\w+\s+from\s+['"]([^'"]+\.(png|jpg|jpeg|svg|webp|gif|ico|woff|woff2|ttf|eot|mp4))['"];?/gi;
|
|
@@ -297,7 +297,7 @@ var AssetScanner = class {
|
|
|
297
297
|
CDN_URL_PATTERN.lastIndex = 0;
|
|
298
298
|
while ((m = CDN_URL_PATTERN.exec(content)) !== null) {
|
|
299
299
|
const url = m[0];
|
|
300
|
-
if (!
|
|
300
|
+
if (!import_ai_localize_shared2.ASSET_EXTENSIONS.some((ext) => url.includes(`.${ext}`))) continue;
|
|
301
301
|
const line = this.getLineNumber(content, m.index);
|
|
302
302
|
if (!legacyCdnUrls.find((u) => u.url === url && u.line === line)) {
|
|
303
303
|
legacyCdnUrls.push({ filePath, line, url, assetPath: this.extractPathFromUrl(url) });
|
|
@@ -310,7 +310,7 @@ var AssetScanner = class {
|
|
|
310
310
|
}
|
|
311
311
|
getAssetType(assetPath) {
|
|
312
312
|
const ext = path.extname(assetPath).toLowerCase().replace(".", "");
|
|
313
|
-
return
|
|
313
|
+
return import_ai_localize_shared2.ASSET_EXTENSIONS.includes(ext) ? ext : "other";
|
|
314
314
|
}
|
|
315
315
|
extractPathFromUrl(url) {
|
|
316
316
|
try {
|
|
@@ -325,17 +325,17 @@ var AssetScanner = class {
|
|
|
325
325
|
var fs2 = __toESM(require("fs"));
|
|
326
326
|
var path2 = __toESM(require("path"));
|
|
327
327
|
var crypto = __toESM(require("crypto"));
|
|
328
|
-
var
|
|
328
|
+
var import_ai_localize_shared3 = require("ai-localize-shared");
|
|
329
329
|
var IncrementalScanCache = class {
|
|
330
330
|
cachePath;
|
|
331
331
|
cache;
|
|
332
332
|
constructor(cacheDir) {
|
|
333
|
-
(0,
|
|
333
|
+
(0, import_ai_localize_shared3.ensureDir)(cacheDir);
|
|
334
334
|
this.cachePath = path2.join(cacheDir, "scan-cache.json");
|
|
335
335
|
this.cache = this.load();
|
|
336
336
|
}
|
|
337
337
|
load() {
|
|
338
|
-
const existing = (0,
|
|
338
|
+
const existing = (0, import_ai_localize_shared3.readJsonSafe)(this.cachePath);
|
|
339
339
|
if (existing?.version === "1") return existing;
|
|
340
340
|
return { version: "1", lastRun: (/* @__PURE__ */ new Date()).toISOString(), fileHashes: {}, processedFiles: {} };
|
|
341
341
|
}
|
|
@@ -355,7 +355,7 @@ var IncrementalScanCache = class {
|
|
|
355
355
|
}
|
|
356
356
|
persist() {
|
|
357
357
|
this.cache.lastRun = (/* @__PURE__ */ new Date()).toISOString();
|
|
358
|
-
(0,
|
|
358
|
+
(0, import_ai_localize_shared3.writeJson)(this.cachePath, this.cache);
|
|
359
359
|
}
|
|
360
360
|
hashFile(filePath) {
|
|
361
361
|
try {
|
|
@@ -373,7 +373,7 @@ var IncrementalScanCache = class {
|
|
|
373
373
|
// src/project-scanner.ts
|
|
374
374
|
var path3 = __toESM(require("path"));
|
|
375
375
|
var os = __toESM(require("os"));
|
|
376
|
-
var
|
|
376
|
+
var import_ai_localize_shared4 = require("ai-localize-shared");
|
|
377
377
|
var ProjectScanner = class {
|
|
378
378
|
config;
|
|
379
379
|
sourceRoot;
|
|
@@ -391,8 +391,8 @@ var ProjectScanner = class {
|
|
|
391
391
|
}
|
|
392
392
|
async scan(options = {}) {
|
|
393
393
|
const startTime = Date.now();
|
|
394
|
-
const filesToScan = options.files?.length ? options.files : (0,
|
|
395
|
-
...
|
|
394
|
+
const filesToScan = options.files?.length ? options.files : (0, import_ai_localize_shared4.collectFiles)(this.sourceRoot, import_ai_localize_shared4.SOURCE_EXTENSIONS, [
|
|
395
|
+
...import_ai_localize_shared4.DEFAULT_IGNORE_DIRS,
|
|
396
396
|
...this.config.ignorePatterns || []
|
|
397
397
|
]);
|
|
398
398
|
const allTexts = [];
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
normalizeText,
|
|
8
8
|
TEXT_ATTRIBUTE_NAMES,
|
|
9
9
|
generateLocaleKey
|
|
10
|
-
} from "
|
|
10
|
+
} from "ai-localize-shared";
|
|
11
11
|
var TRANSLATION_IMPORT_SOURCES = /* @__PURE__ */ new Set([
|
|
12
12
|
"react-i18next",
|
|
13
13
|
"i18next",
|
|
@@ -189,7 +189,7 @@ var AstScanner = class {
|
|
|
189
189
|
// src/asset-scanner.ts
|
|
190
190
|
import * as fs from "fs";
|
|
191
191
|
import * as path from "path";
|
|
192
|
-
import { ASSET_EXTENSIONS } from "
|
|
192
|
+
import { ASSET_EXTENSIONS } from "ai-localize-shared";
|
|
193
193
|
var CDN_URL_PATTERN = /https?:\/\/[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,}\/[^\s"'`\)\]>]+/g;
|
|
194
194
|
var CSS_URL_PATTERN = /url\(['"\s]?([^'")]+)['"\s]?\)/g;
|
|
195
195
|
var IMPORT_ASSET_PATTERN = /import\s+\w+\s+from\s+['"]([^'"]+\.(png|jpg|jpeg|svg|webp|gif|ico|woff|woff2|ttf|eot|mp4))['"];?/gi;
|
|
@@ -290,7 +290,7 @@ var AssetScanner = class {
|
|
|
290
290
|
import * as fs2 from "fs";
|
|
291
291
|
import * as path2 from "path";
|
|
292
292
|
import * as crypto from "crypto";
|
|
293
|
-
import { readJsonSafe, writeJson, ensureDir } from "
|
|
293
|
+
import { readJsonSafe, writeJson, ensureDir } from "ai-localize-shared";
|
|
294
294
|
var IncrementalScanCache = class {
|
|
295
295
|
cachePath;
|
|
296
296
|
cache;
|
|
@@ -338,7 +338,7 @@ var IncrementalScanCache = class {
|
|
|
338
338
|
// src/project-scanner.ts
|
|
339
339
|
import * as path3 from "path";
|
|
340
340
|
import * as os from "os";
|
|
341
|
-
import { collectFiles, DEFAULT_IGNORE_DIRS, SOURCE_EXTENSIONS } from "
|
|
341
|
+
import { collectFiles, DEFAULT_IGNORE_DIRS, SOURCE_EXTENSIONS } from "ai-localize-shared";
|
|
342
342
|
var ProjectScanner = class {
|
|
343
343
|
config;
|
|
344
344
|
sourceRoot;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-localize-scanner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "AST-based hardcoded text scanner for frontend applications",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"@babel/traverse": "^7.23.9",
|
|
18
18
|
"@babel/types": "^7.23.9",
|
|
19
19
|
"glob": "^10.3.10",
|
|
20
|
-
"ai-localize-shared": "1.0.
|
|
21
|
-
"ai-localize-config": "1.0.
|
|
20
|
+
"ai-localize-shared": "1.0.1",
|
|
21
|
+
"ai-localize-config": "1.0.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/babel__traverse": "^7.20.5",
|
package/src/asset-scanner.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
|
|
4
|
-
import type { AssetReference, AssetType, LegacyCdnUrl } from '
|
|
5
|
-
import { ASSET_EXTENSIONS } from '
|
|
4
|
+
import type { AssetReference, AssetType, LegacyCdnUrl } from 'ai-localize-shared';
|
|
5
|
+
import { ASSET_EXTENSIONS } from 'ai-localize-shared';
|
|
6
6
|
|
|
7
7
|
const CDN_URL_PATTERN = /https?:\/\/[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,}\/[^\s"'`\)\]>]+/g;
|
|
8
8
|
const CSS_URL_PATTERN = /url\(['"\s]?([^'")]+)['"\s]?\)/g;
|
package/src/ast-scanner.ts
CHANGED
|
@@ -2,13 +2,13 @@ import * as parser from '@babel/parser';
|
|
|
2
2
|
import traverse from '@babel/traverse';
|
|
3
3
|
import * as t from '@babel/types';
|
|
4
4
|
|
|
5
|
-
import type { DetectedText, TextContext } from '
|
|
5
|
+
import type { DetectedText, TextContext } from 'ai-localize-shared';
|
|
6
6
|
import {
|
|
7
7
|
isHumanReadableText,
|
|
8
8
|
normalizeText,
|
|
9
9
|
TEXT_ATTRIBUTE_NAMES,
|
|
10
10
|
generateLocaleKey,
|
|
11
|
-
} from '
|
|
11
|
+
} from 'ai-localize-shared';
|
|
12
12
|
|
|
13
13
|
export interface AstScanOptions {
|
|
14
14
|
filePath: string;
|
|
@@ -2,8 +2,8 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as crypto from 'crypto';
|
|
4
4
|
|
|
5
|
-
import type { IncrementalCache, DetectedText } from '
|
|
6
|
-
import { readJsonSafe, writeJson, ensureDir } from '
|
|
5
|
+
import type { IncrementalCache, DetectedText } from 'ai-localize-shared';
|
|
6
|
+
import { readJsonSafe, writeJson, ensureDir } from 'ai-localize-shared';
|
|
7
7
|
|
|
8
8
|
export class IncrementalScanCache {
|
|
9
9
|
private cachePath: string;
|
package/src/project-scanner.ts
CHANGED
|
@@ -7,8 +7,8 @@ import type {
|
|
|
7
7
|
LegacyCdnUrl,
|
|
8
8
|
ScanResult,
|
|
9
9
|
LocalizationConfig,
|
|
10
|
-
} from '
|
|
11
|
-
import { collectFiles, DEFAULT_IGNORE_DIRS, SOURCE_EXTENSIONS } from '
|
|
10
|
+
} from 'ai-localize-shared';
|
|
11
|
+
import { collectFiles, DEFAULT_IGNORE_DIRS, SOURCE_EXTENSIONS } from 'ai-localize-shared';
|
|
12
12
|
|
|
13
13
|
import { AstScanner } from './ast-scanner.js';
|
|
14
14
|
import { AssetScanner } from './asset-scanner.js';
|