@clearlydev/nx-archweave 0.1.1 → 0.2.0
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/eslint/fsd-boundaries.d.ts +25 -8
- package/dist/eslint/fsd-policy.d.ts +38 -0
- package/dist/eslint/index.d.ts +10 -9
- package/dist/eslint/index.js +227 -34
- package/dist/eslint/slice-groups.d.ts +12 -0
- package/dist/generators/add-agent-rules/generator.js +1175 -23
- package/dist/generators/add-backend/generator.js +1127 -75
- package/dist/generators/add-fsd-lite/generator.js +1274 -96
- package/dist/generators/add-review/files/dependabot.yml +7 -0
- package/dist/generators/add-review/generator.js +1100 -46
- package/dist/generators/doctor/generator.js +780 -96
- package/dist/generators/entity/generator.js +251 -32
- package/dist/generators/feature/generator.js +251 -32
- package/dist/generators/init/generator.js +1955 -549
- package/dist/generators/page/generator.js +251 -32
- package/dist/generators/shared/generator.js +251 -32
- package/dist/generators/widget/generator.js +251 -32
- package/package.json +4 -1
- package/src/generators/add-agent-rules/schema.json +5 -0
- package/src/generators/add-fsd-lite/schema.json +2 -2
- package/src/generators/entity/schema.json +11 -1
- package/src/generators/feature/schema.json +11 -1
- package/src/generators/init/schema.json +13 -2
- package/src/generators/page/schema.json +15 -3
- package/src/generators/shared/schema.json +7 -1
- package/src/generators/widget/schema.json +11 -1
- package/dist/eslint/fsd-boundaries.js +0 -144
- package/dist/eslint/tsconfig-aliases.js +0 -114
- package/dist/generators/add-agent-rules/render.js +0 -46
- package/dist/generators/add-backend/render.js +0 -102
- package/dist/generators/add-fsd-lite/render.js +0 -72
- package/dist/generators/add-github-templates/render.js +0 -26
- package/dist/generators/add-integration/render.js +0 -34
- package/dist/generators/add-review/render.js +0 -96
- package/dist/generators/allow-builds/render.js +0 -82
- package/dist/generators/doctor/integration-report.js +0 -70
- package/dist/generators/doctor/render.js +0 -10
- package/dist/generators/init/render.js +0 -125
- package/dist/generators/init/validation.js +0 -74
- package/dist/generators/install-integration/render.js +0 -128
- package/dist/generators/record-integration/render.js +0 -31
- package/dist/generators/shared/dry-run.js +0 -12
- package/dist/generators/shared/frontend-app.js +0 -57
- package/dist/generators/shared/project-type.js +0 -39
- package/dist/generators/shared/record-pipeline.js +0 -34
- package/dist/generators/shared/run-nx.js +0 -24
- package/dist/generators/shared/template-files.js +0 -38
- package/dist/generators/shared/toolkit-config-file.js +0 -110
- package/dist/generators/slice/core.js +0 -185
- package/dist/generators/slice/render.js +0 -70
- package/dist/lib/nx-plugin.js +0 -7
- package/dist/runtime/integrations-composition-root.js +0 -20
- package/dist/runtime/node-command-runner.js +0 -81
|
@@ -285,6 +285,33 @@ var AGENT_RULE_SECTIONS = {
|
|
|
285
285
|
ko: KO_SECTIONS
|
|
286
286
|
};
|
|
287
287
|
|
|
288
|
+
// ../templates/dist/agents/fsd-policy-notes.js
|
|
289
|
+
var NOTES = {
|
|
290
|
+
en: {
|
|
291
|
+
heading: "This workspace also configures:",
|
|
292
|
+
groups: "- A folder that only groups slices (`features/mypage/{order,claims}`) holds no code and no `index.ts`; each slice in it is separate, and slices in one group never import each other either. Create one with `--group=<name>`.",
|
|
293
|
+
component: "- `shared` exposes each component through its own `index.ts` (`shared/ui/button`); import that, not the files inside it.",
|
|
294
|
+
file: "- Inside `shared`, files may be imported directly (`shared/lib/format/currency`); `shared` still never imports a layer above it.",
|
|
295
|
+
tests: "- Test files (`*.spec.ts`, `*.test.ts`, `__tests__/`) may import another slice's internals; upward imports stay forbidden there too."
|
|
296
|
+
},
|
|
297
|
+
ko: {
|
|
298
|
+
heading: "\uC774 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uB294 \uB2E4\uC74C\uB3C4 \uC124\uC815\uD588\uB2E4:",
|
|
299
|
+
groups: "- \uC2AC\uB77C\uC774\uC2A4\uB97C \uBB36\uAE30\uB9CC \uD558\uB294 \uD3F4\uB354(`features/mypage/{order,claims}`)\uC5D0\uB294 \uCF54\uB4DC\uB3C4 `index.ts`\uB3C4 \uB450\uC9C0 \uC54A\uB294\uB2E4. \uADF8 \uC548\uC758 \uC2AC\uB77C\uC774\uC2A4\uB294 \uAC01\uAC01 \uB3C5\uB9BD\uC774\uB77C, \uAC19\uC740 \uADF8\uB8F9 \uC548\uC5D0\uC11C\uB3C4 \uC11C\uB85C import\uD558\uC9C0 \uC54A\uB294\uB2E4. \uADF8\uB8F9 \uC548\uC5D0 \uB9CC\uB4E4 \uB54C\uB294 `--group=<\uC774\uB984>`\uC744 \uC4F4\uB2E4.",
|
|
300
|
+
component: "- `shared`\uB294 \uCEF4\uD3EC\uB10C\uD2B8\uB9C8\uB2E4 \uC790\uAE30 `index.ts`\uB85C \uACF5\uAC1C\uD55C\uB2E4(`shared/ui/button`). \uADF8 index\uB97C import\uD558\uACE0, \uC548\uCABD \uD30C\uC77C\uC5D0\uB294 \uB2FF\uC9C0 \uC54A\uB294\uB2E4.",
|
|
301
|
+
file: "- `shared` \uC548\uC758 \uD30C\uC77C\uC740 \uC9C1\uC811 import\uD574\uB3C4 \uB41C\uB2E4(`shared/lib/format/currency`). \uB2E4\uB9CC `shared`\uB294 \uC5EC\uC804\uD788 \uC704 \uB808\uC774\uC5B4\uB97C import\uD558\uC9C0 \uC54A\uB294\uB2E4.",
|
|
302
|
+
tests: "- \uD14C\uC2A4\uD2B8 \uD30C\uC77C(`*.spec.ts`, `*.test.ts`, `__tests__/`)\uC740 \uB2E4\uB978 \uC2AC\uB77C\uC774\uC2A4\uC758 \uB0B4\uBD80 \uD30C\uC77C\uC744 import\uD574\uB3C4 \uB41C\uB2E4. \uC704 \uB808\uC774\uC5B4 import\uB294 \uD14C\uC2A4\uD2B8\uC5D0\uC11C\uB3C4 \uAE08\uC9C0\uB2E4."
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
function buildFsdPolicyNotes(locale, notes) {
|
|
306
|
+
const text = NOTES[locale];
|
|
307
|
+
const lines = [
|
|
308
|
+
...notes.sliceGroups ? [text.groups] : [],
|
|
309
|
+
...notes.sharedPublicApi === "component" ? [text.component] : notes.sharedPublicApi === "file" ? [text.file] : [],
|
|
310
|
+
...notes.testFiles ? [text.tests] : []
|
|
311
|
+
];
|
|
312
|
+
return lines.length === 0 ? "" : [text.heading, ...lines].join("\n");
|
|
313
|
+
}
|
|
314
|
+
|
|
288
315
|
// ../template-engine/dist/ai-hosts/ai-hosts.js
|
|
289
316
|
var AI_HOSTS = [
|
|
290
317
|
{ id: "claude-code", label: "Claude Code", nxAgent: "claude", rulesFile: "CLAUDE.md", reviewProvider: "claude" },
|
|
@@ -333,7 +360,13 @@ ${section.body}`).join("\n\n")}
|
|
|
333
360
|
}
|
|
334
361
|
function composeAgentRules(input) {
|
|
335
362
|
const sectionIds = input.sections ?? resolveDefaultAgentSectionIds(input.teamRules ?? false, input.fsdStructure ?? false);
|
|
336
|
-
const
|
|
363
|
+
const notes = input.fsdPolicy === void 0 ? "" : buildFsdPolicyNotes(input.locale, input.fsdPolicy);
|
|
364
|
+
const sections = sectionIds.map((id) => {
|
|
365
|
+
const section = AGENT_RULE_SECTIONS[input.locale][id];
|
|
366
|
+
return id === FSD_AGENT_SECTION_ID && notes !== "" ? { ...section, body: `${section.body}
|
|
367
|
+
|
|
368
|
+
${notes}` } : section;
|
|
369
|
+
});
|
|
337
370
|
const content = renderSections(sections);
|
|
338
371
|
return input.files.map((filePath) => ({ filePath, content }));
|
|
339
372
|
}
|
|
@@ -349,41 +382,63 @@ function validateAgentRules(content, extraRequired = []) {
|
|
|
349
382
|
}
|
|
350
383
|
|
|
351
384
|
// ../template-engine/dist/agent-rules/marker-block.js
|
|
385
|
+
import { createHash } from "node:crypto";
|
|
352
386
|
var AGENT_RULES_BLOCK_START = "<!-- nx-archweave:agent-rules start -->";
|
|
353
387
|
var AGENT_RULES_BLOCK_END = "<!-- nx-archweave:agent-rules end -->";
|
|
388
|
+
var START_MARKER = /<!-- nx-archweave:agent-rules start(?: hash=([0-9a-f]{12}))? -->/g;
|
|
389
|
+
function normalizeForHash(text) {
|
|
390
|
+
return text.replace(/\r\n/g, "\n").replace(/[ \t]+$/gm, "");
|
|
391
|
+
}
|
|
392
|
+
function hashOf(body) {
|
|
393
|
+
return createHash("sha256").update(normalizeForHash(body)).digest("hex").slice(0, 12);
|
|
394
|
+
}
|
|
395
|
+
function withFinalNewline(body) {
|
|
396
|
+
return body.endsWith("\n") ? body : `${body}
|
|
397
|
+
`;
|
|
398
|
+
}
|
|
354
399
|
function renderAgentRulesBlock(body, eol = "\n") {
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
400
|
+
const content = withFinalNewline(normalizeForHash(body));
|
|
401
|
+
const lines = `<!-- nx-archweave:agent-rules start hash=${hashOf(content)} -->
|
|
402
|
+
${content}${AGENT_RULES_BLOCK_END}`;
|
|
358
403
|
return eol === "\n" ? lines : lines.replace(/\r?\n/g, eol);
|
|
359
404
|
}
|
|
360
405
|
function countOf(text, needle) {
|
|
361
406
|
return text.split(needle).length - 1;
|
|
362
407
|
}
|
|
363
|
-
function applyAgentRulesBlock(existing, body) {
|
|
408
|
+
function applyAgentRulesBlock(existing, body, options = {}) {
|
|
364
409
|
if (existing === null || existing.length === 0)
|
|
365
410
|
return { kind: "create", text: `${renderAgentRulesBlock(body)}
|
|
366
411
|
` };
|
|
367
412
|
const eol = existing.includes("\r\n") ? "\r\n" : "\n";
|
|
368
413
|
const block = renderAgentRulesBlock(body, eol);
|
|
369
|
-
const starts =
|
|
414
|
+
const starts = [...existing.matchAll(START_MARKER)];
|
|
370
415
|
const ends = countOf(existing, AGENT_RULES_BLOCK_END);
|
|
371
|
-
if (starts === 0 && ends === 0) {
|
|
416
|
+
if (starts.length === 0 && ends === 0) {
|
|
372
417
|
const head = existing.endsWith("\n") ? existing : `${existing}${eol}`;
|
|
373
418
|
return { kind: "append", text: `${head}${eol}${block}${eol}` };
|
|
374
419
|
}
|
|
375
|
-
if (starts !== 1 || ends !== 1) {
|
|
420
|
+
if (starts.length !== 1 || ends !== 1) {
|
|
376
421
|
return {
|
|
377
422
|
kind: "unrecognized",
|
|
378
|
-
reason: `expected one ${AGENT_RULES_BLOCK_START} \u2026 ${AGENT_RULES_BLOCK_END} pair, found ${starts} start and ${ends} end marker(s)`
|
|
423
|
+
reason: `expected one ${AGENT_RULES_BLOCK_START} \u2026 ${AGENT_RULES_BLOCK_END} pair, found ${starts.length} start and ${ends} end marker(s)`
|
|
379
424
|
};
|
|
380
425
|
}
|
|
381
|
-
const
|
|
426
|
+
const startMatch = starts[0];
|
|
427
|
+
const start = startMatch.index ?? 0;
|
|
382
428
|
const end = existing.indexOf(AGENT_RULES_BLOCK_END);
|
|
383
429
|
if (end < start)
|
|
384
430
|
return { kind: "unrecognized", reason: "the end marker comes before the start marker" };
|
|
385
431
|
const text = existing.slice(0, start) + block + existing.slice(end + AGENT_RULES_BLOCK_END.length);
|
|
386
|
-
|
|
432
|
+
if (text === existing)
|
|
433
|
+
return { kind: "unchanged" };
|
|
434
|
+
const bodyStart = start + startMatch[0].length + (existing.startsWith("\r\n", start + startMatch[0].length) ? 2 : 1);
|
|
435
|
+
const existingBody = normalizeForHash(existing.slice(bodyStart, end));
|
|
436
|
+
const generatedBody = withFinalNewline(normalizeForHash(body));
|
|
437
|
+
const recordedHash = startMatch[1];
|
|
438
|
+
const untouched = recordedHash !== void 0 ? hashOf(existingBody) === recordedHash : existingBody === generatedBody;
|
|
439
|
+
if (!untouched && options.overwrite !== true)
|
|
440
|
+
return { kind: "user-modified", existingBody, generatedBody };
|
|
441
|
+
return { kind: "replace", text };
|
|
387
442
|
}
|
|
388
443
|
|
|
389
444
|
// src/generators/shared/dry-run.ts
|
|
@@ -391,8 +446,933 @@ function resolveDryRun(options) {
|
|
|
391
446
|
return process.env["NX_DRY_RUN"] === "true" || (options.dryRun ?? false);
|
|
392
447
|
}
|
|
393
448
|
|
|
394
|
-
//
|
|
395
|
-
|
|
449
|
+
// ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
450
|
+
function createScanner(text, ignoreTrivia = false) {
|
|
451
|
+
const len = text.length;
|
|
452
|
+
let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
|
|
453
|
+
function scanHexDigits(count, exact) {
|
|
454
|
+
let digits = 0;
|
|
455
|
+
let value2 = 0;
|
|
456
|
+
while (digits < count || !exact) {
|
|
457
|
+
let ch = text.charCodeAt(pos);
|
|
458
|
+
if (ch >= 48 && ch <= 57) {
|
|
459
|
+
value2 = value2 * 16 + ch - 48;
|
|
460
|
+
} else if (ch >= 65 && ch <= 70) {
|
|
461
|
+
value2 = value2 * 16 + ch - 65 + 10;
|
|
462
|
+
} else if (ch >= 97 && ch <= 102) {
|
|
463
|
+
value2 = value2 * 16 + ch - 97 + 10;
|
|
464
|
+
} else {
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
pos++;
|
|
468
|
+
digits++;
|
|
469
|
+
}
|
|
470
|
+
if (digits < count) {
|
|
471
|
+
value2 = -1;
|
|
472
|
+
}
|
|
473
|
+
return value2;
|
|
474
|
+
}
|
|
475
|
+
function setPosition(newPosition) {
|
|
476
|
+
pos = newPosition;
|
|
477
|
+
value = "";
|
|
478
|
+
tokenOffset = 0;
|
|
479
|
+
token = 16;
|
|
480
|
+
scanError = 0;
|
|
481
|
+
}
|
|
482
|
+
function scanNumber() {
|
|
483
|
+
let start = pos;
|
|
484
|
+
if (text.charCodeAt(pos) === 48) {
|
|
485
|
+
pos++;
|
|
486
|
+
} else {
|
|
487
|
+
pos++;
|
|
488
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
489
|
+
pos++;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (pos < text.length && text.charCodeAt(pos) === 46) {
|
|
493
|
+
pos++;
|
|
494
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
495
|
+
pos++;
|
|
496
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
497
|
+
pos++;
|
|
498
|
+
}
|
|
499
|
+
} else {
|
|
500
|
+
scanError = 3;
|
|
501
|
+
return text.substring(start, pos);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
let end = pos;
|
|
505
|
+
if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
|
|
506
|
+
pos++;
|
|
507
|
+
if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
|
|
508
|
+
pos++;
|
|
509
|
+
}
|
|
510
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
511
|
+
pos++;
|
|
512
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
513
|
+
pos++;
|
|
514
|
+
}
|
|
515
|
+
end = pos;
|
|
516
|
+
} else {
|
|
517
|
+
scanError = 3;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return text.substring(start, end);
|
|
521
|
+
}
|
|
522
|
+
function scanString() {
|
|
523
|
+
let result = "", start = pos;
|
|
524
|
+
while (true) {
|
|
525
|
+
if (pos >= len) {
|
|
526
|
+
result += text.substring(start, pos);
|
|
527
|
+
scanError = 2;
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
const ch = text.charCodeAt(pos);
|
|
531
|
+
if (ch === 34) {
|
|
532
|
+
result += text.substring(start, pos);
|
|
533
|
+
pos++;
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
if (ch === 92) {
|
|
537
|
+
result += text.substring(start, pos);
|
|
538
|
+
pos++;
|
|
539
|
+
if (pos >= len) {
|
|
540
|
+
scanError = 2;
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
const ch2 = text.charCodeAt(pos++);
|
|
544
|
+
switch (ch2) {
|
|
545
|
+
case 34:
|
|
546
|
+
result += '"';
|
|
547
|
+
break;
|
|
548
|
+
case 92:
|
|
549
|
+
result += "\\";
|
|
550
|
+
break;
|
|
551
|
+
case 47:
|
|
552
|
+
result += "/";
|
|
553
|
+
break;
|
|
554
|
+
case 98:
|
|
555
|
+
result += "\b";
|
|
556
|
+
break;
|
|
557
|
+
case 102:
|
|
558
|
+
result += "\f";
|
|
559
|
+
break;
|
|
560
|
+
case 110:
|
|
561
|
+
result += "\n";
|
|
562
|
+
break;
|
|
563
|
+
case 114:
|
|
564
|
+
result += "\r";
|
|
565
|
+
break;
|
|
566
|
+
case 116:
|
|
567
|
+
result += " ";
|
|
568
|
+
break;
|
|
569
|
+
case 117:
|
|
570
|
+
const ch3 = scanHexDigits(4, true);
|
|
571
|
+
if (ch3 >= 0) {
|
|
572
|
+
result += String.fromCharCode(ch3);
|
|
573
|
+
} else {
|
|
574
|
+
scanError = 4;
|
|
575
|
+
}
|
|
576
|
+
break;
|
|
577
|
+
default:
|
|
578
|
+
scanError = 5;
|
|
579
|
+
}
|
|
580
|
+
start = pos;
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
if (ch >= 0 && ch <= 31) {
|
|
584
|
+
if (isLineBreak(ch)) {
|
|
585
|
+
result += text.substring(start, pos);
|
|
586
|
+
scanError = 2;
|
|
587
|
+
break;
|
|
588
|
+
} else {
|
|
589
|
+
scanError = 6;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
pos++;
|
|
593
|
+
}
|
|
594
|
+
return result;
|
|
595
|
+
}
|
|
596
|
+
function scanNext() {
|
|
597
|
+
value = "";
|
|
598
|
+
scanError = 0;
|
|
599
|
+
tokenOffset = pos;
|
|
600
|
+
lineStartOffset = lineNumber;
|
|
601
|
+
prevTokenLineStartOffset = tokenLineStartOffset;
|
|
602
|
+
if (pos >= len) {
|
|
603
|
+
tokenOffset = len;
|
|
604
|
+
return token = 17;
|
|
605
|
+
}
|
|
606
|
+
let code = text.charCodeAt(pos);
|
|
607
|
+
if (isWhiteSpace(code)) {
|
|
608
|
+
do {
|
|
609
|
+
pos++;
|
|
610
|
+
value += String.fromCharCode(code);
|
|
611
|
+
code = text.charCodeAt(pos);
|
|
612
|
+
} while (isWhiteSpace(code));
|
|
613
|
+
return token = 15;
|
|
614
|
+
}
|
|
615
|
+
if (isLineBreak(code)) {
|
|
616
|
+
pos++;
|
|
617
|
+
value += String.fromCharCode(code);
|
|
618
|
+
if (code === 13 && text.charCodeAt(pos) === 10) {
|
|
619
|
+
pos++;
|
|
620
|
+
value += "\n";
|
|
621
|
+
}
|
|
622
|
+
lineNumber++;
|
|
623
|
+
tokenLineStartOffset = pos;
|
|
624
|
+
return token = 14;
|
|
625
|
+
}
|
|
626
|
+
switch (code) {
|
|
627
|
+
// tokens: []{}:,
|
|
628
|
+
case 123:
|
|
629
|
+
pos++;
|
|
630
|
+
return token = 1;
|
|
631
|
+
case 125:
|
|
632
|
+
pos++;
|
|
633
|
+
return token = 2;
|
|
634
|
+
case 91:
|
|
635
|
+
pos++;
|
|
636
|
+
return token = 3;
|
|
637
|
+
case 93:
|
|
638
|
+
pos++;
|
|
639
|
+
return token = 4;
|
|
640
|
+
case 58:
|
|
641
|
+
pos++;
|
|
642
|
+
return token = 6;
|
|
643
|
+
case 44:
|
|
644
|
+
pos++;
|
|
645
|
+
return token = 5;
|
|
646
|
+
// strings
|
|
647
|
+
case 34:
|
|
648
|
+
pos++;
|
|
649
|
+
value = scanString();
|
|
650
|
+
return token = 10;
|
|
651
|
+
// comments
|
|
652
|
+
case 47:
|
|
653
|
+
const start = pos - 1;
|
|
654
|
+
if (text.charCodeAt(pos + 1) === 47) {
|
|
655
|
+
pos += 2;
|
|
656
|
+
while (pos < len) {
|
|
657
|
+
if (isLineBreak(text.charCodeAt(pos))) {
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
pos++;
|
|
661
|
+
}
|
|
662
|
+
value = text.substring(start, pos);
|
|
663
|
+
return token = 12;
|
|
664
|
+
}
|
|
665
|
+
if (text.charCodeAt(pos + 1) === 42) {
|
|
666
|
+
pos += 2;
|
|
667
|
+
const safeLength = len - 1;
|
|
668
|
+
let commentClosed = false;
|
|
669
|
+
while (pos < safeLength) {
|
|
670
|
+
const ch = text.charCodeAt(pos);
|
|
671
|
+
if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
|
|
672
|
+
pos += 2;
|
|
673
|
+
commentClosed = true;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
pos++;
|
|
677
|
+
if (isLineBreak(ch)) {
|
|
678
|
+
if (ch === 13 && text.charCodeAt(pos) === 10) {
|
|
679
|
+
pos++;
|
|
680
|
+
}
|
|
681
|
+
lineNumber++;
|
|
682
|
+
tokenLineStartOffset = pos;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (!commentClosed) {
|
|
686
|
+
pos++;
|
|
687
|
+
scanError = 1;
|
|
688
|
+
}
|
|
689
|
+
value = text.substring(start, pos);
|
|
690
|
+
return token = 13;
|
|
691
|
+
}
|
|
692
|
+
value += String.fromCharCode(code);
|
|
693
|
+
pos++;
|
|
694
|
+
return token = 16;
|
|
695
|
+
// numbers
|
|
696
|
+
case 45:
|
|
697
|
+
value += String.fromCharCode(code);
|
|
698
|
+
pos++;
|
|
699
|
+
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
|
700
|
+
return token = 16;
|
|
701
|
+
}
|
|
702
|
+
// found a minus, followed by a number so
|
|
703
|
+
// we fall through to proceed with scanning
|
|
704
|
+
// numbers
|
|
705
|
+
case 48:
|
|
706
|
+
case 49:
|
|
707
|
+
case 50:
|
|
708
|
+
case 51:
|
|
709
|
+
case 52:
|
|
710
|
+
case 53:
|
|
711
|
+
case 54:
|
|
712
|
+
case 55:
|
|
713
|
+
case 56:
|
|
714
|
+
case 57:
|
|
715
|
+
value += scanNumber();
|
|
716
|
+
return token = 11;
|
|
717
|
+
// literals and unknown symbols
|
|
718
|
+
default:
|
|
719
|
+
while (pos < len && isUnknownContentCharacter(code)) {
|
|
720
|
+
pos++;
|
|
721
|
+
code = text.charCodeAt(pos);
|
|
722
|
+
}
|
|
723
|
+
if (tokenOffset !== pos) {
|
|
724
|
+
value = text.substring(tokenOffset, pos);
|
|
725
|
+
switch (value) {
|
|
726
|
+
case "true":
|
|
727
|
+
return token = 8;
|
|
728
|
+
case "false":
|
|
729
|
+
return token = 9;
|
|
730
|
+
case "null":
|
|
731
|
+
return token = 7;
|
|
732
|
+
}
|
|
733
|
+
return token = 16;
|
|
734
|
+
}
|
|
735
|
+
value += String.fromCharCode(code);
|
|
736
|
+
pos++;
|
|
737
|
+
return token = 16;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
function isUnknownContentCharacter(code) {
|
|
741
|
+
if (isWhiteSpace(code) || isLineBreak(code)) {
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
744
|
+
switch (code) {
|
|
745
|
+
case 125:
|
|
746
|
+
case 93:
|
|
747
|
+
case 123:
|
|
748
|
+
case 91:
|
|
749
|
+
case 34:
|
|
750
|
+
case 58:
|
|
751
|
+
case 44:
|
|
752
|
+
case 47:
|
|
753
|
+
return false;
|
|
754
|
+
}
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
757
|
+
function scanNextNonTrivia() {
|
|
758
|
+
let result;
|
|
759
|
+
do {
|
|
760
|
+
result = scanNext();
|
|
761
|
+
} while (result >= 12 && result <= 15);
|
|
762
|
+
return result;
|
|
763
|
+
}
|
|
764
|
+
return {
|
|
765
|
+
setPosition,
|
|
766
|
+
getPosition: () => pos,
|
|
767
|
+
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
|
768
|
+
getToken: () => token,
|
|
769
|
+
getTokenValue: () => value,
|
|
770
|
+
getTokenOffset: () => tokenOffset,
|
|
771
|
+
getTokenLength: () => pos - tokenOffset,
|
|
772
|
+
getTokenStartLine: () => lineStartOffset,
|
|
773
|
+
getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
|
|
774
|
+
getTokenError: () => scanError
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function isWhiteSpace(ch) {
|
|
778
|
+
return ch === 32 || ch === 9;
|
|
779
|
+
}
|
|
780
|
+
function isLineBreak(ch) {
|
|
781
|
+
return ch === 10 || ch === 13;
|
|
782
|
+
}
|
|
783
|
+
function isDigit(ch) {
|
|
784
|
+
return ch >= 48 && ch <= 57;
|
|
785
|
+
}
|
|
786
|
+
var CharacterCodes;
|
|
787
|
+
(function(CharacterCodes2) {
|
|
788
|
+
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
789
|
+
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
790
|
+
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
791
|
+
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
792
|
+
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
793
|
+
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
794
|
+
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
795
|
+
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
796
|
+
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
797
|
+
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
798
|
+
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
799
|
+
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
800
|
+
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
801
|
+
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
802
|
+
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
803
|
+
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
804
|
+
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
805
|
+
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
806
|
+
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
807
|
+
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
808
|
+
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
809
|
+
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
810
|
+
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
811
|
+
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
812
|
+
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
813
|
+
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
814
|
+
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
815
|
+
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
816
|
+
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
817
|
+
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
818
|
+
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
819
|
+
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
820
|
+
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
821
|
+
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
822
|
+
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
823
|
+
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
824
|
+
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
825
|
+
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
826
|
+
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
827
|
+
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
828
|
+
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
829
|
+
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
830
|
+
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
831
|
+
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
832
|
+
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
833
|
+
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
834
|
+
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
835
|
+
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
836
|
+
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
837
|
+
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
838
|
+
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
839
|
+
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
840
|
+
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
841
|
+
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
842
|
+
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
843
|
+
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
844
|
+
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
845
|
+
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
846
|
+
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
847
|
+
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
848
|
+
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
849
|
+
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
850
|
+
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
851
|
+
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
852
|
+
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
853
|
+
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
854
|
+
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
855
|
+
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
856
|
+
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
857
|
+
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
858
|
+
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
859
|
+
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
860
|
+
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
861
|
+
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
862
|
+
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
863
|
+
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
864
|
+
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
865
|
+
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
866
|
+
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
867
|
+
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
868
|
+
})(CharacterCodes || (CharacterCodes = {}));
|
|
869
|
+
|
|
870
|
+
// ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
871
|
+
var cachedSpaces = new Array(20).fill(0).map((_, index) => {
|
|
872
|
+
return " ".repeat(index);
|
|
873
|
+
});
|
|
874
|
+
var maxCachedValues = 200;
|
|
875
|
+
var cachedBreakLinesWithSpaces = {
|
|
876
|
+
" ": {
|
|
877
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
878
|
+
return "\n" + " ".repeat(index);
|
|
879
|
+
}),
|
|
880
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
881
|
+
return "\r" + " ".repeat(index);
|
|
882
|
+
}),
|
|
883
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
884
|
+
return "\r\n" + " ".repeat(index);
|
|
885
|
+
})
|
|
886
|
+
},
|
|
887
|
+
" ": {
|
|
888
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
889
|
+
return "\n" + " ".repeat(index);
|
|
890
|
+
}),
|
|
891
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
892
|
+
return "\r" + " ".repeat(index);
|
|
893
|
+
}),
|
|
894
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
895
|
+
return "\r\n" + " ".repeat(index);
|
|
896
|
+
})
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
// ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
901
|
+
var ParseOptions;
|
|
902
|
+
(function(ParseOptions2) {
|
|
903
|
+
ParseOptions2.DEFAULT = {
|
|
904
|
+
allowTrailingComma: false
|
|
905
|
+
};
|
|
906
|
+
})(ParseOptions || (ParseOptions = {}));
|
|
907
|
+
function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
|
|
908
|
+
let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: void 0 };
|
|
909
|
+
function ensurePropertyComplete(endOffset) {
|
|
910
|
+
if (currentParent.type === "property") {
|
|
911
|
+
currentParent.length = endOffset - currentParent.offset;
|
|
912
|
+
currentParent = currentParent.parent;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
function onValue(valueNode) {
|
|
916
|
+
currentParent.children.push(valueNode);
|
|
917
|
+
return valueNode;
|
|
918
|
+
}
|
|
919
|
+
const visitor = {
|
|
920
|
+
onObjectBegin: (offset) => {
|
|
921
|
+
currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
|
|
922
|
+
},
|
|
923
|
+
onObjectProperty: (name, offset, length) => {
|
|
924
|
+
currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
|
|
925
|
+
currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
|
|
926
|
+
},
|
|
927
|
+
onObjectEnd: (offset, length) => {
|
|
928
|
+
ensurePropertyComplete(offset + length);
|
|
929
|
+
currentParent.length = offset + length - currentParent.offset;
|
|
930
|
+
currentParent = currentParent.parent;
|
|
931
|
+
ensurePropertyComplete(offset + length);
|
|
932
|
+
},
|
|
933
|
+
onArrayBegin: (offset, length) => {
|
|
934
|
+
currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
|
|
935
|
+
},
|
|
936
|
+
onArrayEnd: (offset, length) => {
|
|
937
|
+
currentParent.length = offset + length - currentParent.offset;
|
|
938
|
+
currentParent = currentParent.parent;
|
|
939
|
+
ensurePropertyComplete(offset + length);
|
|
940
|
+
},
|
|
941
|
+
onLiteralValue: (value, offset, length) => {
|
|
942
|
+
onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
|
|
943
|
+
ensurePropertyComplete(offset + length);
|
|
944
|
+
},
|
|
945
|
+
onSeparator: (sep, offset, length) => {
|
|
946
|
+
if (currentParent.type === "property") {
|
|
947
|
+
if (sep === ":") {
|
|
948
|
+
currentParent.colonOffset = offset;
|
|
949
|
+
} else if (sep === ",") {
|
|
950
|
+
ensurePropertyComplete(offset);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
onError: (error, offset, length) => {
|
|
955
|
+
errors.push({ error, offset, length });
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
visit(text, visitor, options);
|
|
959
|
+
const result = currentParent.children[0];
|
|
960
|
+
if (result) {
|
|
961
|
+
delete result.parent;
|
|
962
|
+
}
|
|
963
|
+
return result;
|
|
964
|
+
}
|
|
965
|
+
function findNodeAtLocation(root, path) {
|
|
966
|
+
if (!root) {
|
|
967
|
+
return void 0;
|
|
968
|
+
}
|
|
969
|
+
let node = root;
|
|
970
|
+
for (let segment of path) {
|
|
971
|
+
if (typeof segment === "string") {
|
|
972
|
+
if (node.type !== "object" || !Array.isArray(node.children)) {
|
|
973
|
+
return void 0;
|
|
974
|
+
}
|
|
975
|
+
let found = false;
|
|
976
|
+
for (const propertyNode of node.children) {
|
|
977
|
+
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
|
|
978
|
+
node = propertyNode.children[1];
|
|
979
|
+
found = true;
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
if (!found) {
|
|
984
|
+
return void 0;
|
|
985
|
+
}
|
|
986
|
+
} else {
|
|
987
|
+
const index = segment;
|
|
988
|
+
if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
|
|
989
|
+
return void 0;
|
|
990
|
+
}
|
|
991
|
+
node = node.children[index];
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
return node;
|
|
995
|
+
}
|
|
996
|
+
function visit(text, visitor, options = ParseOptions.DEFAULT) {
|
|
997
|
+
const _scanner = createScanner(text, false);
|
|
998
|
+
const _jsonPath = [];
|
|
999
|
+
let suppressedCallbacks = 0;
|
|
1000
|
+
function toNoArgVisit(visitFunction) {
|
|
1001
|
+
return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
1002
|
+
}
|
|
1003
|
+
function toOneArgVisit(visitFunction) {
|
|
1004
|
+
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
1005
|
+
}
|
|
1006
|
+
function toOneArgVisitWithPath(visitFunction) {
|
|
1007
|
+
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
|
|
1008
|
+
}
|
|
1009
|
+
function toBeginVisit(visitFunction) {
|
|
1010
|
+
return visitFunction ? () => {
|
|
1011
|
+
if (suppressedCallbacks > 0) {
|
|
1012
|
+
suppressedCallbacks++;
|
|
1013
|
+
} else {
|
|
1014
|
+
let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
|
|
1015
|
+
if (cbReturn === false) {
|
|
1016
|
+
suppressedCallbacks = 1;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
} : () => true;
|
|
1020
|
+
}
|
|
1021
|
+
function toEndVisit(visitFunction) {
|
|
1022
|
+
return visitFunction ? () => {
|
|
1023
|
+
if (suppressedCallbacks > 0) {
|
|
1024
|
+
suppressedCallbacks--;
|
|
1025
|
+
}
|
|
1026
|
+
if (suppressedCallbacks === 0) {
|
|
1027
|
+
visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
|
|
1028
|
+
}
|
|
1029
|
+
} : () => true;
|
|
1030
|
+
}
|
|
1031
|
+
const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
|
|
1032
|
+
const disallowComments = options && options.disallowComments;
|
|
1033
|
+
const allowTrailingComma = options && options.allowTrailingComma;
|
|
1034
|
+
function scanNext() {
|
|
1035
|
+
while (true) {
|
|
1036
|
+
const token = _scanner.scan();
|
|
1037
|
+
switch (_scanner.getTokenError()) {
|
|
1038
|
+
case 4:
|
|
1039
|
+
handleError(
|
|
1040
|
+
14
|
|
1041
|
+
/* ParseErrorCode.InvalidUnicode */
|
|
1042
|
+
);
|
|
1043
|
+
break;
|
|
1044
|
+
case 5:
|
|
1045
|
+
handleError(
|
|
1046
|
+
15
|
|
1047
|
+
/* ParseErrorCode.InvalidEscapeCharacter */
|
|
1048
|
+
);
|
|
1049
|
+
break;
|
|
1050
|
+
case 3:
|
|
1051
|
+
handleError(
|
|
1052
|
+
13
|
|
1053
|
+
/* ParseErrorCode.UnexpectedEndOfNumber */
|
|
1054
|
+
);
|
|
1055
|
+
break;
|
|
1056
|
+
case 1:
|
|
1057
|
+
if (!disallowComments) {
|
|
1058
|
+
handleError(
|
|
1059
|
+
11
|
|
1060
|
+
/* ParseErrorCode.UnexpectedEndOfComment */
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
break;
|
|
1064
|
+
case 2:
|
|
1065
|
+
handleError(
|
|
1066
|
+
12
|
|
1067
|
+
/* ParseErrorCode.UnexpectedEndOfString */
|
|
1068
|
+
);
|
|
1069
|
+
break;
|
|
1070
|
+
case 6:
|
|
1071
|
+
handleError(
|
|
1072
|
+
16
|
|
1073
|
+
/* ParseErrorCode.InvalidCharacter */
|
|
1074
|
+
);
|
|
1075
|
+
break;
|
|
1076
|
+
}
|
|
1077
|
+
switch (token) {
|
|
1078
|
+
case 12:
|
|
1079
|
+
case 13:
|
|
1080
|
+
if (disallowComments) {
|
|
1081
|
+
handleError(
|
|
1082
|
+
10
|
|
1083
|
+
/* ParseErrorCode.InvalidCommentToken */
|
|
1084
|
+
);
|
|
1085
|
+
} else {
|
|
1086
|
+
onComment();
|
|
1087
|
+
}
|
|
1088
|
+
break;
|
|
1089
|
+
case 16:
|
|
1090
|
+
handleError(
|
|
1091
|
+
1
|
|
1092
|
+
/* ParseErrorCode.InvalidSymbol */
|
|
1093
|
+
);
|
|
1094
|
+
break;
|
|
1095
|
+
case 15:
|
|
1096
|
+
case 14:
|
|
1097
|
+
break;
|
|
1098
|
+
default:
|
|
1099
|
+
return token;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
function handleError(error, skipUntilAfter = [], skipUntil = []) {
|
|
1104
|
+
onError(error);
|
|
1105
|
+
if (skipUntilAfter.length + skipUntil.length > 0) {
|
|
1106
|
+
let token = _scanner.getToken();
|
|
1107
|
+
while (token !== 17) {
|
|
1108
|
+
if (skipUntilAfter.indexOf(token) !== -1) {
|
|
1109
|
+
scanNext();
|
|
1110
|
+
break;
|
|
1111
|
+
} else if (skipUntil.indexOf(token) !== -1) {
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
token = scanNext();
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
function parseString(isValue) {
|
|
1119
|
+
const value = _scanner.getTokenValue();
|
|
1120
|
+
if (isValue) {
|
|
1121
|
+
onLiteralValue(value);
|
|
1122
|
+
} else {
|
|
1123
|
+
onObjectProperty(value);
|
|
1124
|
+
_jsonPath.push(value);
|
|
1125
|
+
}
|
|
1126
|
+
scanNext();
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
function parseLiteral() {
|
|
1130
|
+
switch (_scanner.getToken()) {
|
|
1131
|
+
case 11:
|
|
1132
|
+
const tokenValue = _scanner.getTokenValue();
|
|
1133
|
+
let value = Number(tokenValue);
|
|
1134
|
+
if (isNaN(value)) {
|
|
1135
|
+
handleError(
|
|
1136
|
+
2
|
|
1137
|
+
/* ParseErrorCode.InvalidNumberFormat */
|
|
1138
|
+
);
|
|
1139
|
+
value = 0;
|
|
1140
|
+
}
|
|
1141
|
+
onLiteralValue(value);
|
|
1142
|
+
break;
|
|
1143
|
+
case 7:
|
|
1144
|
+
onLiteralValue(null);
|
|
1145
|
+
break;
|
|
1146
|
+
case 8:
|
|
1147
|
+
onLiteralValue(true);
|
|
1148
|
+
break;
|
|
1149
|
+
case 9:
|
|
1150
|
+
onLiteralValue(false);
|
|
1151
|
+
break;
|
|
1152
|
+
default:
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
scanNext();
|
|
1156
|
+
return true;
|
|
1157
|
+
}
|
|
1158
|
+
function parseProperty() {
|
|
1159
|
+
if (_scanner.getToken() !== 10) {
|
|
1160
|
+
handleError(3, [], [
|
|
1161
|
+
2,
|
|
1162
|
+
5
|
|
1163
|
+
/* SyntaxKind.CommaToken */
|
|
1164
|
+
]);
|
|
1165
|
+
return false;
|
|
1166
|
+
}
|
|
1167
|
+
parseString(false);
|
|
1168
|
+
if (_scanner.getToken() === 6) {
|
|
1169
|
+
onSeparator(":");
|
|
1170
|
+
scanNext();
|
|
1171
|
+
if (!parseValue()) {
|
|
1172
|
+
handleError(4, [], [
|
|
1173
|
+
2,
|
|
1174
|
+
5
|
|
1175
|
+
/* SyntaxKind.CommaToken */
|
|
1176
|
+
]);
|
|
1177
|
+
}
|
|
1178
|
+
} else {
|
|
1179
|
+
handleError(5, [], [
|
|
1180
|
+
2,
|
|
1181
|
+
5
|
|
1182
|
+
/* SyntaxKind.CommaToken */
|
|
1183
|
+
]);
|
|
1184
|
+
}
|
|
1185
|
+
_jsonPath.pop();
|
|
1186
|
+
return true;
|
|
1187
|
+
}
|
|
1188
|
+
function parseObject() {
|
|
1189
|
+
onObjectBegin();
|
|
1190
|
+
scanNext();
|
|
1191
|
+
let needsComma = false;
|
|
1192
|
+
while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
|
|
1193
|
+
if (_scanner.getToken() === 5) {
|
|
1194
|
+
if (!needsComma) {
|
|
1195
|
+
handleError(4, [], []);
|
|
1196
|
+
}
|
|
1197
|
+
onSeparator(",");
|
|
1198
|
+
scanNext();
|
|
1199
|
+
if (_scanner.getToken() === 2 && allowTrailingComma) {
|
|
1200
|
+
break;
|
|
1201
|
+
}
|
|
1202
|
+
} else if (needsComma) {
|
|
1203
|
+
handleError(6, [], []);
|
|
1204
|
+
}
|
|
1205
|
+
if (!parseProperty()) {
|
|
1206
|
+
handleError(4, [], [
|
|
1207
|
+
2,
|
|
1208
|
+
5
|
|
1209
|
+
/* SyntaxKind.CommaToken */
|
|
1210
|
+
]);
|
|
1211
|
+
}
|
|
1212
|
+
needsComma = true;
|
|
1213
|
+
}
|
|
1214
|
+
onObjectEnd();
|
|
1215
|
+
if (_scanner.getToken() !== 2) {
|
|
1216
|
+
handleError(7, [
|
|
1217
|
+
2
|
|
1218
|
+
/* SyntaxKind.CloseBraceToken */
|
|
1219
|
+
], []);
|
|
1220
|
+
} else {
|
|
1221
|
+
scanNext();
|
|
1222
|
+
}
|
|
1223
|
+
return true;
|
|
1224
|
+
}
|
|
1225
|
+
function parseArray() {
|
|
1226
|
+
onArrayBegin();
|
|
1227
|
+
scanNext();
|
|
1228
|
+
let isFirstElement = true;
|
|
1229
|
+
let needsComma = false;
|
|
1230
|
+
while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
|
|
1231
|
+
if (_scanner.getToken() === 5) {
|
|
1232
|
+
if (!needsComma) {
|
|
1233
|
+
handleError(4, [], []);
|
|
1234
|
+
}
|
|
1235
|
+
onSeparator(",");
|
|
1236
|
+
scanNext();
|
|
1237
|
+
if (_scanner.getToken() === 4 && allowTrailingComma) {
|
|
1238
|
+
break;
|
|
1239
|
+
}
|
|
1240
|
+
} else if (needsComma) {
|
|
1241
|
+
handleError(6, [], []);
|
|
1242
|
+
}
|
|
1243
|
+
if (isFirstElement) {
|
|
1244
|
+
_jsonPath.push(0);
|
|
1245
|
+
isFirstElement = false;
|
|
1246
|
+
} else {
|
|
1247
|
+
_jsonPath[_jsonPath.length - 1]++;
|
|
1248
|
+
}
|
|
1249
|
+
if (!parseValue()) {
|
|
1250
|
+
handleError(4, [], [
|
|
1251
|
+
4,
|
|
1252
|
+
5
|
|
1253
|
+
/* SyntaxKind.CommaToken */
|
|
1254
|
+
]);
|
|
1255
|
+
}
|
|
1256
|
+
needsComma = true;
|
|
1257
|
+
}
|
|
1258
|
+
onArrayEnd();
|
|
1259
|
+
if (!isFirstElement) {
|
|
1260
|
+
_jsonPath.pop();
|
|
1261
|
+
}
|
|
1262
|
+
if (_scanner.getToken() !== 4) {
|
|
1263
|
+
handleError(8, [
|
|
1264
|
+
4
|
|
1265
|
+
/* SyntaxKind.CloseBracketToken */
|
|
1266
|
+
], []);
|
|
1267
|
+
} else {
|
|
1268
|
+
scanNext();
|
|
1269
|
+
}
|
|
1270
|
+
return true;
|
|
1271
|
+
}
|
|
1272
|
+
function parseValue() {
|
|
1273
|
+
switch (_scanner.getToken()) {
|
|
1274
|
+
case 3:
|
|
1275
|
+
return parseArray();
|
|
1276
|
+
case 1:
|
|
1277
|
+
return parseObject();
|
|
1278
|
+
case 10:
|
|
1279
|
+
return parseString(true);
|
|
1280
|
+
default:
|
|
1281
|
+
return parseLiteral();
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
scanNext();
|
|
1285
|
+
if (_scanner.getToken() === 17) {
|
|
1286
|
+
if (options.allowEmptyContent) {
|
|
1287
|
+
return true;
|
|
1288
|
+
}
|
|
1289
|
+
handleError(4, [], []);
|
|
1290
|
+
return false;
|
|
1291
|
+
}
|
|
1292
|
+
if (!parseValue()) {
|
|
1293
|
+
handleError(4, [], []);
|
|
1294
|
+
return false;
|
|
1295
|
+
}
|
|
1296
|
+
if (_scanner.getToken() !== 17) {
|
|
1297
|
+
handleError(9, [], []);
|
|
1298
|
+
}
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
function getNodeType(value) {
|
|
1302
|
+
switch (typeof value) {
|
|
1303
|
+
case "boolean":
|
|
1304
|
+
return "boolean";
|
|
1305
|
+
case "number":
|
|
1306
|
+
return "number";
|
|
1307
|
+
case "string":
|
|
1308
|
+
return "string";
|
|
1309
|
+
case "object": {
|
|
1310
|
+
if (!value) {
|
|
1311
|
+
return "null";
|
|
1312
|
+
} else if (Array.isArray(value)) {
|
|
1313
|
+
return "array";
|
|
1314
|
+
}
|
|
1315
|
+
return "object";
|
|
1316
|
+
}
|
|
1317
|
+
default:
|
|
1318
|
+
return "null";
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
// ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
|
|
1323
|
+
var ScanError;
|
|
1324
|
+
(function(ScanError2) {
|
|
1325
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
1326
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
1327
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
1328
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
1329
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
1330
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
1331
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
1332
|
+
})(ScanError || (ScanError = {}));
|
|
1333
|
+
var SyntaxKind;
|
|
1334
|
+
(function(SyntaxKind2) {
|
|
1335
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
1336
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
1337
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
1338
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
1339
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
1340
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
1341
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
1342
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
1343
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
1344
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
1345
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
1346
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
1347
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
1348
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
1349
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
1350
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
1351
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
1352
|
+
})(SyntaxKind || (SyntaxKind = {}));
|
|
1353
|
+
var parseTree2 = parseTree;
|
|
1354
|
+
var findNodeAtLocation2 = findNodeAtLocation;
|
|
1355
|
+
var ParseErrorCode;
|
|
1356
|
+
(function(ParseErrorCode2) {
|
|
1357
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
1358
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
1359
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
1360
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
1361
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
1362
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
1363
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
1364
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
1365
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
1366
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
1367
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
1368
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
1369
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
1370
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
1371
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
1372
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
1373
|
+
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
1374
|
+
|
|
1375
|
+
// src/generators/shared/json-edit.ts
|
|
396
1376
|
function detectIndent(raw) {
|
|
397
1377
|
for (const line of raw.split("\n")) {
|
|
398
1378
|
const match = /^(\t+| +)/.exec(line);
|
|
@@ -400,6 +1380,81 @@ function detectIndent(raw) {
|
|
|
400
1380
|
}
|
|
401
1381
|
return " ";
|
|
402
1382
|
}
|
|
1383
|
+
function styleOf(raw) {
|
|
1384
|
+
return { eol: raw.includes("\r\n") ? "\r\n" : "\n", unit: detectIndent(raw) };
|
|
1385
|
+
}
|
|
1386
|
+
function lineIndentAt(raw, offset) {
|
|
1387
|
+
const lineStart = raw.lastIndexOf("\n", offset - 1) + 1;
|
|
1388
|
+
return /^[ \t]*/.exec(raw.slice(lineStart))?.[0] ?? "";
|
|
1389
|
+
}
|
|
1390
|
+
function isMultiline(raw, node) {
|
|
1391
|
+
return raw.slice(node.offset, node.offset + node.length).includes("\n");
|
|
1392
|
+
}
|
|
1393
|
+
function isPrimitive(value) {
|
|
1394
|
+
return value === null || ["string", "number", "boolean"].includes(typeof value);
|
|
1395
|
+
}
|
|
1396
|
+
function renderValue(value, indent, style) {
|
|
1397
|
+
if (isPrimitive(value)) return JSON.stringify(value);
|
|
1398
|
+
if (Array.isArray(value)) {
|
|
1399
|
+
if (value.every(isPrimitive)) return `[${value.map((item) => JSON.stringify(item)).join(", ")}]`;
|
|
1400
|
+
const inner2 = `${indent}${style.unit}`;
|
|
1401
|
+
return `[${style.eol}${value.map((item) => `${inner2}${renderValue(item, inner2, style)}`).join(`,${style.eol}`)}${style.eol}${indent}]`;
|
|
1402
|
+
}
|
|
1403
|
+
const entries = Object.entries(value);
|
|
1404
|
+
if (entries.length === 0) return "{}";
|
|
1405
|
+
const inner = `${indent}${style.unit}`;
|
|
1406
|
+
const body = entries.map(([key, item]) => `${inner}${JSON.stringify(key)}: ${renderValue(item, inner, style)}`).join(`,${style.eol}`);
|
|
1407
|
+
return `{${style.eol}${body}${style.eol}${indent}}`;
|
|
1408
|
+
}
|
|
1409
|
+
function splice(raw, start, end, text) {
|
|
1410
|
+
return raw.slice(0, start) + text + raw.slice(end);
|
|
1411
|
+
}
|
|
1412
|
+
function nest(keys, value) {
|
|
1413
|
+
return keys.reduceRight((inner, key) => ({ [key]: inner }), value);
|
|
1414
|
+
}
|
|
1415
|
+
function insertProperty(raw, object, key, value, style) {
|
|
1416
|
+
const properties = object.children ?? [];
|
|
1417
|
+
const objectIndent = lineIndentAt(raw, object.offset);
|
|
1418
|
+
if (properties.length === 0) {
|
|
1419
|
+
const inner = `${objectIndent}${style.unit}`;
|
|
1420
|
+
const text = `{${style.eol}${inner}${JSON.stringify(String(key))}: ${renderValue(value, inner, style)}${style.eol}${objectIndent}}`;
|
|
1421
|
+
return splice(raw, object.offset, object.offset + object.length, text);
|
|
1422
|
+
}
|
|
1423
|
+
const last = properties[properties.length - 1];
|
|
1424
|
+
const end = last.offset + last.length;
|
|
1425
|
+
if (!isMultiline(raw, object)) {
|
|
1426
|
+
return splice(raw, end, end, `, ${JSON.stringify(String(key))}: ${renderValue(value, "", style)}`);
|
|
1427
|
+
}
|
|
1428
|
+
const indent = lineIndentAt(raw, last.offset);
|
|
1429
|
+
return splice(raw, end, end, `,${style.eol}${indent}${JSON.stringify(String(key))}: ${renderValue(value, indent, style)}`);
|
|
1430
|
+
}
|
|
1431
|
+
function setJsonValue(raw, path, value) {
|
|
1432
|
+
const style = styleOf(raw);
|
|
1433
|
+
const root = parseTree2(raw);
|
|
1434
|
+
if (root === void 0) throw new Error("setJsonValue: not a JSON document");
|
|
1435
|
+
const existing = findNodeAtLocation2(root, path);
|
|
1436
|
+
if (existing !== void 0) {
|
|
1437
|
+
return splice(raw, existing.offset, existing.offset + existing.length, renderValue(value, lineIndentAt(raw, existing.offset), style));
|
|
1438
|
+
}
|
|
1439
|
+
for (let depth = path.length - 1; depth >= 0; depth--) {
|
|
1440
|
+
const parent = depth === 0 ? root : findNodeAtLocation2(root, path.slice(0, depth));
|
|
1441
|
+
if (parent === void 0) continue;
|
|
1442
|
+
if (parent.type !== "object") throw new Error(`setJsonValue: ${path.slice(0, depth).join(".") || "the root"} is not an object`);
|
|
1443
|
+
return insertProperty(raw, parent, path[depth], nest(path.slice(depth + 1), value), style);
|
|
1444
|
+
}
|
|
1445
|
+
throw new Error("setJsonValue: unreachable");
|
|
1446
|
+
}
|
|
1447
|
+
function applyJsonEdits(raw, edits) {
|
|
1448
|
+
if (raw === null) {
|
|
1449
|
+
let text = "{}\n";
|
|
1450
|
+
for (const [path, value] of edits) text = setJsonValue(text, path, value);
|
|
1451
|
+
return text;
|
|
1452
|
+
}
|
|
1453
|
+
return edits.reduce((text, [path, value]) => setJsonValue(text, path, value), raw);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/generators/shared/toolkit-config-file.ts
|
|
1457
|
+
var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
|
|
403
1458
|
function readToolkitConfigFile(tree) {
|
|
404
1459
|
const raw = tree.read(TOOLKIT_CONFIG_PATH, "utf-8");
|
|
405
1460
|
if (raw === null) return { raw: null, parsed: null };
|
|
@@ -435,12 +1490,7 @@ function recordAiHosts(tree, hosts, write) {
|
|
|
435
1490
|
if (Array.isArray(recorded) && recorded.length === hosts.length && recorded.every((id, index) => id === hosts[index])) {
|
|
436
1491
|
return "unchanged";
|
|
437
1492
|
}
|
|
438
|
-
if (write)
|
|
439
|
-
const indent = raw === null ? " " : detectIndent(raw);
|
|
440
|
-
const body = JSON.stringify({ ...existing, aiHosts: [...hosts] }, null, indent);
|
|
441
|
-
tree.write(TOOLKIT_CONFIG_PATH, raw === null || raw.endsWith("\n") ? `${body}
|
|
442
|
-
` : body);
|
|
443
|
-
}
|
|
1493
|
+
if (write) tree.write(TOOLKIT_CONFIG_PATH, applyJsonEdits(raw, [[["aiHosts"], [...hosts]]]));
|
|
444
1494
|
return raw === null ? "created" : "updated";
|
|
445
1495
|
}
|
|
446
1496
|
|
|
@@ -450,7 +1500,8 @@ var ACTION_LINE = {
|
|
|
450
1500
|
appended: (result) => `${result.filePath}: nx-archweave block added after the existing content (nothing else changed)`,
|
|
451
1501
|
updated: (result) => `${result.filePath}: nx-archweave block updated (nothing outside it changed)`,
|
|
452
1502
|
unchanged: (result) => `${result.filePath}: unchanged`,
|
|
453
|
-
unrecognized: (result) => `${result.filePath}: not written \u2014 ${result.reason ?? "the nx-archweave markers could not be placed"}
|
|
1503
|
+
unrecognized: (result) => `${result.filePath}: not written \u2014 ${result.reason ?? "the nx-archweave markers could not be placed"}`,
|
|
1504
|
+
"user-modified": (result) => `${result.filePath}: not written \u2014 the nx-archweave block was edited by hand, so it is kept`
|
|
454
1505
|
};
|
|
455
1506
|
function renderAddAgentRulesReport(report) {
|
|
456
1507
|
const lines = [];
|
|
@@ -461,6 +1512,11 @@ function renderAddAgentRulesReport(report) {
|
|
|
461
1512
|
lines.push("");
|
|
462
1513
|
for (const file of report.files) {
|
|
463
1514
|
lines.push(` ${ACTION_LINE[file.action](file)}`);
|
|
1515
|
+
if (file.action === "user-modified") {
|
|
1516
|
+
lines.push(" What this run would write instead (your block \u2192 generated):");
|
|
1517
|
+
for (const line of (file.diff ?? "").split("\n")) lines.push(` ${line}`);
|
|
1518
|
+
lines.push(" Rerun with --overwriteBlock to replace the block with the generated one.");
|
|
1519
|
+
}
|
|
464
1520
|
}
|
|
465
1521
|
const RECORD_LINE = {
|
|
466
1522
|
created: "toolkit.config.json: aiHosts recorded (file created)",
|
|
@@ -474,7 +1530,7 @@ function renderAddAgentRulesReport(report) {
|
|
|
474
1530
|
if (recordLine !== null) lines.push(` ${recordLine}`);
|
|
475
1531
|
if (report.files.some((file) => file.action === "unrecognized")) {
|
|
476
1532
|
lines.push("");
|
|
477
|
-
lines.push('Manual fix needed: keep exactly one "<!-- nx-archweave:agent-rules start -->" \u2026 "<!-- nx-archweave:agent-rules end -->"');
|
|
1533
|
+
lines.push('Manual fix needed: keep exactly one "<!-- nx-archweave:agent-rules start \u2026 -->" \u2026 "<!-- nx-archweave:agent-rules end -->"');
|
|
478
1534
|
lines.push("pair in the file (or remove both markers), then rerun add-agent-rules.");
|
|
479
1535
|
}
|
|
480
1536
|
if (report.dryRun) {
|
|
@@ -490,6 +1546,87 @@ function renderAddAgentRulesReport(report) {
|
|
|
490
1546
|
return lines.join("\n");
|
|
491
1547
|
}
|
|
492
1548
|
|
|
1549
|
+
// src/generators/add-review/render.ts
|
|
1550
|
+
function renderLineDiff(existing, generated) {
|
|
1551
|
+
const a = existing.split("\n");
|
|
1552
|
+
const b = generated.split("\n");
|
|
1553
|
+
const m = a.length;
|
|
1554
|
+
const n = b.length;
|
|
1555
|
+
const lcs = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
1556
|
+
for (let i2 = m - 1; i2 >= 0; i2--) {
|
|
1557
|
+
for (let j2 = n - 1; j2 >= 0; j2--) {
|
|
1558
|
+
lcs[i2][j2] = a[i2] === b[j2] ? lcs[i2 + 1][j2 + 1] + 1 : Math.max(lcs[i2 + 1][j2], lcs[i2][j2 + 1]);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
const out = ["--- existing", "+++ generated"];
|
|
1562
|
+
let i = 0;
|
|
1563
|
+
let j = 0;
|
|
1564
|
+
while (i < m && j < n) {
|
|
1565
|
+
if (a[i] === b[j]) {
|
|
1566
|
+
out.push(` ${a[i]}`);
|
|
1567
|
+
i++;
|
|
1568
|
+
j++;
|
|
1569
|
+
} else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
|
1570
|
+
out.push(`- ${a[i]}`);
|
|
1571
|
+
i++;
|
|
1572
|
+
} else {
|
|
1573
|
+
out.push(`+ ${b[j]}`);
|
|
1574
|
+
j++;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
while (i < m) out.push(`- ${a[i++]}`);
|
|
1578
|
+
while (j < n) out.push(`+ ${b[j++]}`);
|
|
1579
|
+
return out.join("\n");
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
// src/eslint/fsd-policy.ts
|
|
1583
|
+
var PRESETS = {
|
|
1584
|
+
basic: {
|
|
1585
|
+
sliceGroups: { auto: true, include: [], exclude: [] },
|
|
1586
|
+
sharedPublicApi: "segment",
|
|
1587
|
+
testFiles: false,
|
|
1588
|
+
segments: [],
|
|
1589
|
+
platformSuffixes: [],
|
|
1590
|
+
routerDirs: []
|
|
1591
|
+
},
|
|
1592
|
+
practical: {
|
|
1593
|
+
sliceGroups: { auto: true, include: [], exclude: [] },
|
|
1594
|
+
sharedPublicApi: "file",
|
|
1595
|
+
testFiles: ["**/*.{spec,test}.*", "**/__tests__/**"],
|
|
1596
|
+
segments: [],
|
|
1597
|
+
platformSuffixes: [],
|
|
1598
|
+
routerDirs: []
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
var isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1602
|
+
function resolveFsdPolicy(recorded, overrides = {}) {
|
|
1603
|
+
const fsd = typeof recorded === "object" && recorded !== null ? recorded : {};
|
|
1604
|
+
const preset = fsd["preset"] === "practical" ? "practical" : "basic";
|
|
1605
|
+
const policy = { ...PRESETS[preset] };
|
|
1606
|
+
const groups = fsd["sliceGroups"];
|
|
1607
|
+
if (groups === false) policy.sliceGroups = false;
|
|
1608
|
+
else if (groups === "auto") policy.sliceGroups = { auto: true, include: [], exclude: [] };
|
|
1609
|
+
else if (typeof groups === "object" && groups !== null) {
|
|
1610
|
+
const value = groups;
|
|
1611
|
+
policy.sliceGroups = {
|
|
1612
|
+
auto: value["auto"] !== false,
|
|
1613
|
+
include: isStringArray(value["include"]) ? value["include"] : [],
|
|
1614
|
+
exclude: isStringArray(value["exclude"]) ? value["exclude"] : []
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
const shared = fsd["sharedPublicApi"];
|
|
1618
|
+
if (shared === "segment" || shared === "component" || shared === "file") policy.sharedPublicApi = shared;
|
|
1619
|
+
const tests = fsd["testFiles"];
|
|
1620
|
+
if (tests === false || isStringArray(tests)) policy.testFiles = tests;
|
|
1621
|
+
if (isStringArray(fsd["segments"])) policy.segments = fsd["segments"];
|
|
1622
|
+
if (isStringArray(fsd["platformSuffixes"])) policy.platformSuffixes = fsd["platformSuffixes"];
|
|
1623
|
+
if (isStringArray(fsd["routerDirs"])) policy.routerDirs = fsd["routerDirs"];
|
|
1624
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
1625
|
+
if (value !== void 0) policy[key] = value;
|
|
1626
|
+
}
|
|
1627
|
+
return policy;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
493
1630
|
// src/generators/add-agent-rules/generator.ts
|
|
494
1631
|
function resolveTeamRules(option, config) {
|
|
495
1632
|
if (option !== void 0) return option;
|
|
@@ -504,6 +1641,13 @@ function resolveFsdStructure(config) {
|
|
|
504
1641
|
const frontend = config?.["frontend"];
|
|
505
1642
|
return typeof frontend === "string" && frontend !== "none";
|
|
506
1643
|
}
|
|
1644
|
+
var POLICY_KEYS = ["preset", "sliceGroups", "sharedPublicApi", "testFiles"];
|
|
1645
|
+
function resolveFsdPolicyNotes(config) {
|
|
1646
|
+
const fsd = config?.["fsd"];
|
|
1647
|
+
if (typeof fsd !== "object" || fsd === null || !POLICY_KEYS.some((key) => key in fsd)) return void 0;
|
|
1648
|
+
const policy = resolveFsdPolicy(fsd);
|
|
1649
|
+
return { sliceGroups: policy.sliceGroups !== false, sharedPublicApi: policy.sharedPublicApi, testFiles: policy.testFiles !== false };
|
|
1650
|
+
}
|
|
507
1651
|
function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } = {}) {
|
|
508
1652
|
const config = readToolkitConfig(tree);
|
|
509
1653
|
const hosts = resolveAiHostsOption(options.hosts, config);
|
|
@@ -511,7 +1655,7 @@ function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } =
|
|
|
511
1655
|
const locale = resolveLocaleOption(options.locale, config);
|
|
512
1656
|
const teamRules = resolveTeamRules(options.teamRules, config);
|
|
513
1657
|
const dryRun = options.dryRun ?? false;
|
|
514
|
-
const composed = composeAgentRules({ files, locale, teamRules, fsdStructure: fsdStructure ?? resolveFsdStructure(config) });
|
|
1658
|
+
const composed = composeAgentRules({ files, locale, teamRules, fsdStructure: fsdStructure ?? resolveFsdStructure(config), fsdPolicy: resolveFsdPolicyNotes(config) });
|
|
515
1659
|
const results = composed.map(({ filePath, content }) => {
|
|
516
1660
|
if (!validateAgentRules(content, teamRules ? ["team-rules"] : [])) {
|
|
517
1661
|
throw new Error(
|
|
@@ -519,12 +1663,20 @@ function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } =
|
|
|
519
1663
|
);
|
|
520
1664
|
}
|
|
521
1665
|
const existing = tree.read(filePath, "utf-8");
|
|
522
|
-
const outcome = applyAgentRulesBlock(existing, content);
|
|
1666
|
+
const outcome = applyAgentRulesBlock(existing, content, { overwrite: options.overwriteBlock === true });
|
|
523
1667
|
switch (outcome.kind) {
|
|
524
1668
|
case "unchanged":
|
|
525
1669
|
return { filePath, action: "unchanged", reason: null, content: null };
|
|
526
1670
|
case "unrecognized":
|
|
527
1671
|
return { filePath, action: "unrecognized", reason: outcome.reason, content: null };
|
|
1672
|
+
case "user-modified":
|
|
1673
|
+
return {
|
|
1674
|
+
filePath,
|
|
1675
|
+
action: "user-modified",
|
|
1676
|
+
reason: null,
|
|
1677
|
+
content: null,
|
|
1678
|
+
diff: renderLineDiff(outcome.existingBody, outcome.generatedBody)
|
|
1679
|
+
};
|
|
528
1680
|
case "create":
|
|
529
1681
|
case "append":
|
|
530
1682
|
case "replace": {
|