@synopackageland/ui 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +25 -0
- package/dist/components/app/app-layout/AppLayout.vue.d.ts +8 -1
- package/dist/components/app/app-sidebar/AppTopNav.vue.d.ts +13 -0
- package/dist/components/app/app-sidebar/AppTopNavItems.vue.d.ts +13 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8739 -8518
- package/dist/json/catalog.d.ts +8 -0
- package/dist/json/registry.d.ts +136 -0
- package/dist/json-ai-prompt.md +1 -1
- package/dist/json-catalog.schema.json +15 -1
- package/dist/json-preview/preview.js +12219 -9652
- package/dist/json.js +157 -155
- package/dist/lib/adaptiveLayout.d.ts +4 -0
- package/dist/reka-runtime.json +1 -1
- package/dist/theme.css +1 -1
- package/dist/themes/dsm7-embedded-theme.css +1 -1
- package/dist/themes/dsm7-embedded.css +1 -1
- package/dist/themes/dsm7.css +1 -1
- package/docs/adaptive-layout.md +5 -0
- package/docs/json-ui.md +2 -0
- package/docs/theme-hooks.md +168 -0
- package/package.json +3 -2
package/dist/json.js
CHANGED
|
@@ -5,9 +5,9 @@ import { createStateStore as $t, defineCatalog as jt } from "@json-render/core";
|
|
|
5
5
|
import { defineRegistry as M, useBoundProp as b, JSONUIProvider as W, Renderer as B } from "@json-render/vue";
|
|
6
6
|
import { ActionProvider as Ot, JSONUIProvider as At, Renderer as Pt, StateProvider as kt, ValidationProvider as Ct, VisibilityProvider as It, defineRegistry as Rt, useActions as Kt, useBoundProp as Lt, useStateStore as Dt } from "@json-render/vue";
|
|
7
7
|
import { schema as H } from "@json-render/vue/schema";
|
|
8
|
-
import { schema as
|
|
8
|
+
import { schema as Nt } from "@json-render/vue/schema";
|
|
9
9
|
import { h as d, defineComponent as G, openBlock as X, createBlock as Y, unref as j, withCtx as Q, createVNode as Z } from "vue";
|
|
10
|
-
import { LoadingArea as ee, InputGroup as te, ListItem as oe, CellStatus as ne, CellText as ie, DataTable as K, Dialog as
|
|
10
|
+
import { LoadingArea as ee, InputGroup as te, ListItem as oe, CellStatus as ne, CellText as ie, DataTable as K, Dialog as ae, Badge as se, Progress as re, EmptyState as le, Callout as ce, Card as de, Surface as pe, SettingsRow as ue, SettingsSection as me, FormItem as he, Form as fe, RadioGroup as ge, Switch as be, Checkbox as ye, Select as we, Input as ve, Button as Se, SectionTabs as $e, AppSidebar as je, AppToolbar as xe, PageHeader as Oe, PageContent as Ae, ResponsiveView as Pe, AppLayout as ke, AppRoot as Ce, getRegisteredIcon as Ie } from "./index.js";
|
|
11
11
|
const J = t.lazy(() => t.object({
|
|
12
12
|
key: t.string(),
|
|
13
13
|
label: t.string(),
|
|
@@ -42,10 +42,11 @@ const J = t.lazy(() => t.object({
|
|
|
42
42
|
sidebarWidth: t.string().optional(),
|
|
43
43
|
minHeight: t.string().optional(),
|
|
44
44
|
responsive: t.boolean().optional(),
|
|
45
|
-
wideLayout: t.enum(["window", "web"]).optional()
|
|
45
|
+
wideLayout: t.enum(["window", "web"]).optional(),
|
|
46
|
+
navigation: t.enum(["sidebar", "top"]).optional()
|
|
46
47
|
}),
|
|
47
48
|
slots: ["default", "sidebar", "toolbar", "footer"],
|
|
48
|
-
description:
|
|
49
|
+
description: `DSM application interior with optional sidebar, toolbar, main content and footer regions. Set wideLayout "web" only for a standalone Portal page; DSM windows keep the default "window" at every width. navigation "top" shows the sidebar slot's SidebarNav as one bar above the page (phones keep the drawer).`
|
|
49
50
|
},
|
|
50
51
|
ResponsiveView: {
|
|
51
52
|
props: t.object({ mode: t.enum(["auto", "mobile", "window", "web"]).optional() }),
|
|
@@ -380,8 +381,8 @@ const De = {
|
|
|
380
381
|
sm: "var(--ui-space-2)",
|
|
381
382
|
md: "var(--ui-space-3)",
|
|
382
383
|
lg: "var(--ui-space-4)"
|
|
383
|
-
}, Ue = { start: "flex-start", center: "center", end: "flex-end", stretch: "stretch" },
|
|
384
|
-
function
|
|
384
|
+
}, Ue = { start: "flex-start", center: "center", end: "flex-end", stretch: "stretch" }, Ne = { start: "flex-start", center: "center", end: "flex-end", between: "space-between" };
|
|
385
|
+
function Te(e) {
|
|
385
386
|
return { default: () => e };
|
|
386
387
|
}
|
|
387
388
|
function C(e) {
|
|
@@ -394,7 +395,7 @@ function _(e) {
|
|
|
394
395
|
children: e.children?.map(_)
|
|
395
396
|
};
|
|
396
397
|
}
|
|
397
|
-
function
|
|
398
|
+
function Ee(e) {
|
|
398
399
|
return e.map((o) => ({ ...o, items: o.items.map(_) }));
|
|
399
400
|
}
|
|
400
401
|
const Je = {
|
|
@@ -403,33 +404,34 @@ const Je = {
|
|
|
403
404
|
sidebarWidth: e.sidebarWidth,
|
|
404
405
|
minHeight: e.minHeight,
|
|
405
406
|
responsive: e.responsive,
|
|
406
|
-
wideLayout: e.wideLayout
|
|
407
|
+
wideLayout: e.wideLayout,
|
|
408
|
+
navigation: e.navigation
|
|
407
409
|
}, o),
|
|
408
410
|
ResponsiveView: ({ props: e, slots: o }) => d(Pe, { mode: e.mode }, o),
|
|
409
411
|
Page: ({ props: e, slots: o }) => d(Ae, { width: e.width ?? "fill", surface: e.surface }, o),
|
|
410
412
|
PageHeader: ({ props: e, slots: o }) => d(Oe, e, o),
|
|
411
413
|
Toolbar: ({ props: e, slots: o }) => d(xe, e, o),
|
|
412
414
|
SidebarNav: ({ props: e, bindings: o, emit: n }) => {
|
|
413
|
-
const [
|
|
415
|
+
const [a, i] = b(e.value, o?.value);
|
|
414
416
|
return d(je, {
|
|
415
|
-
modelValue:
|
|
416
|
-
groups:
|
|
417
|
+
modelValue: a,
|
|
418
|
+
groups: Ee(e.groups),
|
|
417
419
|
searchable: e.searchable,
|
|
418
420
|
collapsible: e.collapsible,
|
|
419
421
|
searchPlaceholder: e.searchPlaceholder,
|
|
420
|
-
"onUpdate:modelValue": (
|
|
421
|
-
i(
|
|
422
|
+
"onUpdate:modelValue": (s) => {
|
|
423
|
+
i(s), n("change");
|
|
422
424
|
}
|
|
423
425
|
});
|
|
424
426
|
},
|
|
425
427
|
Tabs: ({ props: e, bindings: o, emit: n }) => {
|
|
426
|
-
const [
|
|
428
|
+
const [a, i] = b(e.value, o?.value);
|
|
427
429
|
return d($e, {
|
|
428
|
-
modelValue:
|
|
430
|
+
modelValue: a ?? "",
|
|
429
431
|
items: e.items,
|
|
430
432
|
ariaLabel: e.ariaLabel,
|
|
431
|
-
"onUpdate:modelValue": (
|
|
432
|
-
i(
|
|
433
|
+
"onUpdate:modelValue": (s) => {
|
|
434
|
+
i(s), n("change");
|
|
433
435
|
}
|
|
434
436
|
});
|
|
435
437
|
},
|
|
@@ -440,7 +442,7 @@ const Je = {
|
|
|
440
442
|
flexDirection: e.direction ?? "column",
|
|
441
443
|
gap: De[e.gap ?? "md"],
|
|
442
444
|
alignItems: Ue[e.align ?? "stretch"],
|
|
443
|
-
justifyContent:
|
|
445
|
+
justifyContent: Ne[e.justify ?? "start"],
|
|
444
446
|
flexWrap: e.wrap ? "wrap" : "nowrap"
|
|
445
447
|
}
|
|
446
448
|
}, o),
|
|
@@ -461,9 +463,9 @@ const Je = {
|
|
|
461
463
|
});
|
|
462
464
|
},
|
|
463
465
|
Input: ({ props: e, bindings: o, emit: n }) => {
|
|
464
|
-
const [
|
|
466
|
+
const [a, i] = b(e.value, o?.value);
|
|
465
467
|
return d(ve, {
|
|
466
|
-
modelValue:
|
|
468
|
+
modelValue: a,
|
|
467
469
|
type: e.type,
|
|
468
470
|
placeholder: e.placeholder,
|
|
469
471
|
disabled: e.disabled,
|
|
@@ -471,56 +473,56 @@ const Je = {
|
|
|
471
473
|
invalid: e.invalid,
|
|
472
474
|
size: e.size,
|
|
473
475
|
ariaLabel: e.ariaLabel,
|
|
474
|
-
"onUpdate:modelValue": (
|
|
475
|
-
i(e.type === "number" &&
|
|
476
|
+
"onUpdate:modelValue": (s) => {
|
|
477
|
+
i(e.type === "number" && s !== "" ? Number(s) : s), n("change");
|
|
476
478
|
}
|
|
477
479
|
});
|
|
478
480
|
},
|
|
479
481
|
Select: ({ props: e, bindings: o, emit: n }) => {
|
|
480
|
-
const [
|
|
482
|
+
const [a, i] = b(e.value, o?.value);
|
|
481
483
|
return d(we, {
|
|
482
|
-
modelValue:
|
|
484
|
+
modelValue: a,
|
|
483
485
|
options: e.options,
|
|
484
486
|
placeholder: e.placeholder,
|
|
485
487
|
disabled: e.disabled,
|
|
486
488
|
search: e.search,
|
|
487
|
-
"onUpdate:modelValue": (
|
|
488
|
-
i(
|
|
489
|
+
"onUpdate:modelValue": (s) => {
|
|
490
|
+
i(s), n("change");
|
|
489
491
|
}
|
|
490
492
|
});
|
|
491
493
|
},
|
|
492
494
|
Checkbox: ({ props: e, bindings: o, emit: n }) => {
|
|
493
|
-
const [
|
|
495
|
+
const [a, i] = b(e.checked, o?.checked);
|
|
494
496
|
return d(ye, {
|
|
495
|
-
modelValue:
|
|
497
|
+
modelValue: a ?? !1,
|
|
496
498
|
label: e.label,
|
|
497
499
|
description: e.description,
|
|
498
500
|
disabled: e.disabled,
|
|
499
|
-
"onUpdate:modelValue": (
|
|
500
|
-
i(
|
|
501
|
+
"onUpdate:modelValue": (s) => {
|
|
502
|
+
i(s), n("change");
|
|
501
503
|
}
|
|
502
504
|
});
|
|
503
505
|
},
|
|
504
506
|
Switch: ({ props: e, bindings: o, emit: n }) => {
|
|
505
|
-
const [
|
|
507
|
+
const [a, i] = b(e.checked, o?.checked);
|
|
506
508
|
return d(be, {
|
|
507
|
-
modelValue:
|
|
509
|
+
modelValue: a ?? !1,
|
|
508
510
|
label: e.label,
|
|
509
511
|
disabled: e.disabled,
|
|
510
|
-
"onUpdate:modelValue": (
|
|
511
|
-
i(
|
|
512
|
+
"onUpdate:modelValue": (s) => {
|
|
513
|
+
i(s), n("change");
|
|
512
514
|
}
|
|
513
515
|
});
|
|
514
516
|
},
|
|
515
517
|
RadioGroup: ({ props: e, bindings: o, emit: n }) => {
|
|
516
|
-
const [
|
|
518
|
+
const [a, i] = b(e.value, o?.value);
|
|
517
519
|
return d(ge, {
|
|
518
|
-
modelValue:
|
|
520
|
+
modelValue: a,
|
|
519
521
|
options: e.options,
|
|
520
522
|
orientation: e.orientation,
|
|
521
523
|
disabled: e.disabled,
|
|
522
|
-
"onUpdate:modelValue": (
|
|
523
|
-
i(
|
|
524
|
+
"onUpdate:modelValue": (s) => {
|
|
525
|
+
i(s), n("change");
|
|
524
526
|
}
|
|
525
527
|
});
|
|
526
528
|
},
|
|
@@ -537,14 +539,14 @@ const Je = {
|
|
|
537
539
|
fieldWidth: e.fieldWidth,
|
|
538
540
|
direction: e.direction
|
|
539
541
|
}, o),
|
|
540
|
-
SettingsSection: ({ props: e, bindings: o, slots: n, emit:
|
|
541
|
-
const [i,
|
|
542
|
+
SettingsSection: ({ props: e, bindings: o, slots: n, emit: a }) => {
|
|
543
|
+
const [i, s] = b(e.open, o?.open);
|
|
542
544
|
return d(me, {
|
|
543
545
|
title: e.title,
|
|
544
546
|
collapsible: e.collapsible,
|
|
545
547
|
open: i,
|
|
546
548
|
"onUpdate:open": (r) => {
|
|
547
|
-
|
|
549
|
+
s(r), a("openChange");
|
|
548
550
|
}
|
|
549
551
|
}, n);
|
|
550
552
|
},
|
|
@@ -556,8 +558,8 @@ const Je = {
|
|
|
556
558
|
align: e.align
|
|
557
559
|
}, o),
|
|
558
560
|
Surface: ({ props: e, slots: o }) => d(pe, e, o),
|
|
559
|
-
Card: ({ props: e, bindings: o, slots: n, emit:
|
|
560
|
-
const [i,
|
|
561
|
+
Card: ({ props: e, bindings: o, slots: n, emit: a }) => {
|
|
562
|
+
const [i, s] = b(e.expanded, o?.expanded);
|
|
561
563
|
return d(de, {
|
|
562
564
|
title: e.title,
|
|
563
565
|
layoutType: e.layoutType,
|
|
@@ -565,7 +567,7 @@ const Je = {
|
|
|
565
567
|
expanded: i,
|
|
566
568
|
footerAlign: e.footerAlign,
|
|
567
569
|
"onUpdate:expanded": (r) => {
|
|
568
|
-
|
|
570
|
+
s(r), a("expandedChange");
|
|
569
571
|
}
|
|
570
572
|
}, n);
|
|
571
573
|
},
|
|
@@ -582,10 +584,10 @@ const Je = {
|
|
|
582
584
|
icon: C(e.icon)
|
|
583
585
|
}, o),
|
|
584
586
|
Progress: ({ props: e }) => d(re, e),
|
|
585
|
-
Badge: ({ props: e }) => d(
|
|
586
|
-
Dialog: ({ props: e, bindings: o, slots: n, emit:
|
|
587
|
-
const [i,
|
|
588
|
-
return d(
|
|
587
|
+
Badge: ({ props: e }) => d(se, { tone: e.tone }, Te(e.text)),
|
|
588
|
+
Dialog: ({ props: e, bindings: o, slots: n, emit: a }) => {
|
|
589
|
+
const [i, s] = b(e.open, o?.open);
|
|
590
|
+
return d(ae, {
|
|
589
591
|
open: i ?? !1,
|
|
590
592
|
title: e.title,
|
|
591
593
|
description: e.description,
|
|
@@ -593,7 +595,7 @@ const Je = {
|
|
|
593
595
|
width: e.width,
|
|
594
596
|
showClose: e.showClose,
|
|
595
597
|
"onUpdate:open": (r) => {
|
|
596
|
-
|
|
598
|
+
s(r), a("openChange");
|
|
597
599
|
}
|
|
598
600
|
}, n);
|
|
599
601
|
},
|
|
@@ -649,28 +651,28 @@ const Je = {
|
|
|
649
651
|
}
|
|
650
652
|
}), Ve = ["label", "title", "description", "text", "placeholder", "emptyText", "help", "ariaLabel", "valueLabel", "searchPlaceholder"];
|
|
651
653
|
function z(e, o = "") {
|
|
652
|
-
return Array.isArray(e) ? e : Object.entries(e).flatMap(([n,
|
|
654
|
+
return Array.isArray(e) ? e : Object.entries(e).flatMap(([n, a]) => m(a) ? z(a, `${o}${n}.`) : [`${o}${n}`]);
|
|
653
655
|
}
|
|
654
656
|
const m = (e) => typeof e == "object" && e !== null && !Array.isArray(e), u = (...e) => e.map((o) => "/" + String(o).replaceAll("~", "~0").replaceAll("/", "~1")).join("");
|
|
655
657
|
function _e(e, o) {
|
|
656
|
-
const n = Array.from({ length: o.length + 1 }, (
|
|
657
|
-
for (let
|
|
658
|
+
const n = Array.from({ length: o.length + 1 }, (a, i) => i);
|
|
659
|
+
for (let a = 1; a <= e.length; a++) {
|
|
658
660
|
let i = n[0];
|
|
659
|
-
n[0] =
|
|
660
|
-
for (let
|
|
661
|
-
const r = n[
|
|
662
|
-
n[
|
|
661
|
+
n[0] = a;
|
|
662
|
+
for (let s = 1; s <= o.length; s++) {
|
|
663
|
+
const r = n[s];
|
|
664
|
+
n[s] = Math.min(n[s] + 1, n[s - 1] + 1, i + (e[a - 1].toLowerCase() === o[s - 1].toLowerCase() ? 0 : 1)), i = r;
|
|
663
665
|
}
|
|
664
666
|
}
|
|
665
667
|
return n[o.length];
|
|
666
668
|
}
|
|
667
669
|
function y(e, o) {
|
|
668
|
-
let n,
|
|
670
|
+
let n, a = 1 / 0;
|
|
669
671
|
for (const i of o) {
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
+
const s = _e(e, i);
|
|
673
|
+
s < a && ([n, a] = [i, s]);
|
|
672
674
|
}
|
|
673
|
-
return n !== void 0 &&
|
|
675
|
+
return n !== void 0 && a <= Math.max(2, Math.floor(e.length / 3)) ? n : void 0;
|
|
674
676
|
}
|
|
675
677
|
const ze = ["$state", "$item", "$index", "$bindState", "$bindItem", "$cond", "$computed", "$template"], qe = (e) => m(e) && ze.some((o) => Object.hasOwn(e, o)), I = (e) => qe(e) || (Array.isArray(e) ? e.some(I) : m(e) && Object.values(e).some(I));
|
|
676
678
|
function P(e) {
|
|
@@ -694,22 +696,22 @@ class Me {
|
|
|
694
696
|
}
|
|
695
697
|
}
|
|
696
698
|
function mt(e, o = {}) {
|
|
697
|
-
const n = o.catalog ?? A,
|
|
699
|
+
const n = o.catalog ?? A, a = n.data.components, i = new Me();
|
|
698
700
|
if (!m(e))
|
|
699
|
-
return i.error({ code: "invalid_spec", path: "", message: "A spec must be a JSON object.", hint: 'Return {"root": "<key>", "elements": {...}, "state": {...}}.' }),
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
const r = Object.keys(
|
|
703
|
-
typeof e.root != "string" || e.root === "" ? i.error({ code: "missing_root", path: "/root", message: '"root" must name the top element.', hint: r.length ? v('Set "root" to one of', r) : 'Add "root" and the element it names.' }) :
|
|
704
|
-
for (const [p, f] of Object.entries(
|
|
701
|
+
return i.error({ code: "invalid_spec", path: "", message: "A spec must be a JSON object.", hint: 'Return {"root": "<key>", "elements": {...}, "state": {...}}.' }), N(i);
|
|
702
|
+
const s = m(e.elements) ? e.elements : void 0;
|
|
703
|
+
s || i.error({ code: "invalid_elements", path: "/elements", message: '"elements" must be an object keyed by element id.', hint: 'Use a flat map: {"elements": {"root": {"type": "AppRoot", "props": {}, "children": []}}}.' });
|
|
704
|
+
const r = Object.keys(s ?? {});
|
|
705
|
+
typeof e.root != "string" || e.root === "" ? i.error({ code: "missing_root", path: "/root", message: '"root" must name the top element.', hint: r.length ? v('Set "root" to one of', r) : 'Add "root" and the element it names.' }) : s && !Object.hasOwn(s, e.root) && i.error({ code: "root_not_found", path: "/root", message: `Root "${e.root}" is not in "elements".`, hint: v("Existing element keys", r) });
|
|
706
|
+
for (const [p, f] of Object.entries(s ?? {})) {
|
|
705
707
|
const w = (...g) => u("elements", p, ...g);
|
|
706
708
|
if (!m(f)) {
|
|
707
709
|
i.error({ code: "invalid_element", path: w(), elementKey: p, message: 'An element must be an object with "type", "props" and "children".' });
|
|
708
710
|
continue;
|
|
709
711
|
}
|
|
710
712
|
const h = f.type;
|
|
711
|
-
if (typeof h != "string" || !Object.hasOwn(
|
|
712
|
-
const g = typeof h == "string" ? y(h, Object.keys(
|
|
713
|
+
if (typeof h != "string" || !Object.hasOwn(a, h)) {
|
|
714
|
+
const g = typeof h == "string" ? y(h, Object.keys(a)) : void 0;
|
|
713
715
|
i.error({
|
|
714
716
|
code: "unknown_component",
|
|
715
717
|
path: w("type"),
|
|
@@ -719,11 +721,11 @@ function mt(e, o = {}) {
|
|
|
719
721
|
});
|
|
720
722
|
continue;
|
|
721
723
|
}
|
|
722
|
-
We(i, p, h,
|
|
724
|
+
We(i, p, h, a[h], f.props), Be(i, p, h, a[h], f, s);
|
|
723
725
|
}
|
|
724
726
|
const c = o.messages && z(o.messages), l = {
|
|
725
727
|
issues: i,
|
|
726
|
-
components:
|
|
728
|
+
components: a,
|
|
727
729
|
actions: [
|
|
728
730
|
...(n.schema?.builtInActions ?? []).map((p) => p.name),
|
|
729
731
|
...Object.keys(n.data.actions ?? {}),
|
|
@@ -734,15 +736,15 @@ function mt(e, o = {}) {
|
|
|
734
736
|
functions: o.functions || c ? [...o.functions ?? [], ...c ? ["t"] : []] : void 0,
|
|
735
737
|
messageKeys: c
|
|
736
738
|
};
|
|
737
|
-
return
|
|
739
|
+
return s && typeof e.root == "string" && Object.hasOwn(s, e.root) && He(l, e.root, s), N(i);
|
|
738
740
|
}
|
|
739
|
-
function We(e, o, n,
|
|
740
|
-
const
|
|
741
|
+
function We(e, o, n, a, i) {
|
|
742
|
+
const s = (...l) => u("elements", o, "props", ...l);
|
|
741
743
|
if (!m(i)) {
|
|
742
|
-
e.error({ code: "invalid_props", path:
|
|
744
|
+
e.error({ code: "invalid_props", path: s(), elementKey: o, message: '"props" must be an object.', hint: 'Use "props": {} when the component needs none.' });
|
|
743
745
|
return;
|
|
744
746
|
}
|
|
745
|
-
const r = P(
|
|
747
|
+
const r = P(a);
|
|
746
748
|
if (!r) return;
|
|
747
749
|
const c = Object.keys(r);
|
|
748
750
|
for (const [l, p] of Object.entries(i)) {
|
|
@@ -751,7 +753,7 @@ function We(e, o, n, s, i) {
|
|
|
751
753
|
const h = y(l, c);
|
|
752
754
|
e.error({
|
|
753
755
|
code: "unknown_prop",
|
|
754
|
-
path:
|
|
756
|
+
path: s(l),
|
|
755
757
|
elementKey: o,
|
|
756
758
|
message: `${n} has no prop "${l}".`,
|
|
757
759
|
hint: h ? `Did you mean "${h}"? Run "syno-pkg-land-ui describe ${n}".` : v(`${n} props`, c)
|
|
@@ -764,28 +766,28 @@ function We(e, o, n, s, i) {
|
|
|
764
766
|
for (const h of w.error.issues)
|
|
765
767
|
e.error({
|
|
766
768
|
code: "invalid_prop",
|
|
767
|
-
path:
|
|
769
|
+
path: s(l, ...h.path.map((g) => String(g))),
|
|
768
770
|
elementKey: o,
|
|
769
771
|
message: `${n}.${l}: ${h.message}`,
|
|
770
772
|
hint: Fe(h)
|
|
771
773
|
});
|
|
772
774
|
}
|
|
773
775
|
for (const l of c)
|
|
774
|
-
!Object.hasOwn(i, l) && !R(r[l]) && e.error({ code: "missing_prop", path:
|
|
776
|
+
!Object.hasOwn(i, l) && !R(r[l]) && e.error({ code: "missing_prop", path: s(l), elementKey: o, message: `${n} requires prop "${l}".`, hint: `Run "syno-pkg-land-ui describe ${n}" for its type.` });
|
|
775
777
|
}
|
|
776
778
|
function q(e, o) {
|
|
777
779
|
const n = [];
|
|
778
|
-
if (Array.isArray(o.children) && o.children.forEach((
|
|
779
|
-
typeof
|
|
780
|
+
if (Array.isArray(o.children) && o.children.forEach((a, i) => {
|
|
781
|
+
typeof a == "string" && n.push({ child: a, path: u("elements", e, "children", i) });
|
|
780
782
|
}), m(o.slots))
|
|
781
|
-
for (const [
|
|
782
|
-
Array.isArray(i) && i.forEach((
|
|
783
|
-
typeof
|
|
783
|
+
for (const [a, i] of Object.entries(o.slots))
|
|
784
|
+
Array.isArray(i) && i.forEach((s, r) => {
|
|
785
|
+
typeof s == "string" && n.push({ child: s, path: u("elements", e, "slots", a, r) });
|
|
784
786
|
});
|
|
785
787
|
return n;
|
|
786
788
|
}
|
|
787
|
-
function Be(e, o, n,
|
|
788
|
-
const r =
|
|
789
|
+
function Be(e, o, n, a, i, s) {
|
|
790
|
+
const r = a.slots ?? [], { children: c } = i;
|
|
789
791
|
if (c !== void 0 && !(Array.isArray(c) && c.every((l) => typeof l == "string")) ? e.error({ code: "invalid_children", path: u("elements", o, "children"), elementKey: o, message: '"children" must be an array of element keys.' }) : c?.length && !r.includes("default") && e.error({
|
|
790
792
|
code: "children_not_allowed",
|
|
791
793
|
path: u("elements", o, "children"),
|
|
@@ -810,8 +812,8 @@ function Be(e, o, n, s, i, a) {
|
|
|
810
812
|
});
|
|
811
813
|
}
|
|
812
814
|
for (const l of q(o, i))
|
|
813
|
-
if (!Object.hasOwn(
|
|
814
|
-
const p = y(l.child, Object.keys(
|
|
815
|
+
if (!Object.hasOwn(s, l.child)) {
|
|
816
|
+
const p = y(l.child, Object.keys(s));
|
|
815
817
|
e.error({
|
|
816
818
|
code: "missing_child",
|
|
817
819
|
path: l.path,
|
|
@@ -822,42 +824,42 @@ function Be(e, o, n, s, i, a) {
|
|
|
822
824
|
}
|
|
823
825
|
}
|
|
824
826
|
function He(e, o, n) {
|
|
825
|
-
const { issues:
|
|
827
|
+
const { issues: a } = e, i = /* @__PURE__ */ new Set(), s = (r, c, l, p) => {
|
|
826
828
|
const f = n[r];
|
|
827
829
|
if (!m(f)) return;
|
|
828
830
|
i.add(r);
|
|
829
831
|
const w = m(f.repeat);
|
|
830
832
|
Qe(e, r, f, p || w);
|
|
831
833
|
const h = f.type === "AppRoot";
|
|
832
|
-
h && l &&
|
|
834
|
+
h && l && a.error({ code: "nested_app_root", path: u("elements", r), elementKey: r, message: "AppRoot cannot be nested inside another AppRoot.", hint: "Use a single AppRoot at the top of the spec." });
|
|
833
835
|
for (const g of q(r, f))
|
|
834
836
|
if (Object.hasOwn(n, g.child)) {
|
|
835
837
|
if (c.includes(g.child)) {
|
|
836
|
-
|
|
838
|
+
a.error({ code: "cycle", path: g.path, elementKey: r, message: `"${g.child}" is its own ancestor.`, hint: "Element references must form a tree." });
|
|
837
839
|
continue;
|
|
838
840
|
}
|
|
839
|
-
|
|
841
|
+
s(g.child, [...c, g.child], l || h, p || w);
|
|
840
842
|
}
|
|
841
843
|
};
|
|
842
|
-
|
|
844
|
+
s(o, [o], !1, !1);
|
|
843
845
|
for (const r of Object.keys(n))
|
|
844
|
-
i.has(r) ||
|
|
846
|
+
i.has(r) || a.warn({ code: "orphaned_element", path: u("elements", r), elementKey: r, message: `"${r}" is not reachable from the root.`, hint: "Reference it from a parent or delete it." });
|
|
845
847
|
}
|
|
846
848
|
function Ge(e, o) {
|
|
847
849
|
let n = e;
|
|
848
|
-
for (const
|
|
849
|
-
const i =
|
|
850
|
+
for (const a of o.split("/").slice(1)) {
|
|
851
|
+
const i = a.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
850
852
|
if (Array.isArray(n) && /^\d+$/.test(i)) n = n[Number(i)];
|
|
851
853
|
else if (m(n) && Object.hasOwn(n, i)) n = n[i];
|
|
852
854
|
else return { found: !1 };
|
|
853
855
|
}
|
|
854
856
|
return { found: !0, value: n };
|
|
855
857
|
}
|
|
856
|
-
function S(e, o, n,
|
|
858
|
+
function S(e, o, n, a, { mustExist: i }) {
|
|
857
859
|
if (typeof n != "string" || !n.startsWith("/")) {
|
|
858
860
|
e.issues.error({
|
|
859
861
|
code: "invalid_state_path",
|
|
860
|
-
path:
|
|
862
|
+
path: a,
|
|
861
863
|
elementKey: o,
|
|
862
864
|
message: `State paths are JSON Pointers; got ${JSON.stringify(n)}.`,
|
|
863
865
|
hint: typeof n == "string" ? `Use "/${n.replace(/^\.?\/?/, "").replaceAll(".", "/")}".` : 'Use a string such as "/settings/enabled".'
|
|
@@ -866,42 +868,42 @@ function S(e, o, n, s, { mustExist: i }) {
|
|
|
866
868
|
}
|
|
867
869
|
i && !Ge(e.state, n).found && e.issues.warn({
|
|
868
870
|
code: "state_path_missing",
|
|
869
|
-
path:
|
|
871
|
+
path: a,
|
|
870
872
|
elementKey: o,
|
|
871
873
|
message: `State "${n}" has no initial value.`,
|
|
872
874
|
hint: `Seed it in the spec's "state", or pass the host state with --state, so the first render has a value.`
|
|
873
875
|
});
|
|
874
876
|
}
|
|
875
|
-
function $(e, o, n,
|
|
877
|
+
function $(e, o, n, a, i) {
|
|
876
878
|
if (Array.isArray(n)) {
|
|
877
|
-
n.forEach((
|
|
879
|
+
n.forEach((s, r) => $(e, o, s, a + u(r), i));
|
|
878
880
|
return;
|
|
879
881
|
}
|
|
880
882
|
if (m(n)) {
|
|
881
|
-
for (const
|
|
882
|
-
Object.hasOwn(n,
|
|
883
|
-
for (const
|
|
884
|
-
Object.hasOwn(n,
|
|
883
|
+
for (const s of ["$state", "$bindState"])
|
|
884
|
+
Object.hasOwn(n, s) && S(e, o, n[s], a + u(s), { mustExist: !0 });
|
|
885
|
+
for (const s of ["$item", "$bindItem", "$index"])
|
|
886
|
+
Object.hasOwn(n, s) && !i && e.issues.error({
|
|
885
887
|
code: "item_outside_repeat",
|
|
886
|
-
path:
|
|
888
|
+
path: a + u(s),
|
|
887
889
|
elementKey: o,
|
|
888
|
-
message: `${
|
|
890
|
+
message: `${s} only works inside an element with "repeat" or its descendants.`,
|
|
889
891
|
hint: 'Add "repeat": {"statePath": "/list"} to an ancestor, or read the value with $state.'
|
|
890
892
|
});
|
|
891
893
|
if (typeof n.$template == "string")
|
|
892
|
-
for (const
|
|
893
|
-
S(e, o,
|
|
894
|
-
typeof n.$computed == "string" && Xe(e, o, n,
|
|
895
|
-
for (const [
|
|
896
|
-
["$state", "$bindState", "$item", "$bindItem", "$index", "$template"].includes(
|
|
894
|
+
for (const s of n.$template.matchAll(/\$\{([^}]*)\}/g))
|
|
895
|
+
S(e, o, s[1], a + u("$template"), { mustExist: !0 });
|
|
896
|
+
typeof n.$computed == "string" && Xe(e, o, n, a);
|
|
897
|
+
for (const [s, r] of Object.entries(n))
|
|
898
|
+
["$state", "$bindState", "$item", "$bindItem", "$index", "$template"].includes(s) || $(e, o, r, a + u(s), i);
|
|
897
899
|
}
|
|
898
900
|
}
|
|
899
|
-
function Xe(e, o, n,
|
|
901
|
+
function Xe(e, o, n, a) {
|
|
900
902
|
const i = n.$computed;
|
|
901
903
|
if (!e.functions)
|
|
902
904
|
e.issues.warn({
|
|
903
905
|
code: "unverified_function",
|
|
904
|
-
path:
|
|
906
|
+
path: a + u("$computed"),
|
|
905
907
|
elementKey: o,
|
|
906
908
|
message: `$computed "${i}" must be registered by the host.`,
|
|
907
909
|
hint: `Pass the host function names with --functions ${i} to verify it.`
|
|
@@ -910,29 +912,29 @@ function Xe(e, o, n, s) {
|
|
|
910
912
|
const r = y(i, e.functions);
|
|
911
913
|
e.issues.error({
|
|
912
914
|
code: "unknown_function",
|
|
913
|
-
path:
|
|
915
|
+
path: a + u("$computed"),
|
|
914
916
|
elementKey: o,
|
|
915
917
|
message: `$computed "${i}" is not a host function.`,
|
|
916
918
|
hint: `${r ? `Did you mean "${r}"? ` : ""}${v("Host functions", e.functions)}`
|
|
917
919
|
});
|
|
918
920
|
}
|
|
919
921
|
if (i !== "t" || !e.messageKeys) return;
|
|
920
|
-
const
|
|
921
|
-
if (typeof
|
|
922
|
-
const r = typeof
|
|
922
|
+
const s = m(n.args) ? n.args.key : void 0;
|
|
923
|
+
if (typeof s != "string" || !e.messageKeys.includes(s)) {
|
|
924
|
+
const r = typeof s == "string" ? y(s, e.messageKeys) : void 0;
|
|
923
925
|
e.issues.error({
|
|
924
926
|
code: "missing_i18n_key",
|
|
925
|
-
path:
|
|
927
|
+
path: a + u("args", "key"),
|
|
926
928
|
elementKey: o,
|
|
927
|
-
message: `Message key ${JSON.stringify(
|
|
929
|
+
message: `Message key ${JSON.stringify(s)} is not in the message catalog.`,
|
|
928
930
|
hint: r ? `Did you mean "${r}"? Otherwise add the key to every locale.` : "Add the key to every locale, or use an existing key."
|
|
929
931
|
});
|
|
930
932
|
}
|
|
931
933
|
}
|
|
932
934
|
const Ye = ["statePath", "clearStatePath"];
|
|
933
|
-
function Qe(e, o, n,
|
|
935
|
+
function Qe(e, o, n, a) {
|
|
934
936
|
const i = (...c) => u("elements", o, ...c);
|
|
935
|
-
if ($(e, o, n.props, i("props"),
|
|
937
|
+
if ($(e, o, n.props, i("props"), a), e.messageKeys && m(n.props))
|
|
936
938
|
for (const c of Ve) {
|
|
937
939
|
const l = n.props[c];
|
|
938
940
|
typeof l == "string" && l.trim() && e.issues.warn({
|
|
@@ -943,8 +945,8 @@ function Qe(e, o, n, s) {
|
|
|
943
945
|
hint: 'Use {"$computed": "t", "args": {"key": "<message key>"}}.'
|
|
944
946
|
});
|
|
945
947
|
}
|
|
946
|
-
n.visible !== void 0 && $(e, o, n.visible, i("visible"),
|
|
947
|
-
const
|
|
948
|
+
n.visible !== void 0 && $(e, o, n.visible, i("visible"), a), m(n.repeat) && S(e, o, n.repeat.statePath, i("repeat", "statePath"), { mustExist: !0 });
|
|
949
|
+
const s = typeof n.type == "string" ? n.type : "", r = e.components[s]?.events ?? [];
|
|
948
950
|
if (m(n.on))
|
|
949
951
|
for (const [c, l] of Object.entries(n.on)) {
|
|
950
952
|
if (!r.includes(c)) {
|
|
@@ -953,19 +955,19 @@ function Qe(e, o, n, s) {
|
|
|
953
955
|
code: "unknown_event",
|
|
954
956
|
path: i("on", c),
|
|
955
957
|
elementKey: o,
|
|
956
|
-
message: `${
|
|
957
|
-
hint: p ? `Did you mean "${p}"?` : r.length ? v(`${
|
|
958
|
+
message: `${s} does not emit "${c}".`,
|
|
959
|
+
hint: p ? `Did you mean "${p}"?` : r.length ? v(`${s} events`, r) : `${s} emits no events.`
|
|
958
960
|
});
|
|
959
961
|
}
|
|
960
|
-
U(e, o, l, i("on", c),
|
|
962
|
+
U(e, o, l, i("on", c), a);
|
|
961
963
|
}
|
|
962
964
|
if (m(n.watch))
|
|
963
965
|
for (const [c, l] of Object.entries(n.watch))
|
|
964
|
-
S(e, o, c, i("watch", c), { mustExist: !1 }), U(e, o, l, i("watch", c),
|
|
966
|
+
S(e, o, c, i("watch", c), { mustExist: !1 }), U(e, o, l, i("watch", c), a);
|
|
965
967
|
}
|
|
966
|
-
function U(e, o, n,
|
|
968
|
+
function U(e, o, n, a, i) {
|
|
967
969
|
(Array.isArray(n) ? n : [n]).forEach((r, c) => {
|
|
968
|
-
const l = Array.isArray(n) ?
|
|
970
|
+
const l = Array.isArray(n) ? a + u(c) : a;
|
|
969
971
|
if (!m(r) || typeof r.action != "string") {
|
|
970
972
|
e.issues.error({ code: "invalid_action_binding", path: l, elementKey: o, message: 'An action binding is {"action": "<name>", "params": {...}}.' });
|
|
971
973
|
return;
|
|
@@ -987,7 +989,7 @@ function U(e, o, n, s, i) {
|
|
|
987
989
|
}
|
|
988
990
|
});
|
|
989
991
|
}
|
|
990
|
-
function
|
|
992
|
+
function N(e) {
|
|
991
993
|
return { valid: e.errors.length === 0, errors: e.errors, warnings: e.warnings };
|
|
992
994
|
}
|
|
993
995
|
const x = V;
|
|
@@ -1025,8 +1027,8 @@ function ft(e) {
|
|
|
1025
1027
|
}
|
|
1026
1028
|
function gt(e) {
|
|
1027
1029
|
if (!Object.hasOwn(x, e)) return;
|
|
1028
|
-
const o = x[e], n = Object.fromEntries(Object.entries(P(o) ?? {}).map(([
|
|
1029
|
-
|
|
1030
|
+
const o = x[e], n = Object.fromEntries(Object.entries(P(o) ?? {}).map(([a, i]) => [
|
|
1031
|
+
a,
|
|
1030
1032
|
{ required: !R(i), schema: Ze(i) }
|
|
1031
1033
|
]));
|
|
1032
1034
|
return {
|
|
@@ -1037,7 +1039,7 @@ function gt(e) {
|
|
|
1037
1039
|
events: o.events ?? [],
|
|
1038
1040
|
example: {
|
|
1039
1041
|
type: e,
|
|
1040
|
-
props: Object.fromEntries(Object.entries(n).filter(([,
|
|
1042
|
+
props: Object.fromEntries(Object.entries(n).filter(([, a]) => a.required).map(([a, { schema: i }]) => [a, et(i)])),
|
|
1041
1043
|
children: []
|
|
1042
1044
|
}
|
|
1043
1045
|
};
|
|
@@ -1066,35 +1068,35 @@ const O = { type: "string", pattern: "^/" }, tt = {
|
|
|
1066
1068
|
preventDefault: { type: "boolean" }
|
|
1067
1069
|
},
|
|
1068
1070
|
additionalProperties: !1
|
|
1069
|
-
},
|
|
1071
|
+
}, T = { anyOf: [{ $ref: "#/$defs/actionBinding" }, { type: "array", items: { $ref: "#/$defs/actionBinding" } }] }, E = { type: "array", items: { type: "string" } };
|
|
1070
1072
|
function nt(e, o, n) {
|
|
1071
|
-
const
|
|
1073
|
+
const a = (r) => Array.isArray(r) ? r.map(a) : !r || typeof r != "object" ? r : Object.fromEntries(Object.entries(r).map(([c, l]) => [
|
|
1072
1074
|
c,
|
|
1073
|
-
c === "$ref" && typeof l == "string" ? l.replace("#/$defs/", `#/$defs/${o}`) :
|
|
1074
|
-
])), { $defs: i, ...
|
|
1075
|
-
delete
|
|
1076
|
-
for (const [r, c] of Object.entries(i ?? {})) n[o + r] =
|
|
1077
|
-
return s
|
|
1075
|
+
c === "$ref" && typeof l == "string" ? l.replace("#/$defs/", `#/$defs/${o}`) : a(l)
|
|
1076
|
+
])), { $defs: i, ...s } = e;
|
|
1077
|
+
delete s.$schema;
|
|
1078
|
+
for (const [r, c] of Object.entries(i ?? {})) n[o + r] = a(c);
|
|
1079
|
+
return a(s);
|
|
1078
1080
|
}
|
|
1079
1081
|
function it(e, o, n) {
|
|
1080
|
-
const
|
|
1081
|
-
let
|
|
1082
|
-
if (
|
|
1083
|
-
const r = nt(t.toJSONSchema(t.object(
|
|
1084
|
-
|
|
1082
|
+
const a = P(o), i = o.slots ?? [];
|
|
1083
|
+
let s = { type: "object" };
|
|
1084
|
+
if (a) {
|
|
1085
|
+
const r = nt(t.toJSONSchema(t.object(a)), `${e}__`, n), c = r.properties;
|
|
1086
|
+
s = {
|
|
1085
1087
|
...r,
|
|
1086
1088
|
properties: Object.fromEntries(Object.entries(c).map(([l, p]) => [
|
|
1087
1089
|
l,
|
|
1088
1090
|
{ anyOf: [p, { $ref: "#/$defs/expression" }] }
|
|
1089
1091
|
]))
|
|
1090
|
-
}, r.required?.length || delete
|
|
1092
|
+
}, r.required?.length || delete s.required;
|
|
1091
1093
|
}
|
|
1092
1094
|
return {
|
|
1093
1095
|
if: { properties: { type: { const: e } } },
|
|
1094
1096
|
then: {
|
|
1095
1097
|
...o.description ? { description: o.description } : {},
|
|
1096
1098
|
properties: {
|
|
1097
|
-
props:
|
|
1099
|
+
props: s,
|
|
1098
1100
|
...i.includes("default") ? {} : { children: { maxItems: 0 } },
|
|
1099
1101
|
slots: { propertyNames: { enum: i.filter((r) => r !== "default") } },
|
|
1100
1102
|
on: { propertyNames: { enum: o.events ?? [] } }
|
|
@@ -1103,22 +1105,22 @@ function it(e, o, n) {
|
|
|
1103
1105
|
};
|
|
1104
1106
|
}
|
|
1105
1107
|
function bt(e = A) {
|
|
1106
|
-
const o = e.data.components, n = { expression: tt, actionBinding: ot },
|
|
1108
|
+
const o = e.data.components, n = { expression: tt, actionBinding: ot }, a = Object.entries(o).map(([i, s]) => it(i, s, n));
|
|
1107
1109
|
return n.element = {
|
|
1108
1110
|
type: "object",
|
|
1109
1111
|
required: ["type", "props"],
|
|
1110
1112
|
properties: {
|
|
1111
1113
|
type: { enum: Object.keys(o) },
|
|
1112
1114
|
props: { type: "object" },
|
|
1113
|
-
children:
|
|
1114
|
-
slots: { type: "object", additionalProperties:
|
|
1115
|
+
children: E,
|
|
1116
|
+
slots: { type: "object", additionalProperties: E },
|
|
1115
1117
|
visible: {},
|
|
1116
|
-
on: { type: "object", additionalProperties:
|
|
1117
|
-
watch: { type: "object", propertyNames: O, additionalProperties:
|
|
1118
|
+
on: { type: "object", additionalProperties: T },
|
|
1119
|
+
watch: { type: "object", propertyNames: O, additionalProperties: T },
|
|
1118
1120
|
repeat: { type: "object", required: ["statePath"], properties: { statePath: O, key: { type: "string" } }, additionalProperties: !1 }
|
|
1119
1121
|
},
|
|
1120
1122
|
additionalProperties: !1,
|
|
1121
|
-
allOf:
|
|
1123
|
+
allOf: a
|
|
1122
1124
|
}, {
|
|
1123
1125
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1124
1126
|
title: "Synology Package Land JSON UI spec",
|
|
@@ -1146,7 +1148,7 @@ export {
|
|
|
1146
1148
|
jt as defineCatalog,
|
|
1147
1149
|
Rt as defineRegistry,
|
|
1148
1150
|
gt as describeSynoJsonComponent,
|
|
1149
|
-
|
|
1151
|
+
Nt as jsonRenderVueSchema,
|
|
1150
1152
|
ht as listSynoJsonComponents,
|
|
1151
1153
|
pt as synoJsonAiPrompt,
|
|
1152
1154
|
Ke as synoJsonAiRules,
|