apdev-js 0.1.1 → 0.2.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/README.md +1 -1
- package/dist/cli.js +290 -98
- package/dist/index.cjs +269 -79
- package/dist/index.d.cts +42 -4
- package/dist/index.d.ts +42 -4
- package/dist/index.js +278 -92
- package/package.json +23 -7
- package/src/charsets/base.json +44 -0
- package/src/charsets/chinese.json +9 -0
- package/src/charsets/japanese.json +11 -0
- package/src/charsets/korean.json +11 -0
package/dist/index.js
CHANGED
|
@@ -6,82 +6,102 @@ var getDirname = () => path.dirname(getFilename());
|
|
|
6
6
|
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
7
|
|
|
8
8
|
// src/check-chars.ts
|
|
9
|
-
import { readFileSync } from "fs";
|
|
10
|
-
import { extname } from "path";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
[
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
[9472, 9599],
|
|
41
|
-
// Box Drawing
|
|
42
|
-
[9632, 9727],
|
|
43
|
-
// Geometric Shapes
|
|
44
|
-
[11008, 11263],
|
|
45
|
-
// Miscellaneous Symbols and Arrows
|
|
46
|
-
[65024, 65039]
|
|
47
|
-
// Variation Selectors
|
|
48
|
-
];
|
|
49
|
-
var ALL_RANGES = [...EMOJI_RANGES, ...EXTRA_ALLOWED_RANGES];
|
|
50
|
-
var DANGEROUS_CODEPOINTS = /* @__PURE__ */ new Map([
|
|
51
|
-
// Bidi control characters (Trojan Source - CVE-2021-42574)
|
|
52
|
-
[8234, "LEFT-TO-RIGHT EMBEDDING"],
|
|
53
|
-
[8235, "RIGHT-TO-LEFT EMBEDDING"],
|
|
54
|
-
[8236, "POP DIRECTIONAL FORMATTING"],
|
|
55
|
-
[8237, "LEFT-TO-RIGHT OVERRIDE"],
|
|
56
|
-
[8238, "RIGHT-TO-LEFT OVERRIDE"],
|
|
57
|
-
[8294, "LEFT-TO-RIGHT ISOLATE"],
|
|
58
|
-
[8295, "RIGHT-TO-LEFT ISOLATE"],
|
|
59
|
-
[8296, "FIRST STRONG ISOLATE"],
|
|
60
|
-
[8297, "POP DIRECTIONAL ISOLATE"],
|
|
61
|
-
// Zero-width characters
|
|
62
|
-
[8203, "ZERO WIDTH SPACE"],
|
|
63
|
-
[8204, "ZERO WIDTH NON-JOINER"],
|
|
64
|
-
[8205, "ZERO WIDTH JOINER"],
|
|
65
|
-
[8206, "LEFT-TO-RIGHT MARK"],
|
|
66
|
-
[8207, "RIGHT-TO-LEFT MARK"],
|
|
67
|
-
[8288, "WORD JOINER"]
|
|
68
|
-
]);
|
|
69
|
-
var PYTHON_SUFFIXES = /* @__PURE__ */ new Set([".py"]);
|
|
70
|
-
var JS_SUFFIXES = /* @__PURE__ */ new Set([".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs"]);
|
|
71
|
-
function isAllowedChar(c) {
|
|
72
|
-
const code = c.codePointAt(0);
|
|
73
|
-
if (code <= 127) {
|
|
74
|
-
return true;
|
|
9
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
10
|
+
import { extname, dirname, join, sep } from "path";
|
|
11
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
12
|
+
function getCharsetsDir() {
|
|
13
|
+
const thisDir = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath2(import.meta.url));
|
|
14
|
+
const devPath = join(thisDir, "charsets");
|
|
15
|
+
if (existsSync(devPath)) {
|
|
16
|
+
return devPath;
|
|
17
|
+
}
|
|
18
|
+
return join(thisDir, "..", "src", "charsets");
|
|
19
|
+
}
|
|
20
|
+
function loadCharset(nameOrPath) {
|
|
21
|
+
if (nameOrPath.includes(sep) || nameOrPath.includes("/") || nameOrPath.endsWith(".json")) {
|
|
22
|
+
if (!existsSync(nameOrPath)) {
|
|
23
|
+
throw new Error(`Charset file not found: ${nameOrPath}`);
|
|
24
|
+
}
|
|
25
|
+
return JSON.parse(readFileSync(nameOrPath, "utf-8"));
|
|
26
|
+
}
|
|
27
|
+
const filePath = join(getCharsetsDir(), `${nameOrPath}.json`);
|
|
28
|
+
if (!existsSync(filePath)) {
|
|
29
|
+
throw new Error(`Unknown charset: ${nameOrPath}`);
|
|
30
|
+
}
|
|
31
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
32
|
+
}
|
|
33
|
+
function parseRanges(entries) {
|
|
34
|
+
return entries.map((e) => [parseInt(e.start, 16), parseInt(e.end, 16)]);
|
|
35
|
+
}
|
|
36
|
+
function parseDangerous(entries) {
|
|
37
|
+
const map = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const e of entries) {
|
|
39
|
+
map.set(parseInt(e.code, 16), e.name);
|
|
75
40
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
41
|
+
return map;
|
|
42
|
+
}
|
|
43
|
+
function resolveCharsets(charsetNames, charsetFiles) {
|
|
44
|
+
const base = loadCharset("base");
|
|
45
|
+
const rangesSet = /* @__PURE__ */ new Map();
|
|
46
|
+
const dangerous = parseDangerous(base.dangerous ?? []);
|
|
47
|
+
function addRanges(entries) {
|
|
48
|
+
for (const [s, e] of parseRanges(entries)) {
|
|
49
|
+
rangesSet.set(`${s}-${e}`, [s, e]);
|
|
79
50
|
}
|
|
80
51
|
}
|
|
52
|
+
addRanges(base.emoji_ranges ?? []);
|
|
53
|
+
addRanges(base.extra_ranges ?? []);
|
|
54
|
+
for (const name of charsetNames) {
|
|
55
|
+
const data = loadCharset(name);
|
|
56
|
+
addRanges(data.emoji_ranges ?? []);
|
|
57
|
+
addRanges(data.extra_ranges ?? []);
|
|
58
|
+
if (data.dangerous) {
|
|
59
|
+
for (const [code, dname] of parseDangerous(data.dangerous)) {
|
|
60
|
+
dangerous.set(code, dname);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const path2 of charsetFiles) {
|
|
65
|
+
const data = loadCharset(path2);
|
|
66
|
+
addRanges(data.emoji_ranges ?? []);
|
|
67
|
+
addRanges(data.extra_ranges ?? []);
|
|
68
|
+
if (data.dangerous) {
|
|
69
|
+
for (const [code, dname] of parseDangerous(data.dangerous)) {
|
|
70
|
+
dangerous.set(code, dname);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const ranges = [...rangesSet.values()].sort((a, b) => a[0] - b[0]);
|
|
75
|
+
return { ranges, dangerous };
|
|
76
|
+
}
|
|
77
|
+
var PYTHON_SUFFIXES = /* @__PURE__ */ new Set([".py"]);
|
|
78
|
+
var JS_SUFFIXES = /* @__PURE__ */ new Set([".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs"]);
|
|
79
|
+
function isInRanges(code, ranges) {
|
|
80
|
+
if (code <= 127) return true;
|
|
81
|
+
for (const [start, end] of ranges) {
|
|
82
|
+
if (code >= start && code <= end) return true;
|
|
83
|
+
}
|
|
81
84
|
return false;
|
|
82
85
|
}
|
|
86
|
+
var _baseRanges = null;
|
|
87
|
+
var _baseDangerous = null;
|
|
88
|
+
function getBaseDefaults() {
|
|
89
|
+
if (!_baseRanges || !_baseDangerous) {
|
|
90
|
+
const defaults = resolveCharsets([], []);
|
|
91
|
+
_baseRanges = defaults.ranges;
|
|
92
|
+
_baseDangerous = defaults.dangerous;
|
|
93
|
+
}
|
|
94
|
+
return { ranges: _baseRanges, dangerous: _baseDangerous };
|
|
95
|
+
}
|
|
96
|
+
function isAllowedChar(c) {
|
|
97
|
+
const { ranges, dangerous } = getBaseDefaults();
|
|
98
|
+
const code = c.codePointAt(0);
|
|
99
|
+
if (dangerous.has(code)) return false;
|
|
100
|
+
return isInRanges(code, ranges);
|
|
101
|
+
}
|
|
83
102
|
function isDangerousChar(c) {
|
|
84
|
-
|
|
103
|
+
const { dangerous } = getBaseDefaults();
|
|
104
|
+
return dangerous.has(c.codePointAt(0));
|
|
85
105
|
}
|
|
86
106
|
function computeCommentMask(content, suffix) {
|
|
87
107
|
if (PYTHON_SUFFIXES.has(suffix)) {
|
|
@@ -200,8 +220,13 @@ function computeCommentMaskJs(content) {
|
|
|
200
220
|
}
|
|
201
221
|
return mask;
|
|
202
222
|
}
|
|
203
|
-
function checkFile(filePath, maxProblems = 5) {
|
|
223
|
+
function checkFile(filePath, maxProblems = 5, extraRanges, dangerousMap) {
|
|
204
224
|
const problems = [];
|
|
225
|
+
if (!extraRanges || !dangerousMap) {
|
|
226
|
+
const defaults = getBaseDefaults();
|
|
227
|
+
extraRanges ??= defaults.ranges;
|
|
228
|
+
dangerousMap ??= defaults.dangerous;
|
|
229
|
+
}
|
|
205
230
|
try {
|
|
206
231
|
const content = readFileSync(filePath, "utf-8");
|
|
207
232
|
const suffix = extname(filePath).toLowerCase();
|
|
@@ -211,15 +236,15 @@ function checkFile(filePath, maxProblems = 5) {
|
|
|
211
236
|
for (const char of content) {
|
|
212
237
|
position++;
|
|
213
238
|
const code = char.codePointAt(0);
|
|
214
|
-
if (
|
|
239
|
+
if (dangerousMap.has(code)) {
|
|
215
240
|
if (!commentMask.has(offset)) {
|
|
216
|
-
const name =
|
|
241
|
+
const name = dangerousMap.get(code);
|
|
217
242
|
const hex = code.toString(16).toUpperCase().padStart(4, "0");
|
|
218
243
|
problems.push(
|
|
219
244
|
`Dangerous character in code at position ${position}: U+${hex} (${name})`
|
|
220
245
|
);
|
|
221
246
|
}
|
|
222
|
-
} else if (!
|
|
247
|
+
} else if (!isInRanges(code, extraRanges)) {
|
|
223
248
|
const hex = code.toString(16).toUpperCase().padStart(4, "0");
|
|
224
249
|
problems.push(
|
|
225
250
|
`Illegal character at position ${position}: ${JSON.stringify(char)} (U+${hex})`
|
|
@@ -230,15 +255,169 @@ function checkFile(filePath, maxProblems = 5) {
|
|
|
230
255
|
}
|
|
231
256
|
offset += char.length;
|
|
232
257
|
}
|
|
233
|
-
} catch {
|
|
234
|
-
problems.push(`Failed to read file: ${filePath}`);
|
|
258
|
+
} catch (e) {
|
|
259
|
+
problems.push(`Failed to read file: ${filePath} (${e})`);
|
|
235
260
|
}
|
|
236
261
|
return problems;
|
|
237
262
|
}
|
|
238
|
-
|
|
263
|
+
var SKIP_SUFFIXES = /* @__PURE__ */ new Set([
|
|
264
|
+
// Bytecode
|
|
265
|
+
".pyc",
|
|
266
|
+
".pyo",
|
|
267
|
+
// Images
|
|
268
|
+
".png",
|
|
269
|
+
".jpg",
|
|
270
|
+
".jpeg",
|
|
271
|
+
".gif",
|
|
272
|
+
".bmp",
|
|
273
|
+
".ico",
|
|
274
|
+
".svg",
|
|
275
|
+
".webp",
|
|
276
|
+
// Fonts
|
|
277
|
+
".ttf",
|
|
278
|
+
".otf",
|
|
279
|
+
".woff",
|
|
280
|
+
".woff2",
|
|
281
|
+
".eot",
|
|
282
|
+
// Archives
|
|
283
|
+
".zip",
|
|
284
|
+
".tar",
|
|
285
|
+
".gz",
|
|
286
|
+
".bz2",
|
|
287
|
+
".xz",
|
|
288
|
+
".7z",
|
|
289
|
+
// Compiled / binary
|
|
290
|
+
".so",
|
|
291
|
+
".dylib",
|
|
292
|
+
".dll",
|
|
293
|
+
".exe",
|
|
294
|
+
".o",
|
|
295
|
+
".a",
|
|
296
|
+
".whl",
|
|
297
|
+
".egg",
|
|
298
|
+
// Media
|
|
299
|
+
".mp3",
|
|
300
|
+
".mp4",
|
|
301
|
+
".wav",
|
|
302
|
+
".avi",
|
|
303
|
+
".mov",
|
|
304
|
+
".flac",
|
|
305
|
+
".ogg",
|
|
306
|
+
// Documents
|
|
307
|
+
".pdf",
|
|
308
|
+
".doc",
|
|
309
|
+
".docx",
|
|
310
|
+
".xls",
|
|
311
|
+
".xlsx",
|
|
312
|
+
".ppt",
|
|
313
|
+
".pptx",
|
|
314
|
+
// Data
|
|
315
|
+
".db",
|
|
316
|
+
".sqlite",
|
|
317
|
+
".sqlite3",
|
|
318
|
+
".pickle",
|
|
319
|
+
".pkl"
|
|
320
|
+
]);
|
|
321
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
322
|
+
"__pycache__",
|
|
323
|
+
"node_modules",
|
|
324
|
+
".git",
|
|
325
|
+
".venv",
|
|
326
|
+
"venv",
|
|
327
|
+
".tox",
|
|
328
|
+
".mypy_cache",
|
|
329
|
+
".pytest_cache",
|
|
330
|
+
".ruff_cache",
|
|
331
|
+
"dist",
|
|
332
|
+
"build"
|
|
333
|
+
]);
|
|
334
|
+
var DEFAULT_DIRS = ["src", "tests", "examples"];
|
|
335
|
+
var DEFAULT_GLOBS = ["*.md", "*.yml", "*.yaml", "*.json", ".gitignore"];
|
|
336
|
+
function walkDir(directory) {
|
|
337
|
+
const files = [];
|
|
338
|
+
let entries;
|
|
339
|
+
try {
|
|
340
|
+
entries = readdirSync(directory).sort();
|
|
341
|
+
} catch {
|
|
342
|
+
return files;
|
|
343
|
+
}
|
|
344
|
+
for (const name of entries) {
|
|
345
|
+
if (name.startsWith(".")) continue;
|
|
346
|
+
const fullPath = join(directory, name);
|
|
347
|
+
let stat;
|
|
348
|
+
try {
|
|
349
|
+
stat = statSync(fullPath);
|
|
350
|
+
} catch {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (stat.isDirectory()) {
|
|
354
|
+
if (SKIP_DIRS.has(name) || name.endsWith(".egg-info")) continue;
|
|
355
|
+
files.push(...walkDir(fullPath));
|
|
356
|
+
} else if (stat.isFile()) {
|
|
357
|
+
if (SKIP_SUFFIXES.has(extname(name).toLowerCase())) continue;
|
|
358
|
+
files.push(fullPath);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return files;
|
|
362
|
+
}
|
|
363
|
+
function defaultProjectFiles() {
|
|
364
|
+
const cwd = process.cwd();
|
|
365
|
+
const files = [];
|
|
366
|
+
for (const dirname3 of DEFAULT_DIRS) {
|
|
367
|
+
const d = join(cwd, dirname3);
|
|
368
|
+
if (existsSync(d) && statSync(d).isDirectory()) {
|
|
369
|
+
files.push(...walkDir(d));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
for (const pattern of DEFAULT_GLOBS) {
|
|
373
|
+
if (pattern.startsWith("*.")) {
|
|
374
|
+
const suffix = pattern.slice(1);
|
|
375
|
+
try {
|
|
376
|
+
for (const name of readdirSync(cwd).sort()) {
|
|
377
|
+
if (name.endsWith(suffix) && statSync(join(cwd, name)).isFile()) {
|
|
378
|
+
files.push(join(cwd, name));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
} catch {
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
const fullPath = join(cwd, pattern);
|
|
385
|
+
if (existsSync(fullPath) && statSync(fullPath).isFile()) {
|
|
386
|
+
files.push(fullPath);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return files;
|
|
391
|
+
}
|
|
392
|
+
function resolvePaths(paths) {
|
|
393
|
+
if (paths.length === 0) {
|
|
394
|
+
return defaultProjectFiles();
|
|
395
|
+
}
|
|
396
|
+
const result = [];
|
|
397
|
+
for (const p of paths) {
|
|
398
|
+
try {
|
|
399
|
+
if (statSync(p).isDirectory()) {
|
|
400
|
+
result.push(...walkDir(p));
|
|
401
|
+
} else {
|
|
402
|
+
result.push(p);
|
|
403
|
+
}
|
|
404
|
+
} catch {
|
|
405
|
+
result.push(p);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return result;
|
|
409
|
+
}
|
|
410
|
+
function checkPaths(paths, extraRanges, dangerousMap) {
|
|
411
|
+
const resolved = resolvePaths(paths);
|
|
412
|
+
if (resolved.length === 0) {
|
|
413
|
+
console.log("No files to check.");
|
|
414
|
+
return 0;
|
|
415
|
+
}
|
|
239
416
|
let hasError = false;
|
|
240
|
-
|
|
241
|
-
|
|
417
|
+
let checked = 0;
|
|
418
|
+
for (const path2 of resolved) {
|
|
419
|
+
const problems = checkFile(path2, 5, extraRanges, dangerousMap);
|
|
420
|
+
checked++;
|
|
242
421
|
if (problems.length > 0) {
|
|
243
422
|
hasError = true;
|
|
244
423
|
console.log(`
|
|
@@ -248,12 +427,15 @@ ${path2} contains illegal characters:`);
|
|
|
248
427
|
}
|
|
249
428
|
}
|
|
250
429
|
}
|
|
430
|
+
if (!hasError) {
|
|
431
|
+
console.log(`All ${checked} files passed.`);
|
|
432
|
+
}
|
|
251
433
|
return hasError ? 1 : 0;
|
|
252
434
|
}
|
|
253
435
|
|
|
254
436
|
// src/check-imports.ts
|
|
255
|
-
import { readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
256
|
-
import { join, relative, sep, extname as extname2, basename } from "path";
|
|
437
|
+
import { readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
438
|
+
import { join as join2, relative, sep as sep2, extname as extname2, basename } from "path";
|
|
257
439
|
import ts from "typescript";
|
|
258
440
|
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
259
441
|
".ts",
|
|
@@ -273,7 +455,7 @@ var INDEX_BASENAMES = /* @__PURE__ */ new Set([
|
|
|
273
455
|
]);
|
|
274
456
|
function fileToModule(filePath, srcDir) {
|
|
275
457
|
const rel = relative(srcDir, filePath);
|
|
276
|
-
const parts = rel.split(
|
|
458
|
+
const parts = rel.split(sep2);
|
|
277
459
|
const last = parts[parts.length - 1];
|
|
278
460
|
if (last === "index.ts" || last === "index.js" || last === "index.tsx" || last === "index.jsx") {
|
|
279
461
|
parts.pop();
|
|
@@ -341,13 +523,13 @@ function resolveImports(rawImports, basePackage, currentModule, isPackage) {
|
|
|
341
523
|
function findSourceFiles(dir) {
|
|
342
524
|
const results = [];
|
|
343
525
|
function walk(d) {
|
|
344
|
-
const entries =
|
|
526
|
+
const entries = readdirSync2(d);
|
|
345
527
|
for (const entry of entries) {
|
|
346
528
|
if (entry === "node_modules" || entry === "dist" || entry === ".git") {
|
|
347
529
|
continue;
|
|
348
530
|
}
|
|
349
|
-
const full =
|
|
350
|
-
const stat =
|
|
531
|
+
const full = join2(d, entry);
|
|
532
|
+
const stat = statSync2(full);
|
|
351
533
|
if (stat.isDirectory()) {
|
|
352
534
|
walk(full);
|
|
353
535
|
} else if (SUPPORTED_EXTENSIONS.has(extname2(entry))) {
|
|
@@ -435,7 +617,7 @@ function findCycles(graph) {
|
|
|
435
617
|
function checkCircularImports(srcDir, basePackage) {
|
|
436
618
|
let stat;
|
|
437
619
|
try {
|
|
438
|
-
stat =
|
|
620
|
+
stat = statSync2(srcDir);
|
|
439
621
|
} catch {
|
|
440
622
|
console.error(`Error: ${srcDir}/ directory not found`);
|
|
441
623
|
return 1;
|
|
@@ -463,10 +645,10 @@ Found ${cycles.length} circular import(s):
|
|
|
463
645
|
|
|
464
646
|
// src/config.ts
|
|
465
647
|
import { readFileSync as readFileSync3 } from "fs";
|
|
466
|
-
import { join as
|
|
648
|
+
import { join as join3 } from "path";
|
|
467
649
|
function loadConfig(projectDir) {
|
|
468
650
|
const dir = projectDir ?? process.cwd();
|
|
469
|
-
const pkgPath =
|
|
651
|
+
const pkgPath = join3(dir, "package.json");
|
|
470
652
|
let raw;
|
|
471
653
|
try {
|
|
472
654
|
raw = readFileSync3(pkgPath, "utf-8");
|
|
@@ -483,12 +665,12 @@ function loadConfig(projectDir) {
|
|
|
483
665
|
|
|
484
666
|
// src/index.ts
|
|
485
667
|
import { readFileSync as readFileSync4 } from "fs";
|
|
486
|
-
import { dirname, join as
|
|
487
|
-
import { fileURLToPath as
|
|
668
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
669
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
488
670
|
function readVersion() {
|
|
489
|
-
const thisDir = typeof __dirname !== "undefined" ? __dirname :
|
|
671
|
+
const thisDir = typeof __dirname !== "undefined" ? __dirname : dirname2(fileURLToPath3(import.meta.url));
|
|
490
672
|
try {
|
|
491
|
-
const pkg = JSON.parse(readFileSync4(
|
|
673
|
+
const pkg = JSON.parse(readFileSync4(join4(thisDir, "..", "package.json"), "utf-8"));
|
|
492
674
|
return pkg.version ?? "0.0.0";
|
|
493
675
|
} catch {
|
|
494
676
|
return "0.0.0";
|
|
@@ -503,6 +685,10 @@ export {
|
|
|
503
685
|
fileToModule,
|
|
504
686
|
findCycles,
|
|
505
687
|
isAllowedChar,
|
|
688
|
+
isDangerousChar,
|
|
689
|
+
loadCharset,
|
|
506
690
|
loadConfig,
|
|
691
|
+
resolveCharsets,
|
|
692
|
+
resolvePaths,
|
|
507
693
|
version
|
|
508
694
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apdev-js",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "General-purpose development tools for TypeScript/JavaScript projects - character validation, circular import detection, and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"dist",
|
|
21
|
-
"release.sh"
|
|
21
|
+
"release.sh",
|
|
22
|
+
"src/charsets"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
25
|
"build": "tsup",
|
|
@@ -30,9 +31,16 @@
|
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
|
32
33
|
"development-tools",
|
|
34
|
+
"quality-assurance",
|
|
35
|
+
"linting",
|
|
36
|
+
"static-analysis",
|
|
33
37
|
"character-validation",
|
|
34
38
|
"circular-imports",
|
|
35
|
-
"
|
|
39
|
+
"release-automation",
|
|
40
|
+
"unicode-checker",
|
|
41
|
+
"trojan-source-detection",
|
|
42
|
+
"typescript",
|
|
43
|
+
"javascript"
|
|
36
44
|
],
|
|
37
45
|
"author": "aipartnerup <tercel.yi@gmail.com>",
|
|
38
46
|
"license": "Apache-2.0",
|
|
@@ -46,12 +54,20 @@
|
|
|
46
54
|
"url": "https://github.com/aipartnerup/apdev/issues"
|
|
47
55
|
},
|
|
48
56
|
"dependencies": {
|
|
49
|
-
"commander": "^13.0.0"
|
|
50
|
-
|
|
57
|
+
"commander": "^13.0.0"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"typescript": "^5.0.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"typescript": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
51
66
|
},
|
|
52
67
|
"devDependencies": {
|
|
53
68
|
"@types/node": "^22.0.0",
|
|
54
69
|
"tsup": "^8.0.0",
|
|
70
|
+
"typescript": "^5.7.0",
|
|
55
71
|
"vitest": "^3.0.0"
|
|
56
72
|
}
|
|
57
|
-
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base",
|
|
3
|
+
"description": "Default: ASCII + emoji + technical symbols",
|
|
4
|
+
"emoji_ranges": [
|
|
5
|
+
{ "start": "0x1F300", "end": "0x1F5FF", "name": "Symbols and Pictographs" },
|
|
6
|
+
{ "start": "0x1F600", "end": "0x1F64F", "name": "Emoticons" },
|
|
7
|
+
{ "start": "0x1F680", "end": "0x1F6FF", "name": "Transport and Map Symbols" },
|
|
8
|
+
{ "start": "0x1F780", "end": "0x1F7FF", "name": "Geometric Shapes Extended" },
|
|
9
|
+
{ "start": "0x1F900", "end": "0x1F9FF", "name": "Supplemental Symbols and Pictographs" },
|
|
10
|
+
{ "start": "0x2600", "end": "0x26FF", "name": "Miscellaneous Symbols" },
|
|
11
|
+
{ "start": "0x2700", "end": "0x27BF", "name": "Dingbats" }
|
|
12
|
+
],
|
|
13
|
+
"extra_ranges": [
|
|
14
|
+
{ "start": "0x0080", "end": "0x00FF", "name": "Latin-1 Supplement" },
|
|
15
|
+
{ "start": "0x2000", "end": "0x206F", "name": "General Punctuation" },
|
|
16
|
+
{ "start": "0x2100", "end": "0x214F", "name": "Letterlike Symbols" },
|
|
17
|
+
{ "start": "0x2190", "end": "0x21FF", "name": "Arrows" },
|
|
18
|
+
{ "start": "0x2200", "end": "0x22FF", "name": "Mathematical Operators" },
|
|
19
|
+
{ "start": "0x2300", "end": "0x23FF", "name": "Miscellaneous Technical" },
|
|
20
|
+
{ "start": "0x2500", "end": "0x257F", "name": "Box Drawing" },
|
|
21
|
+
{ "start": "0x2580", "end": "0x259F", "name": "Block Elements" },
|
|
22
|
+
{ "start": "0x25A0", "end": "0x25FF", "name": "Geometric Shapes" },
|
|
23
|
+
{ "start": "0x2800", "end": "0x28FF", "name": "Braille Patterns" },
|
|
24
|
+
{ "start": "0x2B00", "end": "0x2BFF", "name": "Miscellaneous Symbols and Arrows" },
|
|
25
|
+
{ "start": "0xFE00", "end": "0xFE0F", "name": "Variation Selectors" }
|
|
26
|
+
],
|
|
27
|
+
"dangerous": [
|
|
28
|
+
{ "code": "0x202A", "name": "LEFT-TO-RIGHT EMBEDDING" },
|
|
29
|
+
{ "code": "0x202B", "name": "RIGHT-TO-LEFT EMBEDDING" },
|
|
30
|
+
{ "code": "0x202C", "name": "POP DIRECTIONAL FORMATTING" },
|
|
31
|
+
{ "code": "0x202D", "name": "LEFT-TO-RIGHT OVERRIDE" },
|
|
32
|
+
{ "code": "0x202E", "name": "RIGHT-TO-LEFT OVERRIDE" },
|
|
33
|
+
{ "code": "0x2066", "name": "LEFT-TO-RIGHT ISOLATE" },
|
|
34
|
+
{ "code": "0x2067", "name": "RIGHT-TO-LEFT ISOLATE" },
|
|
35
|
+
{ "code": "0x2068", "name": "FIRST STRONG ISOLATE" },
|
|
36
|
+
{ "code": "0x2069", "name": "POP DIRECTIONAL ISOLATE" },
|
|
37
|
+
{ "code": "0x200B", "name": "ZERO WIDTH SPACE" },
|
|
38
|
+
{ "code": "0x200C", "name": "ZERO WIDTH NON-JOINER" },
|
|
39
|
+
{ "code": "0x200D", "name": "ZERO WIDTH JOINER" },
|
|
40
|
+
{ "code": "0x200E", "name": "LEFT-TO-RIGHT MARK" },
|
|
41
|
+
{ "code": "0x200F", "name": "RIGHT-TO-LEFT MARK" },
|
|
42
|
+
{ "code": "0x2060", "name": "WORD JOINER" }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chinese",
|
|
3
|
+
"description": "Chinese: CJK Unified Ideographs, CJK Punctuation, Fullwidth Forms",
|
|
4
|
+
"extra_ranges": [
|
|
5
|
+
{ "start": "0x3000", "end": "0x303F", "name": "CJK Symbols and Punctuation" },
|
|
6
|
+
{ "start": "0x4E00", "end": "0x9FFF", "name": "CJK Unified Ideographs" },
|
|
7
|
+
{ "start": "0xFF00", "end": "0xFFEF", "name": "Fullwidth Forms" }
|
|
8
|
+
]
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "japanese",
|
|
3
|
+
"description": "Japanese: Hiragana, Katakana, CJK Unified Ideographs, CJK Punctuation, Fullwidth Forms",
|
|
4
|
+
"extra_ranges": [
|
|
5
|
+
{ "start": "0x3000", "end": "0x303F", "name": "CJK Symbols and Punctuation" },
|
|
6
|
+
{ "start": "0x3040", "end": "0x309F", "name": "Hiragana" },
|
|
7
|
+
{ "start": "0x30A0", "end": "0x30FF", "name": "Katakana" },
|
|
8
|
+
{ "start": "0x4E00", "end": "0x9FFF", "name": "CJK Unified Ideographs" },
|
|
9
|
+
{ "start": "0xFF00", "end": "0xFFEF", "name": "Fullwidth Forms" }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "korean",
|
|
3
|
+
"description": "Korean: Hangul Jamo, Hangul Syllables, CJK Unified Ideographs, CJK Punctuation, Fullwidth Forms",
|
|
4
|
+
"extra_ranges": [
|
|
5
|
+
{ "start": "0x1100", "end": "0x11FF", "name": "Hangul Jamo" },
|
|
6
|
+
{ "start": "0x3000", "end": "0x303F", "name": "CJK Symbols and Punctuation" },
|
|
7
|
+
{ "start": "0x4E00", "end": "0x9FFF", "name": "CJK Unified Ideographs" },
|
|
8
|
+
{ "start": "0xAC00", "end": "0xD7AF", "name": "Hangul Syllables" },
|
|
9
|
+
{ "start": "0xFF00", "end": "0xFFEF", "name": "Fullwidth Forms" }
|
|
10
|
+
]
|
|
11
|
+
}
|