@valbuild/core 0.129.0 → 0.134.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +188 -0
- package/dist/declarations/src/index.d.ts +11 -1
- package/dist/declarations/src/initSchema.d.ts +20 -0
- package/dist/declarations/src/module.d.ts +21 -4
- package/dist/declarations/src/preview.d.ts +65 -8
- package/dist/declarations/src/render.d.ts +26 -0
- package/dist/declarations/src/schema/array.d.ts +8 -5
- package/dist/declarations/src/schema/boolean.d.ts +8 -6
- package/dist/declarations/src/schema/code.d.ts +8 -6
- package/dist/declarations/src/schema/color.d.ts +8 -6
- package/dist/declarations/src/schema/date.d.ts +8 -6
- package/dist/declarations/src/schema/datetime.d.ts +8 -6
- package/dist/declarations/src/schema/discriminatedUnion.d.ts +8 -5
- package/dist/declarations/src/schema/enum.d.ts +8 -6
- package/dist/declarations/src/schema/file.d.ts +8 -6
- package/dist/declarations/src/schema/image.d.ts +8 -6
- package/dist/declarations/src/schema/index.d.ts +31 -2
- package/dist/declarations/src/schema/keyOf.d.ts +8 -6
- package/dist/declarations/src/schema/literal.d.ts +8 -6
- package/dist/declarations/src/schema/locale.d.ts +1 -2
- package/dist/declarations/src/schema/number.d.ts +8 -6
- package/dist/declarations/src/schema/object.d.ts +18 -5
- package/dist/declarations/src/schema/record.d.ts +8 -5
- package/dist/declarations/src/schema/richtext.d.ts +8 -6
- package/dist/declarations/src/schema/route.d.ts +8 -6
- package/dist/declarations/src/schema/settings.d.ts +1 -1
- package/dist/declarations/src/schema/string.d.ts +8 -11
- package/dist/declarations/src/schema/validation/ValidationFix.d.ts +1 -1
- package/dist/declarations/src/schema/view.d.ts +197 -0
- package/dist/declarations/src/selector/index.d.ts +4 -2
- package/dist/declarations/src/selector/view.d.ts +22 -0
- package/dist/declarations/src/source/index.d.ts +2 -1
- package/dist/declarations/src/source/settings.d.ts +27 -0
- package/dist/declarations/src/source/view.d.ts +41 -0
- package/dist/declarations/src/source/viewHandle.d.ts +69 -0
- package/dist/{index-f5842720.cjs.prod.js → index-48a8f8a5.cjs.prod.js} +1281 -353
- package/dist/{index-21fd16b1.cjs.dev.js → index-85a2ffba.cjs.dev.js} +1281 -353
- package/dist/{index-06bb2832.esm.js → index-e3458565.esm.js} +1280 -354
- package/dist/valbuild-core.cjs.dev.js +3 -1
- package/dist/valbuild-core.cjs.prod.js +3 -1
- package/dist/valbuild-core.esm.js +1 -1
- package/package.json +1 -1
- package/patch/dist/valbuild-core-patch.cjs.dev.js +1 -1
- package/patch/dist/valbuild-core-patch.cjs.prod.js +1 -1
- package/patch/dist/valbuild-core-patch.esm.js +2 -2
|
@@ -413,8 +413,93 @@ var Schema = /*#__PURE__*/function () {
|
|
|
413
413
|
* For example, if you have an object schema, you must assert each key / value pair manually.
|
|
414
414
|
*/
|
|
415
415
|
}, {
|
|
416
|
-
key: "
|
|
416
|
+
key: "executePreview",
|
|
417
417
|
value:
|
|
418
|
+
/**
|
|
419
|
+
* This value's preview, and every preview below it.
|
|
420
|
+
*
|
|
421
|
+
* The default is the whole of it for a LEAF: a leaf has nothing below it, so
|
|
422
|
+
* all it can contribute is {@link PreviewNode.self}. Containers override this
|
|
423
|
+
* and recurse; object and discriminated union add nothing of their own beyond
|
|
424
|
+
* the self they inherit here, and array and record add `rows`.
|
|
425
|
+
*
|
|
426
|
+
* @param scope Which paths the caller needs a preview for. Absent means the
|
|
427
|
+
* whole module, which is what every caller passed before scoping existed.
|
|
428
|
+
* See {@link PreviewScope}: a container prunes recursion where nothing is
|
|
429
|
+
* wanted, and previews a WINDOW when its own path is not wanted but some of
|
|
430
|
+
* its items are — which is the single-visible-row case.
|
|
431
|
+
* @param selfIsReifiedByParent Set by an array or record on its DIRECT items,
|
|
432
|
+
* and by nothing else. Such an item's preview is the same closure the
|
|
433
|
+
* container is already running into {@link PreviewNode.rows}, so emitting a
|
|
434
|
+
* `self` for it as well would call the user's closure twice per row — which
|
|
435
|
+
* it did, and which the scoped-preview tests caught by counting. The flag
|
|
436
|
+
* does not travel further down: a grandchild is nobody's row.
|
|
437
|
+
*/
|
|
438
|
+
function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
439
|
+
if (selfIsReifiedByParent) {
|
|
440
|
+
return {};
|
|
441
|
+
}
|
|
442
|
+
return this.executeSelfPreview(sourcePath, src, scope);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* THIS value as a preview, at its own path — `{ self }` and nothing else.
|
|
447
|
+
*
|
|
448
|
+
* Every schema can produce one, which is the point: before this existed a
|
|
449
|
+
* value's preview was reified only by its CONTAINER, so a value with no
|
|
450
|
+
* container had none. A module root is exactly that, and `.preview(...)` on
|
|
451
|
+
* a module's own schema was therefore dead code — the studio showed the file
|
|
452
|
+
* name and nothing a developer wrote could change it. So is any field of an
|
|
453
|
+
* object, which reifies no rows.
|
|
454
|
+
*
|
|
455
|
+
* Gated on {@link PreviewScope.wants} rather than `wantsUnder`: a caller
|
|
456
|
+
* asking about a CONTAINER wants its rows, and computing a self for every
|
|
457
|
+
* descendant on the way past would run each item's closure twice.
|
|
458
|
+
*/
|
|
459
|
+
}, {
|
|
460
|
+
key: "executeSelfPreview",
|
|
461
|
+
value: function executeSelfPreview(sourcePath, src, scope) {
|
|
462
|
+
if (src === null || src === undefined) {
|
|
463
|
+
return {};
|
|
464
|
+
}
|
|
465
|
+
if (!this.declaresItemPreview()) {
|
|
466
|
+
return {};
|
|
467
|
+
}
|
|
468
|
+
if (scope !== undefined && !scope.wants(sourcePath)) {
|
|
469
|
+
return {};
|
|
470
|
+
}
|
|
471
|
+
try {
|
|
472
|
+
// NB NB: the closure is user code.
|
|
473
|
+
var item = this.executePreviewItem(src);
|
|
474
|
+
if (item === null) {
|
|
475
|
+
return {};
|
|
476
|
+
}
|
|
477
|
+
var title = item.title,
|
|
478
|
+
subtitle = item.subtitle,
|
|
479
|
+
image = item.image;
|
|
480
|
+
// Assigned into an annotated local rather than returned as a literal: a
|
|
481
|
+
// computed key widens `status` to `string`.
|
|
482
|
+
var res = {};
|
|
483
|
+
res[sourcePath] = {
|
|
484
|
+
status: "success",
|
|
485
|
+
data: {
|
|
486
|
+
self: {
|
|
487
|
+
title: title,
|
|
488
|
+
subtitle: subtitle,
|
|
489
|
+
image: image
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
return res;
|
|
494
|
+
} catch (e) {
|
|
495
|
+
var _res = {};
|
|
496
|
+
_res[sourcePath] = {
|
|
497
|
+
status: "error",
|
|
498
|
+
message: e instanceof Error ? e.message : "Unknown error"
|
|
499
|
+
};
|
|
500
|
+
return _res;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
418
503
|
/**
|
|
419
504
|
* This value AS A PREVIEW — what a container's row, a reference dropdown or
|
|
420
505
|
* a search hit shows for it. Runs the schema's own `preview` closure;
|
|
@@ -425,7 +510,9 @@ var Schema = /*#__PURE__*/function () {
|
|
|
425
510
|
* `executePreview` reifies an {@link ArrayPreview} / {@link RecordPreview}
|
|
426
511
|
* from item-level declarations.
|
|
427
512
|
*/
|
|
428
|
-
|
|
513
|
+
}, {
|
|
514
|
+
key: "executePreviewItem",
|
|
515
|
+
value: function executePreviewItem(src) {
|
|
429
516
|
return null;
|
|
430
517
|
}
|
|
431
518
|
/**
|
|
@@ -506,6 +593,241 @@ var Schema = /*#__PURE__*/function () {
|
|
|
506
593
|
|
|
507
594
|
// TODO: SourceError<"Could not determine type of Schema">
|
|
508
595
|
|
|
596
|
+
function ownKeys(e, r) {
|
|
597
|
+
var t = Object.keys(e);
|
|
598
|
+
if (Object.getOwnPropertySymbols) {
|
|
599
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
600
|
+
r && (o = o.filter(function (r) {
|
|
601
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
602
|
+
})), t.push.apply(t, o);
|
|
603
|
+
}
|
|
604
|
+
return t;
|
|
605
|
+
}
|
|
606
|
+
function _objectSpread2(e) {
|
|
607
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
608
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
609
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
610
|
+
_defineProperty(e, r, t[r]);
|
|
611
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
612
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
return e;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* THE RULE, and the only sentence that needs to be remembered:
|
|
620
|
+
*
|
|
621
|
+
* **`.describe()` is INPUT HELP and is shown wherever that field — or a
|
|
622
|
+
* record's key — is being ENTERED; `.preview()` is a NAME and is shown
|
|
623
|
+
* wherever the value is REFERRED TO rather than edited; `.render()` is
|
|
624
|
+
* LAYOUT and applies only while the field is open in front of you.**
|
|
625
|
+
*
|
|
626
|
+
* The test that settles every case: **can the reader change something here?**
|
|
627
|
+
* If yes it is a place for a description — the input beside a label, the key
|
|
628
|
+
* box in "New entry", "Rename key", "Duplicate", "New page", the key half of a
|
|
629
|
+
* reference dropdown. If no, it is a place for a preview — a list row, a
|
|
630
|
+
* reference once chosen, a search hit, a sitemap row, the heading of what you
|
|
631
|
+
* navigated to.
|
|
632
|
+
*
|
|
633
|
+
* That is why a description is plain data on the serialized schema and a
|
|
634
|
+
* preview is a closure: a description is true before any value exists and says
|
|
635
|
+
* the same thing to everyone filling the field in, and a preview cannot exist
|
|
636
|
+
* without the one value it names. So a description must never be used as a
|
|
637
|
+
* subtitle — it would repeat one sentence under every row of a list — and a
|
|
638
|
+
* preview must never be used as help text, because there is nothing to preview
|
|
639
|
+
* until after the value has been entered.
|
|
640
|
+
*
|
|
641
|
+
* None of the three substitutes for another: a field with a perfect
|
|
642
|
+
* description still previews as `#3` until someone writes the preview.
|
|
643
|
+
*/
|
|
644
|
+
/**
|
|
645
|
+
* A PREVIEW is how a VALUE is shown wherever a preview of it is needed — a row
|
|
646
|
+
* in a sortable list, a key in a reference dropdown, a search hit, a
|
|
647
|
+
* reference — which is everywhere the value is NAVIGABLE to rather than open.
|
|
648
|
+
* It is never how the field itself is edited: that is a RENDER (`render.ts`),
|
|
649
|
+
* which applies only when you are looking at the field. The two do not
|
|
650
|
+
* intersect — a schema can carry both, and each is read in its own places.
|
|
651
|
+
*
|
|
652
|
+
* A preview is declared on the schema of the VALUE being previewed:
|
|
653
|
+
*
|
|
654
|
+
* ```ts
|
|
655
|
+
* const author = s.object({ name: s.string() })
|
|
656
|
+
* .preview(({ val }) => ({ title: val.name }));
|
|
657
|
+
* const authors = s.array(author);
|
|
658
|
+
* ```
|
|
659
|
+
*
|
|
660
|
+
* The container reifies its rows by running each ITEM's preview closure — see
|
|
661
|
+
* {@link ArrayPreview} / {@link RecordPreview}. (Previews used to be declared
|
|
662
|
+
* on the container instead; a `.preview` on an array/record now previews the
|
|
663
|
+
* array/record itself as a value, for when IT is the item of something.)
|
|
664
|
+
*/
|
|
665
|
+
/**
|
|
666
|
+
* What a preview shows for one value: the user's `preview` callback returns
|
|
667
|
+
* this, and the Studio draws a row from it.
|
|
668
|
+
*
|
|
669
|
+
* NB: {@link ArrayPreview} / {@link RecordPreview} name the DATA a container
|
|
670
|
+
* previews with. The Studio also has React components called `ArrayPreview` /
|
|
671
|
+
* `RecordPreview` (the fallback rendering of an array / record field, part of
|
|
672
|
+
* the `<Type>Preview` convention in `components/Preview.tsx`). They do not
|
|
673
|
+
* collide today because no file needs both - if one ever does, alias this type
|
|
674
|
+
* at the import rather than renaming that convention.
|
|
675
|
+
*/
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* What `.preview(...)` takes, on every schema: the value's own source in, a
|
|
679
|
+
* {@link PreviewItem} out. `NonNullable` because a container skips null items
|
|
680
|
+
* rather than previewing them.
|
|
681
|
+
*
|
|
682
|
+
* Declared through method syntax deliberately (the same bivariance shape
|
|
683
|
+
* React's event handler types use): `nullable()` copies a schema's closure
|
|
684
|
+
* into the `Src | null` variant of the same class, and with a plain function
|
|
685
|
+
* type the checker cannot see that `NonNullable<Src | null>` IS
|
|
686
|
+
* `NonNullable<Src>` while `Src` is still a type parameter — every schema's
|
|
687
|
+
* `nullable()` would need a cast instead.
|
|
688
|
+
*/
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* How a CONTAINER's children preview. `parent` is the discriminant, and every
|
|
692
|
+
* consumer narrows on it rather than on the union as a whole. There is no
|
|
693
|
+
* `layout` here on purpose - how a preview is laid out is the editor's
|
|
694
|
+
* business, not the schema's.
|
|
695
|
+
*/
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Everything known about ONE path, which is two independent things.
|
|
699
|
+
*
|
|
700
|
+
* They are separate fields rather than a union because a path can have both,
|
|
701
|
+
* and that is not a corner case: `s.array(section).preview(...)` where
|
|
702
|
+
* `section` also previews is a section list that shows its rows AND names
|
|
703
|
+
* itself when it is nested in something. One of them would have had to win.
|
|
704
|
+
*
|
|
705
|
+
* - {@link self} - what THIS value is called, from its own schema's
|
|
706
|
+
* `.preview(...)`. This is the only answer for a value with no container to
|
|
707
|
+
* ask: a module root (whose `.preview` was never run before this existed) and
|
|
708
|
+
* any field of an object.
|
|
709
|
+
* - {@link rows} - what its CHILDREN are called, from the ITEM schema's
|
|
710
|
+
* `.preview(...)`, reified by the container. Kept alongside `self` rather
|
|
711
|
+
* than derived from the children's `self` entries because a list needs every
|
|
712
|
+
* row in one answer, and because an EMPTY list still has to preview as an
|
|
713
|
+
* empty list - which is a fact about the schema, not about any value.
|
|
714
|
+
*/
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Fold `incoming` into `target`, path by path. MUTATES `target`.
|
|
718
|
+
*
|
|
719
|
+
* Every `executePreview` used to copy child results across with a plain
|
|
720
|
+
* assignment, which was fine while one path held one thing. It no longer does:
|
|
721
|
+
* a container writes `rows` at its own path and its `self` arrives from the
|
|
722
|
+
* same walk, so an overwrite silently drops whichever landed first. Merging is
|
|
723
|
+
* per FIELD, and an error at a path beats any data there - a preview that threw
|
|
724
|
+
* must not be reported as a preview that is merely absent.
|
|
725
|
+
*/
|
|
726
|
+
function mergePreviewInto(target, incoming) {
|
|
727
|
+
for (var keyS in incoming) {
|
|
728
|
+
var key = keyS;
|
|
729
|
+
var next = incoming[key];
|
|
730
|
+
var current = target[key];
|
|
731
|
+
if (current === undefined || next.status === "error") {
|
|
732
|
+
target[key] = next;
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (current.status === "error" || next.status === "loading") {
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
if (current.status === "loading") {
|
|
739
|
+
target[key] = next;
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
target[key] = {
|
|
743
|
+
status: "success",
|
|
744
|
+
data: _objectSpread2(_objectSpread2({}, current.data), next.data)
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Which paths a preview is being computed FOR.
|
|
751
|
+
*
|
|
752
|
+
* `executePreview` takes a whole module, so one request has always walked every
|
|
753
|
+
* node in it and run every `preview` closure - for `handboka`, with `preview` at
|
|
754
|
+
* two nested array levels, that is every chapter and every section to serve one
|
|
755
|
+
* visible row. A scope is what makes the walk proportional to what is being
|
|
756
|
+
* looked at instead of to the project.
|
|
757
|
+
*
|
|
758
|
+
* Two questions, because a container and its items need different answers:
|
|
759
|
+
*
|
|
760
|
+
* - {@link PreviewScope.wants} - is a preview AT this exact path wanted? A
|
|
761
|
+
* container answers `true` here when the whole of it is being shown, and its
|
|
762
|
+
* preview is then computed in full.
|
|
763
|
+
* - {@link PreviewScope.wantsUnder} - could anything at or below this path be
|
|
764
|
+
* wanted? Recursion is pruned where this is `false`, and a container whose own
|
|
765
|
+
* path is not wanted but which has wanted descendants previews a WINDOW: only
|
|
766
|
+
* the items that were asked for. That is the case a single visible row is, and
|
|
767
|
+
* it is why {@link ArrayPreview} carries indices.
|
|
768
|
+
*
|
|
769
|
+
* Absent scope means the whole module, which is what every existing caller
|
|
770
|
+
* passes and what every existing caller got.
|
|
771
|
+
*/
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* A scope covering exactly `paths` and their subtrees.
|
|
775
|
+
*
|
|
776
|
+
* Compares SEGMENTS rather than string prefixes. A source path's module path is
|
|
777
|
+
* a quoted, dot-joined encoding (`?p="a".1."b"`), so `startsWith` gets the
|
|
778
|
+
* ancestor test wrong wherever a key is a prefix of a sibling key or contains a
|
|
779
|
+
* dot or a quote - `"title"` against `"titles"` being the cheapest example.
|
|
780
|
+
* Segments are parsed once here, not per comparison.
|
|
781
|
+
*/
|
|
782
|
+
function previewScope(paths) {
|
|
783
|
+
var wanted = paths.map(function (path) {
|
|
784
|
+
var _splitModuleFilePathA = splitModuleFilePathAndModulePath(path),
|
|
785
|
+
_splitModuleFilePathA2 = _slicedToArray(_splitModuleFilePathA, 2),
|
|
786
|
+
moduleFilePath = _splitModuleFilePathA2[0],
|
|
787
|
+
modulePath = _splitModuleFilePathA2[1];
|
|
788
|
+
return {
|
|
789
|
+
moduleFilePath: moduleFilePath,
|
|
790
|
+
segments: modulePath === "" ? [] : splitModulePath(modulePath)
|
|
791
|
+
};
|
|
792
|
+
});
|
|
793
|
+
var parse = function parse(path) {
|
|
794
|
+
var _splitModuleFilePathA3 = splitModuleFilePathAndModulePath(path),
|
|
795
|
+
_splitModuleFilePathA4 = _slicedToArray(_splitModuleFilePathA3, 2),
|
|
796
|
+
moduleFilePath = _splitModuleFilePathA4[0],
|
|
797
|
+
modulePath = _splitModuleFilePathA4[1];
|
|
798
|
+
return {
|
|
799
|
+
moduleFilePath: moduleFilePath,
|
|
800
|
+
segments: modulePath === "" ? [] : splitModulePath(modulePath)
|
|
801
|
+
};
|
|
802
|
+
};
|
|
803
|
+
var isPrefix = function isPrefix(prefix, of) {
|
|
804
|
+
if (prefix.length > of.length) return false;
|
|
805
|
+
for (var i = 0; i < prefix.length; i++) {
|
|
806
|
+
if (prefix[i] !== of[i]) return false;
|
|
807
|
+
}
|
|
808
|
+
return true;
|
|
809
|
+
};
|
|
810
|
+
return {
|
|
811
|
+
wants: function wants(path) {
|
|
812
|
+
var at = parse(path);
|
|
813
|
+
return wanted.some(function (entry) {
|
|
814
|
+
return entry.moduleFilePath === at.moduleFilePath && entry.segments.length === at.segments.length && isPrefix(entry.segments, at.segments);
|
|
815
|
+
});
|
|
816
|
+
},
|
|
817
|
+
wantsUnder: function wantsUnder(path) {
|
|
818
|
+
var at = parse(path);
|
|
819
|
+
return wanted.some(function (entry) {
|
|
820
|
+
return entry.moduleFilePath === at.moduleFilePath && (
|
|
821
|
+
// Either direction: a wanted path below `path` means recurse into it,
|
|
822
|
+
// and a wanted path ABOVE it means the whole subtree was asked for.
|
|
823
|
+
isPrefix(at.segments, entry.segments) || isPrefix(entry.segments, at.segments));
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// TODO: improve this so that we do not get RawString and string, only string. Are there other things?
|
|
830
|
+
|
|
509
831
|
// Identity symbols are registered in the global Symbol registry so that
|
|
510
832
|
// multiple bundled copies of @valbuild/core (e.g. the editor SPA bundle vs.
|
|
511
833
|
// the host Next.js bundle) resolve to the same Symbol instance. Without
|
|
@@ -618,28 +940,6 @@ function unsafeCreateSourcePath(path, itemKey) {
|
|
|
618
940
|
return "".concat(path).concat(Internal.ModuleFilePathSep).concat(JSON.stringify(itemKey));
|
|
619
941
|
}
|
|
620
942
|
|
|
621
|
-
function ownKeys(e, r) {
|
|
622
|
-
var t = Object.keys(e);
|
|
623
|
-
if (Object.getOwnPropertySymbols) {
|
|
624
|
-
var o = Object.getOwnPropertySymbols(e);
|
|
625
|
-
r && (o = o.filter(function (r) {
|
|
626
|
-
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
627
|
-
})), t.push.apply(t, o);
|
|
628
|
-
}
|
|
629
|
-
return t;
|
|
630
|
-
}
|
|
631
|
-
function _objectSpread2(e) {
|
|
632
|
-
for (var r = 1; r < arguments.length; r++) {
|
|
633
|
-
var t = null != arguments[r] ? arguments[r] : {};
|
|
634
|
-
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
635
|
-
_defineProperty(e, r, t[r]);
|
|
636
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
637
|
-
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
return e;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
943
|
var StringSchema = /*#__PURE__*/function (_Schema) {
|
|
644
944
|
function StringSchema(options) {
|
|
645
945
|
var _this;
|
|
@@ -670,10 +970,13 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
|
|
|
670
970
|
/**
|
|
671
971
|
* Describe this field.
|
|
672
972
|
*
|
|
673
|
-
* The description is shown
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
973
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
974
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
975
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
976
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
977
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
978
|
+
* read somewhere else. The description also travels in the serialized
|
|
979
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
677
980
|
*
|
|
678
981
|
* Pass `null` to clear a description set earlier.
|
|
679
982
|
*
|
|
@@ -1010,11 +1313,6 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1010
1313
|
* is a `render`, which travels in the serialized schema instead of through
|
|
1011
1314
|
* this pipeline.
|
|
1012
1315
|
*/
|
|
1013
|
-
}, {
|
|
1014
|
-
key: "executePreview",
|
|
1015
|
-
value: function executePreview() {
|
|
1016
|
-
return {};
|
|
1017
|
-
}
|
|
1018
1316
|
}]);
|
|
1019
1317
|
}(Schema);
|
|
1020
1318
|
var string = function string(options) {
|
|
@@ -1047,10 +1345,13 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1047
1345
|
/**
|
|
1048
1346
|
* Describe this field.
|
|
1049
1347
|
*
|
|
1050
|
-
* The description is shown
|
|
1051
|
-
*
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1348
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
1349
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
1350
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
1351
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
1352
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
1353
|
+
* read somewhere else. The description also travels in the serialized
|
|
1354
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
1054
1355
|
*
|
|
1055
1356
|
* Pass `null` to clear a description set earlier.
|
|
1056
1357
|
*
|
|
@@ -1362,7 +1663,7 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1362
1663
|
}
|
|
1363
1664
|
}, {
|
|
1364
1665
|
key: "executePreview",
|
|
1365
|
-
value: function executePreview(sourcePath, src, scope) {
|
|
1666
|
+
value: function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
1366
1667
|
var res = {};
|
|
1367
1668
|
if (src === null) {
|
|
1368
1669
|
return res;
|
|
@@ -1379,11 +1680,14 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1379
1680
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
1380
1681
|
continue;
|
|
1381
1682
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1683
|
+
mergePreviewInto(res, this.items[_key3]["executePreview"](subPath, itemSrc, scope));
|
|
1684
|
+
}
|
|
1685
|
+
// An object reifies no rows of its own, so the only thing it adds is what
|
|
1686
|
+
// IT is called — which nothing else can supply for a field of an object.
|
|
1687
|
+
// Its own items are NOT rows, so the flag stops here rather than travelling
|
|
1688
|
+
// down with the recursion above.
|
|
1689
|
+
if (!selfIsReifiedByParent) {
|
|
1690
|
+
mergePreviewInto(res, this.executeSelfPreview(sourcePath, src, scope));
|
|
1387
1691
|
}
|
|
1388
1692
|
return res;
|
|
1389
1693
|
}
|
|
@@ -1424,10 +1728,13 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1424
1728
|
/**
|
|
1425
1729
|
* Describe this field.
|
|
1426
1730
|
*
|
|
1427
|
-
* The description is shown
|
|
1428
|
-
*
|
|
1429
|
-
*
|
|
1430
|
-
*
|
|
1731
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
1732
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
1733
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
1734
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
1735
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
1736
|
+
* read somewhere else. The description also travels in the serialized
|
|
1737
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
1431
1738
|
*
|
|
1432
1739
|
* Pass `null` to clear a description set earlier.
|
|
1433
1740
|
*
|
|
@@ -1586,7 +1893,7 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1586
1893
|
}
|
|
1587
1894
|
}, {
|
|
1588
1895
|
key: "executePreview",
|
|
1589
|
-
value: function executePreview(sourcePath, src, scope) {
|
|
1896
|
+
value: function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
1590
1897
|
var res = {};
|
|
1591
1898
|
if (src === null) {
|
|
1592
1899
|
return res;
|
|
@@ -1601,11 +1908,10 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1601
1908
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
1602
1909
|
continue;
|
|
1603
1910
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1911
|
+
mergePreviewInto(res,
|
|
1912
|
+
// `true`: this item is a ROW, and its preview is the closure reified
|
|
1913
|
+
// into `rows` below. See `executePreview` on `Schema`.
|
|
1914
|
+
this.item["executePreview"](subPath, itemSrc, scope, true));
|
|
1609
1915
|
}
|
|
1610
1916
|
// The rows preview comes from the ITEM schema's own `preview` — the
|
|
1611
1917
|
// container just runs it per row. Asked as a fact rather than by running
|
|
@@ -1652,13 +1958,29 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1652
1958
|
};
|
|
1653
1959
|
}
|
|
1654
1960
|
}
|
|
1655
|
-
|
|
1961
|
+
var rows = {};
|
|
1962
|
+
rows[sourcePath] = {
|
|
1656
1963
|
status: "success",
|
|
1657
1964
|
data: {
|
|
1658
|
-
|
|
1659
|
-
|
|
1965
|
+
rows: {
|
|
1966
|
+
parent: "array",
|
|
1967
|
+
items: items
|
|
1968
|
+
}
|
|
1660
1969
|
}
|
|
1661
1970
|
};
|
|
1971
|
+
mergePreviewInto(res, rows);
|
|
1972
|
+
}
|
|
1973
|
+
// ...and what the LIST ITSELF is called, which is a different closure on a
|
|
1974
|
+
// different schema: `s.array(section.preview(...)).preview(...)` previews
|
|
1975
|
+
// its rows AND names itself for when it is nested in something. Merged
|
|
1976
|
+
// rather than assigned, or one of the two would win. See `PreviewNode`.
|
|
1977
|
+
//
|
|
1978
|
+
// Unless this list is itself a ROW of an outer array or record, which has
|
|
1979
|
+
// already run this very closure to reify it — a container both PASSES the
|
|
1980
|
+
// flag to its items and RECEIVES it as one, and honouring only the first
|
|
1981
|
+
// half ran `s.array(s.array(x).preview(...))`'s closure twice per row.
|
|
1982
|
+
if (!selfIsReifiedByParent) {
|
|
1983
|
+
mergePreviewInto(res, this.executeSelfPreview(sourcePath, src, scope));
|
|
1662
1984
|
}
|
|
1663
1985
|
return res;
|
|
1664
1986
|
}
|
|
@@ -1761,10 +2083,13 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1761
2083
|
/**
|
|
1762
2084
|
* Describe this field.
|
|
1763
2085
|
*
|
|
1764
|
-
* The description is shown
|
|
1765
|
-
*
|
|
1766
|
-
*
|
|
1767
|
-
*
|
|
2086
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
2087
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
2088
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
2089
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
2090
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
2091
|
+
* read somewhere else. The description also travels in the serialized
|
|
2092
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
1768
2093
|
*
|
|
1769
2094
|
* Pass `null` to clear a description set earlier.
|
|
1770
2095
|
*
|
|
@@ -1953,11 +2278,6 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1953
2278
|
description: this.description
|
|
1954
2279
|
};
|
|
1955
2280
|
}
|
|
1956
|
-
}, {
|
|
1957
|
-
key: "executePreview",
|
|
1958
|
-
value: function executePreview() {
|
|
1959
|
-
return {};
|
|
1960
|
-
}
|
|
1961
2281
|
}]);
|
|
1962
2282
|
}(Schema);
|
|
1963
2283
|
var literal = function literal(value) {
|
|
@@ -2013,10 +2333,13 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2013
2333
|
/**
|
|
2014
2334
|
* Describe this field.
|
|
2015
2335
|
*
|
|
2016
|
-
* The description is shown
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
2019
|
-
*
|
|
2336
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
2337
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
2338
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
2339
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
2340
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
2341
|
+
* read somewhere else. The description also travels in the serialized
|
|
2342
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
2020
2343
|
*
|
|
2021
2344
|
* Pass `null` to clear a description set earlier.
|
|
2022
2345
|
*
|
|
@@ -2469,7 +2792,7 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2469
2792
|
}
|
|
2470
2793
|
}, {
|
|
2471
2794
|
key: "executePreview",
|
|
2472
|
-
value: function executePreview(sourcePath, src, scope) {
|
|
2795
|
+
value: function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
2473
2796
|
var res = {};
|
|
2474
2797
|
if (src === null) {
|
|
2475
2798
|
return res;
|
|
@@ -2494,10 +2817,16 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2494
2817
|
return false;
|
|
2495
2818
|
});
|
|
2496
2819
|
if (thisSchema) {
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2820
|
+
// The variant owns the path — see the note on `executeCustomValidateAt`.
|
|
2821
|
+
// It contributes a `self` of its own here; the union's comes second and
|
|
2822
|
+
// wins, because `executePreviewItem` already encodes the precedence (the
|
|
2823
|
+
// union's own closure if it has one, else the matched variant's) and
|
|
2824
|
+
// there must not be a second copy of that rule.
|
|
2825
|
+
// The variant SHARES this path, so the flag passes straight through: a
|
|
2826
|
+
// union that is a row is a variant that is a row.
|
|
2827
|
+
mergePreviewInto(res, thisSchema["executePreview"](sourcePath, src, scope, selfIsReifiedByParent));
|
|
2828
|
+
if (!selfIsReifiedByParent) {
|
|
2829
|
+
mergePreviewInto(res, this.executeSelfPreview(sourcePath, src, scope));
|
|
2501
2830
|
}
|
|
2502
2831
|
return res;
|
|
2503
2832
|
}
|
|
@@ -2510,8 +2839,8 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2510
2839
|
}]);
|
|
2511
2840
|
}(Schema);
|
|
2512
2841
|
var discriminatedUnion = function discriminatedUnion(key) {
|
|
2513
|
-
for (var _len = arguments.length, objects = new Array(_len > 1 ? _len - 1 : 0),
|
|
2514
|
-
objects[
|
|
2842
|
+
for (var _len = arguments.length, objects = new Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) {
|
|
2843
|
+
objects[_key2 - 1] = arguments[_key2];
|
|
2515
2844
|
}
|
|
2516
2845
|
return new DiscriminatedUnionSchema(key, objects);
|
|
2517
2846
|
};
|
|
@@ -3488,10 +3817,13 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
|
|
|
3488
3817
|
/**
|
|
3489
3818
|
* Describe this field.
|
|
3490
3819
|
*
|
|
3491
|
-
* The description is shown
|
|
3492
|
-
*
|
|
3493
|
-
*
|
|
3494
|
-
*
|
|
3820
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
3821
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
3822
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
3823
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
3824
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
3825
|
+
* read somewhere else. The description also travels in the serialized
|
|
3826
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
3495
3827
|
*
|
|
3496
3828
|
* Pass `null` to clear a description set earlier.
|
|
3497
3829
|
*
|
|
@@ -3872,11 +4204,6 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
|
|
|
3872
4204
|
description: this.description
|
|
3873
4205
|
};
|
|
3874
4206
|
}
|
|
3875
|
-
}, {
|
|
3876
|
-
key: "executePreview",
|
|
3877
|
-
value: function executePreview() {
|
|
3878
|
-
return {};
|
|
3879
|
-
}
|
|
3880
4207
|
}]);
|
|
3881
4208
|
}(Schema);
|
|
3882
4209
|
|
|
@@ -3932,10 +4259,13 @@ var RouteSchema = /*#__PURE__*/function (_Schema) {
|
|
|
3932
4259
|
/**
|
|
3933
4260
|
* Describe this field.
|
|
3934
4261
|
*
|
|
3935
|
-
* The description is shown
|
|
3936
|
-
*
|
|
3937
|
-
*
|
|
3938
|
-
*
|
|
4262
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
4263
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
4264
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
4265
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
4266
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
4267
|
+
* read somewhere else. The description also travels in the serialized
|
|
4268
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
3939
4269
|
*
|
|
3940
4270
|
* Pass `null` to clear a description set earlier.
|
|
3941
4271
|
*
|
|
@@ -4164,11 +4494,6 @@ var RouteSchema = /*#__PURE__*/function (_Schema) {
|
|
|
4164
4494
|
description: this.description
|
|
4165
4495
|
};
|
|
4166
4496
|
}
|
|
4167
|
-
}, {
|
|
4168
|
-
key: "executePreview",
|
|
4169
|
-
value: function executePreview() {
|
|
4170
|
-
return {};
|
|
4171
|
-
}
|
|
4172
4497
|
}]);
|
|
4173
4498
|
}(Schema);
|
|
4174
4499
|
var route = function route(options) {
|
|
@@ -4201,10 +4526,13 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
|
|
|
4201
4526
|
/**
|
|
4202
4527
|
* Describe this field.
|
|
4203
4528
|
*
|
|
4204
|
-
* The description is shown
|
|
4205
|
-
*
|
|
4206
|
-
*
|
|
4207
|
-
*
|
|
4529
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
4530
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
4531
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
4532
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
4533
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
4534
|
+
* read somewhere else. The description also travels in the serialized
|
|
4535
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
4208
4536
|
*
|
|
4209
4537
|
* Pass `null` to clear a description set earlier.
|
|
4210
4538
|
*
|
|
@@ -4850,11 +5178,6 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
|
|
|
4850
5178
|
description: this.description
|
|
4851
5179
|
};
|
|
4852
5180
|
}
|
|
4853
|
-
}, {
|
|
4854
|
-
key: "executePreview",
|
|
4855
|
-
value: function executePreview() {
|
|
4856
|
-
return {};
|
|
4857
|
-
}
|
|
4858
5181
|
}]);
|
|
4859
5182
|
}(Schema);
|
|
4860
5183
|
var richtext = function richtext(options) {
|
|
@@ -5369,10 +5692,13 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5369
5692
|
/**
|
|
5370
5693
|
* Describe this field.
|
|
5371
5694
|
*
|
|
5372
|
-
* The description is shown
|
|
5373
|
-
*
|
|
5374
|
-
*
|
|
5375
|
-
*
|
|
5695
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
5696
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
5697
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
5698
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
5699
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
5700
|
+
* read somewhere else. The description also travels in the serialized
|
|
5701
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
5376
5702
|
*
|
|
5377
5703
|
* Pass `null` to clear a description set earlier.
|
|
5378
5704
|
*
|
|
@@ -6165,7 +6491,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6165
6491
|
}
|
|
6166
6492
|
}, {
|
|
6167
6493
|
key: "executePreview",
|
|
6168
|
-
value: function executePreview(sourcePath, src, scope) {
|
|
6494
|
+
value: function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
6169
6495
|
var res = {};
|
|
6170
6496
|
if (src === null) {
|
|
6171
6497
|
return res;
|
|
@@ -6190,11 +6516,10 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6190
6516
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
6191
6517
|
continue;
|
|
6192
6518
|
}
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
}
|
|
6519
|
+
mergePreviewInto(res,
|
|
6520
|
+
// `true`: this item is a ROW, and its preview is the closure reified
|
|
6521
|
+
// into `rows` below. See `executePreview` on `Schema`.
|
|
6522
|
+
this.item["executePreview"](subPath, itemSrc, scope, true));
|
|
6198
6523
|
}
|
|
6199
6524
|
// The entries preview comes from the ITEM schema's own `preview` — the
|
|
6200
6525
|
// container just runs it per entry. Asked as a fact rather than by running
|
|
@@ -6206,7 +6531,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6206
6531
|
var items = [];
|
|
6207
6532
|
for (var _i2 = 0, _Object$entries = Object.entries(src); _i2 < _Object$entries.length; _i2++) {
|
|
6208
6533
|
var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
|
|
6209
|
-
|
|
6534
|
+
_key3 = _Object$entries$_i[0],
|
|
6210
6535
|
val = _Object$entries$_i[1];
|
|
6211
6536
|
if (isJson(val)) {
|
|
6212
6537
|
continue; // as above: nothing to select from an un-loaded entry
|
|
@@ -6214,7 +6539,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6214
6539
|
if (val === null || val === undefined) {
|
|
6215
6540
|
continue;
|
|
6216
6541
|
}
|
|
6217
|
-
if (window !== null && !window.wantsUnder(unsafeCreateSourcePath(sourcePath,
|
|
6542
|
+
if (window !== null && !window.wantsUnder(unsafeCreateSourcePath(sourcePath, _key3))) {
|
|
6218
6543
|
continue;
|
|
6219
6544
|
}
|
|
6220
6545
|
// Per KEY, not per record: the closure is user code, and one entry whose
|
|
@@ -6226,26 +6551,37 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6226
6551
|
var title = _item.title,
|
|
6227
6552
|
subtitle = _item.subtitle,
|
|
6228
6553
|
image = _item.image;
|
|
6229
|
-
items.push([
|
|
6554
|
+
items.push([_key3, {
|
|
6230
6555
|
title: title,
|
|
6231
6556
|
subtitle: subtitle,
|
|
6232
6557
|
image: image
|
|
6233
6558
|
}]);
|
|
6234
6559
|
}
|
|
6235
6560
|
} catch (e) {
|
|
6236
|
-
res[unsafeCreateSourcePath(sourcePath,
|
|
6561
|
+
res[unsafeCreateSourcePath(sourcePath, _key3)] = {
|
|
6237
6562
|
status: "error",
|
|
6238
6563
|
message: e instanceof Error ? e.message : "Unknown error"
|
|
6239
6564
|
};
|
|
6240
6565
|
}
|
|
6241
6566
|
}
|
|
6242
|
-
|
|
6567
|
+
var rows = {};
|
|
6568
|
+
rows[sourcePath] = {
|
|
6243
6569
|
status: "success",
|
|
6244
6570
|
data: {
|
|
6245
|
-
|
|
6246
|
-
|
|
6571
|
+
rows: {
|
|
6572
|
+
parent: "record",
|
|
6573
|
+
items: items
|
|
6574
|
+
}
|
|
6247
6575
|
}
|
|
6248
6576
|
};
|
|
6577
|
+
mergePreviewInto(res, rows);
|
|
6578
|
+
}
|
|
6579
|
+
// ...and what the RECORD ITSELF is called — a different closure on a
|
|
6580
|
+
// different schema. Skipped when this record is itself a ROW, whose
|
|
6581
|
+
// closure the outer container has already run. See the same block in
|
|
6582
|
+
// `array`, and `PreviewNode`.
|
|
6583
|
+
if (!selfIsReifiedByParent) {
|
|
6584
|
+
mergePreviewInto(res, this.executeSelfPreview(sourcePath, src, scope));
|
|
6249
6585
|
}
|
|
6250
6586
|
return res;
|
|
6251
6587
|
}
|
|
@@ -6370,6 +6706,16 @@ function record(keyOrSchema, schema) {
|
|
|
6370
6706
|
* written without removing the key.
|
|
6371
6707
|
*/
|
|
6372
6708
|
|
|
6709
|
+
/**
|
|
6710
|
+
* How the Studio behaves for the people editing this project.
|
|
6711
|
+
*
|
|
6712
|
+
* Not how it looks — that is {@link ThemeSettingsSource} — and not one person's
|
|
6713
|
+
* own preferences, which stay in their browser. This is the project's word on
|
|
6714
|
+
* what its editors are offered, which is why it is content: a team that has
|
|
6715
|
+
* decided something about the way they work should not need a developer and a
|
|
6716
|
+
* deploy to say so.
|
|
6717
|
+
*/
|
|
6718
|
+
|
|
6373
6719
|
/**
|
|
6374
6720
|
* How the Studio looks in this project.
|
|
6375
6721
|
*
|
|
@@ -6737,11 +7083,6 @@ var LocaleSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6737
7083
|
description: this.description
|
|
6738
7084
|
};
|
|
6739
7085
|
}
|
|
6740
|
-
}, {
|
|
6741
|
-
key: "executePreview",
|
|
6742
|
-
value: function executePreview() {
|
|
6743
|
-
return {};
|
|
6744
|
-
}
|
|
6745
7086
|
}]);
|
|
6746
7087
|
}(Schema);
|
|
6747
7088
|
|
|
@@ -6786,10 +7127,13 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6786
7127
|
/**
|
|
6787
7128
|
* Describe this field.
|
|
6788
7129
|
*
|
|
6789
|
-
* The description is shown
|
|
6790
|
-
*
|
|
6791
|
-
*
|
|
6792
|
-
*
|
|
7130
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
7131
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
7132
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
7133
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
7134
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
7135
|
+
* read somewhere else. The description also travels in the serialized
|
|
7136
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
6793
7137
|
*
|
|
6794
7138
|
* Pass `null` to clear a description set earlier.
|
|
6795
7139
|
*
|
|
@@ -6963,11 +7307,6 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6963
7307
|
description: this.description
|
|
6964
7308
|
};
|
|
6965
7309
|
}
|
|
6966
|
-
}, {
|
|
6967
|
-
key: "executePreview",
|
|
6968
|
-
value: function executePreview() {
|
|
6969
|
-
return {};
|
|
6970
|
-
}
|
|
6971
7310
|
}]);
|
|
6972
7311
|
}(Schema);
|
|
6973
7312
|
var _boolean = function _boolean() {
|
|
@@ -7480,10 +7819,13 @@ var ColorSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7480
7819
|
/**
|
|
7481
7820
|
* Describe this field.
|
|
7482
7821
|
*
|
|
7483
|
-
* The description is shown
|
|
7484
|
-
*
|
|
7485
|
-
*
|
|
7486
|
-
*
|
|
7822
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
7823
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
7824
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
7825
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
7826
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
7827
|
+
* read somewhere else. The description also travels in the serialized
|
|
7828
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
7487
7829
|
*
|
|
7488
7830
|
* Pass `null` to clear a description set earlier.
|
|
7489
7831
|
*
|
|
@@ -7707,11 +8049,6 @@ var ColorSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7707
8049
|
description: this.description
|
|
7708
8050
|
};
|
|
7709
8051
|
}
|
|
7710
|
-
}, {
|
|
7711
|
-
key: "executePreview",
|
|
7712
|
-
value: function executePreview() {
|
|
7713
|
-
return {};
|
|
7714
|
-
}
|
|
7715
8052
|
}]);
|
|
7716
8053
|
}(Schema);
|
|
7717
8054
|
var color = function color(options) {
|
|
@@ -7762,10 +8099,13 @@ var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7762
8099
|
/**
|
|
7763
8100
|
* Describe this field.
|
|
7764
8101
|
*
|
|
7765
|
-
* The description is shown
|
|
7766
|
-
*
|
|
7767
|
-
*
|
|
7768
|
-
*
|
|
8102
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
8103
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
8104
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
8105
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
8106
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
8107
|
+
* read somewhere else. The description also travels in the serialized
|
|
8108
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
7769
8109
|
*
|
|
7770
8110
|
* Pass `null` to clear a description set earlier.
|
|
7771
8111
|
*
|
|
@@ -7978,12 +8318,6 @@ var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7978
8318
|
description: this.description
|
|
7979
8319
|
};
|
|
7980
8320
|
}
|
|
7981
|
-
}, {
|
|
7982
|
-
key: "executePreview",
|
|
7983
|
-
value: function executePreview() {
|
|
7984
|
-
// A leaf: nothing below it to preview.
|
|
7985
|
-
return {};
|
|
7986
|
-
}
|
|
7987
8321
|
}]);
|
|
7988
8322
|
}(Schema);
|
|
7989
8323
|
|
|
@@ -8323,7 +8657,7 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8323
8657
|
}
|
|
8324
8658
|
}, {
|
|
8325
8659
|
key: "executePreview",
|
|
8326
|
-
value: function executePreview(sourcePath, src, scope) {
|
|
8660
|
+
value: function executePreview(sourcePath, src, scope, selfIsReifiedByParent) {
|
|
8327
8661
|
var res = {};
|
|
8328
8662
|
if (src === null) {
|
|
8329
8663
|
return res;
|
|
@@ -8337,11 +8671,14 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8337
8671
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
8338
8672
|
continue;
|
|
8339
8673
|
}
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8674
|
+
mergePreviewInto(res, this.items[_key4]["executePreview"](subPath, itemSrc, scope));
|
|
8675
|
+
}
|
|
8676
|
+
// An object reifies no rows of its own, so the only thing it adds is what
|
|
8677
|
+
// IT is called — which nothing else can supply for a field of an object.
|
|
8678
|
+
// Its own items are NOT rows, so the flag stops here rather than travelling
|
|
8679
|
+
// down with the recursion above.
|
|
8680
|
+
if (!selfIsReifiedByParent) {
|
|
8681
|
+
mergePreviewInto(res, this.executeSelfPreview(sourcePath, src, scope));
|
|
8345
8682
|
}
|
|
8346
8683
|
return res;
|
|
8347
8684
|
}
|
|
@@ -8404,6 +8741,9 @@ function settings() {
|
|
|
8404
8741
|
dir: THEME_LOGO_DIRECTORY
|
|
8405
8742
|
}).nullable().describe("The project's own mark, shown where Val's is in the Studio. A square-ish mark rather than a wordmark: the slot is 32px wide.")
|
|
8406
8743
|
}),
|
|
8744
|
+
studio: new SettingsSchema({
|
|
8745
|
+
tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it.")
|
|
8746
|
+
}),
|
|
8407
8747
|
locales: new SettingsSchema({
|
|
8408
8748
|
// Nullable because the source type is, and because the Studio writes
|
|
8409
8749
|
// `null` for every sibling the first time a section is created.
|
|
@@ -8453,6 +8793,317 @@ function localesSectionErrors(src) {
|
|
|
8453
8793
|
return errors;
|
|
8454
8794
|
}
|
|
8455
8795
|
|
|
8796
|
+
/**
|
|
8797
|
+
* Type-level-only slot carrying the SOURCE TYPE of the module a view names.
|
|
8798
|
+
*
|
|
8799
|
+
* Optional, and that is what makes the marker writable: `{ view: "/foo.val.ts" }`
|
|
8800
|
+
* is a plain literal, and an optional symbol-keyed property costs the author
|
|
8801
|
+
* nothing to satisfy. It exists so the read side can say WHAT is behind the
|
|
8802
|
+
* pointer — `ValView<FooSrc>` rather than `ValView<unknown>` — without the
|
|
8803
|
+
* author having to write a type they do not have.
|
|
8804
|
+
*/
|
|
8805
|
+
|
|
8806
|
+
/**
|
|
8807
|
+
* The source of a view field: a pointer to another module, and nothing else.
|
|
8808
|
+
*
|
|
8809
|
+
* Written as a plain object, like media and for the same reason — the same
|
|
8810
|
+
* value has to work in a `.val.ts` and in a `*.val.json` entry, and a literal
|
|
8811
|
+
* survives the static extraction that a constructor call does not. See
|
|
8812
|
+
* `architecture/media.md`.
|
|
8813
|
+
*
|
|
8814
|
+
* `Id` is the target's module file path as a LITERAL type, inferred from the
|
|
8815
|
+
* module handed to `s.view(...)`. So the path autocompletes at the call site,
|
|
8816
|
+
* and a source naming a different module than its schema does is a type error.
|
|
8817
|
+
*
|
|
8818
|
+
* Nothing decides "this is a view" by looking at the value; the SCHEMA does
|
|
8819
|
+
* (`type === "view"`). {@link isValViewSource} exists for the few places that have
|
|
8820
|
+
* a value and no schema, and is not the normal way to ask.
|
|
8821
|
+
*/
|
|
8822
|
+
|
|
8823
|
+
/**
|
|
8824
|
+
* Is this value shaped like a view marker?
|
|
8825
|
+
*
|
|
8826
|
+
* A shape test, not an identity: `view` is a reserved object key
|
|
8827
|
+
* (`ObjectSchemaProps`), so no ordinary object source can take this shape — but
|
|
8828
|
+
* hand-written JSON can, which is why validation checks the value against the
|
|
8829
|
+
* schema rather than trusting it.
|
|
8830
|
+
*/
|
|
8831
|
+
function isValViewSource(value) {
|
|
8832
|
+
return _typeof(value) === "object" && value !== null && !Array.isArray(value) && "view" in value && typeof value.view === "string";
|
|
8833
|
+
}
|
|
8834
|
+
|
|
8835
|
+
/** The source type of the module a selector points at. */
|
|
8836
|
+
|
|
8837
|
+
/**
|
|
8838
|
+
* A field that points at ANOTHER module, for the Val editor's benefit.
|
|
8839
|
+
*
|
|
8840
|
+
* The source is `{ view: "/other.val.ts" }` — a pointer, and nothing else. The
|
|
8841
|
+
* module it names keeps its own source, its own patches, its own validation and
|
|
8842
|
+
* its own address; this field puts a row on THIS module's screen that an editor
|
|
8843
|
+
* clicks through to it.
|
|
8844
|
+
*
|
|
8845
|
+
* Two type parameters, each earning its place:
|
|
8846
|
+
*
|
|
8847
|
+
* - `Id` — the target's module file path as a literal, so the author writes
|
|
8848
|
+
* `{ view: "/other.val.ts" }` with autocomplete, and naming a different module
|
|
8849
|
+
* than the schema does is a type error rather than a validation error.
|
|
8850
|
+
* - `T` — the target's source type, carried on a phantom slot so the READ side
|
|
8851
|
+
* can say `ValView<T>` rather than `ValView<unknown>`. Nothing reads it yet;
|
|
8852
|
+
* it is here so that resolving a view through `useVal` can be added without
|
|
8853
|
+
* changing what is stored.
|
|
8854
|
+
*/
|
|
8855
|
+
var ValViewSchema = /*#__PURE__*/function (_Schema) {
|
|
8856
|
+
function ValViewSchema(moduleFilePath) {
|
|
8857
|
+
var _this;
|
|
8858
|
+
var valModule = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
8859
|
+
var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
8860
|
+
var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
8861
|
+
var description = arguments.length > 4 ? arguments[4] : undefined;
|
|
8862
|
+
var renderInput = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
|
|
8863
|
+
_classCallCheck(this, ValViewSchema);
|
|
8864
|
+
_this = _callSuper(this, ValViewSchema);
|
|
8865
|
+
_this.moduleFilePath = moduleFilePath;
|
|
8866
|
+
_this.valModule = valModule;
|
|
8867
|
+
_this.isReadonly = isReadonly;
|
|
8868
|
+
_this.isHidden = isHidden;
|
|
8869
|
+
_this.description = description;
|
|
8870
|
+
_this.renderInput = renderInput;
|
|
8871
|
+
return _this;
|
|
8872
|
+
}
|
|
8873
|
+
|
|
8874
|
+
/**
|
|
8875
|
+
* Describe this field.
|
|
8876
|
+
*
|
|
8877
|
+
* Shown next to the field's label in the Val editor — here, the place to say
|
|
8878
|
+
* WHY the other module is on this screen, since an editor who follows the row
|
|
8879
|
+
* is about to change content that other pages use too.
|
|
8880
|
+
*
|
|
8881
|
+
* @example
|
|
8882
|
+
* import otherVal from "./other.val"; // another module
|
|
8883
|
+
* const schema = s.object({
|
|
8884
|
+
* shared: s.view(otherVal).describe("Shared by every page"),
|
|
8885
|
+
* title: s.string(),
|
|
8886
|
+
* });
|
|
8887
|
+
* export default c.define("/example.val.ts", schema, {
|
|
8888
|
+
* shared: { view: "/other.val.ts" },
|
|
8889
|
+
* title: "Hello",
|
|
8890
|
+
* });
|
|
8891
|
+
*/
|
|
8892
|
+
_inherits(ValViewSchema, _Schema);
|
|
8893
|
+
return _createClass(ValViewSchema, [{
|
|
8894
|
+
key: "describe",
|
|
8895
|
+
value: function describe(description) {
|
|
8896
|
+
return new ValViewSchema(this.moduleFilePath, this.valModule, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined, this.renderInput);
|
|
8897
|
+
}
|
|
8898
|
+
|
|
8899
|
+
/**
|
|
8900
|
+
* The stored pointer must name the module the SCHEMA names.
|
|
8901
|
+
*
|
|
8902
|
+
* It cannot disagree in a `.val.ts` — the source type is the literal path, so
|
|
8903
|
+
* a mismatch does not compile. It can disagree in hand-written JSON (a
|
|
8904
|
+
* `.jsonValues()` entry, an external record), which is what this is for.
|
|
8905
|
+
*/
|
|
8906
|
+
}, {
|
|
8907
|
+
key: "executeValidate",
|
|
8908
|
+
value: function executeValidate(path, src) {
|
|
8909
|
+
if (!isValViewSource(src)) {
|
|
8910
|
+
return _defineProperty({}, path, [{
|
|
8911
|
+
message: "Expected a view pointer ({ view: \"".concat(this.moduleFilePath, "\" }), got '").concat(src === null ? "null" : _typeof(src), "'"),
|
|
8912
|
+
value: src,
|
|
8913
|
+
fixes: ["view:check-module"]
|
|
8914
|
+
}]);
|
|
8915
|
+
}
|
|
8916
|
+
if (src.view !== this.moduleFilePath) {
|
|
8917
|
+
return _defineProperty({}, path, [{
|
|
8918
|
+
message: "This view points at '".concat(src.view, "', but its schema says '").concat(this.moduleFilePath, "'"),
|
|
8919
|
+
value: src,
|
|
8920
|
+
fixes: ["view:check-module"]
|
|
8921
|
+
}]);
|
|
8922
|
+
}
|
|
8923
|
+
return false;
|
|
8924
|
+
}
|
|
8925
|
+
}, {
|
|
8926
|
+
key: "executeCustomValidateAt",
|
|
8927
|
+
value: function executeCustomValidateAt(_path, _src) {
|
|
8928
|
+
return [];
|
|
8929
|
+
}
|
|
8930
|
+
}, {
|
|
8931
|
+
key: "executeAssert",
|
|
8932
|
+
value: function executeAssert(path, src) {
|
|
8933
|
+
if (isValViewSource(src)) {
|
|
8934
|
+
return {
|
|
8935
|
+
success: true,
|
|
8936
|
+
data: src
|
|
8937
|
+
};
|
|
8938
|
+
}
|
|
8939
|
+
return {
|
|
8940
|
+
success: false,
|
|
8941
|
+
errors: _defineProperty({}, path, [{
|
|
8942
|
+
message: "Expected a view pointer ({ view: string }), got '".concat(src === null ? "null" : _typeof(src), "'"),
|
|
8943
|
+
typeError: true
|
|
8944
|
+
}])
|
|
8945
|
+
};
|
|
8946
|
+
}
|
|
8947
|
+
|
|
8948
|
+
/**
|
|
8949
|
+
* Not available: a view points at a module, and `null` is not a module.
|
|
8950
|
+
* Throws if called.
|
|
8951
|
+
*
|
|
8952
|
+
* @example
|
|
8953
|
+
* import otherVal from "./other.val"; // another module
|
|
8954
|
+
* // `s.view(otherVal).nullable()` throws — a view is never nullable.
|
|
8955
|
+
* const schema = s.object({ shared: s.view(otherVal), title: s.string() });
|
|
8956
|
+
* export default c.define("/example.val.ts", schema, {
|
|
8957
|
+
* shared: { view: "/other.val.ts" },
|
|
8958
|
+
* title: "Hello",
|
|
8959
|
+
* });
|
|
8960
|
+
*/
|
|
8961
|
+
}, {
|
|
8962
|
+
key: "nullable",
|
|
8963
|
+
value: function nullable() {
|
|
8964
|
+
throw new Error("s.view() cannot be nullable: it points at a module");
|
|
8965
|
+
}
|
|
8966
|
+
|
|
8967
|
+
/**
|
|
8968
|
+
* Marks the row read-only.
|
|
8969
|
+
*
|
|
8970
|
+
* The view's OWN flag, and it says nothing about the module it names: that
|
|
8971
|
+
* module has its own `readonly`, which is what governs editing once an
|
|
8972
|
+
* editor is there. A view is a link rather than an editor, so this changes
|
|
8973
|
+
* nothing about the row today — it exists because every schema has it, and
|
|
8974
|
+
* because a view that renders its target inline would need it.
|
|
8975
|
+
*
|
|
8976
|
+
* @example
|
|
8977
|
+
* import otherVal from "./other.val"; // another module
|
|
8978
|
+
* const schema = s.object({
|
|
8979
|
+
* shared: s.view(otherVal).readonly(),
|
|
8980
|
+
* title: s.string(),
|
|
8981
|
+
* });
|
|
8982
|
+
* export default c.define("/example.val.ts", schema, {
|
|
8983
|
+
* shared: { view: "/other.val.ts" },
|
|
8984
|
+
* title: "Hello",
|
|
8985
|
+
* });
|
|
8986
|
+
*/
|
|
8987
|
+
}, {
|
|
8988
|
+
key: "readonly",
|
|
8989
|
+
value: function readonly() {
|
|
8990
|
+
var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
8991
|
+
return new ValViewSchema(this.moduleFilePath, this.valModule, isReadonly, this.isHidden, this.description, this.renderInput);
|
|
8992
|
+
}
|
|
8993
|
+
|
|
8994
|
+
/**
|
|
8995
|
+
* Hide the ROW in the editor.
|
|
8996
|
+
*
|
|
8997
|
+
* The view's OWN flag, and it is the only thing that decides whether the row
|
|
8998
|
+
* is drawn — a view whose TARGET is hidden is still shown, and still leads
|
|
8999
|
+
* there. That is the point of it: a module that many modules `keyOf` into is
|
|
9000
|
+
* noise in the nav and belongs on exactly one page, so it is hidden from the
|
|
9001
|
+
* listing and reached through the view that puts it where it belongs.
|
|
9002
|
+
*
|
|
9003
|
+
* @example
|
|
9004
|
+
* import otherVal from "./other.val"; // another module
|
|
9005
|
+
* const schema = s.object({
|
|
9006
|
+
* shared: s.view(otherVal).hidden(),
|
|
9007
|
+
* title: s.string(),
|
|
9008
|
+
* });
|
|
9009
|
+
* export default c.define("/example.val.ts", schema, {
|
|
9010
|
+
* shared: { view: "/other.val.ts" },
|
|
9011
|
+
* title: "Hello",
|
|
9012
|
+
* });
|
|
9013
|
+
*/
|
|
9014
|
+
}, {
|
|
9015
|
+
key: "hidden",
|
|
9016
|
+
value: function hidden() {
|
|
9017
|
+
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
9018
|
+
return new ValViewSchema(this.moduleFilePath, this.valModule, this.isReadonly, isHidden, this.description, this.renderInput);
|
|
9019
|
+
}
|
|
9020
|
+
|
|
9021
|
+
/**
|
|
9022
|
+
* How this field is laid out in the editor. Static configuration, not a
|
|
9023
|
+
* callback — see `render.ts`.
|
|
9024
|
+
*
|
|
9025
|
+
* @example
|
|
9026
|
+
* import otherVal from "./other.val"; // another module
|
|
9027
|
+
* const schema = s.object({
|
|
9028
|
+
* shared: s.view(otherVal).render({ as: "inline" }),
|
|
9029
|
+
* title: s.string(),
|
|
9030
|
+
* });
|
|
9031
|
+
* export default c.define("/example.val.ts", schema, {
|
|
9032
|
+
* shared: { view: "/other.val.ts" },
|
|
9033
|
+
* title: "Hello",
|
|
9034
|
+
* });
|
|
9035
|
+
*/
|
|
9036
|
+
}, {
|
|
9037
|
+
key: "render",
|
|
9038
|
+
value: function render(input) {
|
|
9039
|
+
return new ValViewSchema(this.moduleFilePath, this.valModule, this.isReadonly, this.isHidden, this.description, input);
|
|
9040
|
+
}
|
|
9041
|
+
}, {
|
|
9042
|
+
key: "executeSerialize",
|
|
9043
|
+
value: function executeSerialize() {
|
|
9044
|
+
var _this$renderInput;
|
|
9045
|
+
return {
|
|
9046
|
+
type: "view",
|
|
9047
|
+
render: (_this$renderInput = this.renderInput) !== null && _this$renderInput !== void 0 ? _this$renderInput : undefined,
|
|
9048
|
+
opt: false,
|
|
9049
|
+
moduleFilePath: this.moduleFilePath,
|
|
9050
|
+
readonly: this.isReadonly,
|
|
9051
|
+
hidden: this.isHidden,
|
|
9052
|
+
description: this.description
|
|
9053
|
+
};
|
|
9054
|
+
}
|
|
9055
|
+
}, {
|
|
9056
|
+
key: "executePreview",
|
|
9057
|
+
value: function executePreview() {
|
|
9058
|
+
return {};
|
|
9059
|
+
}
|
|
9060
|
+
}]);
|
|
9061
|
+
}(Schema);
|
|
9062
|
+
|
|
9063
|
+
/**
|
|
9064
|
+
* Point at another module, so the Val editor shows a way into it from here.
|
|
9065
|
+
*
|
|
9066
|
+
* A view stores a pointer and nothing else: the module it names keeps its own
|
|
9067
|
+
* source, patches, validation and address, and an editor reaches it by clicking
|
|
9068
|
+
* through rather than by hunting for it. It is there so content that has to live
|
|
9069
|
+
* in its own module — a `keyOf` target, shared settings, a route-keyed record —
|
|
9070
|
+
* can still be found from the page it belongs to.
|
|
9071
|
+
*
|
|
9072
|
+
* Reading it in consuming code gives you a pointer with no fields on it. Read
|
|
9073
|
+
* the module it names directly instead.
|
|
9074
|
+
*
|
|
9075
|
+
* @example
|
|
9076
|
+
* import otherVal from "./other.val"; // another module
|
|
9077
|
+
* const schema = s.object({ shared: s.view(otherVal), title: s.string() });
|
|
9078
|
+
* export default c.define("/example.val.ts", schema, {
|
|
9079
|
+
* shared: { view: "/other.val.ts" },
|
|
9080
|
+
* title: "Hello",
|
|
9081
|
+
* });
|
|
9082
|
+
*/
|
|
9083
|
+
var view = function view(valModule) {
|
|
9084
|
+
var path = getValPath(valModule);
|
|
9085
|
+
if (!path) {
|
|
9086
|
+
throw new Error("s.view() must be given a Val module");
|
|
9087
|
+
}
|
|
9088
|
+
return new ValViewSchema(path, valModule);
|
|
9089
|
+
};
|
|
9090
|
+
|
|
9091
|
+
/**
|
|
9092
|
+
* The brand that says "this is a module", carrying the module's own id.
|
|
9093
|
+
*
|
|
9094
|
+
* `Id` is inferred from {@link define}'s first argument, so a module's PATH is
|
|
9095
|
+
* in its type. That is what lets `s.view(fooVal)` produce a schema whose source
|
|
9096
|
+
* type is the literal `{ view: "/foo.val.ts" }` — the path autocompletes at the
|
|
9097
|
+
* call site, and a source that names a different module than the schema does is
|
|
9098
|
+
* a type error rather than something validation has to catch later.
|
|
9099
|
+
*
|
|
9100
|
+
* Defaulted to `string` so every `ValModule<T>` written without it keeps
|
|
9101
|
+
* meaning what it did. The property is covariant, so a module with a known id
|
|
9102
|
+
* is still assignable everywhere `ValModule<T>` is expected.
|
|
9103
|
+
*/
|
|
9104
|
+
|
|
9105
|
+
/** A module's own path, read back off its type. */
|
|
9106
|
+
|
|
8456
9107
|
/**
|
|
8457
9108
|
* What may be WRITTEN as an external record's source, on top of the marker.
|
|
8458
9109
|
*
|
|
@@ -8472,6 +9123,17 @@ function localesSectionErrors(src) {
|
|
|
8472
9123
|
function define(id,
|
|
8473
9124
|
// TODO: `/${string}`
|
|
8474
9125
|
schema, source) {
|
|
9126
|
+
// A module cannot BE a view of another module. `s.view()` stores nothing, so
|
|
9127
|
+
// the module's whole source would be `undefined` — which type-checks, because
|
|
9128
|
+
// `undefined` is a `SelectorSource`, and then fails everywhere downstream that
|
|
9129
|
+
// expects a module to have source. A view is a field of a module, never the
|
|
9130
|
+
// module. Thrown rather than typed: making the `schema` parameter conditional
|
|
9131
|
+
// on T would put it in a non-inferable position and break inference for every
|
|
9132
|
+
// other schema. `extractValModules` reports what this throws as a module
|
|
9133
|
+
// error, which is where a developer will look.
|
|
9134
|
+
if (schema instanceof ValViewSchema) {
|
|
9135
|
+
throw Error("Cannot define '".concat(id, "' as a view: s.view() shows another module and stores nothing, so it cannot be a module's own schema. Put it in an s.object({ ... }) field instead."));
|
|
9136
|
+
}
|
|
8475
9137
|
return _defineProperty(_defineProperty(_defineProperty({}, GetSource, source), GetSchema, schema), Path, id);
|
|
8476
9138
|
}
|
|
8477
9139
|
function getSource(valModule) {
|
|
@@ -8581,10 +9243,25 @@ function resolvePath(path, valModule, schema) {
|
|
|
8581
9243
|
if (_typeof(resolvedSource) !== "object" && !Array.isArray(resolvedSource)) {
|
|
8582
9244
|
throw Error("Schema type error: expected source to be type of record, but got ".concat(_typeof(resolvedSource)));
|
|
8583
9245
|
}
|
|
8584
|
-
|
|
9246
|
+
// PRESENCE, not truthiness. An entry that exists and is falsy is an
|
|
9247
|
+
// entry: `null` for a declared key nobody has written yet, but also `""`,
|
|
9248
|
+
// `0` and `false` in any record at all. Testing the value made every one
|
|
9249
|
+
// of those report as a key the record does not have, so nothing could
|
|
9250
|
+
// resolve them — not the Studio, not the language server, not a fix.
|
|
9251
|
+
//
|
|
9252
|
+
// A record source that is itself `null` keeps resolving as `null`, one
|
|
9253
|
+
// part per level, the way the object branch below does: the path still
|
|
9254
|
+
// names a real place in the schema, and the caller wants the schema
|
|
9255
|
+
// there in order to say that nothing is written yet.
|
|
9256
|
+
//
|
|
9257
|
+
// `hasOwnProperty`, never `in`: `in` walks the prototype chain, so
|
|
9258
|
+
// `"toString"` would resolve on every record and hand back
|
|
9259
|
+
// `Object.prototype.toString` as if it were Source. Same reason
|
|
9260
|
+
// `patch/json.ts` guards every key it reads.
|
|
9261
|
+
if (resolvedSource !== null && !Object.prototype.hasOwnProperty.call(resolvedSource, part)) {
|
|
8585
9262
|
throw Error("Invalid path: record source did not have key ".concat(part, " from path: ").concat(path));
|
|
8586
9263
|
}
|
|
8587
|
-
resolvedSource = resolvedSource[part];
|
|
9264
|
+
resolvedSource = resolvedSource === null ? resolvedSource : resolvedSource[part];
|
|
8588
9265
|
resolvedSchema = resolvedSchema instanceof RecordSchema ? (_resolvedSchema2 = resolvedSchema) === null || _resolvedSchema2 === void 0 ? void 0 : _resolvedSchema2["item"] : resolvedSchema.item;
|
|
8589
9266
|
// A `.jsonValues()` entry value is a lazily-loaded JsonSource marker. We
|
|
8590
9267
|
// can resolve the entry itself (schema is now `item`), but we cannot
|
|
@@ -8786,7 +9463,15 @@ function safeResolvePath(path, valModule, schema) {
|
|
|
8786
9463
|
}
|
|
8787
9464
|
};
|
|
8788
9465
|
}
|
|
8789
|
-
|
|
9466
|
+
// A `null` record keeps resolving as `null`, as the object branch below
|
|
9467
|
+
// does — see the same note in `resolvePath`. Without it, indexing `null`
|
|
9468
|
+
// threw a TypeError out of the function whose whole point is not to
|
|
9469
|
+
// throw.
|
|
9470
|
+
//
|
|
9471
|
+
// Own properties only. Testing `resolvedSource[part] === undefined` let
|
|
9472
|
+
// an inherited name through — `"toString"` is not undefined on any
|
|
9473
|
+
// object — so the walk continued into `Object.prototype`.
|
|
9474
|
+
if (resolvedSource !== null && !Object.prototype.hasOwnProperty.call(resolvedSource, part)) {
|
|
8790
9475
|
return {
|
|
8791
9476
|
v: {
|
|
8792
9477
|
status: "source-undefined",
|
|
@@ -8796,7 +9481,7 @@ function safeResolvePath(path, valModule, schema) {
|
|
|
8796
9481
|
}
|
|
8797
9482
|
};
|
|
8798
9483
|
}
|
|
8799
|
-
resolvedSource = resolvedSource[part];
|
|
9484
|
+
resolvedSource = resolvedSource === null ? resolvedSource : resolvedSource[part];
|
|
8800
9485
|
resolvedSchema = resolvedSchema instanceof RecordSchema ? (_resolvedSchema4 = resolvedSchema) === null || _resolvedSchema4 === void 0 ? void 0 : _resolvedSchema4["item"] : resolvedSchema.item;
|
|
8801
9486
|
// jsonValues entry: cannot descend deeper until the backing `*.val.json`
|
|
8802
9487
|
// content is loaded into the source tree.
|
|
@@ -9055,10 +9740,13 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9055
9740
|
/**
|
|
9056
9741
|
* Describe this field.
|
|
9057
9742
|
*
|
|
9058
|
-
* The description is shown
|
|
9059
|
-
*
|
|
9060
|
-
*
|
|
9061
|
-
*
|
|
9743
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
9744
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
9745
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
9746
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
9747
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
9748
|
+
* read somewhere else. The description also travels in the serialized
|
|
9749
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
9062
9750
|
*
|
|
9063
9751
|
* Pass `null` to clear a description set earlier.
|
|
9064
9752
|
*
|
|
@@ -9282,11 +9970,6 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9282
9970
|
description: this.description
|
|
9283
9971
|
};
|
|
9284
9972
|
}
|
|
9285
|
-
}, {
|
|
9286
|
-
key: "executePreview",
|
|
9287
|
-
value: function executePreview() {
|
|
9288
|
-
return {};
|
|
9289
|
-
}
|
|
9290
9973
|
}]);
|
|
9291
9974
|
}(Schema);
|
|
9292
9975
|
var number = function number(options) {
|
|
@@ -9399,10 +10082,13 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9399
10082
|
/**
|
|
9400
10083
|
* Describe this field.
|
|
9401
10084
|
*
|
|
9402
|
-
* The description is shown
|
|
9403
|
-
*
|
|
9404
|
-
*
|
|
9405
|
-
*
|
|
10085
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
10086
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
10087
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
10088
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
10089
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
10090
|
+
* read somewhere else. The description also travels in the serialized
|
|
10091
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
9406
10092
|
*
|
|
9407
10093
|
* Pass `null` to clear a description set earlier.
|
|
9408
10094
|
*
|
|
@@ -9684,11 +10370,6 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9684
10370
|
description: this.description
|
|
9685
10371
|
};
|
|
9686
10372
|
}
|
|
9687
|
-
}, {
|
|
9688
|
-
key: "executePreview",
|
|
9689
|
-
value: function executePreview() {
|
|
9690
|
-
return {};
|
|
9691
|
-
}
|
|
9692
10373
|
}]);
|
|
9693
10374
|
}(Schema);
|
|
9694
10375
|
var keyOf = function keyOf(valModule) {
|
|
@@ -9745,10 +10426,13 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9745
10426
|
/**
|
|
9746
10427
|
* Describe this field.
|
|
9747
10428
|
*
|
|
9748
|
-
* The description is shown
|
|
9749
|
-
*
|
|
9750
|
-
*
|
|
9751
|
-
*
|
|
10429
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
10430
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
10431
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
10432
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
10433
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
10434
|
+
* read somewhere else. The description also travels in the serialized
|
|
10435
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
9752
10436
|
*
|
|
9753
10437
|
* Pass `null` to clear a description set earlier.
|
|
9754
10438
|
*
|
|
@@ -10089,11 +10773,6 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10089
10773
|
description: this.description
|
|
10090
10774
|
};
|
|
10091
10775
|
}
|
|
10092
|
-
}, {
|
|
10093
|
-
key: "executePreview",
|
|
10094
|
-
value: function executePreview() {
|
|
10095
|
-
return {};
|
|
10096
|
-
}
|
|
10097
10776
|
}]);
|
|
10098
10777
|
}(Schema);
|
|
10099
10778
|
|
|
@@ -10186,10 +10865,13 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10186
10865
|
/**
|
|
10187
10866
|
* Describe this field.
|
|
10188
10867
|
*
|
|
10189
|
-
* The description is shown
|
|
10190
|
-
*
|
|
10191
|
-
*
|
|
10192
|
-
*
|
|
10868
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
10869
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
10870
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
10871
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
10872
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
10873
|
+
* read somewhere else. The description also travels in the serialized
|
|
10874
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
10193
10875
|
*
|
|
10194
10876
|
* Pass `null` to clear a description set earlier.
|
|
10195
10877
|
*
|
|
@@ -10434,11 +11116,6 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10434
11116
|
description: this.description
|
|
10435
11117
|
};
|
|
10436
11118
|
}
|
|
10437
|
-
}, {
|
|
10438
|
-
key: "executePreview",
|
|
10439
|
-
value: function executePreview() {
|
|
10440
|
-
return {};
|
|
10441
|
-
}
|
|
10442
11119
|
}]);
|
|
10443
11120
|
}(Schema);
|
|
10444
11121
|
var date = function date(options) {
|
|
@@ -10471,10 +11148,13 @@ var DateTimeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10471
11148
|
/**
|
|
10472
11149
|
* Describe this field.
|
|
10473
11150
|
*
|
|
10474
|
-
* The description is shown
|
|
10475
|
-
*
|
|
10476
|
-
*
|
|
10477
|
-
*
|
|
11151
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
11152
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
11153
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
11154
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
11155
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
11156
|
+
* read somewhere else. The description also travels in the serialized
|
|
11157
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
10478
11158
|
*
|
|
10479
11159
|
* Pass `null` to clear a description set earlier.
|
|
10480
11160
|
*
|
|
@@ -10774,11 +11454,6 @@ var DateTimeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10774
11454
|
description: this.description
|
|
10775
11455
|
};
|
|
10776
11456
|
}
|
|
10777
|
-
}, {
|
|
10778
|
-
key: "executePreview",
|
|
10779
|
-
value: function executePreview() {
|
|
10780
|
-
return {};
|
|
10781
|
-
}
|
|
10782
11457
|
}]);
|
|
10783
11458
|
}(Schema);
|
|
10784
11459
|
var datetime = function datetime(options) {
|
|
@@ -10825,10 +11500,13 @@ var CodeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
10825
11500
|
/**
|
|
10826
11501
|
* Describe this field.
|
|
10827
11502
|
*
|
|
10828
|
-
* The description is shown
|
|
10829
|
-
*
|
|
10830
|
-
*
|
|
10831
|
-
*
|
|
11503
|
+
* The description is INPUT HELP: it is shown where this field's value is
|
|
11504
|
+
* entered — beside its input in the Val editor, and for a record's key
|
|
11505
|
+
* schema in every form that asks for a key — so it is where you say what an
|
|
11506
|
+
* editor needs to know to fill it in RIGHT, which the field name cannot
|
|
11507
|
+
* carry. It is not a name for the value: that is `.preview(...)`, and it is
|
|
11508
|
+
* read somewhere else. The description also travels in the serialized
|
|
11509
|
+
* schema, which is what the AI assistant and the MCP tools read.
|
|
10832
11510
|
*
|
|
10833
11511
|
* Pass `null` to clear a description set earlier.
|
|
10834
11512
|
*
|
|
@@ -11019,11 +11697,6 @@ var CodeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
11019
11697
|
description: this.description
|
|
11020
11698
|
};
|
|
11021
11699
|
}
|
|
11022
|
-
}, {
|
|
11023
|
-
key: "executePreview",
|
|
11024
|
-
value: function executePreview() {
|
|
11025
|
-
return {};
|
|
11026
|
-
}
|
|
11027
11700
|
}]);
|
|
11028
11701
|
}(Schema);
|
|
11029
11702
|
var code = function code(options) {
|
|
@@ -11150,6 +11823,7 @@ function initSchema() {
|
|
|
11150
11823
|
image: image,
|
|
11151
11824
|
literal: literal,
|
|
11152
11825
|
keyOf: keyOf,
|
|
11826
|
+
view: view,
|
|
11153
11827
|
record: record,
|
|
11154
11828
|
file: file,
|
|
11155
11829
|
fileset: fileset,
|
|
@@ -11657,6 +12331,185 @@ function resolveSettingsModule(schemas) {
|
|
|
11657
12331
|
};
|
|
11658
12332
|
}
|
|
11659
12333
|
|
|
12334
|
+
/**
|
|
12335
|
+
* Every module a schema points at with `s.view(...)`, at any depth.
|
|
12336
|
+
*
|
|
12337
|
+
* A GENERIC walk over the serialized schema rather than a switch over the
|
|
12338
|
+
* container types, and that is deliberate: a schema can hold another schema in
|
|
12339
|
+
* places an enumeration keeps forgetting — a richtext's `a` and `img` options
|
|
12340
|
+
* each carry one, and a discriminated union's variants are an array of them.
|
|
12341
|
+
* Missing a nesting site here means missing a cycle, and a missed cycle is the
|
|
12342
|
+
* failure this check exists to prevent.
|
|
12343
|
+
*/
|
|
12344
|
+
function viewTargetsOf(schema) {
|
|
12345
|
+
var targets = [];
|
|
12346
|
+
var seen = new Set();
|
|
12347
|
+
function walk(node) {
|
|
12348
|
+
if (_typeof(node) !== "object" || node === null) {
|
|
12349
|
+
return;
|
|
12350
|
+
}
|
|
12351
|
+
// A serialized schema is a tree, but guard anyway: this runs over data the
|
|
12352
|
+
// walk does not own, and a cycle here would hang module extraction.
|
|
12353
|
+
if (seen.has(node)) {
|
|
12354
|
+
return;
|
|
12355
|
+
}
|
|
12356
|
+
seen.add(node);
|
|
12357
|
+
if (Array.isArray(node)) {
|
|
12358
|
+
var _iterator = result._createForOfIteratorHelper(node),
|
|
12359
|
+
_step;
|
|
12360
|
+
try {
|
|
12361
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
12362
|
+
var item = _step.value;
|
|
12363
|
+
walk(item);
|
|
12364
|
+
}
|
|
12365
|
+
} catch (err) {
|
|
12366
|
+
_iterator.e(err);
|
|
12367
|
+
} finally {
|
|
12368
|
+
_iterator.f();
|
|
12369
|
+
}
|
|
12370
|
+
return;
|
|
12371
|
+
}
|
|
12372
|
+
var record = node;
|
|
12373
|
+
if (record["type"] === "view") {
|
|
12374
|
+
var target = record["moduleFilePath"];
|
|
12375
|
+
if (typeof target === "string") {
|
|
12376
|
+
targets.push(target);
|
|
12377
|
+
}
|
|
12378
|
+
// A view schema holds nothing else worth walking.
|
|
12379
|
+
return;
|
|
12380
|
+
}
|
|
12381
|
+
for (var _i = 0, _Object$values = Object.values(record); _i < _Object$values.length; _i++) {
|
|
12382
|
+
var value = _Object$values[_i];
|
|
12383
|
+
walk(value);
|
|
12384
|
+
}
|
|
12385
|
+
}
|
|
12386
|
+
walk(schema);
|
|
12387
|
+
return targets;
|
|
12388
|
+
}
|
|
12389
|
+
|
|
12390
|
+
/**
|
|
12391
|
+
* The cycles in a project's views: `A → B → A`, and `A → A`.
|
|
12392
|
+
*
|
|
12393
|
+
* Each cycle is returned once, as the modules in it in order, rotated so it
|
|
12394
|
+
* starts at the lexicographically smallest — otherwise the same cycle would be
|
|
12395
|
+
* reported once per module it passes through, worded differently each time.
|
|
12396
|
+
*/
|
|
12397
|
+
function findViewCycles(schemas) {
|
|
12398
|
+
var edges = new Map();
|
|
12399
|
+
for (var _i2 = 0, _Object$entries = Object.entries(schemas); _i2 < _Object$entries.length; _i2++) {
|
|
12400
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
|
|
12401
|
+
moduleFilePath = _Object$entries$_i[0],
|
|
12402
|
+
schema = _Object$entries$_i[1];
|
|
12403
|
+
edges.set(moduleFilePath, viewTargetsOf(schema));
|
|
12404
|
+
}
|
|
12405
|
+
var cycles = [];
|
|
12406
|
+
var found = new Set();
|
|
12407
|
+
var done = new Set();
|
|
12408
|
+
var stack = [];
|
|
12409
|
+
var onStack = new Set();
|
|
12410
|
+
function visit(moduleFilePath) {
|
|
12411
|
+
var _edges$get;
|
|
12412
|
+
if (done.has(moduleFilePath)) {
|
|
12413
|
+
return;
|
|
12414
|
+
}
|
|
12415
|
+
if (onStack.has(moduleFilePath)) {
|
|
12416
|
+
var cycle = stack.slice(stack.indexOf(moduleFilePath));
|
|
12417
|
+
var key = canonical(cycle);
|
|
12418
|
+
if (!found.has(key)) {
|
|
12419
|
+
found.add(key);
|
|
12420
|
+
cycles.push(rotate(cycle));
|
|
12421
|
+
}
|
|
12422
|
+
return;
|
|
12423
|
+
}
|
|
12424
|
+
stack.push(moduleFilePath);
|
|
12425
|
+
onStack.add(moduleFilePath);
|
|
12426
|
+
var _iterator2 = result._createForOfIteratorHelper((_edges$get = edges.get(moduleFilePath)) !== null && _edges$get !== void 0 ? _edges$get : []),
|
|
12427
|
+
_step2;
|
|
12428
|
+
try {
|
|
12429
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
12430
|
+
var target = _step2.value;
|
|
12431
|
+
// A target that is not a module of this project is a different error —
|
|
12432
|
+
// the view names something that does not exist — and is reported where
|
|
12433
|
+
// the field is, not here.
|
|
12434
|
+
if (edges.has(target)) {
|
|
12435
|
+
visit(target);
|
|
12436
|
+
}
|
|
12437
|
+
}
|
|
12438
|
+
} catch (err) {
|
|
12439
|
+
_iterator2.e(err);
|
|
12440
|
+
} finally {
|
|
12441
|
+
_iterator2.f();
|
|
12442
|
+
}
|
|
12443
|
+
stack.pop();
|
|
12444
|
+
onStack["delete"](moduleFilePath);
|
|
12445
|
+
done.add(moduleFilePath);
|
|
12446
|
+
}
|
|
12447
|
+
var _iterator3 = result._createForOfIteratorHelper(edges.keys()),
|
|
12448
|
+
_step3;
|
|
12449
|
+
try {
|
|
12450
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
12451
|
+
var _moduleFilePath = _step3.value;
|
|
12452
|
+
visit(_moduleFilePath);
|
|
12453
|
+
}
|
|
12454
|
+
} catch (err) {
|
|
12455
|
+
_iterator3.e(err);
|
|
12456
|
+
} finally {
|
|
12457
|
+
_iterator3.f();
|
|
12458
|
+
}
|
|
12459
|
+
return cycles;
|
|
12460
|
+
}
|
|
12461
|
+
function rotate(cycle) {
|
|
12462
|
+
var at = 0;
|
|
12463
|
+
for (var i = 1; i < cycle.length; i++) {
|
|
12464
|
+
if (cycle[i] < cycle[at]) {
|
|
12465
|
+
at = i;
|
|
12466
|
+
}
|
|
12467
|
+
}
|
|
12468
|
+
return [].concat(_toConsumableArray(cycle.slice(at)), _toConsumableArray(cycle.slice(0, at)));
|
|
12469
|
+
}
|
|
12470
|
+
function canonical(cycle) {
|
|
12471
|
+
return rotate(cycle).join(" -> ");
|
|
12472
|
+
}
|
|
12473
|
+
|
|
12474
|
+
/**
|
|
12475
|
+
* A cycle of views, as one error per module in it.
|
|
12476
|
+
*
|
|
12477
|
+
* Per module rather than once, because a developer opens ONE of them and the
|
|
12478
|
+
* error has to be there when they do. Every copy names the whole cycle, so it
|
|
12479
|
+
* reads the same wherever it is found.
|
|
12480
|
+
*/
|
|
12481
|
+
function viewCycleErrors(schemas) {
|
|
12482
|
+
var errors = [];
|
|
12483
|
+
var _iterator4 = result._createForOfIteratorHelper(findViewCycles(schemas)),
|
|
12484
|
+
_step4;
|
|
12485
|
+
try {
|
|
12486
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
12487
|
+
var cycle = _step4.value;
|
|
12488
|
+
var described = [].concat(_toConsumableArray(cycle), [cycle[0]]).join(" -> ");
|
|
12489
|
+
var _iterator5 = result._createForOfIteratorHelper(cycle),
|
|
12490
|
+
_step5;
|
|
12491
|
+
try {
|
|
12492
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
12493
|
+
var moduleFilePath = _step5.value;
|
|
12494
|
+
errors.push({
|
|
12495
|
+
path: moduleFilePath,
|
|
12496
|
+
message: cycle.length === 1 ? "s.view() cycle: '".concat(moduleFilePath, "' views itself. A view must point at another module.") : "s.view() cycle: ".concat(described, ". Views may not form a cycle.")
|
|
12497
|
+
});
|
|
12498
|
+
}
|
|
12499
|
+
} catch (err) {
|
|
12500
|
+
_iterator5.e(err);
|
|
12501
|
+
} finally {
|
|
12502
|
+
_iterator5.f();
|
|
12503
|
+
}
|
|
12504
|
+
}
|
|
12505
|
+
} catch (err) {
|
|
12506
|
+
_iterator4.e(err);
|
|
12507
|
+
} finally {
|
|
12508
|
+
_iterator4.f();
|
|
12509
|
+
}
|
|
12510
|
+
return errors;
|
|
12511
|
+
}
|
|
12512
|
+
|
|
11660
12513
|
// Lazily constructed: this module is also evaluated inside the `vm` sandbox
|
|
11661
12514
|
// used by loadValModules (when user val modules import @valbuild/core), and
|
|
11662
12515
|
// that sandbox has no `TextEncoder` global. `hash()` is never called from
|
|
@@ -11824,7 +12677,7 @@ function extractValModules(_x) {
|
|
|
11824
12677
|
}
|
|
11825
12678
|
function _extractValModules() {
|
|
11826
12679
|
_extractValModules = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(valModules) {
|
|
11827
|
-
var moduleErrors, addModuleError, sources, schemas, serializedSchemas, shaEntries, moduleIdx, module, at, value, path, schema, source, serializedSchema, pathM, _iterator2, _step2, error, _t, _t2;
|
|
12680
|
+
var moduleErrors, addModuleError, sources, schemas, serializedSchemas, shaEntries, moduleIdx, module, at, value, path, schema, source, serializedSchema, pathM, _iterator2, _step2, error, _iterator3, _step3, _error, _t, _t2;
|
|
11828
12681
|
return _regenerator().w(function (_context) {
|
|
11829
12682
|
while (1) switch (_context.p = _context.n) {
|
|
11830
12683
|
case 0:
|
|
@@ -11977,11 +12830,26 @@ function _extractValModules() {
|
|
|
11977
12830
|
error = _step2.value;
|
|
11978
12831
|
moduleErrors.push(error);
|
|
11979
12832
|
}
|
|
12833
|
+
// Same kind of rule, same reason it is here: a view cycle is a property of the
|
|
12834
|
+
// whole set of schemas, so no single module can see it. Nothing further down
|
|
12835
|
+
// catches it either — a view stores a pointer, not content, so there is no
|
|
12836
|
+
// data cycle for a source walk to trip over.
|
|
11980
12837
|
} catch (err) {
|
|
11981
12838
|
_iterator2.e(err);
|
|
11982
12839
|
} finally {
|
|
11983
12840
|
_iterator2.f();
|
|
11984
12841
|
}
|
|
12842
|
+
_iterator3 = result._createForOfIteratorHelper(viewCycleErrors(serializedSchemas));
|
|
12843
|
+
try {
|
|
12844
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
12845
|
+
_error = _step3.value;
|
|
12846
|
+
moduleErrors.push(_error);
|
|
12847
|
+
}
|
|
12848
|
+
} catch (err) {
|
|
12849
|
+
_iterator3.e(err);
|
|
12850
|
+
} finally {
|
|
12851
|
+
_iterator3.f();
|
|
12852
|
+
}
|
|
11985
12853
|
return _context.a(2, _objectSpread2(_objectSpread2({
|
|
11986
12854
|
sources: sources,
|
|
11987
12855
|
schemas: schemas,
|
|
@@ -12084,7 +12952,7 @@ function hasRemoteFileSchema(schema) {
|
|
|
12084
12952
|
return false;
|
|
12085
12953
|
} else if (schema.type === "boolean" ||
|
|
12086
12954
|
// An enum's values are strings, so there is nothing to look inside.
|
|
12087
|
-
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" || schema.type === "locale") {
|
|
12955
|
+
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" || schema.type === "locale" || schema.type === "view") {
|
|
12088
12956
|
return false;
|
|
12089
12957
|
} else {
|
|
12090
12958
|
var exhaustiveCheck = schema;
|
|
@@ -12159,7 +13027,9 @@ function hasMediaSchema(schema) {
|
|
|
12159
13027
|
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" || schema.type === "locale" ||
|
|
12160
13028
|
// A settings module holds the assistant's configuration, not content, and
|
|
12161
13029
|
// nothing in it is media.
|
|
12162
|
-
schema.type === "settings"
|
|
13030
|
+
schema.type === "settings" ||
|
|
13031
|
+
// A view shows another module; that module answers for its own media.
|
|
13032
|
+
schema.type === "view") {
|
|
12163
13033
|
return false;
|
|
12164
13034
|
} else {
|
|
12165
13035
|
// Same contract as above: adding a schema type without teaching this
|
|
@@ -12475,6 +13345,160 @@ function discriminatedUnionBranchOf(schema, tag) {
|
|
|
12475
13345
|
return undefined;
|
|
12476
13346
|
}
|
|
12477
13347
|
|
|
13348
|
+
/**
|
|
13349
|
+
* Where a resolved view handle keeps the module it points at.
|
|
13350
|
+
*
|
|
13351
|
+
* A symbol, so it is invisible to `JSON.stringify`, `Object.keys`, the source
|
|
13352
|
+
* SHAs and every walk that treats source as data — the handle still IS
|
|
13353
|
+
* `{ view: "/foo.val.ts" }` everywhere that matters.
|
|
13354
|
+
*/
|
|
13355
|
+
var ViewTargetModule = Symbol["for"]("val/ViewTargetModule");
|
|
13356
|
+
|
|
13357
|
+
/**
|
|
13358
|
+
* A view's source with the module it names attached.
|
|
13359
|
+
*
|
|
13360
|
+
* `useVal(page.header)` needs the target's SOURCE and its SCHEMA, and the
|
|
13361
|
+
* stored pointer has neither — it is a path. The app has no way to turn a path
|
|
13362
|
+
* back into a module either: `val.modules` holds lazy `import()` thunks, and
|
|
13363
|
+
* `<ValModulesClient>` is optional. So the module travels with the handle.
|
|
13364
|
+
*
|
|
13365
|
+
* Attached by the READ path (`stegaEncode`) rather than written into source,
|
|
13366
|
+
* and that is the whole reason it works in draft mode: with an edit pending,
|
|
13367
|
+
* the source comes from the overlay store as plain JSON that never went near a
|
|
13368
|
+
* module. The schema is the module's own either way, so the encoder always has
|
|
13369
|
+
* it to hand.
|
|
13370
|
+
*/
|
|
13371
|
+
|
|
13372
|
+
/** Attach the module a view names to its pointer. */
|
|
13373
|
+
function createViewHandle(source, valModule) {
|
|
13374
|
+
return _objectSpread2(_objectSpread2({}, source), {}, _defineProperty({}, ViewTargetModule, valModule));
|
|
13375
|
+
}
|
|
13376
|
+
|
|
13377
|
+
/** Is this a view pointer that carries the module it names? */
|
|
13378
|
+
function isViewHandle(value) {
|
|
13379
|
+
return _typeof(value) === "object" && value !== null && ViewTargetModule in value && value[ViewTargetModule] !== undefined;
|
|
13380
|
+
}
|
|
13381
|
+
|
|
13382
|
+
/** The module a handle carries, or undefined if it carries none. */
|
|
13383
|
+
function viewHandleModule(value) {
|
|
13384
|
+
if (!isViewHandle(value)) {
|
|
13385
|
+
return undefined;
|
|
13386
|
+
}
|
|
13387
|
+
return value[ViewTargetModule];
|
|
13388
|
+
}
|
|
13389
|
+
|
|
13390
|
+
/**
|
|
13391
|
+
* What a reader that needs a MODULE accepts, rather than a value.
|
|
13392
|
+
*
|
|
13393
|
+
* `useValKey`, `useValRoute`, `useValRouteUrl` and their `fetch*` counterparts
|
|
13394
|
+
* all read a path, a schema and a source off what they are handed, so — unlike
|
|
13395
|
+
* `useVal` — they cannot take an arbitrary selector. They CAN take a view
|
|
13396
|
+
* pointing at one, which is the point of a page declaring which module it
|
|
13397
|
+
* shows. {@link resolveViewedModule} is the runtime half, and takes exactly
|
|
13398
|
+
* this, so the two cannot drift.
|
|
13399
|
+
*/
|
|
13400
|
+
|
|
13401
|
+
/**
|
|
13402
|
+
* What a reader was actually handed: the module itself, or — when it is a view
|
|
13403
|
+
* handle — the module that view points at.
|
|
13404
|
+
*
|
|
13405
|
+
* Every reader that needs a module rather than a value goes through this:
|
|
13406
|
+
* `useValKey`, `useValRoute`, `useValRouteUrl` and their `fetch*` counterparts
|
|
13407
|
+
* all pull the path, the schema and the source off the thing they are given,
|
|
13408
|
+
* and a view handle has none of those. It is `{ view: "/foo.val.ts" }` with the
|
|
13409
|
+
* module on a symbol, so reading `Internal.getValPath` off it gives
|
|
13410
|
+
* `undefined`, and every one of those readers treats `undefined` as its own
|
|
13411
|
+
* "no route matched" answer. Without this the call is not an error — it is a
|
|
13412
|
+
* silently empty one.
|
|
13413
|
+
*
|
|
13414
|
+
* A POINTER with no module on it throws rather than being passed through, for
|
|
13415
|
+
* the same reason `stegaEncode` throws on one: symbols do not survive
|
|
13416
|
+
* serialization, so a handle that crossed the server/client boundary as a prop
|
|
13417
|
+
* arrives looking like content and is not.
|
|
13418
|
+
*/
|
|
13419
|
+
|
|
13420
|
+
/*
|
|
13421
|
+
* A widened implementation signature rather than assertions in the body.
|
|
13422
|
+
*
|
|
13423
|
+
* The module rides on a symbol as `unknown` — the encoder that attaches it has
|
|
13424
|
+
* no type for it — and no narrowing tells the checker that what is left after
|
|
13425
|
+
* both guards is the module arm. Declaring the callable signature above and
|
|
13426
|
+
* implementing against `unknown` says that once, where the runtime fact lives,
|
|
13427
|
+
* instead of casting at each of the twelve readers.
|
|
13428
|
+
*/
|
|
13429
|
+
function resolveViewedModule(selector) {
|
|
13430
|
+
var resolved = viewHandleModule(selector);
|
|
13431
|
+
if (resolved !== undefined) {
|
|
13432
|
+
return resolved;
|
|
13433
|
+
}
|
|
13434
|
+
if (isValViewSource(selector)) {
|
|
13435
|
+
throw Error("Cannot resolve the view of '".concat(selector.view, "': it carries no module. ") + "Either it crossed a server/client boundary, which drops the module because it rides on a symbol, " + "or it points at a different module than its schema declares \u2014 which `val validate --fix` repairs. " + "Resolve it in the same component that read the module containing it, or read '".concat(selector.view, "' directly."));
|
|
13436
|
+
}
|
|
13437
|
+
return selector;
|
|
13438
|
+
}
|
|
13439
|
+
|
|
13440
|
+
/**
|
|
13441
|
+
* Every module a schema's views point at, keyed by path.
|
|
13442
|
+
*
|
|
13443
|
+
* Walked GENERICALLY over the schema instance's own properties rather than by
|
|
13444
|
+
* switching on schema type, for the same reason `viewTargetsOf` is: a schema
|
|
13445
|
+
* holds another schema in places an enumeration keeps forgetting. Missing a
|
|
13446
|
+
* site here is a view that cannot be resolved at runtime, which is a worse
|
|
13447
|
+
* failure than the walk being slightly broad.
|
|
13448
|
+
*
|
|
13449
|
+
* Memoised per schema INSTANCE. A module's schema is built once at import, and
|
|
13450
|
+
* `useVal` runs on every render — so without this the walk would be a render
|
|
13451
|
+
* cost rather than a load cost.
|
|
13452
|
+
*/
|
|
13453
|
+
var cache = new WeakMap();
|
|
13454
|
+
function viewModulesOf(schema) {
|
|
13455
|
+
if (schema === undefined) {
|
|
13456
|
+
return new Map();
|
|
13457
|
+
}
|
|
13458
|
+
var cached = cache.get(schema);
|
|
13459
|
+
if (cached) {
|
|
13460
|
+
return cached;
|
|
13461
|
+
}
|
|
13462
|
+
var modules = new Map();
|
|
13463
|
+
var seen = new Set();
|
|
13464
|
+
function walk(node) {
|
|
13465
|
+
if (_typeof(node) !== "object" || node === null || seen.has(node)) {
|
|
13466
|
+
return;
|
|
13467
|
+
}
|
|
13468
|
+
seen.add(node);
|
|
13469
|
+
if (node instanceof ValViewSchema) {
|
|
13470
|
+
var target = node["moduleFilePath"];
|
|
13471
|
+
var valModule = node["valModule"];
|
|
13472
|
+
if (typeof target === "string" && valModule !== undefined) {
|
|
13473
|
+
modules.set(target, valModule);
|
|
13474
|
+
}
|
|
13475
|
+
return;
|
|
13476
|
+
}
|
|
13477
|
+
if (Array.isArray(node)) {
|
|
13478
|
+
var _iterator = result._createForOfIteratorHelper(node),
|
|
13479
|
+
_step;
|
|
13480
|
+
try {
|
|
13481
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
13482
|
+
var item = _step.value;
|
|
13483
|
+
walk(item);
|
|
13484
|
+
}
|
|
13485
|
+
} catch (err) {
|
|
13486
|
+
_iterator.e(err);
|
|
13487
|
+
} finally {
|
|
13488
|
+
_iterator.f();
|
|
13489
|
+
}
|
|
13490
|
+
return;
|
|
13491
|
+
}
|
|
13492
|
+
for (var _i = 0, _Object$values = Object.values(node); _i < _Object$values.length; _i++) {
|
|
13493
|
+
var value = _Object$values[_i];
|
|
13494
|
+
walk(value);
|
|
13495
|
+
}
|
|
13496
|
+
}
|
|
13497
|
+
walk(schema);
|
|
13498
|
+
cache.set(schema, modules);
|
|
13499
|
+
return modules;
|
|
13500
|
+
}
|
|
13501
|
+
|
|
12478
13502
|
function deserializeSchema(serialized) {
|
|
12479
13503
|
var schema = deserializeSchemaImpl(serialized);
|
|
12480
13504
|
if (serialized.readonly) {
|
|
@@ -12486,7 +13510,7 @@ function deserializeSchema(serialized) {
|
|
|
12486
13510
|
return schema;
|
|
12487
13511
|
}
|
|
12488
13512
|
function deserializeSchemaImpl(serialized) {
|
|
12489
|
-
var _serialized$options, _serialized$options2, _serialized$render, _serialized$multiline, _serialized$render2, _serialized$render3, _serialized$render4, _serialized$render5, _serialized$render6, _serialized$render7, _serialized$render8, _serialized$accept, _serialized$dir, _serialized$remote, _serialized$jsonValue, _serialized$render0, _serialized$external, _serialized$render1, _serialized$render12, _serialized$render13, _serialized$render14, _serialized$render15, _serialized$render16, _serialized$render17;
|
|
13513
|
+
var _serialized$options, _serialized$options2, _serialized$render, _serialized$multiline, _serialized$render2, _serialized$render3, _serialized$render4, _serialized$render5, _serialized$render6, _serialized$render7, _serialized$render8, _serialized$accept, _serialized$dir, _serialized$remote, _serialized$jsonValue, _serialized$render0, _serialized$external, _serialized$render1, _serialized$render12, _serialized$render13, _serialized$render14, _serialized$render15, _serialized$render16, _serialized$render17, _serialized$readonly, _serialized$hidden, _serialized$render18;
|
|
12490
13514
|
switch (serialized.type) {
|
|
12491
13515
|
case "string":
|
|
12492
13516
|
return new StringSchema(_objectSpread2(_objectSpread2({}, serialized.options), {}, {
|
|
@@ -12583,6 +13607,11 @@ function deserializeSchemaImpl(serialized) {
|
|
|
12583
13607
|
return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render16 = serialized.render) !== null && _serialized$render16 !== void 0 ? _serialized$render16 : null);
|
|
12584
13608
|
case "code":
|
|
12585
13609
|
return new CodeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render17 = serialized.render) !== null && _serialized$render17 !== void 0 ? _serialized$render17 : null);
|
|
13610
|
+
case "view":
|
|
13611
|
+
return new ValViewSchema(serialized.moduleFilePath,
|
|
13612
|
+
// No module: this schema came off the wire. The Studio navigates to a
|
|
13613
|
+
// view rather than resolving one, so nothing here needs it.
|
|
13614
|
+
undefined, (_serialized$readonly = serialized.readonly) !== null && _serialized$readonly !== void 0 ? _serialized$readonly : false, (_serialized$hidden = serialized.hidden) !== null && _serialized$hidden !== void 0 ? _serialized$hidden : false, serialized.description, (_serialized$render18 = serialized.render) !== null && _serialized$render18 !== void 0 ? _serialized$render18 : null);
|
|
12586
13615
|
default:
|
|
12587
13616
|
{
|
|
12588
13617
|
var exhaustiveCheck = serialized;
|
|
@@ -12597,142 +13626,31 @@ function deserializeSchemaImpl(serialized) {
|
|
|
12597
13626
|
}
|
|
12598
13627
|
|
|
12599
13628
|
/**
|
|
12600
|
-
*
|
|
12601
|
-
* in a sortable list, a key in a reference dropdown, a search hit, a
|
|
12602
|
-
* reference — which is everywhere the value is NAVIGABLE to rather than open.
|
|
12603
|
-
* It is never how the field itself is edited: that is a RENDER (`render.ts`),
|
|
12604
|
-
* which applies only when you are looking at the field. The two do not
|
|
12605
|
-
* intersect — a schema can carry both, and each is read in its own places.
|
|
12606
|
-
*
|
|
12607
|
-
* A preview is declared on the schema of the VALUE being previewed:
|
|
13629
|
+
* THE RULE, and the only sentence that needs to be remembered:
|
|
12608
13630
|
*
|
|
12609
|
-
*
|
|
12610
|
-
*
|
|
12611
|
-
*
|
|
12612
|
-
*
|
|
12613
|
-
* ```
|
|
12614
|
-
*
|
|
12615
|
-
* The container reifies its rows by running each ITEM's preview closure — see
|
|
12616
|
-
* {@link ArrayPreview} / {@link RecordPreview}. (Previews used to be declared
|
|
12617
|
-
* on the container instead; a `.preview` on an array/record now previews the
|
|
12618
|
-
* array/record itself as a value, for when IT is the item of something.)
|
|
12619
|
-
*/
|
|
12620
|
-
/**
|
|
12621
|
-
* What a preview shows for one value: the user's `preview` callback returns
|
|
12622
|
-
* this, and the Studio draws a row from it.
|
|
13631
|
+
* **`.describe()` is INPUT HELP and is shown wherever that field — or a
|
|
13632
|
+
* record's key — is being ENTERED; `.preview()` is a NAME and is shown
|
|
13633
|
+
* wherever the value is REFERRED TO rather than edited; `.render()` is
|
|
13634
|
+
* LAYOUT and applies only while the field is open in front of you.**
|
|
12623
13635
|
*
|
|
12624
|
-
*
|
|
12625
|
-
*
|
|
12626
|
-
*
|
|
12627
|
-
*
|
|
12628
|
-
*
|
|
12629
|
-
*
|
|
12630
|
-
*/
|
|
12631
|
-
|
|
12632
|
-
/**
|
|
12633
|
-
* What `.preview(...)` takes, on every schema: the value's own source in, a
|
|
12634
|
-
* {@link PreviewItem} out. `NonNullable` because a container skips null items
|
|
12635
|
-
* rather than previewing them.
|
|
12636
|
-
*
|
|
12637
|
-
* Declared through method syntax deliberately (the same bivariance shape
|
|
12638
|
-
* React's event handler types use): `nullable()` copies a schema's closure
|
|
12639
|
-
* into the `Src | null` variant of the same class, and with a plain function
|
|
12640
|
-
* type the checker cannot see that `NonNullable<Src | null>` IS
|
|
12641
|
-
* `NonNullable<Src>` while `Src` is still a type parameter — every schema's
|
|
12642
|
-
* `nullable()` would need a cast instead.
|
|
12643
|
-
*/
|
|
12644
|
-
|
|
12645
|
-
/**
|
|
12646
|
-
* Main preview type.
|
|
12647
|
-
*
|
|
12648
|
-
* Deliberately not exported: `parent` is the discriminant, and every consumer
|
|
12649
|
-
* narrows on it rather than on the union as a whole. There is no `layout` here
|
|
12650
|
-
* on purpose - how a preview is laid out is the editor's business, not the
|
|
12651
|
-
* schema's.
|
|
12652
|
-
*/
|
|
12653
|
-
|
|
12654
|
-
/**
|
|
12655
|
-
* Which paths a preview is being computed FOR.
|
|
12656
|
-
*
|
|
12657
|
-
* `executePreview` takes a whole module, so one request has always walked every
|
|
12658
|
-
* node in it and run every `preview` closure - for `handboka`, with `preview` at
|
|
12659
|
-
* two nested array levels, that is every chapter and every section to serve one
|
|
12660
|
-
* visible row. A scope is what makes the walk proportional to what is being
|
|
12661
|
-
* looked at instead of to the project.
|
|
12662
|
-
*
|
|
12663
|
-
* Two questions, because a container and its items need different answers:
|
|
12664
|
-
*
|
|
12665
|
-
* - {@link PreviewScope.wants} - is a preview AT this exact path wanted? A
|
|
12666
|
-
* container answers `true` here when the whole of it is being shown, and its
|
|
12667
|
-
* preview is then computed in full.
|
|
12668
|
-
* - {@link PreviewScope.wantsUnder} - could anything at or below this path be
|
|
12669
|
-
* wanted? Recursion is pruned where this is `false`, and a container whose own
|
|
12670
|
-
* path is not wanted but which has wanted descendants previews a WINDOW: only
|
|
12671
|
-
* the items that were asked for. That is the case a single visible row is, and
|
|
12672
|
-
* it is why {@link ArrayPreview} carries indices.
|
|
13636
|
+
* The test that settles every case: **can the reader change something here?**
|
|
13637
|
+
* If yes it is a place for a description — the input beside a label, the key
|
|
13638
|
+
* box in "New entry", "Rename key", "Duplicate", "New page", the key half of a
|
|
13639
|
+
* reference dropdown. If no, it is a place for a preview — a list row, a
|
|
13640
|
+
* reference once chosen, a search hit, a sitemap row, the heading of what you
|
|
13641
|
+
* navigated to.
|
|
12673
13642
|
*
|
|
12674
|
-
*
|
|
12675
|
-
*
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
*
|
|
13643
|
+
* That is why a description is plain data on the serialized schema and a
|
|
13644
|
+
* preview is a closure: a description is true before any value exists and says
|
|
13645
|
+
* the same thing to everyone filling the field in, and a preview cannot exist
|
|
13646
|
+
* without the one value it names. So a description must never be used as a
|
|
13647
|
+
* subtitle — it would repeat one sentence under every row of a list — and a
|
|
13648
|
+
* preview must never be used as help text, because there is nothing to preview
|
|
13649
|
+
* until after the value has been entered.
|
|
12680
13650
|
*
|
|
12681
|
-
*
|
|
12682
|
-
*
|
|
12683
|
-
* ancestor test wrong wherever a key is a prefix of a sibling key or contains a
|
|
12684
|
-
* dot or a quote - `"title"` against `"titles"` being the cheapest example.
|
|
12685
|
-
* Segments are parsed once here, not per comparison.
|
|
13651
|
+
* None of the three substitutes for another: a field with a perfect
|
|
13652
|
+
* description still previews as `#3` until someone writes the preview.
|
|
12686
13653
|
*/
|
|
12687
|
-
function previewScope(paths) {
|
|
12688
|
-
var wanted = paths.map(function (path) {
|
|
12689
|
-
var _splitModuleFilePathA = splitModuleFilePathAndModulePath(path),
|
|
12690
|
-
_splitModuleFilePathA2 = _slicedToArray(_splitModuleFilePathA, 2),
|
|
12691
|
-
moduleFilePath = _splitModuleFilePathA2[0],
|
|
12692
|
-
modulePath = _splitModuleFilePathA2[1];
|
|
12693
|
-
return {
|
|
12694
|
-
moduleFilePath: moduleFilePath,
|
|
12695
|
-
segments: modulePath === "" ? [] : splitModulePath(modulePath)
|
|
12696
|
-
};
|
|
12697
|
-
});
|
|
12698
|
-
var parse = function parse(path) {
|
|
12699
|
-
var _splitModuleFilePathA3 = splitModuleFilePathAndModulePath(path),
|
|
12700
|
-
_splitModuleFilePathA4 = _slicedToArray(_splitModuleFilePathA3, 2),
|
|
12701
|
-
moduleFilePath = _splitModuleFilePathA4[0],
|
|
12702
|
-
modulePath = _splitModuleFilePathA4[1];
|
|
12703
|
-
return {
|
|
12704
|
-
moduleFilePath: moduleFilePath,
|
|
12705
|
-
segments: modulePath === "" ? [] : splitModulePath(modulePath)
|
|
12706
|
-
};
|
|
12707
|
-
};
|
|
12708
|
-
var isPrefix = function isPrefix(prefix, of) {
|
|
12709
|
-
if (prefix.length > of.length) return false;
|
|
12710
|
-
for (var i = 0; i < prefix.length; i++) {
|
|
12711
|
-
if (prefix[i] !== of[i]) return false;
|
|
12712
|
-
}
|
|
12713
|
-
return true;
|
|
12714
|
-
};
|
|
12715
|
-
return {
|
|
12716
|
-
wants: function wants(path) {
|
|
12717
|
-
var at = parse(path);
|
|
12718
|
-
return wanted.some(function (entry) {
|
|
12719
|
-
return entry.moduleFilePath === at.moduleFilePath && entry.segments.length === at.segments.length && isPrefix(entry.segments, at.segments);
|
|
12720
|
-
});
|
|
12721
|
-
},
|
|
12722
|
-
wantsUnder: function wantsUnder(path) {
|
|
12723
|
-
var at = parse(path);
|
|
12724
|
-
return wanted.some(function (entry) {
|
|
12725
|
-
return entry.moduleFilePath === at.moduleFilePath && (
|
|
12726
|
-
// Either direction: a wanted path below `path` means recurse into it,
|
|
12727
|
-
// and a wanted path ABOVE it means the whole subtree was asked for.
|
|
12728
|
-
isPrefix(at.segments, entry.segments) || isPrefix(entry.segments, at.segments));
|
|
12729
|
-
});
|
|
12730
|
-
}
|
|
12731
|
-
};
|
|
12732
|
-
}
|
|
12733
|
-
|
|
12734
|
-
// TODO: improve this so that we do not get RawString and string, only string. Are there other things?
|
|
12735
|
-
|
|
12736
13654
|
/**
|
|
12737
13655
|
* A RENDER is how the FIELD ITSELF is laid out in the editor, and it applies
|
|
12738
13656
|
* only when you are looking at the field: `.render({ as: "inline" })` on an
|
|
@@ -13249,7 +14167,7 @@ function isPageRouter(routerId) {
|
|
|
13249
14167
|
|
|
13250
14168
|
var corePackageJson = {
|
|
13251
14169
|
name: "@valbuild/core",
|
|
13252
|
-
version: "0.
|
|
14170
|
+
version: "0.134.0",
|
|
13253
14171
|
"private": false,
|
|
13254
14172
|
description: "Val - supercharged hard-coded content",
|
|
13255
14173
|
repository: {
|
|
@@ -13311,6 +14229,14 @@ var Internal = {
|
|
|
13311
14229
|
VERSION: {
|
|
13312
14230
|
core: corePackageJson.version
|
|
13313
14231
|
},
|
|
14232
|
+
// A view's read-path plumbing: `Internal` rather than the public surface,
|
|
14233
|
+
// because an app never builds or unwraps a handle — it passes one to
|
|
14234
|
+
// `useVal`.
|
|
14235
|
+
createViewHandle: createViewHandle,
|
|
14236
|
+
isViewHandle: isViewHandle,
|
|
14237
|
+
resolveViewedModule: resolveViewedModule,
|
|
14238
|
+
viewHandleModule: viewHandleModule,
|
|
14239
|
+
viewModulesOf: viewModulesOf,
|
|
13314
14240
|
mediaUrl: mediaUrl,
|
|
13315
14241
|
resolveMedia: resolveMedia,
|
|
13316
14242
|
isRemoteMediaPath: isRemoteMediaPath,
|
|
@@ -13458,6 +14384,7 @@ exports.THEME_LOGO_DIRECTORY = THEME_LOGO_DIRECTORY;
|
|
|
13458
14384
|
exports.THEME_RADIUS_LENGTHS = THEME_RADIUS_LENGTHS;
|
|
13459
14385
|
exports.THEME_RADIUS_STEPS = THEME_RADIUS_STEPS;
|
|
13460
14386
|
exports.VAL_EXTENSION = VAL_EXTENSION;
|
|
14387
|
+
exports.ValViewSchema = ValViewSchema;
|
|
13461
14388
|
exports._classCallCheck = _classCallCheck;
|
|
13462
14389
|
exports._createClass = _createClass;
|
|
13463
14390
|
exports._slicedToArray = _slicedToArray;
|
|
@@ -13477,6 +14404,7 @@ exports.initVal = initVal;
|
|
|
13477
14404
|
exports.isInlineRender = isInlineRender;
|
|
13478
14405
|
exports.isPageRouter = isPageRouter;
|
|
13479
14406
|
exports.isRootModuleFilePath = isRootModuleFilePath;
|
|
14407
|
+
exports.isValViewSource = isValViewSource;
|
|
13480
14408
|
exports.localeOfValue = localeOfValue;
|
|
13481
14409
|
exports.localeTagError = localeTagError;
|
|
13482
14410
|
exports.missingDeclaredKeys = missingDeclaredKeys;
|