@jskit-ai/ui-generator 0.1.40 → 0.1.42

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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/ui-generator",
4
- version: "0.1.40",
4
+ version: "0.1.42",
5
5
  kind: "generator",
6
6
  description: "Create non-CRUD pages, reusable UI elements, and subpage hosts.",
7
7
  options: {
@@ -278,7 +278,7 @@ export default Object.freeze({
278
278
  mutations: {
279
279
  dependencies: {
280
280
  runtime: {
281
- "@jskit-ai/users-web": "0.1.72"
281
+ "@jskit-ai/users-web": "0.1.74"
282
282
  },
283
283
  dev: {}
284
284
  },
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@jskit-ai/ui-generator",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "dependencies": {
9
- "@jskit-ai/kernel": "0.1.57",
10
- "@jskit-ai/shell-web": "0.1.56"
9
+ "@jskit-ai/kernel": "0.1.59",
10
+ "@jskit-ai/shell-web": "0.1.58"
11
11
  },
12
12
  "exports": {
13
13
  "./server/buildTemplateContext": "./src/server/buildTemplateContext.js"
@@ -3,6 +3,8 @@ import {
3
3
  resolvePageTargetDetails
4
4
  } from "@jskit-ai/kernel/server/support";
5
5
 
6
+ const DEFAULT_GENERATED_LINK_ICON = "mdi-view-list-outline";
7
+
6
8
  function resolveLinkToPropLine(linkTo = "") {
7
9
  if (!linkTo) {
8
10
  return "";
@@ -34,6 +36,7 @@ async function buildUiPageTemplateContext({
34
36
  __JSKIT_UI_LINK_PLACEMENT_ID__: pageTarget.placementId,
35
37
  __JSKIT_UI_LINK_PLACEMENT_TARGET__: String(linkTarget.placementTarget?.id || ""),
36
38
  __JSKIT_UI_LINK_COMPONENT_TOKEN__: String(linkTarget.componentToken || ""),
39
+ __JSKIT_UI_LINK_ICON__: DEFAULT_GENERATED_LINK_ICON,
37
40
  __JSKIT_UI_LINK_WORKSPACE_SUFFIX__: pageTarget.routeUrlSuffix,
38
41
  __JSKIT_UI_LINK_NON_WORKSPACE_SUFFIX__: pageTarget.routeUrlSuffix,
39
42
  __JSKIT_UI_LINK_WHEN_LINE__: String(linkTarget.whenLine || ""),
@@ -31,6 +31,7 @@ function renderPageLinkPlacementBlock({
31
31
  ` componentToken: "${context.__JSKIT_UI_LINK_COMPONENT_TOKEN__}",\n` +
32
32
  " props: {\n" +
33
33
  ` label: "${label}",\n` +
34
+ ` icon: "${context.__JSKIT_UI_LINK_ICON__}",\n` +
34
35
  ` surface: "${surface}",\n` +
35
36
  ` scopedSuffix: "${context.__JSKIT_UI_LINK_WORKSPACE_SUFFIX__}",\n` +
36
37
  ` unscopedSuffix: "${context.__JSKIT_UI_LINK_NON_WORKSPACE_SUFFIX__}",\n` +
@@ -25,15 +25,15 @@ import {
25
25
 
26
26
  const DEFAULT_SUBPAGES_POSITION = "sub-pages";
27
27
  const SECTION_CONTAINER_SHELL_COMPONENT = "SectionContainerShell";
28
- const TAB_LINK_COMPONENT_TOKEN = "local.main.ui.tab-link-item";
28
+ const SUBPAGES_LINK_COMPONENT_TOKEN = "local.main.ui.surface-aware-menu-link-item";
29
29
  const DEFAULT_MENU_COMPONENT_DIRECTORY = path.join(DEFAULT_COMPONENT_DIRECTORY, "menus");
30
- const TAB_LINK_COMPONENT_DEFINITION = findLocalLinkItemDefinition(TAB_LINK_COMPONENT_TOKEN);
30
+ const SUBPAGES_LINK_COMPONENT_DEFINITION = findLocalLinkItemDefinition(SUBPAGES_LINK_COMPONENT_TOKEN);
31
31
 
32
- if (!TAB_LINK_COMPONENT_DEFINITION) {
33
- throw new Error(`ui-generator add-subpages could not resolve ${TAB_LINK_COMPONENT_TOKEN} scaffold definition.`);
32
+ if (!SUBPAGES_LINK_COMPONENT_DEFINITION) {
33
+ throw new Error(`ui-generator add-subpages could not resolve ${SUBPAGES_LINK_COMPONENT_TOKEN} scaffold definition.`);
34
34
  }
35
35
 
36
- const TAB_LINK_COMPONENT = TAB_LINK_COMPONENT_DEFINITION.componentName;
36
+ const SUBPAGES_LINK_COMPONENT = SUBPAGES_LINK_COMPONENT_DEFINITION.componentName;
37
37
 
38
38
  const ROUTE_TAG_PATTERN = /<route\b[^>]*>[\s\S]*?<\/route>\s*/gi;
39
39
  const TEMPLATE_TOKEN_PATTERN = /<\/?template\b[^>]*>/gi;
@@ -145,7 +145,7 @@ async function ensureSubpagesSupportScaffold({
145
145
  );
146
146
  const tabLinkPath = resolvePathWithinApp(
147
147
  resolvedAppRoot,
148
- path.join(normalizedTabLinkComponentDirectory, `${TAB_LINK_COMPONENT}.vue`),
148
+ path.join(normalizedTabLinkComponentDirectory, `${SUBPAGES_LINK_COMPONENT}.vue`),
149
149
  { context: "ui-generator add-subpages" }
150
150
  );
151
151
 
@@ -156,7 +156,7 @@ async function ensureSubpagesSupportScaffold({
156
156
  );
157
157
  }
158
158
 
159
- const providerRegisterLine = `registerMainClientComponent("${TAB_LINK_COMPONENT_TOKEN}", () => ${TAB_LINK_COMPONENT});`;
159
+ const providerRegisterLine = `registerMainClientComponent("${SUBPAGES_LINK_COMPONENT_TOKEN}", () => ${SUBPAGES_LINK_COMPONENT});`;
160
160
  const providerHasTabLinkRegistration = providerSource.includes(providerRegisterLine);
161
161
  const touchedFiles = new Set();
162
162
  const supportFiles = [
@@ -168,7 +168,7 @@ async function ensureSubpagesSupportScaffold({
168
168
  if (!providerHasTabLinkRegistration) {
169
169
  supportFiles.push({
170
170
  path: tabLinkPath,
171
- desiredSource: await readLocalLinkItemComponentSource(TAB_LINK_COMPONENT_DEFINITION)
171
+ desiredSource: await readLocalLinkItemComponentSource(SUBPAGES_LINK_COMPONENT_DEFINITION)
172
172
  });
173
173
  }
174
174
 
@@ -191,7 +191,7 @@ async function ensureSubpagesSupportScaffold({
191
191
  touchedFiles.add(supportFile.path.relativePath);
192
192
  }
193
193
 
194
- const providerImportLine = `import ${TAB_LINK_COMPONENT} from "/${toPosixPath(path.join(normalizedTabLinkComponentDirectory, `${TAB_LINK_COMPONENT}.vue`))}";`;
194
+ const providerImportLine = `import ${SUBPAGES_LINK_COMPONENT} from "/${toPosixPath(path.join(normalizedTabLinkComponentDirectory, `${SUBPAGES_LINK_COMPONENT}.vue`))}";`;
195
195
  if (providerHasTabLinkRegistration) {
196
196
  return Object.freeze({
197
197
  touchedFiles: [...touchedFiles].sort((left, right) => left.localeCompare(right)),
@@ -313,7 +313,7 @@ function renderSubpagesTemplate({
313
313
  "<template>",
314
314
  renderSectionContainerOpenTag({ title, subtitle }),
315
315
  " <template #tabs>",
316
- ` <ShellOutlet target="${normalizedTarget}" default-link-component-token="${TAB_LINK_COMPONENT_TOKEN}" />`,
316
+ ` <ShellOutlet target="${normalizedTarget}" default-link-component-token="${SUBPAGES_LINK_COMPONENT_TOKEN}" />`,
317
317
  " </template>"
318
318
  ];
319
319
 
@@ -483,8 +483,8 @@ export {
483
483
  DEFAULT_SUBPAGES_POSITION,
484
484
  DEFAULT_COMPONENT_DIRECTORY,
485
485
  SECTION_CONTAINER_SHELL_COMPONENT,
486
- TAB_LINK_COMPONENT,
487
- TAB_LINK_COMPONENT_TOKEN,
486
+ SUBPAGES_LINK_COMPONENT,
487
+ SUBPAGES_LINK_COMPONENT_TOKEN,
488
488
  resolvePageTargetDetails,
489
489
  resolveNearestParentSubpagesHost,
490
490
  deriveDefaultSubpagesHost,
@@ -97,7 +97,7 @@ test("ui-generator add-subpages derives the default target from an index-route p
97
97
 
98
98
  assert.deepEqual(result.touchedFiles, [
99
99
  "packages/main/src/client/providers/MainClientProvider.js",
100
- "src/components/menus/TabLinkItem.vue",
100
+ "src/components/menus/SurfaceAwareMenuLinkItem.vue",
101
101
  "src/components/SectionContainerShell.vue",
102
102
  `src/pages/${targetFile}`
103
103
  ]);
@@ -105,12 +105,12 @@ test("ui-generator add-subpages derives the default target from an index-route p
105
105
  const pageSource = await readPageFile(appRoot, targetFile);
106
106
  assert.match(
107
107
  pageSource,
108
- /<ShellOutlet target="practice:sub-pages" default-link-component-token="local\.main\.ui\.tab-link-item" \/>/
108
+ /<ShellOutlet target="practice:sub-pages" default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item" \/>/
109
109
  );
110
110
  assert.match(pageSource, /<RouterView \/>/);
111
111
  assert.equal(
112
- await readFile(path.join(appRoot, "src", "components", "menus", "TabLinkItem.vue"), "utf8"),
113
- await readLocalLinkItemComponentSource("local.main.ui.tab-link-item")
112
+ await readFile(path.join(appRoot, "src", "components", "menus", "SurfaceAwareMenuLinkItem.vue"), "utf8"),
113
+ await readLocalLinkItemComponentSource("local.main.ui.surface-aware-menu-link-item")
114
114
  );
115
115
  });
116
116
  });
@@ -132,7 +132,7 @@ test("ui-generator add-subpages derives the default target from a dynamic file-r
132
132
  const pageSource = await readPageFile(appRoot, targetFile);
133
133
  assert.match(
134
134
  pageSource,
135
- /<ShellOutlet target="contacts-contact-id:sub-pages" default-link-component-token="local\.main\.ui\.tab-link-item" \/>/
135
+ /<ShellOutlet target="contacts-contact-id:sub-pages" default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item" \/>/
136
136
  );
137
137
  });
138
138
  });
@@ -154,7 +154,7 @@ test("ui-generator add-subpages derives the default target from a nested route p
154
154
  const pageSource = await readPageFile(appRoot, targetFile);
155
155
  assert.match(
156
156
  pageSource,
157
- /<ShellOutlet target="catalog-products:sub-pages" default-link-component-token="local\.main\.ui\.tab-link-item" \/>/
157
+ /<ShellOutlet target="catalog-products:sub-pages" default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item" \/>/
158
158
  );
159
159
  });
160
160
  });
@@ -199,7 +199,7 @@ test("ui-generator add-subpages supports explicit target host:position", async (
199
199
  const pageSource = await readPageFile(appRoot, targetFile);
200
200
  assert.match(
201
201
  pageSource,
202
- /<ShellOutlet target="practice-hub:secondary-tabs" default-link-component-token="local\.main\.ui\.tab-link-item" \/>/
202
+ /<ShellOutlet target="practice-hub:secondary-tabs" default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item" \/>/
203
203
  );
204
204
  });
205
205
  });
@@ -211,7 +211,7 @@ test("ui-generator add-subpages does not rewrite existing scaffold support compo
211
211
  const targetFile = "w/[workspaceSlug]/admin/practice/index.vue";
212
212
  await writePageFile(appRoot, targetFile);
213
213
  const customSectionShellSource = `<template><section class="custom-shell"><slot /></section></template>\n`;
214
- const customTabLinkSource = `<template><button class="custom-tab-link"><slot /></button></template>\n`;
214
+ const customSurfaceAwareLinkSource = `<template><button class="custom-surface-aware-link"><slot /></button></template>\n`;
215
215
  await writeFile(
216
216
  path.join(appRoot, "src", "components", "SectionContainerShell.vue"),
217
217
  customSectionShellSource,
@@ -219,8 +219,8 @@ test("ui-generator add-subpages does not rewrite existing scaffold support compo
219
219
  );
220
220
  await mkdir(path.join(appRoot, "src", "components", "menus"), { recursive: true });
221
221
  await writeFile(
222
- path.join(appRoot, "src", "components", "menus", "TabLinkItem.vue"),
223
- customTabLinkSource,
222
+ path.join(appRoot, "src", "components", "menus", "SurfaceAwareMenuLinkItem.vue"),
223
+ customSurfaceAwareLinkSource,
224
224
  "utf8"
225
225
  );
226
226
 
@@ -242,8 +242,8 @@ test("ui-generator add-subpages does not rewrite existing scaffold support compo
242
242
  customSectionShellSource
243
243
  );
244
244
  assert.equal(
245
- await readFile(path.join(appRoot, "src", "components", "menus", "TabLinkItem.vue"), "utf8"),
246
- customTabLinkSource
245
+ await readFile(path.join(appRoot, "src", "components", "menus", "SurfaceAwareMenuLinkItem.vue"), "utf8"),
246
+ customSurfaceAwareLinkSource
247
247
  );
248
248
  });
249
249
  });
@@ -332,7 +332,7 @@ test("ui-generator add-subpages accepts target files with a src/pages prefix", a
332
332
  const pageSource = await readFile(path.join(appRoot, targetFile), "utf8");
333
333
  assert.match(
334
334
  pageSource,
335
- /<ShellOutlet target="practice:sub-pages" default-link-component-token="local\.main\.ui\.tab-link-item" \/>/
335
+ /<ShellOutlet target="practice:sub-pages" default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item" \/>/
336
336
  );
337
337
  assert.match(pageSource, /<RouterView \/>/);
338
338
  });
@@ -250,6 +250,7 @@ test("buildUiPageTemplateContext supports explicit link component token and link
250
250
  }
251
251
  });
252
252
  assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
253
+ assert.equal(context.__JSKIT_UI_LINK_ICON__, "mdi-view-list-outline");
253
254
  assert.equal(context.__JSKIT_UI_LINK_WORKSPACE_SUFFIX__, "/contacts/[contactId]/notes");
254
255
  assert.equal(context.__JSKIT_UI_LINK_NON_WORKSPACE_SUFFIX__, "/contacts/[contactId]/notes");
255
256
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./notes\",\n");
@@ -314,7 +315,8 @@ test("buildUiPageTemplateContext infers subpage link placement, tab token, and l
314
315
  });
315
316
 
316
317
  assert.equal(context.__JSKIT_UI_LINK_PLACEMENT_TARGET__, "contact-view:sub-pages");
317
- assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
318
+ assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.surface-aware-menu-link-item");
319
+ assert.equal(context.__JSKIT_UI_LINK_ICON__, "mdi-view-list-outline");
318
320
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./notes\",\n");
319
321
  });
320
322
  });
@@ -352,7 +354,7 @@ test("buildUiPageTemplateContext inherits a file-route parent host for deeper de
352
354
  });
353
355
 
354
356
  assert.equal(context.__JSKIT_UI_LINK_PLACEMENT_TARGET__, "contact-view:sub-pages");
355
- assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
357
+ assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.surface-aware-menu-link-item");
356
358
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./notes/history\",\n");
357
359
  });
358
360
  });
@@ -390,7 +392,8 @@ test("buildUiPageTemplateContext infers subpage link placement from an index-rou
390
392
  });
391
393
 
392
394
  assert.equal(context.__JSKIT_UI_LINK_PLACEMENT_TARGET__, "catalog:sub-pages");
393
- assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
395
+ assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.surface-aware-menu-link-item");
396
+ assert.equal(context.__JSKIT_UI_LINK_ICON__, "mdi-view-list-outline");
394
397
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./products\",\n");
395
398
  });
396
399
  });
@@ -441,7 +444,7 @@ test("buildUiPageTemplateContext finds the nearest index-route parent host", asy
441
444
  });
442
445
 
443
446
  assert.equal(context.__JSKIT_UI_LINK_PLACEMENT_TARGET__, "catalog-products:sub-pages");
444
- assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
447
+ assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.surface-aware-menu-link-item");
445
448
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./variants\",\n");
446
449
  });
447
450
  });
@@ -479,7 +482,7 @@ test("buildUiPageTemplateContext infers subpage link placement from an index rou
479
482
  });
480
483
 
481
484
  assert.equal(context.__JSKIT_UI_LINK_PLACEMENT_TARGET__, "customer-view:sub-pages");
482
- assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.tab-link-item");
485
+ assert.equal(context.__JSKIT_UI_LINK_COMPONENT_TOKEN__, "local.main.ui.surface-aware-menu-link-item");
483
486
  assert.equal(context.__JSKIT_UI_LINK_TO_PROP_LINE__, " to: \"./pets\",\n");
484
487
  assert.equal(context.__JSKIT_UI_LINK_WORKSPACE_SUFFIX__, "/customers/[customerId]/pets");
485
488
  });
@@ -162,6 +162,7 @@ test("ui-generator page subcommand supports link placement options", async () =>
162
162
  const placementSource = await readFile(path.join(appRoot, "src", "placement.js"), "utf8");
163
163
  assert.match(placementSource, /target: "shell-layout:top-right"/);
164
164
  assert.match(placementSource, /componentToken: "local\.main\.ui\.tab-link-item"/);
165
+ assert.match(placementSource, /icon: "mdi-view-list-outline"/);
165
166
  assert.match(placementSource, /to: "\.\/notes"/);
166
167
  });
167
168
  });
@@ -196,7 +197,8 @@ test("ui-generator page subcommand infers subpage link placement, tab token, and
196
197
 
197
198
  const placementSource = await readFile(path.join(appRoot, "src", "placement.js"), "utf8");
198
199
  assert.match(placementSource, /target: "contact-view:sub-pages"/);
199
- assert.match(placementSource, /componentToken: "local\.main\.ui\.tab-link-item"/);
200
+ assert.match(placementSource, /componentToken: "local\.main\.ui\.surface-aware-menu-link-item"/);
201
+ assert.match(placementSource, /icon: "mdi-view-list-outline"/);
200
202
  assert.match(placementSource, /to: "\.\/notes"/);
201
203
  });
202
204
  });
@@ -246,7 +248,7 @@ test("ui-generator page subcommand prefers the nearest index-route parent host",
246
248
 
247
249
  const placementSource = await readFile(path.join(appRoot, "src", "placement.js"), "utf8");
248
250
  assert.match(placementSource, /target: "catalog-products:sub-pages"/);
249
- assert.match(placementSource, /componentToken: "local\.main\.ui\.tab-link-item"/);
251
+ assert.match(placementSource, /componentToken: "local\.main\.ui\.surface-aware-menu-link-item"/);
250
252
  assert.match(placementSource, /to: "\.\/variants"/);
251
253
  });
252
254
  });