@abgov/nx-adsp 13.30.0 → 13.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +41 -32
  2. package/package.json +1 -1
  3. package/src/generators/angular-app/angular-app.js +2 -2
  4. package/src/generators/angular-app/files/AGENTS.md__tmpl__ +16 -0
  5. package/src/generators/express-service/express-service.spec.ts +26 -13
  6. package/src/generators/express-service/schema.json +1 -1
  7. package/src/generators/react-app/files/AGENTS.md__tmpl__ +16 -0
  8. package/src/generators/react-app/react-app.js +2 -2
  9. package/src/generators/vue-admin-crud/files/src/views/__editViewFileName__.vue__tmpl__ +1 -3
  10. package/src/generators/vue-admin-crud/files/src/views/__listViewFileName__.vue__tmpl__ +33 -4
  11. package/src/generators/vue-admin-crud/schema.d.ts +2 -0
  12. package/src/generators/vue-admin-crud/schema.json +7 -8
  13. package/src/generators/vue-admin-crud/vue-admin-crud.js +6 -1
  14. package/src/generators/vue-admin-crud/vue-admin-crud.js.map +1 -1
  15. package/src/generators/vue-admin-crud/vue-admin-crud.spec.ts +74 -13
  16. package/src/generators/vue-app/files/AGENTS.md__tmpl__ +56 -11
  17. package/src/generators/vue-app/files/src/App.vue__tmpl__ +18 -4
  18. package/src/generators/vue-app/files/src/composables/useApi.spec.ts__tmpl__ +5 -3
  19. package/src/generators/vue-app/files/src/composables/useApi.ts__tmpl__ +14 -2
  20. package/src/generators/vue-app/vue-app.js +33 -6
  21. package/src/generators/vue-app/vue-app.js.map +1 -1
  22. package/src/generators/vue-app/vue-app.spec.ts +152 -17
  23. package/src/generators/vue-components/files/AGENTS.md__tmpl__ +35 -16
  24. package/src/generators/vue-components/files/src/index.ts__tmpl__ +3 -0
  25. package/src/generators/vue-components/files/src/lib/formatters.ts__tmpl__ +58 -0
  26. package/src/generators/vue-components/files/src/lib/patterns/AppLayout.spec.ts__tmpl__ +32 -0
  27. package/src/generators/vue-components/files/src/lib/patterns/AppLayout.vue__tmpl__ +28 -21
  28. package/src/generators/vue-components/files/src/lib/patterns/AppSideMenu.vue__tmpl__ +14 -3
  29. package/src/generators/vue-components/files/src/lib/patterns/FilterBar.vue__tmpl__ +7 -1
  30. package/src/generators/vue-components/files/src/lib/patterns/WorkspaceTable.vue__tmpl__ +7 -1
  31. package/src/generators/vue-components/vue-components.d.ts +1 -0
  32. package/src/generators/vue-components/vue-components.js +18 -39
  33. package/src/generators/vue-components/vue-components.js.map +1 -1
  34. package/src/generators/vue-components/vue-components.spec.ts +95 -2
  35. package/src/generators/vue-detail-view/files/src/views/__viewFileName__.vue__tmpl__ +51 -2
  36. package/src/generators/vue-detail-view/schema.d.ts +18 -0
  37. package/src/generators/vue-detail-view/schema.json +2 -2
  38. package/src/generators/vue-detail-view/vue-detail-view.js +4 -1
  39. package/src/generators/vue-detail-view/vue-detail-view.js.map +1 -1
  40. package/src/generators/vue-detail-view/vue-detail-view.spec.ts +36 -6
  41. package/src/generators/vue-intake-view/files/shared/src/views/__confirmationViewFileName__.vue__tmpl__ +60 -6
  42. package/src/generators/vue-intake-view/files/shared/src/views/__reviewViewFileName__.vue__tmpl__ +21 -0
  43. package/src/generators/vue-intake-view/schema.d.ts +10 -0
  44. package/src/generators/vue-intake-view/schema.json +12 -9
  45. package/src/generators/vue-intake-view/vue-intake-view.js +9 -3
  46. package/src/generators/vue-intake-view/vue-intake-view.js.map +1 -1
  47. package/src/generators/vue-intake-view/vue-intake-view.spec.ts +81 -12
  48. package/src/generators/vue-workspace-view/files/src/views/__viewFileName__.vue__tmpl__ +49 -1
  49. package/src/generators/vue-workspace-view/schema.d.ts +22 -0
  50. package/src/generators/vue-workspace-view/schema.json +8 -9
  51. package/src/generators/vue-workspace-view/vue-workspace-view.js +7 -1
  52. package/src/generators/vue-workspace-view/vue-workspace-view.js.map +1 -1
  53. package/src/generators/vue-workspace-view/vue-workspace-view.spec.ts +73 -7
  54. package/src/utils/paired-project.d.ts +10 -0
  55. package/src/utils/paired-project.js +125 -18
  56. package/src/utils/paired-project.js.map +1 -1
  57. package/src/utils/paired-project.spec.ts +126 -0
  58. package/src/utils/quality.js +43 -9
  59. package/src/utils/quality.js.map +1 -1
  60. package/src/utils/quality.spec.ts +35 -2
  61. package/src/utils/vue-eslint.d.ts +2 -0
  62. package/src/utils/vue-eslint.js +48 -0
  63. package/src/utils/vue-eslint.js.map +1 -0
  64. package/src/utils/vue-side-menu.d.ts +13 -1
  65. package/src/utils/vue-side-menu.js +50 -5
  66. package/src/utils/vue-side-menu.js.map +1 -1
  67. package/src/utils/vue-side-menu.spec.ts +100 -0
  68. package/src/utils/vue-tsconfig.d.ts +26 -0
  69. package/src/utils/vue-tsconfig.js +49 -0
  70. package/src/utils/vue-tsconfig.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/quality.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/quality.ts"],"names":[],"mappings":"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"}
@@ -239,8 +239,10 @@ describe('addAxeAccessibilityCheck', () => {
239
239
  expect(spec).toContain("import AxeBuilder from '@axe-core/playwright'");
240
240
  expect(spec).toContain("['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']");
241
241
  expect(spec).toContain('.withTags(WCAG_TAGS).analyze()');
242
- expect(spec).toContain("await page.goto('/')");
243
- expect(spec).toContain('expect(summary, summary.join');
242
+ // Navigation and the failure message are asserted by the ROUTES tests below
243
+ // -- both are now per-route rather than a single hardcoded '/'.
244
+ expect(spec).toContain('await page.goto(route)');
245
+ expect(spec).toContain('summary.join');
244
246
  });
245
247
 
246
248
  it('is idempotent — a second call does not clobber a manually-edited file', () => {
@@ -252,4 +254,35 @@ describe('addAxeAccessibilityCheck', () => {
252
254
 
253
255
  expect(tree.read(specPath).toString()).toBe('// manually edited\n');
254
256
  });
257
+
258
+ // The spec is a seed, not a finished gate: its coverage is exactly its ROUTES
259
+ // array, and no generator maintains that list. It shipped with a hardcoded
260
+ // `page.goto('/')` and no hint of that, so a consumer reasonably read a green
261
+ // run as "accessibility is covered" while it checked one route -- the one route
262
+ // that exercises almost none of the goa-* elements the app is built from.
263
+ it('drives its coverage from an editable ROUTES list, seeded with /', () => {
264
+ addAxeAccessibilityCheck(tree, 'apps/my-app-e2e');
265
+ const spec = tree.read('apps/my-app-e2e/src/a11y.spec.ts').toString();
266
+
267
+ expect(spec).toContain("const ROUTES = ['/']");
268
+ // A route the list doesn't name is never checked, so the list has to be the
269
+ // thing that's iterated -- not one hardcoded navigation.
270
+ expect(spec).toContain('for (const route of ROUTES)');
271
+ expect(spec).toContain('await page.goto(route)');
272
+ expect(spec).not.toContain("page.goto('/')");
273
+ // The failure has to name the route, or a multi-route run can't be triaged.
274
+ expect(spec).toContain('violations: ${route}');
275
+ });
276
+
277
+ it('tells the reader to expand the route list, and what to expect when they do', () => {
278
+ addAxeAccessibilityCheck(tree, 'apps/my-app-e2e');
279
+ const spec = tree.read('apps/my-app-e2e/src/a11y.spec.ts').toString();
280
+
281
+ expect(spec).toContain('ADD YOUR ROUTES HERE');
282
+ // Routes arrive by hand as well as from generators -- the reader has to know
283
+ // nothing keeps the list in sync.
284
+ expect(spec).toContain('hand-editing the router');
285
+ // And that a failure may not be theirs to fix.
286
+ expect(spec).toContain('shadow DOM');
287
+ });
255
288
  });
@@ -0,0 +1,2 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare function disableSlotAttributeRule(host: Tree, projectRoot: string, reason: string): void;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.disableSlotAttributeRule = disableSlotAttributeRule;
4
+ const internal_1 = require("@nx/eslint/internal");
5
+ // Turns off vue/no-deprecated-slot-attribute for a generated Vue project.
6
+ //
7
+ // Every project this plugin generates projects content into a goa-* web
8
+ // component's native slot via the `slot` attribute -- `slot="actions"` on
9
+ // goa-modal in the shared wrapper lib, `slot="header"`/`slot="footer"` on
10
+ // goa-one-column-layout in the app shell. That is legitimate custom-element
11
+ // usage, not the deprecated Vue 2 component-slot syntax the rule targets, and
12
+ // there is no alternative: Vue's `v-slot`/`#name` shorthand only addresses slots
13
+ // declared by a Vue component, never a custom element's.
14
+ //
15
+ // Shared rather than per-generator on purpose. This hazard was originally solved
16
+ // only inside the vue-components generator, so when the app shell later adopted
17
+ // goa-one-column-layout its `slot` attributes tripped the rule and `nx lint`
18
+ // failed on unmodified generator output. Any generator emitting a native slot
19
+ // attribute must call this, so keep it in one place.
20
+ //
21
+ // Uses @nx/eslint's own override helpers rather than hand-editing a specific file
22
+ // format: create-nx-workspace's current default is flat config
23
+ // (eslint.config.mjs), a JS module exporting an array rather than JSON.
24
+ // addOverrideToLintConfig/lintConfigHasOverride detect flat vs legacy internally
25
+ // (via @nx/eslint's own useFlatConfig check) and edit whichever is in effect --
26
+ // AST-aware for flat config, not string splicing.
27
+ function disableSlotAttributeRule(host, projectRoot, reason) {
28
+ if (!(0, internal_1.isEslintConfigSupported)(host, projectRoot)) {
29
+ console.warn(`\n⚠ No ESLint config found for ${projectRoot} — could not disable vue/no-deprecated-slot-attribute.\n` +
30
+ ` ${reason}; if lint flags it, turn that rule off for this project.\n`);
31
+ return;
32
+ }
33
+ // `files` is `string | string[]` per the Linter type — normalize before checking.
34
+ const isVueOverride = (o) => (Array.isArray(o.files) ? o.files : o.files ? [o.files] : []).some((f) => f.includes('vue'));
35
+ const alreadyDisabled = (0, internal_1.lintConfigHasOverride)(host, projectRoot, (o) => {
36
+ var _a;
37
+ return isVueOverride(o) &&
38
+ ((_a = o.rules) === null || _a === void 0 ? void 0 : _a['vue/no-deprecated-slot-attribute']) === 'off';
39
+ });
40
+ if (alreadyDisabled) {
41
+ return;
42
+ }
43
+ (0, internal_1.addOverrideToLintConfig)(host, projectRoot, {
44
+ files: ['*.vue'],
45
+ rules: { 'vue/no-deprecated-slot-attribute': 'off' },
46
+ });
47
+ }
48
+ //# sourceMappingURL=vue-eslint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-eslint.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/vue-eslint.ts"],"names":[],"mappings":";;AA8BA,4DAkCC;AA/DD,kDAI6B;AAG7B,0EAA0E;AAC1E,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAC9E,iFAAiF;AACjF,yDAAyD;AACzD,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,6EAA6E;AAC7E,8EAA8E;AAC9E,qDAAqD;AACrD,EAAE;AACF,kFAAkF;AAClF,+DAA+D;AAC/D,wEAAwE;AACxE,iFAAiF;AACjF,gFAAgF;AAChF,kDAAkD;AAClD,SAAgB,wBAAwB,CACtC,IAAU,EACV,WAAmB,EACnB,MAAc;IAEd,IAAI,CAAC,IAAA,kCAAuB,EAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,IAAI,CACV,mCAAmC,WAAW,0DAA0D;YACtG,MAAM,MAAM,4DAA4D,CAC3E,CAAC;QACF,OAAO;IACT,CAAC;IAED,kFAAkF;IAClF,MAAM,aAAa,GAAG,CAAC,CAA4C,EAAE,EAAE,CACrE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACvE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAClB,CAAC;IAEJ,MAAM,eAAe,GAAG,IAAA,gCAAqB,EAC3C,IAAI,EACJ,WAAW,EACX,CAAC,CAAC,EAAE,EAAE;;QACJ,OAAA,aAAa,CAAC,CAAC,CAAC;YAChB,CAAA,MAAA,CAAC,CAAC,KAAK,0CAAG,kCAAkC,CAAC,MAAK,KAAK,CAAA;KAAA,CAC1D,CAAC;IACF,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAA,kCAAuB,EAAC,IAAI,EAAE,WAAW,EAAE;QACzC,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,KAAK,EAAE,EAAE,kCAAkC,EAAE,KAAK,EAAE;KACrD,CAAC,CAAC;AACL,CAAC"}
@@ -4,9 +4,21 @@ export interface SideMenuItemSpec {
4
4
  label: string;
5
5
  /** Route path the item navigates to, e.g. '/queue'. */
6
6
  to: string;
7
+ /**
8
+ * Ionicon name, e.g. 'list'. Effectively required: goa-work-side-menu-item
9
+ * renders a blank item when it has no icon, so a generator that omits this
10
+ * produces nav that looks broken on arrival. Passed straight through to the
11
+ * element's <ion-icon>, so any valid ionicon name works.
12
+ */
13
+ icon?: string;
7
14
  }
8
15
  /**
9
- * Adds a nav item to a generated app's side menu.
16
+ * Appends a nav item to a generated app's side menu.
17
+ *
18
+ * Appends rather than prepends so the shell's own 'Home' entry stays first and
19
+ * generated items accumulate in the order they were run. Inserting at the head
20
+ * (an earlier version of this function) pushed Home to the bottom of the nav
21
+ * after the first generator run, which no consuming app wants.
10
22
  *
11
23
  * A no-op when the app has no `primaryItems` array. That is the signal the app
12
24
  * was generated with `--layout=header` (a public app has no side menu at all),
@@ -11,8 +11,42 @@ exports.insertSideMenuItem = insertSideMenuItem;
11
11
  // read and change in one obvious place -- not behaviour resolved at runtime by
12
12
  // the shell that every app then has to work around.
13
13
  const ANCHOR = 'const primaryItems = [';
14
+ // Finds the `]` closing the array literal that ANCHOR opens, so items can be
15
+ // appended at the end rather than inserted at the head. Tracks nesting depth and
16
+ // skips over string literals, so a label containing a bracket can't end the scan
17
+ // early. Returns -1 if the literal is unterminated (a hand-edited App.vue we
18
+ // shouldn't touch).
19
+ function findArrayEnd(content, openIndex) {
20
+ let depth = 1;
21
+ let quote = null;
22
+ for (let i = openIndex; i < content.length; i++) {
23
+ const ch = content[i];
24
+ if (quote) {
25
+ if (ch === '\\')
26
+ i++;
27
+ else if (ch === quote)
28
+ quote = null;
29
+ continue;
30
+ }
31
+ if (ch === "'" || ch === '"' || ch === '`')
32
+ quote = ch;
33
+ else if (ch === '[' || ch === '{')
34
+ depth++;
35
+ else if (ch === ']' || ch === '}') {
36
+ depth--;
37
+ if (depth === 0)
38
+ return i;
39
+ }
40
+ }
41
+ return -1;
42
+ }
14
43
  /**
15
- * Adds a nav item to a generated app's side menu.
44
+ * Appends a nav item to a generated app's side menu.
45
+ *
46
+ * Appends rather than prepends so the shell's own 'Home' entry stays first and
47
+ * generated items accumulate in the order they were run. Inserting at the head
48
+ * (an earlier version of this function) pushed Home to the bottom of the nav
49
+ * after the first generator run, which no consuming app wants.
16
50
  *
17
51
  * A no-op when the app has no `primaryItems` array. That is the signal the app
18
52
  * was generated with `--layout=header` (a public app has no side menu at all),
@@ -33,9 +67,20 @@ function insertSideMenuItem(host, projectRoot, item) {
33
67
  return;
34
68
  if (content.includes(`to: '${item.to}'`))
35
69
  return;
36
- const insertAt = anchorIndex + ANCHOR.length;
37
- host.write(appPath, content.slice(0, insertAt) +
38
- `\n { label: '${item.label}', to: '${item.to}' },` +
39
- content.slice(insertAt));
70
+ const openIndex = anchorIndex + ANCHOR.length;
71
+ const closeIndex = findArrayEnd(content, openIndex);
72
+ if (closeIndex === -1)
73
+ return;
74
+ const icon = item.icon ? `, icon: '${item.icon}'` : '';
75
+ const entry = `{ label: '${item.label}', to: '${item.to}'${icon} },`;
76
+ // Trim the whitespace ahead of the closing bracket and re-emit it, rather than
77
+ // inserting in front of it: the array may already end with a newline (a
78
+ // previous append) or not (the one-line literal formatFiles produces), and
79
+ // prepending a newline to the former leaves a blank line between entries.
80
+ const head = content.slice(0, closeIndex).replace(/\s+$/, '');
81
+ // The last element may or may not carry a trailing comma depending on whether
82
+ // formatFiles has run; add one if it's missing so appending stays valid.
83
+ const separator = head.endsWith('[') || head.endsWith(',') ? '' : ',';
84
+ host.write(appPath, `${head}${separator}\n ${entry}\n` + content.slice(closeIndex));
40
85
  }
41
86
  //# sourceMappingURL=vue-side-menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vue-side-menu.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/vue-side-menu.ts"],"names":[],"mappings":";;AA+BA,gDAqBC;AA3CD,8EAA8E;AAC9E,gFAAgF;AAChF,4EAA4E;AAC5E,EAAE;AACF,iFAAiF;AACjF,8EAA8E;AAC9E,iFAAiF;AACjF,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,MAAM,GAAG,wBAAwB,CAAC;AAExC;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAChC,IAAU,EACV,WAAmB,EACnB,IAAsB;;IAEtB,MAAM,OAAO,GAAG,GAAG,WAAW,cAAc,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,0CAAE,QAAQ,EAAE,CAAC;IAC/C,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAElC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,WAAW,KAAK,CAAC,CAAC;QAAE,OAAO;IAE/B,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,EAAE,GAAG,CAAC;QAAE,OAAO;IAEjD,MAAM,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7C,IAAI,CAAC,KAAK,CACR,OAAO,EACP,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QACxB,iBAAiB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,EAAE,MAAM;QACnD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC1B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"vue-side-menu.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/vue-side-menu.ts"],"names":[],"mappings":"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"}
@@ -68,4 +68,104 @@ describe('insertSideMenuItem', () => {
68
68
  insertSideMenuItem(host, 'apps/missing', { label: 'X', to: '/x' }),
69
69
  ).not.toThrow();
70
70
  });
71
+
72
+ // The original spec asserted both items were present but never their relative
73
+ // order, so it passed while the function prepended and pushed Home to the
74
+ // bottom of every generated app's nav.
75
+ it("appends after the shell's own Home entry rather than before it", () => {
76
+ host.write('apps/staff/src/App.vue', INTERNAL_APP);
77
+ insertSideMenuItem(host, 'apps/staff', {
78
+ label: 'Review queue',
79
+ to: '/queue',
80
+ });
81
+ const app = host.read('apps/staff/src/App.vue')?.toString() ?? '';
82
+ expect(app.indexOf("to: '/'")).toBeLessThan(app.indexOf("to: '/queue'"));
83
+ });
84
+
85
+ it('accumulates multiple items in the order they were added', () => {
86
+ host.write('apps/staff/src/App.vue', INTERNAL_APP);
87
+ insertSideMenuItem(host, 'apps/staff', { label: 'Queue', to: '/queue' });
88
+ insertSideMenuItem(host, 'apps/staff', {
89
+ label: 'Livestock categories',
90
+ to: '/livestock',
91
+ });
92
+ const app = host.read('apps/staff/src/App.vue')?.toString() ?? '';
93
+ expect(app.indexOf("to: '/'")).toBeLessThan(app.indexOf("to: '/queue'"));
94
+ expect(app.indexOf("to: '/queue'")).toBeLessThan(
95
+ app.indexOf("to: '/livestock'"),
96
+ );
97
+ });
98
+
99
+ it('emits the icon, which the element needs to render a non-blank item', () => {
100
+ host.write('apps/staff/src/App.vue', INTERNAL_APP);
101
+ insertSideMenuItem(host, 'apps/staff', {
102
+ label: 'Queue',
103
+ to: '/queue',
104
+ icon: 'list',
105
+ });
106
+ expect(host.read('apps/staff/src/App.vue')?.toString()).toContain(
107
+ "{ label: 'Queue', to: '/queue', icon: 'list' },",
108
+ );
109
+ });
110
+
111
+ it('appends validly when the array literal has no trailing comma', () => {
112
+ host.write(
113
+ 'apps/staff/src/App.vue',
114
+ `<script setup lang="ts">
115
+ const primaryItems = [{ label: 'Home', to: '/' }];
116
+ </script>
117
+ `,
118
+ );
119
+ insertSideMenuItem(host, 'apps/staff', { label: 'Queue', to: '/queue' });
120
+ const app = host.read('apps/staff/src/App.vue')?.toString() ?? '';
121
+ expect(app).toContain("{ label: 'Home', to: '/' },");
122
+ expect(app.indexOf("to: '/'")).toBeLessThan(app.indexOf("to: '/queue'"));
123
+ });
124
+
125
+ it('does not end its scan early on a bracket inside a label', () => {
126
+ host.write(
127
+ 'apps/staff/src/App.vue',
128
+ `<script setup lang="ts">
129
+ const primaryItems = [
130
+ { label: 'Reports [beta]', to: '/reports' },
131
+ ];
132
+ </script>
133
+ `,
134
+ );
135
+ insertSideMenuItem(host, 'apps/staff', { label: 'Queue', to: '/queue' });
136
+ const app = host.read('apps/staff/src/App.vue')?.toString() ?? '';
137
+ expect(app.indexOf("to: '/reports'")).toBeLessThan(
138
+ app.indexOf("to: '/queue'"),
139
+ );
140
+ });
141
+
142
+ it('is a silent no-op on an unterminated array literal', () => {
143
+ const broken = `<script setup lang="ts">
144
+ const primaryItems = [
145
+ </script>
146
+ `;
147
+ host.write('apps/staff/src/App.vue', broken);
148
+ insertSideMenuItem(host, 'apps/staff', { label: 'Queue', to: '/queue' });
149
+ expect(host.read('apps/staff/src/App.vue')?.toString()).toBe(broken);
150
+ });
151
+
152
+ it('does not leave blank lines between accumulated entries', () => {
153
+ host.write('apps/staff/src/App.vue', INTERNAL_APP);
154
+ insertSideMenuItem(host, 'apps/staff', {
155
+ label: 'A',
156
+ to: '/a',
157
+ icon: 'list',
158
+ });
159
+ insertSideMenuItem(host, 'apps/staff', {
160
+ label: 'B',
161
+ to: '/b',
162
+ icon: 'list',
163
+ });
164
+ const app = host.read('apps/staff/src/App.vue')?.toString() ?? '';
165
+ const array = app.slice(
166
+ app.indexOf('const primaryItems = ['),
167
+ app.indexOf('];') + 2,
168
+ );
169
+ expect(array).not.toMatch(/\n\s*\n/);
170
+ });
71
171
  });
@@ -0,0 +1,26 @@
1
+ import { Tree } from '@nx/devkit';
2
+ /**
3
+ * Backfills a `module` setting on a generated Vue project's tsconfig when it
4
+ * declares `moduleResolution: "bundler"` without one.
5
+ *
6
+ * @nx/vue's library and application generators write `moduleResolution:
7
+ * "bundler"` into the project's tsconfig.json but leave `module` to be
8
+ * inherited. In a create-nx-workspace TS-solution workspace the base sets
9
+ * `module: "nodenext"`, and that pair is invalid two ways over:
10
+ *
11
+ * error TS5095: Option 'bundler' can only be used when 'module' is set to
12
+ * 'preserve', 'commonjs', or 'es2015' or later.
13
+ * error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left
14
+ * unspecified) when option 'module' is set to 'NodeNext'.
15
+ *
16
+ * so `nx build` fails on completely unmodified generator output. `esnext`
17
+ * matches what @nx/vue itself writes beside `bundler` in the app's
18
+ * tsconfig.app.json, so this aligns the project with its own sibling config
19
+ * rather than introducing a third convention.
20
+ *
21
+ * Deliberately conditional and idempotent: it only acts when
22
+ * `moduleResolution` is bundler-flavoured *and* `module` is absent, so a
23
+ * project whose tsconfig is already valid -- or which has been deliberately
24
+ * pinned to something else -- is left alone.
25
+ */
26
+ export declare function ensureBundlerModuleOption(host: Tree, tsconfigPath: string): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureBundlerModuleOption = ensureBundlerModuleOption;
4
+ const devkit_1 = require("@nx/devkit");
5
+ // `moduleResolution` values that TypeScript only accepts alongside a
6
+ // bundler-compatible `module` (TS5095) and which additionally conflict with an
7
+ // inherited `module: nodenext` (TS5109).
8
+ const BUNDLER_RESOLUTIONS = ['bundler', 'Bundler'];
9
+ /**
10
+ * Backfills a `module` setting on a generated Vue project's tsconfig when it
11
+ * declares `moduleResolution: "bundler"` without one.
12
+ *
13
+ * @nx/vue's library and application generators write `moduleResolution:
14
+ * "bundler"` into the project's tsconfig.json but leave `module` to be
15
+ * inherited. In a create-nx-workspace TS-solution workspace the base sets
16
+ * `module: "nodenext"`, and that pair is invalid two ways over:
17
+ *
18
+ * error TS5095: Option 'bundler' can only be used when 'module' is set to
19
+ * 'preserve', 'commonjs', or 'es2015' or later.
20
+ * error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left
21
+ * unspecified) when option 'module' is set to 'NodeNext'.
22
+ *
23
+ * so `nx build` fails on completely unmodified generator output. `esnext`
24
+ * matches what @nx/vue itself writes beside `bundler` in the app's
25
+ * tsconfig.app.json, so this aligns the project with its own sibling config
26
+ * rather than introducing a third convention.
27
+ *
28
+ * Deliberately conditional and idempotent: it only acts when
29
+ * `moduleResolution` is bundler-flavoured *and* `module` is absent, so a
30
+ * project whose tsconfig is already valid -- or which has been deliberately
31
+ * pinned to something else -- is left alone.
32
+ */
33
+ function ensureBundlerModuleOption(host, tsconfigPath) {
34
+ if (!host.exists(tsconfigPath))
35
+ return;
36
+ (0, devkit_1.updateJson)(host, tsconfigPath, (tsconfig) => {
37
+ const compilerOptions = tsconfig.compilerOptions;
38
+ if (!compilerOptions)
39
+ return tsconfig;
40
+ if (!BUNDLER_RESOLUTIONS.includes(compilerOptions.moduleResolution)) {
41
+ return tsconfig;
42
+ }
43
+ if (compilerOptions.module)
44
+ return tsconfig;
45
+ compilerOptions.module = 'esnext';
46
+ return tsconfig;
47
+ });
48
+ }
49
+ //# sourceMappingURL=vue-tsconfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-tsconfig.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/vue-tsconfig.ts"],"names":[],"mappings":";;AA+BA,8DAiBC;AAhDD,uCAA8C;AAE9C,qEAAqE;AACrE,+EAA+E;AAC/E,yCAAyC;AACzC,MAAM,mBAAmB,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,yBAAyB,CACvC,IAAU,EACV,YAAoB;IAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;QAAE,OAAO;IAEvC,IAAA,mBAAU,EAAC,IAAI,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC1C,MAAM,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;QACjD,IAAI,CAAC,eAAe;YAAE,OAAO,QAAQ,CAAC;QACtC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,eAAe,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC;QAE5C,eAAe,CAAC,MAAM,GAAG,QAAQ,CAAC;QAClC,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}