@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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/dist/eslint/fsd-boundaries.d.ts +25 -8
  3. package/dist/eslint/fsd-policy.d.ts +38 -0
  4. package/dist/eslint/index.d.ts +10 -9
  5. package/dist/eslint/index.js +227 -34
  6. package/dist/eslint/slice-groups.d.ts +12 -0
  7. package/dist/generators/add-agent-rules/generator.js +1175 -23
  8. package/dist/generators/add-backend/generator.js +1127 -75
  9. package/dist/generators/add-fsd-lite/generator.js +1274 -96
  10. package/dist/generators/add-review/files/dependabot.yml +7 -0
  11. package/dist/generators/add-review/generator.js +1100 -46
  12. package/dist/generators/doctor/generator.js +780 -96
  13. package/dist/generators/entity/generator.js +251 -32
  14. package/dist/generators/feature/generator.js +251 -32
  15. package/dist/generators/init/generator.js +1955 -549
  16. package/dist/generators/page/generator.js +251 -32
  17. package/dist/generators/shared/generator.js +251 -32
  18. package/dist/generators/widget/generator.js +251 -32
  19. package/package.json +4 -1
  20. package/src/generators/add-agent-rules/schema.json +5 -0
  21. package/src/generators/add-fsd-lite/schema.json +2 -2
  22. package/src/generators/entity/schema.json +11 -1
  23. package/src/generators/feature/schema.json +11 -1
  24. package/src/generators/init/schema.json +13 -2
  25. package/src/generators/page/schema.json +15 -3
  26. package/src/generators/shared/schema.json +7 -1
  27. package/src/generators/widget/schema.json +11 -1
  28. package/dist/eslint/fsd-boundaries.js +0 -144
  29. package/dist/eslint/tsconfig-aliases.js +0 -114
  30. package/dist/generators/add-agent-rules/render.js +0 -46
  31. package/dist/generators/add-backend/render.js +0 -102
  32. package/dist/generators/add-fsd-lite/render.js +0 -72
  33. package/dist/generators/add-github-templates/render.js +0 -26
  34. package/dist/generators/add-integration/render.js +0 -34
  35. package/dist/generators/add-review/render.js +0 -96
  36. package/dist/generators/allow-builds/render.js +0 -82
  37. package/dist/generators/doctor/integration-report.js +0 -70
  38. package/dist/generators/doctor/render.js +0 -10
  39. package/dist/generators/init/render.js +0 -125
  40. package/dist/generators/init/validation.js +0 -74
  41. package/dist/generators/install-integration/render.js +0 -128
  42. package/dist/generators/record-integration/render.js +0 -31
  43. package/dist/generators/shared/dry-run.js +0 -12
  44. package/dist/generators/shared/frontend-app.js +0 -57
  45. package/dist/generators/shared/project-type.js +0 -39
  46. package/dist/generators/shared/record-pipeline.js +0 -34
  47. package/dist/generators/shared/run-nx.js +0 -24
  48. package/dist/generators/shared/template-files.js +0 -38
  49. package/dist/generators/shared/toolkit-config-file.js +0 -110
  50. package/dist/generators/slice/core.js +0 -185
  51. package/dist/generators/slice/render.js +0 -70
  52. package/dist/lib/nx-plugin.js +0 -7
  53. package/dist/runtime/integrations-composition-root.js +0 -20
  54. package/dist/runtime/node-command-runner.js +0 -81
@@ -47,13 +47,26 @@ function packageManagerCommands(pm, flavor = "classic") {
47
47
  }
48
48
 
49
49
  // ../template-engine/dist/backend/eslint-boundaries.js
50
- var SCOPE_CONSTRAINTS = [
51
- { sourceTag: "scope:frontend", notDependOnLibsWithTags: ["scope:backend"] },
52
- { sourceTag: "scope:backend", notDependOnLibsWithTags: ["scope:frontend"] },
53
- { sourceTag: "scope:shared", notDependOnLibsWithTags: ["scope:frontend", "scope:backend"] }
54
- ];
50
+ var DEFAULT_BOUNDARY_TAGS = { frontend: "scope:frontend", backend: "scope:backend", shared: "scope:shared" };
51
+ function readBoundaryTags(config) {
52
+ const boundaries = config?.["boundaries"];
53
+ const tags = typeof boundaries === "object" && boundaries !== null ? boundaries["tags"] : void 0;
54
+ const pick = (role) => {
55
+ const value = typeof tags === "object" && tags !== null ? tags[role] : void 0;
56
+ return typeof value === "string" && value.trim() !== "" ? value : DEFAULT_BOUNDARY_TAGS[role];
57
+ };
58
+ return { frontend: pick("frontend"), backend: pick("backend"), shared: pick("shared") };
59
+ }
60
+ function scopeConstraints(tags = DEFAULT_BOUNDARY_TAGS) {
61
+ return [
62
+ { sourceTag: tags.frontend, notDependOnLibsWithTags: [tags.backend] },
63
+ { sourceTag: tags.backend, notDependOnLibsWithTags: [tags.frontend] },
64
+ { sourceTag: tags.shared, notDependOnLibsWithTags: [tags.frontend, tags.backend] }
65
+ ];
66
+ }
67
+ var SCOPE_CONSTRAINTS = scopeConstraints();
55
68
  var ESLINT_CONFIG_CANDIDATES = ["eslint.config.mjs", "eslint.config.js", "eslint.config.cjs"];
56
- var APPLIED_MARKER = "sourceTag: 'scope:frontend'";
69
+ var appliedMarker = (tags) => `sourceTag: '${tags.frontend}'`;
57
70
  var ALLOW_ALL_BLOCK = /depConstraints:\s*\[\s*\{\s*sourceTag:\s*'\*',\s*onlyDependOnLibsWithTags:\s*\[\s*'\*'\s*\],?\s*\},?\s*\]/g;
58
71
  function maskComments(text) {
59
72
  const out = text.split("");
@@ -106,17 +119,17 @@ function findAllowAllMatches(masked) {
106
119
  }
107
120
  return matches;
108
121
  }
109
- function classifyBoundaryConstraints(configText) {
122
+ function classifyBoundaryConstraints(configText, tags = DEFAULT_BOUNDARY_TAGS) {
110
123
  const masked = maskComments(configText);
111
- if (masked.includes(APPLIED_MARKER))
124
+ if (masked.includes(appliedMarker(tags)))
112
125
  return "enforced";
113
126
  if (findAllowAllMatches(masked).length > 0)
114
127
  return "allow-all";
115
128
  return "unknown";
116
129
  }
117
- function renderConstraintsBlock(indent, eol) {
118
- const renderList = (tags) => tags.map((t) => `'${t}'`).join(", ");
119
- const inner = SCOPE_CONSTRAINTS.map((c) => {
130
+ function renderConstraintsBlock(indent, eol, tags) {
131
+ const renderList = (list) => list.map((t) => `'${t}'`).join(", ");
132
+ const inner = scopeConstraints(tags).map((c) => {
120
133
  const field = c.notDependOnLibsWithTags ? `notDependOnLibsWithTags: [${renderList(c.notDependOnLibsWithTags)}]` : `onlyDependOnLibsWithTags: [${renderList(c.onlyDependOnLibsWithTags ?? [])}]`;
121
134
  return [`${indent} {`, `${indent} sourceTag: '${c.sourceTag}',`, `${indent} ${field},`, `${indent} },`].join(eol);
122
135
  }).join(eol);
@@ -134,8 +147,8 @@ function renderConstraintsBlock(indent, eol) {
134
147
  `${indent}]`
135
148
  ].join(eol);
136
149
  }
137
- function applyBoundaryConstraints(configText) {
138
- const classification = classifyBoundaryConstraints(configText);
150
+ function applyBoundaryConstraints(configText, tags = DEFAULT_BOUNDARY_TAGS) {
151
+ const classification = classifyBoundaryConstraints(configText, tags);
139
152
  if (classification === "enforced")
140
153
  return { status: "already-applied" };
141
154
  if (classification === "unknown")
@@ -149,17 +162,17 @@ function applyBoundaryConstraints(configText) {
149
162
  const eol = configText.includes("\r\n") ? "\r\n" : "\n";
150
163
  const lineStart = configText.lastIndexOf("\n", match.index) + 1;
151
164
  const indent = /^[ \t]*/.exec(configText.slice(lineStart, match.index))?.[0] ?? "";
152
- const replacement = renderConstraintsBlock(indent, eol);
165
+ const replacement = renderConstraintsBlock(indent, eol, tags);
153
166
  const text = configText.slice(0, match.index) + replacement + configText.slice(match.index + match.length);
154
167
  return { status: "applied", text };
155
168
  }
156
- function buildBoundarySnippet() {
169
+ function buildBoundarySnippet(tags = DEFAULT_BOUNDARY_TAGS) {
157
170
  return [
158
171
  "// nx-archweave project boundaries \u2014 merge these entries into the depConstraints",
159
172
  "// array of the '@nx/enforce-module-boundaries' rule in your root ESLint config.",
160
173
  "// They ride on top of your existing entries: constraints apply conjunctively,",
161
174
  "// so the allow-all baseline can stay.",
162
- renderConstraintsBlock("", "\n")
175
+ renderConstraintsBlock("", "\n", tags)
163
176
  ].join("\n");
164
177
  }
165
178
 
@@ -179,7 +192,7 @@ function sharedTypesApiTypesContent() {
179
192
  ""
180
193
  ].join("\n");
181
194
  }
182
- function sharedTypesPackageJsonContent(packageName) {
195
+ function sharedTypesPackageJsonContent(packageName, sharedTag = "scope:shared") {
183
196
  return `${JSON.stringify({
184
197
  name: packageName,
185
198
  version: "0.0.1",
@@ -196,7 +209,7 @@ function sharedTypesPackageJsonContent(packageName) {
196
209
  },
197
210
  nx: {
198
211
  projectType: "library",
199
- tags: ["scope:shared"],
212
+ tags: [sharedTag],
200
213
  targets: {}
201
214
  }
202
215
  }, null, 2)}
@@ -204,21 +217,36 @@ function sharedTypesPackageJsonContent(packageName) {
204
217
  }
205
218
 
206
219
  // ../template-engine/dist/backend/compose-backend-wiring.js
220
+ var DEFAULT_SHARED_TYPES_ROOT = "libs/shared-types";
221
+ function readSharedTypesConfig(config) {
222
+ const value = config?.["sharedTypes"];
223
+ if (value === false)
224
+ return false;
225
+ if (typeof value !== "object" || value === null)
226
+ return { path: DEFAULT_SHARED_TYPES_ROOT };
227
+ const record = value;
228
+ const path = typeof record["path"] === "string" && record["path"].trim() !== "" ? record["path"].replace(/\/+$/, "") : DEFAULT_SHARED_TYPES_ROOT;
229
+ const importPath = typeof record["importPath"] === "string" && record["importPath"].trim() !== "" ? record["importPath"] : void 0;
230
+ return importPath === void 0 ? { path } : { path, importPath };
231
+ }
207
232
  function composeBackendWiring(input) {
208
233
  const scoped = /^@([^/]+)\//.exec(input.workspaceName);
209
234
  const scope = scoped ? `@${scoped[1]}` : `@${input.workspaceName.split("/").pop() || "workspace"}`;
210
- const sharedTypesPackageName = `${scope}/shared-types`;
235
+ const sharedTypesRoot = input.sharedTypes?.path ?? DEFAULT_SHARED_TYPES_ROOT;
236
+ const sharedTypesPackageName = input.sharedTypes?.importPath ?? `${scope}/shared-types`;
237
+ const tagByRole = input.tags ?? DEFAULT_BOUNDARY_TAGS;
211
238
  return {
212
239
  sharedTypesFiles: [
213
- { filePath: "libs/shared-types/package.json", content: sharedTypesPackageJsonContent(sharedTypesPackageName) },
214
- { filePath: "libs/shared-types/src/index.ts", content: sharedTypesIndexContent() },
215
- { filePath: "libs/shared-types/src/lib/api-types.ts", content: sharedTypesApiTypesContent() }
240
+ { filePath: `${sharedTypesRoot}/package.json`, content: sharedTypesPackageJsonContent(sharedTypesPackageName, tagByRole.shared) },
241
+ { filePath: `${sharedTypesRoot}/src/index.ts`, content: sharedTypesIndexContent() },
242
+ { filePath: `${sharedTypesRoot}/src/lib/api-types.ts`, content: sharedTypesApiTypesContent() }
216
243
  ],
217
244
  sharedTypesPackageName,
218
- tagByRole: { frontend: "scope:frontend", backend: "scope:backend", shared: "scope:shared" }
245
+ sharedTypesRoot,
246
+ tagByRole
219
247
  };
220
248
  }
221
- function addSharedTypesNpmWorkspace(packageJsonText) {
249
+ function addSharedTypesNpmWorkspace(packageJsonText, entry = DEFAULT_SHARED_TYPES_ROOT) {
222
250
  let parsed;
223
251
  try {
224
252
  parsed = JSON.parse(packageJsonText);
@@ -239,19 +267,19 @@ function addSharedTypesNpmWorkspace(packageJsonText) {
239
267
  } else {
240
268
  return { status: "unrecognized" };
241
269
  }
242
- if (target.some((entry) => entry === "libs/shared-types" || entry === "libs/*"))
270
+ const parentGlob = `${entry.split("/").slice(0, -1).join("/")}/*`;
271
+ if (target.some((existing) => existing === entry || existing === parentGlob))
243
272
  return { status: "present" };
244
- const surgical = insertSharedTypesWorkspace(packageJsonText, field === void 0 ? "absent" : Array.isArray(field) ? "array" : "object");
273
+ const surgical = insertSharedTypesWorkspace(packageJsonText, field === void 0 ? "absent" : Array.isArray(field) ? "array" : "object", JSON.stringify(entry));
245
274
  if (surgical !== null)
246
275
  return { status: "added", text: surgical };
247
276
  if (field === void 0)
248
277
  pkg["workspaces"] = target;
249
- target.push("libs/shared-types");
278
+ target.push(entry);
250
279
  const indent = /\n([ \t]+)"/.exec(packageJsonText)?.[1] ?? " ";
251
280
  const trailing = packageJsonText.endsWith("\n") ? "\n" : "";
252
281
  return { status: "added", text: `${JSON.stringify(pkg, null, indent)}${trailing}` };
253
282
  }
254
- var SHARED_TYPES_ENTRY = '"libs/shared-types"';
255
283
  function skipJsonValue(text, start) {
256
284
  if (text[start] === '"') {
257
285
  let i = start + 1;
@@ -309,20 +337,20 @@ function objectMembers(text, open) {
309
337
  i = valueEnd;
310
338
  }
311
339
  }
312
- function appendToArray(text, open, close, eol) {
340
+ function appendToArray(text, open, close, eol, quoted) {
313
341
  const inner = text.slice(open + 1, close - 1);
314
342
  if (inner.trim() === "")
315
- return `${text.slice(0, open + 1)}${SHARED_TYPES_ENTRY}${text.slice(close - 1)}`;
343
+ return `${text.slice(0, open + 1)}${quoted}${text.slice(close - 1)}`;
316
344
  if (!inner.includes("\n")) {
317
345
  const body = inner.replace(/\s+$/, "");
318
- return `${text.slice(0, open + 1)}${body}, ${SHARED_TYPES_ENTRY}${inner.slice(body.length)}${text.slice(close - 1)}`;
346
+ return `${text.slice(0, open + 1)}${body}, ${quoted}${inner.slice(body.length)}${text.slice(close - 1)}`;
319
347
  }
320
348
  const lastEntryLineStart = text.lastIndexOf("\n", open + 1 + inner.trimEnd().length - 1) + 1;
321
349
  const itemIndent = /^[ \t]*/.exec(text.slice(lastEntryLineStart))?.[0] ?? " ";
322
350
  const bodyEnd = open + 1 + inner.trimEnd().length;
323
- return `${text.slice(0, bodyEnd)},${eol}${itemIndent}${SHARED_TYPES_ENTRY}${text.slice(bodyEnd)}`;
351
+ return `${text.slice(0, bodyEnd)},${eol}${itemIndent}${quoted}${text.slice(bodyEnd)}`;
324
352
  }
325
- function insertSharedTypesWorkspace(text, form) {
353
+ function insertSharedTypesWorkspace(text, form, quoted) {
326
354
  const eol = text.includes("\r\n") ? "\r\n" : "\n";
327
355
  const rootOpen = text.indexOf("{");
328
356
  if (rootOpen === -1)
@@ -336,26 +364,28 @@ function insertSharedTypesWorkspace(text, form) {
336
364
  const indent = /\n([ \t]+)"/.exec(text)?.[1] ?? " ";
337
365
  if (last === void 0) {
338
366
  const close = skipJsonValue(text, rootOpen) - 1;
339
- return `${text.slice(0, rootOpen + 1)}${eol}${indent}"workspaces": [${SHARED_TYPES_ENTRY}]${eol}${text.slice(close)}`;
367
+ return `${text.slice(0, rootOpen + 1)}${eol}${indent}"workspaces": [${quoted}]${eol}${text.slice(close)}`;
340
368
  }
341
- return `${text.slice(0, last.valueEnd)},${eol}${indent}"workspaces": [${SHARED_TYPES_ENTRY}]${text.slice(last.valueEnd)}`;
369
+ return `${text.slice(0, last.valueEnd)},${eol}${indent}"workspaces": [${quoted}]${text.slice(last.valueEnd)}`;
342
370
  }
343
371
  if (workspaces === void 0)
344
372
  return null;
345
373
  if (form === "array") {
346
374
  if (text[workspaces.valueStart] !== "[")
347
375
  return null;
348
- return appendToArray(text, workspaces.valueStart, workspaces.valueEnd, eol);
376
+ return appendToArray(text, workspaces.valueStart, workspaces.valueEnd, eol, quoted);
349
377
  }
350
378
  if (text[workspaces.valueStart] !== "{")
351
379
  return null;
352
380
  const packages = objectMembers(text, workspaces.valueStart)?.find((member) => member.key === "packages");
353
381
  if (packages === void 0 || text[packages.valueStart] !== "[")
354
382
  return null;
355
- return appendToArray(text, packages.valueStart, packages.valueEnd, eol);
383
+ return appendToArray(text, packages.valueStart, packages.valueEnd, eol, quoted);
356
384
  }
357
- function addSharedTypesWorkspaceGlob(yamlText) {
358
- if (/^\s*-\s*['"]?(libs\/shared-types|libs\/\*)['"]?\s*$/m.test(yamlText)) {
385
+ function addSharedTypesWorkspaceGlob(yamlText, entry = DEFAULT_SHARED_TYPES_ROOT) {
386
+ const escape = (value) => value.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
387
+ const parentGlob = `${entry.split("/").slice(0, -1).join("/")}/*`;
388
+ if (new RegExp(`^\\s*-\\s*['"]?(${escape(entry)}|${escape(parentGlob)})['"]?\\s*$`, "m").test(yamlText)) {
359
389
  return { status: "present" };
360
390
  }
361
391
  const lines = yamlText.split("\n");
@@ -375,7 +405,7 @@ function addSharedTypesWorkspaceGlob(yamlText) {
375
405
  if (lastEntry === packagesIndex)
376
406
  return { status: "unrecognized" };
377
407
  const indent = /^(\s+)-/.exec(lines[lastEntry])?.[1] ?? " ";
378
- lines.splice(lastEntry + 1, 0, `${indent}- 'libs/shared-types'`);
408
+ lines.splice(lastEntry + 1, 0, `${indent}- '${entry}'`);
379
409
  return { status: "added", text: lines.join("\n") };
380
410
  }
381
411
 
@@ -384,8 +414,933 @@ function resolveDryRun(options) {
384
414
  return process.env["NX_DRY_RUN"] === "true" || (options.dryRun ?? false);
385
415
  }
386
416
 
387
- // src/generators/shared/toolkit-config-file.ts
388
- var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
417
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
418
+ function createScanner(text, ignoreTrivia = false) {
419
+ const len = text.length;
420
+ let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
421
+ function scanHexDigits(count, exact) {
422
+ let digits = 0;
423
+ let value2 = 0;
424
+ while (digits < count || !exact) {
425
+ let ch = text.charCodeAt(pos);
426
+ if (ch >= 48 && ch <= 57) {
427
+ value2 = value2 * 16 + ch - 48;
428
+ } else if (ch >= 65 && ch <= 70) {
429
+ value2 = value2 * 16 + ch - 65 + 10;
430
+ } else if (ch >= 97 && ch <= 102) {
431
+ value2 = value2 * 16 + ch - 97 + 10;
432
+ } else {
433
+ break;
434
+ }
435
+ pos++;
436
+ digits++;
437
+ }
438
+ if (digits < count) {
439
+ value2 = -1;
440
+ }
441
+ return value2;
442
+ }
443
+ function setPosition(newPosition) {
444
+ pos = newPosition;
445
+ value = "";
446
+ tokenOffset = 0;
447
+ token = 16;
448
+ scanError = 0;
449
+ }
450
+ function scanNumber() {
451
+ let start = pos;
452
+ if (text.charCodeAt(pos) === 48) {
453
+ pos++;
454
+ } else {
455
+ pos++;
456
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
457
+ pos++;
458
+ }
459
+ }
460
+ if (pos < text.length && text.charCodeAt(pos) === 46) {
461
+ pos++;
462
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
463
+ pos++;
464
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
465
+ pos++;
466
+ }
467
+ } else {
468
+ scanError = 3;
469
+ return text.substring(start, pos);
470
+ }
471
+ }
472
+ let end = pos;
473
+ if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
474
+ pos++;
475
+ if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
476
+ pos++;
477
+ }
478
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
479
+ pos++;
480
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
481
+ pos++;
482
+ }
483
+ end = pos;
484
+ } else {
485
+ scanError = 3;
486
+ }
487
+ }
488
+ return text.substring(start, end);
489
+ }
490
+ function scanString() {
491
+ let result = "", start = pos;
492
+ while (true) {
493
+ if (pos >= len) {
494
+ result += text.substring(start, pos);
495
+ scanError = 2;
496
+ break;
497
+ }
498
+ const ch = text.charCodeAt(pos);
499
+ if (ch === 34) {
500
+ result += text.substring(start, pos);
501
+ pos++;
502
+ break;
503
+ }
504
+ if (ch === 92) {
505
+ result += text.substring(start, pos);
506
+ pos++;
507
+ if (pos >= len) {
508
+ scanError = 2;
509
+ break;
510
+ }
511
+ const ch2 = text.charCodeAt(pos++);
512
+ switch (ch2) {
513
+ case 34:
514
+ result += '"';
515
+ break;
516
+ case 92:
517
+ result += "\\";
518
+ break;
519
+ case 47:
520
+ result += "/";
521
+ break;
522
+ case 98:
523
+ result += "\b";
524
+ break;
525
+ case 102:
526
+ result += "\f";
527
+ break;
528
+ case 110:
529
+ result += "\n";
530
+ break;
531
+ case 114:
532
+ result += "\r";
533
+ break;
534
+ case 116:
535
+ result += " ";
536
+ break;
537
+ case 117:
538
+ const ch3 = scanHexDigits(4, true);
539
+ if (ch3 >= 0) {
540
+ result += String.fromCharCode(ch3);
541
+ } else {
542
+ scanError = 4;
543
+ }
544
+ break;
545
+ default:
546
+ scanError = 5;
547
+ }
548
+ start = pos;
549
+ continue;
550
+ }
551
+ if (ch >= 0 && ch <= 31) {
552
+ if (isLineBreak(ch)) {
553
+ result += text.substring(start, pos);
554
+ scanError = 2;
555
+ break;
556
+ } else {
557
+ scanError = 6;
558
+ }
559
+ }
560
+ pos++;
561
+ }
562
+ return result;
563
+ }
564
+ function scanNext() {
565
+ value = "";
566
+ scanError = 0;
567
+ tokenOffset = pos;
568
+ lineStartOffset = lineNumber;
569
+ prevTokenLineStartOffset = tokenLineStartOffset;
570
+ if (pos >= len) {
571
+ tokenOffset = len;
572
+ return token = 17;
573
+ }
574
+ let code = text.charCodeAt(pos);
575
+ if (isWhiteSpace(code)) {
576
+ do {
577
+ pos++;
578
+ value += String.fromCharCode(code);
579
+ code = text.charCodeAt(pos);
580
+ } while (isWhiteSpace(code));
581
+ return token = 15;
582
+ }
583
+ if (isLineBreak(code)) {
584
+ pos++;
585
+ value += String.fromCharCode(code);
586
+ if (code === 13 && text.charCodeAt(pos) === 10) {
587
+ pos++;
588
+ value += "\n";
589
+ }
590
+ lineNumber++;
591
+ tokenLineStartOffset = pos;
592
+ return token = 14;
593
+ }
594
+ switch (code) {
595
+ // tokens: []{}:,
596
+ case 123:
597
+ pos++;
598
+ return token = 1;
599
+ case 125:
600
+ pos++;
601
+ return token = 2;
602
+ case 91:
603
+ pos++;
604
+ return token = 3;
605
+ case 93:
606
+ pos++;
607
+ return token = 4;
608
+ case 58:
609
+ pos++;
610
+ return token = 6;
611
+ case 44:
612
+ pos++;
613
+ return token = 5;
614
+ // strings
615
+ case 34:
616
+ pos++;
617
+ value = scanString();
618
+ return token = 10;
619
+ // comments
620
+ case 47:
621
+ const start = pos - 1;
622
+ if (text.charCodeAt(pos + 1) === 47) {
623
+ pos += 2;
624
+ while (pos < len) {
625
+ if (isLineBreak(text.charCodeAt(pos))) {
626
+ break;
627
+ }
628
+ pos++;
629
+ }
630
+ value = text.substring(start, pos);
631
+ return token = 12;
632
+ }
633
+ if (text.charCodeAt(pos + 1) === 42) {
634
+ pos += 2;
635
+ const safeLength = len - 1;
636
+ let commentClosed = false;
637
+ while (pos < safeLength) {
638
+ const ch = text.charCodeAt(pos);
639
+ if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
640
+ pos += 2;
641
+ commentClosed = true;
642
+ break;
643
+ }
644
+ pos++;
645
+ if (isLineBreak(ch)) {
646
+ if (ch === 13 && text.charCodeAt(pos) === 10) {
647
+ pos++;
648
+ }
649
+ lineNumber++;
650
+ tokenLineStartOffset = pos;
651
+ }
652
+ }
653
+ if (!commentClosed) {
654
+ pos++;
655
+ scanError = 1;
656
+ }
657
+ value = text.substring(start, pos);
658
+ return token = 13;
659
+ }
660
+ value += String.fromCharCode(code);
661
+ pos++;
662
+ return token = 16;
663
+ // numbers
664
+ case 45:
665
+ value += String.fromCharCode(code);
666
+ pos++;
667
+ if (pos === len || !isDigit(text.charCodeAt(pos))) {
668
+ return token = 16;
669
+ }
670
+ // found a minus, followed by a number so
671
+ // we fall through to proceed with scanning
672
+ // numbers
673
+ case 48:
674
+ case 49:
675
+ case 50:
676
+ case 51:
677
+ case 52:
678
+ case 53:
679
+ case 54:
680
+ case 55:
681
+ case 56:
682
+ case 57:
683
+ value += scanNumber();
684
+ return token = 11;
685
+ // literals and unknown symbols
686
+ default:
687
+ while (pos < len && isUnknownContentCharacter(code)) {
688
+ pos++;
689
+ code = text.charCodeAt(pos);
690
+ }
691
+ if (tokenOffset !== pos) {
692
+ value = text.substring(tokenOffset, pos);
693
+ switch (value) {
694
+ case "true":
695
+ return token = 8;
696
+ case "false":
697
+ return token = 9;
698
+ case "null":
699
+ return token = 7;
700
+ }
701
+ return token = 16;
702
+ }
703
+ value += String.fromCharCode(code);
704
+ pos++;
705
+ return token = 16;
706
+ }
707
+ }
708
+ function isUnknownContentCharacter(code) {
709
+ if (isWhiteSpace(code) || isLineBreak(code)) {
710
+ return false;
711
+ }
712
+ switch (code) {
713
+ case 125:
714
+ case 93:
715
+ case 123:
716
+ case 91:
717
+ case 34:
718
+ case 58:
719
+ case 44:
720
+ case 47:
721
+ return false;
722
+ }
723
+ return true;
724
+ }
725
+ function scanNextNonTrivia() {
726
+ let result;
727
+ do {
728
+ result = scanNext();
729
+ } while (result >= 12 && result <= 15);
730
+ return result;
731
+ }
732
+ return {
733
+ setPosition,
734
+ getPosition: () => pos,
735
+ scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
736
+ getToken: () => token,
737
+ getTokenValue: () => value,
738
+ getTokenOffset: () => tokenOffset,
739
+ getTokenLength: () => pos - tokenOffset,
740
+ getTokenStartLine: () => lineStartOffset,
741
+ getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
742
+ getTokenError: () => scanError
743
+ };
744
+ }
745
+ function isWhiteSpace(ch) {
746
+ return ch === 32 || ch === 9;
747
+ }
748
+ function isLineBreak(ch) {
749
+ return ch === 10 || ch === 13;
750
+ }
751
+ function isDigit(ch) {
752
+ return ch >= 48 && ch <= 57;
753
+ }
754
+ var CharacterCodes;
755
+ (function(CharacterCodes2) {
756
+ CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
757
+ CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
758
+ CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
759
+ CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
760
+ CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
761
+ CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
762
+ CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
763
+ CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
764
+ CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
765
+ CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
766
+ CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
767
+ CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
768
+ CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
769
+ CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
770
+ CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
771
+ CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
772
+ CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
773
+ CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
774
+ CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
775
+ CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
776
+ CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
777
+ CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
778
+ CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
779
+ CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
780
+ CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
781
+ CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
782
+ CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
783
+ CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
784
+ CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
785
+ CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
786
+ CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
787
+ CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
788
+ CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
789
+ CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
790
+ CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
791
+ CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
792
+ CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
793
+ CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
794
+ CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
795
+ CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
796
+ CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
797
+ CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
798
+ CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
799
+ CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
800
+ CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
801
+ CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
802
+ CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
803
+ CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
804
+ CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
805
+ CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
806
+ CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
807
+ CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
808
+ CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
809
+ CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
810
+ CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
811
+ CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
812
+ CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
813
+ CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
814
+ CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
815
+ CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
816
+ CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
817
+ CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
818
+ CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
819
+ CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
820
+ CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
821
+ CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
822
+ CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
823
+ CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
824
+ CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
825
+ CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
826
+ CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
827
+ CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
828
+ CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
829
+ CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
830
+ CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
831
+ CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
832
+ CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
833
+ CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
834
+ CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
835
+ CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
836
+ })(CharacterCodes || (CharacterCodes = {}));
837
+
838
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
839
+ var cachedSpaces = new Array(20).fill(0).map((_, index) => {
840
+ return " ".repeat(index);
841
+ });
842
+ var maxCachedValues = 200;
843
+ var cachedBreakLinesWithSpaces = {
844
+ " ": {
845
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
846
+ return "\n" + " ".repeat(index);
847
+ }),
848
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
849
+ return "\r" + " ".repeat(index);
850
+ }),
851
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
852
+ return "\r\n" + " ".repeat(index);
853
+ })
854
+ },
855
+ " ": {
856
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
857
+ return "\n" + " ".repeat(index);
858
+ }),
859
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
860
+ return "\r" + " ".repeat(index);
861
+ }),
862
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
863
+ return "\r\n" + " ".repeat(index);
864
+ })
865
+ }
866
+ };
867
+
868
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
869
+ var ParseOptions;
870
+ (function(ParseOptions2) {
871
+ ParseOptions2.DEFAULT = {
872
+ allowTrailingComma: false
873
+ };
874
+ })(ParseOptions || (ParseOptions = {}));
875
+ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
876
+ let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: void 0 };
877
+ function ensurePropertyComplete(endOffset) {
878
+ if (currentParent.type === "property") {
879
+ currentParent.length = endOffset - currentParent.offset;
880
+ currentParent = currentParent.parent;
881
+ }
882
+ }
883
+ function onValue(valueNode) {
884
+ currentParent.children.push(valueNode);
885
+ return valueNode;
886
+ }
887
+ const visitor = {
888
+ onObjectBegin: (offset) => {
889
+ currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
890
+ },
891
+ onObjectProperty: (name, offset, length) => {
892
+ currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
893
+ currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
894
+ },
895
+ onObjectEnd: (offset, length) => {
896
+ ensurePropertyComplete(offset + length);
897
+ currentParent.length = offset + length - currentParent.offset;
898
+ currentParent = currentParent.parent;
899
+ ensurePropertyComplete(offset + length);
900
+ },
901
+ onArrayBegin: (offset, length) => {
902
+ currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
903
+ },
904
+ onArrayEnd: (offset, length) => {
905
+ currentParent.length = offset + length - currentParent.offset;
906
+ currentParent = currentParent.parent;
907
+ ensurePropertyComplete(offset + length);
908
+ },
909
+ onLiteralValue: (value, offset, length) => {
910
+ onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
911
+ ensurePropertyComplete(offset + length);
912
+ },
913
+ onSeparator: (sep, offset, length) => {
914
+ if (currentParent.type === "property") {
915
+ if (sep === ":") {
916
+ currentParent.colonOffset = offset;
917
+ } else if (sep === ",") {
918
+ ensurePropertyComplete(offset);
919
+ }
920
+ }
921
+ },
922
+ onError: (error, offset, length) => {
923
+ errors.push({ error, offset, length });
924
+ }
925
+ };
926
+ visit(text, visitor, options);
927
+ const result = currentParent.children[0];
928
+ if (result) {
929
+ delete result.parent;
930
+ }
931
+ return result;
932
+ }
933
+ function findNodeAtLocation(root, path) {
934
+ if (!root) {
935
+ return void 0;
936
+ }
937
+ let node = root;
938
+ for (let segment of path) {
939
+ if (typeof segment === "string") {
940
+ if (node.type !== "object" || !Array.isArray(node.children)) {
941
+ return void 0;
942
+ }
943
+ let found = false;
944
+ for (const propertyNode of node.children) {
945
+ if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
946
+ node = propertyNode.children[1];
947
+ found = true;
948
+ break;
949
+ }
950
+ }
951
+ if (!found) {
952
+ return void 0;
953
+ }
954
+ } else {
955
+ const index = segment;
956
+ if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
957
+ return void 0;
958
+ }
959
+ node = node.children[index];
960
+ }
961
+ }
962
+ return node;
963
+ }
964
+ function visit(text, visitor, options = ParseOptions.DEFAULT) {
965
+ const _scanner = createScanner(text, false);
966
+ const _jsonPath = [];
967
+ let suppressedCallbacks = 0;
968
+ function toNoArgVisit(visitFunction) {
969
+ return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
970
+ }
971
+ function toOneArgVisit(visitFunction) {
972
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
973
+ }
974
+ function toOneArgVisitWithPath(visitFunction) {
975
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
976
+ }
977
+ function toBeginVisit(visitFunction) {
978
+ return visitFunction ? () => {
979
+ if (suppressedCallbacks > 0) {
980
+ suppressedCallbacks++;
981
+ } else {
982
+ let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
983
+ if (cbReturn === false) {
984
+ suppressedCallbacks = 1;
985
+ }
986
+ }
987
+ } : () => true;
988
+ }
989
+ function toEndVisit(visitFunction) {
990
+ return visitFunction ? () => {
991
+ if (suppressedCallbacks > 0) {
992
+ suppressedCallbacks--;
993
+ }
994
+ if (suppressedCallbacks === 0) {
995
+ visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
996
+ }
997
+ } : () => true;
998
+ }
999
+ 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);
1000
+ const disallowComments = options && options.disallowComments;
1001
+ const allowTrailingComma = options && options.allowTrailingComma;
1002
+ function scanNext() {
1003
+ while (true) {
1004
+ const token = _scanner.scan();
1005
+ switch (_scanner.getTokenError()) {
1006
+ case 4:
1007
+ handleError(
1008
+ 14
1009
+ /* ParseErrorCode.InvalidUnicode */
1010
+ );
1011
+ break;
1012
+ case 5:
1013
+ handleError(
1014
+ 15
1015
+ /* ParseErrorCode.InvalidEscapeCharacter */
1016
+ );
1017
+ break;
1018
+ case 3:
1019
+ handleError(
1020
+ 13
1021
+ /* ParseErrorCode.UnexpectedEndOfNumber */
1022
+ );
1023
+ break;
1024
+ case 1:
1025
+ if (!disallowComments) {
1026
+ handleError(
1027
+ 11
1028
+ /* ParseErrorCode.UnexpectedEndOfComment */
1029
+ );
1030
+ }
1031
+ break;
1032
+ case 2:
1033
+ handleError(
1034
+ 12
1035
+ /* ParseErrorCode.UnexpectedEndOfString */
1036
+ );
1037
+ break;
1038
+ case 6:
1039
+ handleError(
1040
+ 16
1041
+ /* ParseErrorCode.InvalidCharacter */
1042
+ );
1043
+ break;
1044
+ }
1045
+ switch (token) {
1046
+ case 12:
1047
+ case 13:
1048
+ if (disallowComments) {
1049
+ handleError(
1050
+ 10
1051
+ /* ParseErrorCode.InvalidCommentToken */
1052
+ );
1053
+ } else {
1054
+ onComment();
1055
+ }
1056
+ break;
1057
+ case 16:
1058
+ handleError(
1059
+ 1
1060
+ /* ParseErrorCode.InvalidSymbol */
1061
+ );
1062
+ break;
1063
+ case 15:
1064
+ case 14:
1065
+ break;
1066
+ default:
1067
+ return token;
1068
+ }
1069
+ }
1070
+ }
1071
+ function handleError(error, skipUntilAfter = [], skipUntil = []) {
1072
+ onError(error);
1073
+ if (skipUntilAfter.length + skipUntil.length > 0) {
1074
+ let token = _scanner.getToken();
1075
+ while (token !== 17) {
1076
+ if (skipUntilAfter.indexOf(token) !== -1) {
1077
+ scanNext();
1078
+ break;
1079
+ } else if (skipUntil.indexOf(token) !== -1) {
1080
+ break;
1081
+ }
1082
+ token = scanNext();
1083
+ }
1084
+ }
1085
+ }
1086
+ function parseString(isValue) {
1087
+ const value = _scanner.getTokenValue();
1088
+ if (isValue) {
1089
+ onLiteralValue(value);
1090
+ } else {
1091
+ onObjectProperty(value);
1092
+ _jsonPath.push(value);
1093
+ }
1094
+ scanNext();
1095
+ return true;
1096
+ }
1097
+ function parseLiteral() {
1098
+ switch (_scanner.getToken()) {
1099
+ case 11:
1100
+ const tokenValue = _scanner.getTokenValue();
1101
+ let value = Number(tokenValue);
1102
+ if (isNaN(value)) {
1103
+ handleError(
1104
+ 2
1105
+ /* ParseErrorCode.InvalidNumberFormat */
1106
+ );
1107
+ value = 0;
1108
+ }
1109
+ onLiteralValue(value);
1110
+ break;
1111
+ case 7:
1112
+ onLiteralValue(null);
1113
+ break;
1114
+ case 8:
1115
+ onLiteralValue(true);
1116
+ break;
1117
+ case 9:
1118
+ onLiteralValue(false);
1119
+ break;
1120
+ default:
1121
+ return false;
1122
+ }
1123
+ scanNext();
1124
+ return true;
1125
+ }
1126
+ function parseProperty() {
1127
+ if (_scanner.getToken() !== 10) {
1128
+ handleError(3, [], [
1129
+ 2,
1130
+ 5
1131
+ /* SyntaxKind.CommaToken */
1132
+ ]);
1133
+ return false;
1134
+ }
1135
+ parseString(false);
1136
+ if (_scanner.getToken() === 6) {
1137
+ onSeparator(":");
1138
+ scanNext();
1139
+ if (!parseValue()) {
1140
+ handleError(4, [], [
1141
+ 2,
1142
+ 5
1143
+ /* SyntaxKind.CommaToken */
1144
+ ]);
1145
+ }
1146
+ } else {
1147
+ handleError(5, [], [
1148
+ 2,
1149
+ 5
1150
+ /* SyntaxKind.CommaToken */
1151
+ ]);
1152
+ }
1153
+ _jsonPath.pop();
1154
+ return true;
1155
+ }
1156
+ function parseObject() {
1157
+ onObjectBegin();
1158
+ scanNext();
1159
+ let needsComma = false;
1160
+ while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
1161
+ if (_scanner.getToken() === 5) {
1162
+ if (!needsComma) {
1163
+ handleError(4, [], []);
1164
+ }
1165
+ onSeparator(",");
1166
+ scanNext();
1167
+ if (_scanner.getToken() === 2 && allowTrailingComma) {
1168
+ break;
1169
+ }
1170
+ } else if (needsComma) {
1171
+ handleError(6, [], []);
1172
+ }
1173
+ if (!parseProperty()) {
1174
+ handleError(4, [], [
1175
+ 2,
1176
+ 5
1177
+ /* SyntaxKind.CommaToken */
1178
+ ]);
1179
+ }
1180
+ needsComma = true;
1181
+ }
1182
+ onObjectEnd();
1183
+ if (_scanner.getToken() !== 2) {
1184
+ handleError(7, [
1185
+ 2
1186
+ /* SyntaxKind.CloseBraceToken */
1187
+ ], []);
1188
+ } else {
1189
+ scanNext();
1190
+ }
1191
+ return true;
1192
+ }
1193
+ function parseArray() {
1194
+ onArrayBegin();
1195
+ scanNext();
1196
+ let isFirstElement = true;
1197
+ let needsComma = false;
1198
+ while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
1199
+ if (_scanner.getToken() === 5) {
1200
+ if (!needsComma) {
1201
+ handleError(4, [], []);
1202
+ }
1203
+ onSeparator(",");
1204
+ scanNext();
1205
+ if (_scanner.getToken() === 4 && allowTrailingComma) {
1206
+ break;
1207
+ }
1208
+ } else if (needsComma) {
1209
+ handleError(6, [], []);
1210
+ }
1211
+ if (isFirstElement) {
1212
+ _jsonPath.push(0);
1213
+ isFirstElement = false;
1214
+ } else {
1215
+ _jsonPath[_jsonPath.length - 1]++;
1216
+ }
1217
+ if (!parseValue()) {
1218
+ handleError(4, [], [
1219
+ 4,
1220
+ 5
1221
+ /* SyntaxKind.CommaToken */
1222
+ ]);
1223
+ }
1224
+ needsComma = true;
1225
+ }
1226
+ onArrayEnd();
1227
+ if (!isFirstElement) {
1228
+ _jsonPath.pop();
1229
+ }
1230
+ if (_scanner.getToken() !== 4) {
1231
+ handleError(8, [
1232
+ 4
1233
+ /* SyntaxKind.CloseBracketToken */
1234
+ ], []);
1235
+ } else {
1236
+ scanNext();
1237
+ }
1238
+ return true;
1239
+ }
1240
+ function parseValue() {
1241
+ switch (_scanner.getToken()) {
1242
+ case 3:
1243
+ return parseArray();
1244
+ case 1:
1245
+ return parseObject();
1246
+ case 10:
1247
+ return parseString(true);
1248
+ default:
1249
+ return parseLiteral();
1250
+ }
1251
+ }
1252
+ scanNext();
1253
+ if (_scanner.getToken() === 17) {
1254
+ if (options.allowEmptyContent) {
1255
+ return true;
1256
+ }
1257
+ handleError(4, [], []);
1258
+ return false;
1259
+ }
1260
+ if (!parseValue()) {
1261
+ handleError(4, [], []);
1262
+ return false;
1263
+ }
1264
+ if (_scanner.getToken() !== 17) {
1265
+ handleError(9, [], []);
1266
+ }
1267
+ return true;
1268
+ }
1269
+ function getNodeType(value) {
1270
+ switch (typeof value) {
1271
+ case "boolean":
1272
+ return "boolean";
1273
+ case "number":
1274
+ return "number";
1275
+ case "string":
1276
+ return "string";
1277
+ case "object": {
1278
+ if (!value) {
1279
+ return "null";
1280
+ } else if (Array.isArray(value)) {
1281
+ return "array";
1282
+ }
1283
+ return "object";
1284
+ }
1285
+ default:
1286
+ return "null";
1287
+ }
1288
+ }
1289
+
1290
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
1291
+ var ScanError;
1292
+ (function(ScanError2) {
1293
+ ScanError2[ScanError2["None"] = 0] = "None";
1294
+ ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
1295
+ ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
1296
+ ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
1297
+ ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
1298
+ ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
1299
+ ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
1300
+ })(ScanError || (ScanError = {}));
1301
+ var SyntaxKind;
1302
+ (function(SyntaxKind2) {
1303
+ SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
1304
+ SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
1305
+ SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
1306
+ SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
1307
+ SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
1308
+ SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
1309
+ SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
1310
+ SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
1311
+ SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
1312
+ SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
1313
+ SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
1314
+ SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
1315
+ SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
1316
+ SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
1317
+ SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
1318
+ SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
1319
+ SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
1320
+ })(SyntaxKind || (SyntaxKind = {}));
1321
+ var parseTree2 = parseTree;
1322
+ var findNodeAtLocation2 = findNodeAtLocation;
1323
+ var ParseErrorCode;
1324
+ (function(ParseErrorCode2) {
1325
+ ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
1326
+ ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
1327
+ ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
1328
+ ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
1329
+ ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
1330
+ ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
1331
+ ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
1332
+ ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
1333
+ ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
1334
+ ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
1335
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
1336
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
1337
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
1338
+ ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
1339
+ ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
1340
+ ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
1341
+ })(ParseErrorCode || (ParseErrorCode = {}));
1342
+
1343
+ // src/generators/shared/json-edit.ts
389
1344
  function detectIndent(raw) {
390
1345
  for (const line of raw.split("\n")) {
391
1346
  const match = /^(\t+| +)/.exec(line);
@@ -393,6 +1348,98 @@ function detectIndent(raw) {
393
1348
  }
394
1349
  return " ";
395
1350
  }
1351
+ function styleOf(raw) {
1352
+ return { eol: raw.includes("\r\n") ? "\r\n" : "\n", unit: detectIndent(raw) };
1353
+ }
1354
+ function lineIndentAt(raw, offset) {
1355
+ const lineStart = raw.lastIndexOf("\n", offset - 1) + 1;
1356
+ return /^[ \t]*/.exec(raw.slice(lineStart))?.[0] ?? "";
1357
+ }
1358
+ function isMultiline(raw, node) {
1359
+ return raw.slice(node.offset, node.offset + node.length).includes("\n");
1360
+ }
1361
+ function isPrimitive(value) {
1362
+ return value === null || ["string", "number", "boolean"].includes(typeof value);
1363
+ }
1364
+ function renderValue(value, indent, style) {
1365
+ if (isPrimitive(value)) return JSON.stringify(value);
1366
+ if (Array.isArray(value)) {
1367
+ if (value.every(isPrimitive)) return `[${value.map((item) => JSON.stringify(item)).join(", ")}]`;
1368
+ const inner2 = `${indent}${style.unit}`;
1369
+ return `[${style.eol}${value.map((item) => `${inner2}${renderValue(item, inner2, style)}`).join(`,${style.eol}`)}${style.eol}${indent}]`;
1370
+ }
1371
+ const entries = Object.entries(value);
1372
+ if (entries.length === 0) return "{}";
1373
+ const inner = `${indent}${style.unit}`;
1374
+ const body = entries.map(([key, item]) => `${inner}${JSON.stringify(key)}: ${renderValue(item, inner, style)}`).join(`,${style.eol}`);
1375
+ return `{${style.eol}${body}${style.eol}${indent}}`;
1376
+ }
1377
+ function splice(raw, start, end, text) {
1378
+ return raw.slice(0, start) + text + raw.slice(end);
1379
+ }
1380
+ function nest(keys, value) {
1381
+ return keys.reduceRight((inner, key) => ({ [key]: inner }), value);
1382
+ }
1383
+ function insertProperty(raw, object, key, value, style) {
1384
+ const properties = object.children ?? [];
1385
+ const objectIndent = lineIndentAt(raw, object.offset);
1386
+ if (properties.length === 0) {
1387
+ const inner = `${objectIndent}${style.unit}`;
1388
+ const text = `{${style.eol}${inner}${JSON.stringify(String(key))}: ${renderValue(value, inner, style)}${style.eol}${objectIndent}}`;
1389
+ return splice(raw, object.offset, object.offset + object.length, text);
1390
+ }
1391
+ const last = properties[properties.length - 1];
1392
+ const end = last.offset + last.length;
1393
+ if (!isMultiline(raw, object)) {
1394
+ return splice(raw, end, end, `, ${JSON.stringify(String(key))}: ${renderValue(value, "", style)}`);
1395
+ }
1396
+ const indent = lineIndentAt(raw, last.offset);
1397
+ return splice(raw, end, end, `,${style.eol}${indent}${JSON.stringify(String(key))}: ${renderValue(value, indent, style)}`);
1398
+ }
1399
+ function setJsonValue(raw, path, value) {
1400
+ const style = styleOf(raw);
1401
+ const root = parseTree2(raw);
1402
+ if (root === void 0) throw new Error("setJsonValue: not a JSON document");
1403
+ const existing = findNodeAtLocation2(root, path);
1404
+ if (existing !== void 0) {
1405
+ return splice(raw, existing.offset, existing.offset + existing.length, renderValue(value, lineIndentAt(raw, existing.offset), style));
1406
+ }
1407
+ for (let depth = path.length - 1; depth >= 0; depth--) {
1408
+ const parent = depth === 0 ? root : findNodeAtLocation2(root, path.slice(0, depth));
1409
+ if (parent === void 0) continue;
1410
+ if (parent.type !== "object") throw new Error(`setJsonValue: ${path.slice(0, depth).join(".") || "the root"} is not an object`);
1411
+ return insertProperty(raw, parent, path[depth], nest(path.slice(depth + 1), value), style);
1412
+ }
1413
+ throw new Error("setJsonValue: unreachable");
1414
+ }
1415
+ function appendJsonArrayItem(raw, path, item) {
1416
+ const style = styleOf(raw);
1417
+ const root = parseTree2(raw);
1418
+ const array = root === void 0 ? void 0 : findNodeAtLocation2(root, path);
1419
+ if (array === void 0) return setJsonValue(raw, path, [item]);
1420
+ if (array.type !== "array") throw new Error(`appendJsonArrayItem: ${path.join(".")} is not an array`);
1421
+ const items = array.children ?? [];
1422
+ if (items.length === 0) return splice(raw, array.offset, array.offset + array.length, renderValue([item], "", style));
1423
+ const last = items[items.length - 1];
1424
+ const end = last.offset + last.length;
1425
+ if (!isMultiline(raw, array)) {
1426
+ const separator = items.length >= 2 ? raw.slice(items[0].offset + items[0].length, items[1].offset) : ", ";
1427
+ return splice(raw, end, end, `${separator}${renderValue(item, "", style)}`);
1428
+ }
1429
+ const indent = lineIndentAt(raw, last.offset);
1430
+ return splice(raw, end, end, `,${style.eol}${indent}${renderValue(item, indent, style)}`);
1431
+ }
1432
+ function applyJsonEdits(raw, edits) {
1433
+ if (raw === null) {
1434
+ let text = "{}\n";
1435
+ for (const [path, value] of edits) text = setJsonValue(text, path, value);
1436
+ return text;
1437
+ }
1438
+ return edits.reduce((text, [path, value]) => setJsonValue(text, path, value), raw);
1439
+ }
1440
+
1441
+ // src/generators/shared/toolkit-config-file.ts
1442
+ var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
396
1443
  function readToolkitConfigFile(tree) {
397
1444
  const raw = tree.read(TOOLKIT_CONFIG_PATH, "utf-8");
398
1445
  if (raw === null) return { raw: null, parsed: null };
@@ -480,8 +1527,9 @@ function renderAddBackendBody(report) {
480
1527
  }
481
1528
  if (report.packageManagerNote !== void 0) lines.push(` note: ${report.packageManagerNote}`);
482
1529
  lines.push(` frontend project: ${report.frontendProject ?? "none (backend-only workspace)"}`);
1530
+ const libPath = report.sharedTypesRoot ?? "libs/shared-types";
483
1531
  lines.push(
484
- report.sharedTypes === "created" ? ` libs/shared-types: created (import it as ${report.sharedTypesPackage})` : " libs/shared-types: already exists \u2014 skipped"
1532
+ report.sharedTypes === "created" ? ` ${libPath}: created (import it as ${report.sharedTypesPackage})` : report.sharedTypes === "disabled" ? " shared-types lib: none (sharedTypes: false in toolkit.config.json)" : ` ${libPath}: already exists \u2014 skipped`
485
1533
  );
486
1534
  if (report.config !== void 0 && report.config !== "unchanged") {
487
1535
  lines.push(` toolkit.config.json: backend "${report.backend}" recorded (${report.config}) \u2014 doctor's backend checks now run`);
@@ -491,11 +1539,11 @@ function renderAddBackendBody(report) {
491
1539
  const registry = packageManagerCommands(pmName).workspaceRegistration;
492
1540
  lines.push(
493
1541
  {
494
- added: ` ${registry}: 'libs/shared-types' registered \u2014 run \`${pmName} install\` once to link it`,
495
- present: ` ${registry}: already covers libs/shared-types`,
1542
+ added: ` ${registry}: '${libPath}' registered \u2014 run \`${pmName} install\` once to link it`,
1543
+ present: ` ${registry}: already covers ${libPath}`,
496
1544
  unrecognized: (
497
1545
  // an integrated layout lists no workspace packages: the paths alias below links it
498
- report.tsconfigPaths === "added" || report.tsconfigPaths === "present" ? ` ${registry}: no workspace package list (integrated layout) \u2014 the tsconfig paths alias links libs/shared-types` : ` ${registry}: shape not recognized \u2014 add 'libs/shared-types' to its workspace list yourself`
1546
+ report.tsconfigPaths === "added" || report.tsconfigPaths === "present" ? ` ${registry}: no workspace package list (integrated layout) \u2014 the tsconfig paths alias links ${libPath}` : ` ${registry}: shape not recognized \u2014 add '${libPath}' to its workspace list yourself`
499
1547
  )
500
1548
  }[report.workspaceGlob]
501
1549
  );
@@ -508,7 +1556,8 @@ function renderAddBackendBody(report) {
508
1556
  added: ` tsconfig.base.json paths: ${report.sharedTypesPackage} added (a classic or integrated setup \u2014 libs resolve through paths)`,
509
1557
  present: " tsconfig.base.json paths: already wired",
510
1558
  "workspace-link": " tsconfig paths: not needed \u2014 the workspace package link is the wiring",
511
- unrecognized: " tsconfig.base.json: could not be parsed \u2014 left untouched"
1559
+ unrecognized: " tsconfig.base.json: could not be parsed \u2014 left untouched",
1560
+ none: " tsconfig paths: nothing to wire (no shared-types lib)"
512
1561
  }[report.tsconfigPaths]
513
1562
  );
514
1563
  switch (report.eslint) {
@@ -538,7 +1587,6 @@ function renderAddBackendReport(report, dryRun) {
538
1587
  }
539
1588
 
540
1589
  // src/generators/add-backend/generator.ts
541
- var SHARED_TYPES_ROOT = "libs/shared-types";
542
1590
  function runAddBackend(tree, options) {
543
1591
  const backend = options.backend;
544
1592
  const apiName = options.apiName ?? "api";
@@ -613,8 +1661,9 @@ function runAddBackend(tree, options) {
613
1661
  } catch {
614
1662
  }
615
1663
  }
616
- const frontendParent = (projects.get(frontendProject)?.root ?? "").split("/").slice(0, -1).join("/");
617
- const apiDirectory = `${frontendParent === "" || frontendParent === "." ? "apps" : frontendParent}/${apiName}`;
1664
+ const frontendRoot = projects.get(frontendProject)?.root ?? "";
1665
+ const frontendParent = frontendRoot.split("/").slice(0, -1).join("/");
1666
+ const apiDirectory = frontendRoot === "" || frontendRoot === "." ? `apps/${apiName}` : `${frontendParent === "" ? "" : `${frontendParent}/`}${apiName}`;
618
1667
  const expressAlignment = backend === "express" && !expressDeclared ? readExpressPeerRange(tree) : void 0;
619
1668
  const quotedExpress = expressAlignment ? `"express@${expressAlignment}"` : void 0;
620
1669
  return {
@@ -630,16 +1679,21 @@ function runAddBackend(tree, options) {
630
1679
  ...refusalShape
631
1680
  };
632
1681
  }
633
- const sharedTypesExists = tree.exists(`${SHARED_TYPES_ROOT}/package.json`) || tree.exists(`${SHARED_TYPES_ROOT}/project.json`);
1682
+ const recordedConfig = readToolkitConfigFile(tree).parsed;
1683
+ const boundaryTags = readBoundaryTags(recordedConfig);
1684
+ const sharedTypesConfig = readSharedTypesConfig(recordedConfig);
1685
+ const withSharedTypes = sharedTypesConfig !== false;
1686
+ const sharedTypesRoot = sharedTypesConfig === false ? "" : sharedTypesConfig.path;
1687
+ const sharedTypesExists = withSharedTypes && (tree.exists(`${sharedTypesRoot}/package.json`) || tree.exists(`${sharedTypesRoot}/project.json`));
634
1688
  const rootPackageJson = tree.read("package.json", "utf-8");
635
1689
  const workspaceName = rootPackageJson ? JSON.parse(rootPackageJson).name ?? "workspace" : "workspace";
636
- const wiring = composeBackendWiring({ workspaceName });
1690
+ const wiring = composeBackendWiring({ workspaceName, tags: boundaryTags, ...sharedTypesConfig === false ? {} : { sharedTypes: sharedTypesConfig } });
637
1691
  const [apiProjectName, apiConfig] = apiEntry;
638
1692
  const tagTargets = [
639
1693
  ...frontendProject === void 0 ? [] : [{ project: frontendProject, root: projects.get(frontendProject)?.root ?? `apps/${frontendProject}` }],
640
1694
  { project: apiProjectName, root: apiConfig.root }
641
1695
  ];
642
- if (sharedTypesExists) tagTargets.push({ project: wiring.sharedTypesPackageName, root: SHARED_TYPES_ROOT });
1696
+ if (sharedTypesExists) tagTargets.push({ project: wiring.sharedTypesPackageName, root: sharedTypesRoot });
643
1697
  const parsedTargets = /* @__PURE__ */ new Map();
644
1698
  const invalidProjects = [];
645
1699
  for (const target of tagTargets) {
@@ -661,7 +1715,7 @@ function runAddBackend(tree, options) {
661
1715
  if (invalidProjects.length > 0) {
662
1716
  return { ...base, refused: "invalid-project-json", frontendProject, invalidProjects, ...refusalShape };
663
1717
  }
664
- const sharedTypes = sharedTypesExists ? "skipped" : "created";
1718
+ const sharedTypes = !withSharedTypes ? "disabled" : sharedTypesExists ? "skipped" : "created";
665
1719
  if (sharedTypes === "created" && write) {
666
1720
  for (const file of wiring.sharedTypesFiles) tree.write(file.filePath, file.content);
667
1721
  }
@@ -672,20 +1726,19 @@ function runAddBackend(tree, options) {
672
1726
  const existing = configParsed ?? {};
673
1727
  if (parseOk && existing["backend"] !== backend) {
674
1728
  configOutcome = configRaw === null ? "created" : "updated";
675
- const indent = configRaw === null ? " " : detectIndent(configRaw);
676
- if (write) tree.write(TOOLKIT_CONFIG_PATH, `${JSON.stringify({ ...existing, backend }, null, indent)}
677
- `);
1729
+ if (write) tree.write(TOOLKIT_CONFIG_PATH, applyJsonEdits(configRaw, [[["backend"], backend]]));
678
1730
  }
679
1731
  }
680
- let workspaceGlob = "unrecognized";
681
- const workspaceYaml = tree.read("pnpm-workspace.yaml", "utf-8");
682
- if (workspaceYaml !== null) {
683
- const globResult = addSharedTypesWorkspaceGlob(workspaceYaml);
1732
+ let workspaceGlob = withSharedTypes ? "unrecognized" : void 0;
1733
+ const workspaceYaml = withSharedTypes ? tree.read("pnpm-workspace.yaml", "utf-8") : null;
1734
+ if (!withSharedTypes) {
1735
+ } else if (workspaceYaml !== null) {
1736
+ const globResult = addSharedTypesWorkspaceGlob(workspaceYaml, sharedTypesRoot);
684
1737
  workspaceGlob = globResult.status;
685
1738
  if (globResult.status === "added" && write) tree.write("pnpm-workspace.yaml", globResult.text);
686
1739
  } else if ((detectedPm === "npm" || detectedPm === "yarn" || detectedPm === "bun") && rootPackageJson !== null) {
687
1740
  const yarnNeedsPrivate = detectedPm === "yarn" && JSON.parse(rootPackageJson).private !== true;
688
- const npmResult = yarnNeedsPrivate ? { status: "unrecognized" } : addSharedTypesNpmWorkspace(rootPackageJson);
1741
+ const npmResult = yarnNeedsPrivate ? { status: "unrecognized" } : addSharedTypesNpmWorkspace(rootPackageJson, sharedTypesRoot);
689
1742
  workspaceGlob = npmResult.status;
690
1743
  if (npmResult.status === "added" && write) tree.write("package.json", npmResult.text);
691
1744
  }
@@ -696,17 +1749,17 @@ function runAddBackend(tree, options) {
696
1749
  const tags2 = holder.tags ?? [];
697
1750
  if (tags2.includes(tag)) return { project, action: "present" };
698
1751
  holder.tags = [...tags2, tag];
699
- if (write) tree.write(target.path, `${JSON.stringify(target.parsed, null, detectIndent(target.raw))}
700
- `);
1752
+ target.raw = appendJsonArrayItem(target.raw, target.kind === "project" ? ["tags"] : ["nx", "tags"], tag);
1753
+ if (write) tree.write(target.path, target.raw);
701
1754
  return { project, action: "added" };
702
1755
  };
703
1756
  const tags = [
704
1757
  ...frontendProject === void 0 ? [] : [mergeTag(frontendProject, wiring.tagByRole.frontend)],
705
1758
  mergeTag(apiProjectName, wiring.tagByRole.backend),
706
- mergeTag(wiring.sharedTypesPackageName, wiring.tagByRole.shared)
1759
+ ...withSharedTypes ? [mergeTag(wiring.sharedTypesPackageName, wiring.tagByRole.shared)] : []
707
1760
  ];
708
- let tsconfigPaths = "workspace-link";
709
- const tsconfigRaw = tree.read("tsconfig.base.json", "utf-8");
1761
+ let tsconfigPaths = withSharedTypes ? "workspace-link" : "none";
1762
+ const tsconfigRaw = withSharedTypes ? tree.read("tsconfig.base.json", "utf-8") : null;
710
1763
  if (tsconfigRaw !== null) {
711
1764
  try {
712
1765
  const tsconfig = JSON.parse(tsconfigRaw);
@@ -717,10 +1770,8 @@ function runAddBackend(tree, options) {
717
1770
  tsconfigPaths = "present";
718
1771
  } else {
719
1772
  tsconfigPaths = "added";
720
- paths[wiring.sharedTypesPackageName] = [`${baseUrl ? "" : "./"}${SHARED_TYPES_ROOT}/src/index.ts`];
721
- tsconfig.compilerOptions.paths = paths;
722
- if (write) tree.write("tsconfig.base.json", `${JSON.stringify(tsconfig, null, detectIndent(tsconfigRaw))}
723
- `);
1773
+ const entry = [`${baseUrl ? "" : "./"}${sharedTypesRoot}/src/index.ts`];
1774
+ if (write) tree.write("tsconfig.base.json", setJsonValue(tsconfigRaw, ["compilerOptions", "paths", wiring.sharedTypesPackageName], entry));
724
1775
  }
725
1776
  }
726
1777
  } catch {
@@ -731,11 +1782,11 @@ function runAddBackend(tree, options) {
731
1782
  let snippet;
732
1783
  if (!applyEslint) {
733
1784
  eslint = "snippet-only";
734
- snippet = buildBoundarySnippet();
1785
+ snippet = buildBoundarySnippet(boundaryTags);
735
1786
  } else {
736
1787
  const configPath = ESLINT_CONFIG_CANDIDATES.find((candidate) => tree.exists(candidate));
737
1788
  const configText = configPath ? tree.read(configPath, "utf-8") : null;
738
- const result = configText !== null ? applyBoundaryConstraints(configText) : { status: "unrecognized" };
1789
+ const result = configText !== null ? applyBoundaryConstraints(configText, boundaryTags) : { status: "unrecognized" };
739
1790
  if (result.status === "applied") {
740
1791
  eslint = "applied";
741
1792
  if (write && configPath) tree.write(configPath, result.text);
@@ -743,7 +1794,7 @@ function runAddBackend(tree, options) {
743
1794
  eslint = "already-applied";
744
1795
  } else {
745
1796
  eslint = "degraded-unrecognized";
746
- snippet = buildBoundarySnippet();
1797
+ snippet = buildBoundarySnippet(boundaryTags);
747
1798
  }
748
1799
  }
749
1800
  return {
@@ -755,7 +1806,8 @@ function runAddBackend(tree, options) {
755
1806
  tsconfigPaths,
756
1807
  eslint,
757
1808
  snippet,
758
- sharedTypesPackage: wiring.sharedTypesPackageName,
1809
+ sharedTypesPackage: withSharedTypes ? wiring.sharedTypesPackageName : void 0,
1810
+ sharedTypesRoot: withSharedTypes ? sharedTypesRoot : void 0,
759
1811
  config: configOutcome,
760
1812
  packageManager,
761
1813
  ...packageManagerNote !== void 0 ? { packageManagerNote } : {}