@valbuild/core 0.105.1 → 0.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/declarations/src/index.d.ts +5 -4
  2. package/dist/declarations/src/initSchema.d.ts +20 -20
  3. package/dist/declarations/src/module.d.ts +10 -0
  4. package/dist/declarations/src/preview.d.ts +40 -2
  5. package/dist/declarations/src/render.d.ts +38 -9
  6. package/dist/declarations/src/schema/array.d.ts +24 -12
  7. package/dist/declarations/src/schema/boolean.d.ts +25 -2
  8. package/dist/declarations/src/schema/color.d.ts +25 -2
  9. package/dist/declarations/src/schema/date.d.ts +25 -2
  10. package/dist/declarations/src/schema/datetime.d.ts +25 -2
  11. package/dist/declarations/src/schema/file.d.ts +25 -2
  12. package/dist/declarations/src/schema/image.d.ts +25 -2
  13. package/dist/declarations/src/schema/index.d.ts +19 -1
  14. package/dist/declarations/src/schema/keyOf.d.ts +25 -2
  15. package/dist/declarations/src/schema/literal.d.ts +25 -2
  16. package/dist/declarations/src/schema/number.d.ts +25 -2
  17. package/dist/declarations/src/schema/object.d.ts +25 -2
  18. package/dist/declarations/src/schema/record.d.ts +25 -13
  19. package/dist/declarations/src/schema/richtext.d.ts +25 -2
  20. package/dist/declarations/src/schema/route.d.ts +25 -2
  21. package/dist/declarations/src/schema/string.d.ts +13 -2
  22. package/dist/declarations/src/schema/union.d.ts +32 -2
  23. package/dist/{index-4013c9f8.cjs.prod.js → index-77914667.cjs.prod.js} +1011 -192
  24. package/dist/{index-baa3109b.cjs.dev.js → index-bce560db.cjs.dev.js} +1011 -192
  25. package/dist/{index-005f51a5.esm.js → index-db33b67c.esm.js} +1011 -192
  26. package/dist/valbuild-core.cjs.dev.js +1 -1
  27. package/dist/valbuild-core.cjs.prod.js +1 -1
  28. package/dist/valbuild-core.esm.js +1 -1
  29. package/package.json +2 -2
  30. package/patch/dist/valbuild-core-patch.cjs.dev.js +1 -1
  31. package/patch/dist/valbuild-core-patch.cjs.prod.js +1 -1
  32. package/patch/dist/valbuild-core-patch.esm.js +2 -2
@@ -23,7 +23,7 @@ export type { ValidationFix } from "./schema/validation/ValidationFix.js";
23
23
  export { VAL_EXTENSION, type SourceArray } from "./source/index.js";
24
24
  export { derefPatch } from "./patch/deref.js";
25
25
  export { type SelectorSource, type SelectorOf, GenericSelector, } from "./selector/index.js";
26
- import { getSource, splitModulePath, splitModuleFilePath, resolvePath, safeResolvePath, splitModuleFilePathAndModulePath, joinModuleFilePathAndModulePath, parentOfSourcePath, patchPathToModulePath, splitJoinedSourcePaths, type ValModule } from "./module.js";
26
+ import { getSource, isValModule, splitModulePath, splitModuleFilePath, resolvePath, safeResolvePath, splitModuleFilePathAndModulePath, joinModuleFilePathAndModulePath, parentOfSourcePath, patchPathToModulePath, splitJoinedSourcePaths, type ValModule } from "./module.js";
27
27
  declare const ModuleFilePathSep = "?p=";
28
28
  export { ModuleFilePathSep };
29
29
  import { SelectorSource, getSchema } from "./selector/index.js";
@@ -59,8 +59,8 @@ export { type SerializedRichTextSchema, RichTextSchema, } from "./schema/richtex
59
59
  export { type SerializedUnionSchema, UnionSchema, type SerializedStringUnionSchema, type SerializedObjectUnionSchema, } from "./schema/union.js";
60
60
  export { type SerializedLiteralSchema, LiteralSchema } from "./schema/literal.js";
61
61
  export { deserializeSchema } from "./schema/deserialize.js";
62
- export { type PreviewItem, type RecordPreview, type ArrayPreview, type ReifiedPreview, type PreviewScope, previewScope, } from "./preview.js";
63
- export { type CodeLanguage, type StringRender, CODE_LANGUAGES } from "./render.js";
62
+ export { type PreviewItem, type ItemPreviewInput, type RecordPreview, type ArrayPreview, type ReifiedPreview, type PreviewScope, previewScope, } from "./preview.js";
63
+ export { type CodeLanguage, type StringRender, type InlineRender, type FieldRender, CODE_LANGUAGES, } from "./render.js";
64
64
  export type { ValRouter, RouteValidationError } from "./router.js";
65
65
  export { getSourcePathFromRoute } from "./getSourcePathFromRoute.js";
66
66
  export declare const FATAL_ERROR_TYPES: readonly ["no-schema", "no-source", "invalid-id", "no-module", "invalid-patch"];
@@ -80,6 +80,7 @@ declare const Internal: {
80
80
  getSchema: typeof getSchema;
81
81
  getValPath: typeof getValPath;
82
82
  getSource: typeof getSource;
83
+ isValModule: typeof isValModule;
83
84
  resolvePath: typeof resolvePath;
84
85
  safeResolvePath: typeof safeResolvePath;
85
86
  splitModuleFilePathAndModulePath: typeof splitModuleFilePathAndModulePath;
@@ -101,7 +102,7 @@ declare const Internal: {
101
102
  hashToRemoteFileHash: typeof hashToRemoteFileHash;
102
103
  splitRemoteRef: typeof splitRemoteRef;
103
104
  };
104
- validate: (val: ValModule<SelectorSource>, path: SourcePath, src: unknown) => import("./schema/validation/ValidationError.js").ValidationErrors | undefined;
105
+ validate: (val: ValModule<SelectorSource>, path: SourcePath, src: unknown) => import("./index.js").ValidationErrors | undefined;
105
106
  isVal: typeof isVal;
106
107
  isJson: typeof isJson;
107
108
  getJsonImport: typeof getJsonImport;
@@ -283,9 +283,9 @@ export type InitSchema = {
283
283
  readonly files: typeof files;
284
284
  };
285
285
  export declare function initSchema(): {
286
- string: <T extends string>(options?: Record<string, never>) => import("./schema/string.js").StringSchema<T>;
287
- boolean: () => import("./schema/boolean.js").BooleanSchema<boolean>;
288
- array: <S extends import("./schema/index.js").Schema<import("./selector/index.js").SelectorSource>>(schema: S) => import("./schema/array.js").ArraySchema<S, import("./schema/index.js").SelectorOfSchema<S>[]>;
286
+ string: <T extends string>(options?: Record<string, never>) => import("./index.js").StringSchema<T>;
287
+ boolean: () => import("./index.js").BooleanSchema<boolean>;
288
+ array: <S extends import("./schema/index.js").Schema<import("./selector/index.js").SelectorSource>>(schema: S) => import("./index.js").ArraySchema<S, import("./schema/index.js").SelectorOfSchema<S>[]>;
289
289
  object: <Props extends {
290
290
  [key: string]: import("./schema/index.js").Schema<import("./selector/index.js").SelectorSource>;
291
291
  } & {
@@ -297,33 +297,33 @@ export declare function initSchema(): {
297
297
  assert?: never;
298
298
  fold?: never;
299
299
  patch_id?: never;
300
- }>(schema: Props) => import("./schema/object.js").ObjectSchema<Props, { [key in keyof Props]: import("./schema/index.js").SelectorOfSchema<Props[key]>; }>;
300
+ }>(schema: Props) => import("./index.js").ObjectSchema<Props, { [key in keyof Props]: import("./schema/index.js").SelectorOfSchema<Props[key]>; }>;
301
301
  number: (options?: {
302
302
  max?: number;
303
303
  min?: number;
304
- }) => import("./schema/number.js").NumberSchema<number>;
305
- union: <Key extends string | import("./schema/index.js").Schema<string>, T extends import("./schema/index.js").Schema<Key extends string ? import("./source/index.js").SourceObject & { [k in Key]: string; } : Key extends import("./schema/index.js").Schema<string> ? string : unknown>[]>(key: Key, ...objects: T) => import("./schema/union.js").UnionSchema<Key, T, T extends import("./schema/index.js").Schema<infer S extends import("./selector/index.js").SelectorSource>[] ? S extends import("./selector/index.js").SelectorSource ? S | (Key extends import("./schema/index.js").Schema<infer K extends import("./selector/index.js").SelectorSource> ? K : never) : never : never>;
306
- richtext: <O extends import("./index.js").RichTextOptions>(options?: O) => import("./schema/richtext.js").RichTextSchema<O, import("./index.js").RichTextSource<O>>;
304
+ }) => import("./index.js").NumberSchema<number>;
305
+ union: <Key extends string | import("./schema/index.js").Schema<string>, T extends import("./schema/index.js").Schema<Key extends string ? import("./source/index.js").SourceObject & { [k in Key]: string; } : Key extends import("./schema/index.js").Schema<string> ? string : unknown>[]>(key: Key, ...objects: T) => import("./index.js").UnionSchema<Key, T, T extends import("./schema/index.js").Schema<infer S extends import("./selector/index.js").SelectorSource>[] ? S extends import("./selector/index.js").SelectorSource ? S | (Key extends import("./schema/index.js").Schema<infer K extends import("./selector/index.js").SelectorSource> ? K : never) : never : never>;
306
+ richtext: <O extends import("./index.js").RichTextOptions>(options?: O) => import("./index.js").RichTextSchema<O, import("./index.js").RichTextSource<O>>;
307
307
  image: typeof image;
308
- literal: <T extends string>(value: T) => import("./schema/literal.js").LiteralSchema<T>;
309
- keyOf: <Src extends import("./selector/index.js").GenericSelector<import("./source/index.js").SourceObject> & import("./module.js").ValModuleBrand>(valModule: Src) => import("./schema/keyOf.js").KeyOfSchema<Src, Src extends import("./selector/index.js").GenericSelector<infer S extends import("./source/index.js").Source, undefined> ? S extends readonly import("./source/index.js").Source[] ? number : S extends import("./source/index.js").SourceObject ? string extends keyof S ? import("./schema/string.js").RawString : keyof S : S extends Record<string, import("./source/index.js").Source> ? import("./schema/string.js").RawString : never : never>;
308
+ literal: <T extends string>(value: T) => import("./index.js").LiteralSchema<T>;
309
+ keyOf: <Src extends import("./selector/index.js").GenericSelector<import("./source/index.js").SourceObject> & import("./module.js").ValModuleBrand>(valModule: Src) => import("./index.js").KeyOfSchema<Src, Src extends import("./selector/index.js").GenericSelector<infer S extends import("./source/index.js").Source, undefined> ? S extends readonly import("./source/index.js").Source[] ? number : S extends import("./source/index.js").SourceObject ? string extends keyof S ? import("./index.js").RawString : keyof S : S extends Record<string, import("./source/index.js").Source> ? import("./index.js").RawString : never : never>;
310
310
  record: typeof record;
311
311
  file: typeof file;
312
- files: (options: import("./schema/files.js").FilesOptions) => import("./schema/record.js").RecordSchema<import("./schema/object.js").ObjectSchema<{
313
- mimeType: import("./schema/string.js").StringSchema<string>;
312
+ files: (options: import("./schema/files.js").FilesOptions) => import("./index.js").RecordSchema<import("./index.js").ObjectSchema<{
313
+ mimeType: import("./index.js").StringSchema<string>;
314
314
  }, {
315
315
  mimeType: string;
316
316
  }>, import("./schema/index.js").Schema<string>, Record<string, import("./schema/files.js").FilesEntryMetadata>>;
317
- date: (options?: Record<string, never>) => import("./schema/date.js").DateSchema<import("./schema/string.js").RawString>;
318
- datetime: (options?: Record<string, never>) => import("./schema/datetime.js").DateTimeSchema<import("./schema/string.js").RawString>;
319
- color: (options?: import("./schema/color.js").ColorOptions) => import("./schema/color.js").ColorSchema<import("./schema/string.js").RawString>;
320
- route: <T extends string>(options?: Record<string, never>) => import("./schema/route.js").RouteSchema<T>;
317
+ date: (options?: Record<string, never>) => import("./index.js").DateSchema<import("./index.js").RawString>;
318
+ datetime: (options?: Record<string, never>) => import("./index.js").DateTimeSchema<import("./index.js").RawString>;
319
+ color: (options?: import("./index.js").ColorOptions) => import("./index.js").ColorSchema<import("./index.js").RawString>;
320
+ route: <T extends string>(options?: Record<string, never>) => import("./index.js").RouteSchema<T>;
321
321
  router: typeof router;
322
- images: <Accept extends `image/${string}`>(options: import("./schema/images.js").ImagesOptions<Accept>) => import("./schema/record.js").RecordSchema<import("./schema/object.js").ObjectSchema<{
323
- width: import("./schema/number.js").NumberSchema<number>;
324
- height: import("./schema/number.js").NumberSchema<number>;
325
- mimeType: import("./schema/string.js").StringSchema<string>;
326
- alt: import("./schema/string.js").StringSchema<string | null>;
322
+ images: <Accept extends `image/${string}`>(options: import("./schema/images.js").ImagesOptions<Accept>) => import("./index.js").RecordSchema<import("./index.js").ObjectSchema<{
323
+ width: import("./index.js").NumberSchema<number>;
324
+ height: import("./index.js").NumberSchema<number>;
325
+ mimeType: import("./index.js").StringSchema<string>;
326
+ alt: import("./index.js").StringSchema<string | null>;
327
327
  }, {
328
328
  width: number;
329
329
  height: number;
@@ -18,6 +18,16 @@ export type ReplaceRawStringWithString<T extends SelectorSource> = SelectorSourc
18
18
  export declare function define<T extends Schema<SelectorSource>>(id: string, // TODO: `/${string}`
19
19
  schema: T, source: ReplaceRawStringWithString<SelectorOfSchema<T>>): ValModule<SelectorOfSchema<T>>;
20
20
  export declare function getSource<T extends Source>(valModule: ValModule<T>): T;
21
+ /**
22
+ * Whether `value` is a Val module, i.e. something {@link define} produced.
23
+ *
24
+ * Checks for the three symbols `define` writes, rather than a class identity:
25
+ * a module may have been created by a different copy of `@valbuild/core` (the
26
+ * editor SPA and the host bundle each ship their own, and the CLI evaluates
27
+ * user modules inside a `node:vm` context). The symbols are created with
28
+ * `Symbol.for`, so they are shared across all of those; a constructor is not.
29
+ */
30
+ export declare function isValModule(value: unknown): value is ValModule<SelectorSource>;
21
31
  export declare function splitModuleFilePathAndModulePath(path: SourcePath | ModuleFilePath): [moduleId: ModuleFilePath, path: ModulePath];
22
32
  export declare function joinModuleFilePathAndModulePath(moduleFilePath: ModuleFilePath, modulePath: ModulePath): SourcePath;
23
33
  export declare function getSourceAtPath(modulePath: ModulePath, valModule: ValModule<SelectorSource> | Source): any;
@@ -3,8 +3,29 @@ import { SelectorSource } from "./selector/index.js";
3
3
  import { ImageSource } from "./source/media.js";
4
4
  import { ModuleFilePath, SourcePath } from "./val/index.js";
5
5
  /**
6
- * What a container shows for ONE of its items: the user's `preview` callback
7
- * returns this, and the Studio draws a row from it.
6
+ * A PREVIEW is how a VALUE is shown wherever a preview of it is needed — a row
7
+ * in a sortable list, a key in a reference dropdown, a search hit, a
8
+ * reference — which is everywhere the value is NAVIGABLE to rather than open.
9
+ * It is never how the field itself is edited: that is a RENDER (`render.ts`),
10
+ * which applies only when you are looking at the field. The two do not
11
+ * intersect — a schema can carry both, and each is read in its own places.
12
+ *
13
+ * A preview is declared on the schema of the VALUE being previewed:
14
+ *
15
+ * ```ts
16
+ * const author = s.object({ name: s.string() })
17
+ * .preview(({ val }) => ({ title: val.name }));
18
+ * const authors = s.array(author);
19
+ * ```
20
+ *
21
+ * The container reifies its rows by running each ITEM's preview closure — see
22
+ * {@link ArrayPreview} / {@link RecordPreview}. (Previews used to be declared
23
+ * on the container instead; a `.preview` on an array/record now previews the
24
+ * array/record itself as a value, for when IT is the item of something.)
25
+ */
26
+ /**
27
+ * What a preview shows for one value: the user's `preview` callback returns
28
+ * this, and the Studio draws a row from it.
8
29
  *
9
30
  * NB: {@link ArrayPreview} / {@link RecordPreview} name the DATA a container
10
31
  * previews with. The Studio also has React components called `ArrayPreview` /
@@ -18,6 +39,23 @@ export type PreviewItem = {
18
39
  subtitle?: string | null;
19
40
  image?: ImageSource | null;
20
41
  };
42
+ /**
43
+ * What `.preview(...)` takes, on every schema: the value's own source in, a
44
+ * {@link PreviewItem} out. `NonNullable` because a container skips null items
45
+ * rather than previewing them.
46
+ *
47
+ * Declared through method syntax deliberately (the same bivariance shape
48
+ * React's event handler types use): `nullable()` copies a schema's closure
49
+ * into the `Src | null` variant of the same class, and with a plain function
50
+ * type the checker cannot see that `NonNullable<Src | null>` IS
51
+ * `NonNullable<Src>` while `Src` is still a type parameter — every schema's
52
+ * `nullable()` would need a cast instead.
53
+ */
54
+ export type ItemPreviewInput<Src> = {
55
+ bivarianceHack(input: {
56
+ val: NonNullable<Src>;
57
+ }): PreviewItem;
58
+ }["bivarianceHack"];
21
59
  export type RecordPreview = {
22
60
  parent: "record";
23
61
  items: [key: string, value: PreviewItem][];
@@ -1,9 +1,19 @@
1
1
  /**
2
- * A RENDER is how one field is laid out in the editor: `s.string().render({ as:
3
- * "textarea" })`, `.render({ as: "code", language })`.
2
+ * A RENDER is how the FIELD ITSELF is laid out in the editor, and it applies
3
+ * only when you are looking at the field: `s.string().render({ as: "textarea"
4
+ * })`, `.render({ as: "code", language })`, `.render({ as: "inline" })` on an
5
+ * array/record item.
4
6
  *
5
- * It is static configuration - plain data, with no closure behind it and no
6
- * dependency on source - which is why it lives in the SERIALIZED schema
7
+ * A PREVIEW (`preview.ts`) is the other thing: how the VALUE is shown wherever
8
+ * a preview of it is needed — a list row, a reference dropdown, a search hit —
9
+ * that is, wherever the value is navigable to rather than open. The two never
10
+ * intersect: a schema can carry both, a `render` is read where the field is
11
+ * edited and a `preview` where the value is previewed. A second `.render(...)`
12
+ * on the same schema REPLACES the first (last one wins), exactly like a second
13
+ * `.preview(...)` replaces the first — they do not merge.
14
+ *
15
+ * A render is static configuration - plain data, with no closure behind it and
16
+ * no dependency on source - which is why it lives in the SERIALIZED schema
7
17
  * (`SerializedStringSchema.render`) and is read straight off it where the field
8
18
  * is drawn. There is no render pipeline, no store and no host round-trip.
9
19
  *
@@ -13,9 +23,6 @@
13
23
  * the shape it needs back is `executePreview`'s, and the honest move is to give
14
24
  * `render` its own execute/store pair again. It is NOT to re-merge the two:
15
25
  * conflating them is what this file was split up to undo.
16
- *
17
- * The dynamic, source-dependent, demand-scoped thing - what a container shows
18
- * for its items - is a PREVIEW. See `preview.ts`.
19
26
  */
20
27
  /**
21
28
  * The list is the declaration and {@link CodeLanguage} is derived from it, so
@@ -24,13 +31,35 @@
24
31
  */
25
32
  export declare const CODE_LANGUAGES: readonly ["typescript", "javascript", "javascriptreact", "typescriptreact", "json", "java", "html", "css", "xml", "markdown", "sql", "python", "rust", "php", "go", "cpp", "sass", "vue", "angular"];
26
33
  export type CodeLanguage = (typeof CODE_LANGUAGES)[number];
34
+ /**
35
+ * `{ as: "inline" }` on a field that is the ITEM of an array or record: the
36
+ * container renders the field itself inside each (sortable) row, instead of a
37
+ * clickable preview row that navigates to it. This is what a page-builder list
38
+ * is made of: `s.array(s.object({...}).render({ as: "inline" }))`.
39
+ *
40
+ * On a field that is not directly under an array or record it is inert — an
41
+ * object's fields are already laid out in place.
42
+ *
43
+ * Like every render it is static configuration (see the top of this file): it
44
+ * travels whole in the serialized schema and the editor reads it straight off
45
+ * the item schema it already has.
46
+ */
47
+ export type InlineRender = {
48
+ as: "inline";
49
+ };
50
+ /**
51
+ * What `.render(...)` takes on every field except `s.string()`, and what the
52
+ * serialized schema carries verbatim.
53
+ */
54
+ export type FieldRender = InlineRender;
27
55
  /**
28
56
  * What `s.string().render(...)` takes, and what the serialized schema carries
29
- * verbatim.
57
+ * verbatim. A string has editor layouts of its own (textarea, code) in
58
+ * addition to the container-facing `inline`.
30
59
  */
31
60
  export type StringRender = {
32
61
  as: "textarea";
33
62
  } | {
34
63
  as: "code";
35
64
  language: CodeLanguage;
36
- };
65
+ } | InlineRender;
@@ -1,14 +1,20 @@
1
1
  import { Schema, SchemaAssertResult, SelectorOfSchema, SerializedSchema } from "./index.js";
2
- import { PreviewItem, PreviewSelector, ReifiedPreview, PreviewScope } from "../preview.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview, PreviewScope } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
3
4
  import { SelectorSource } from "../selector/index.js";
4
5
  import { ModuleFilePath, SourcePath } from "../val/index.js";
5
6
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
6
7
  export type SerializedArraySchema = {
7
8
  type: "array";
9
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
10
+ render?: FieldRender;
8
11
  item: SerializedSchema;
9
12
  opt: boolean;
10
13
  /**
11
- * Set when this schema declares a `preview`.
14
+ * Set when this schema declares a `preview` — of the ARRAY ITSELF as a
15
+ * value, for when it is the item of another container. Whether this array's
16
+ * ROWS preview is carried by the ITEM's serialized schema, where the closure
17
+ * is declared.
12
18
  *
13
19
  * The preview itself cannot be serialized — it is a user closure — but whether
14
20
  * one EXISTS can be, and that is worth carrying: it lets the non-host side
@@ -22,9 +28,6 @@ export type SerializedArraySchema = {
22
28
  hidden?: boolean;
23
29
  description?: string;
24
30
  };
25
- type ArrayPreviewInput<T extends Schema<SelectorSource>> = (input: {
26
- val: PreviewSelector<T>;
27
- }) => PreviewItem;
28
31
  export declare class ArraySchema<T extends Schema<SelectorSource>, Src extends SelectorOfSchema<T>[] | null> extends Schema<Src> {
29
32
  private readonly item;
30
33
  private readonly opt;
@@ -33,7 +36,8 @@ export declare class ArraySchema<T extends Schema<SelectorSource>, Src extends S
33
36
  private readonly isHidden;
34
37
  private readonly description?;
35
38
  private readonly previewInput;
36
- constructor(item: T, opt?: boolean, customValidateFunctions?: ((src: Src) => false | string)[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ArrayPreviewInput<T> | null);
39
+ private readonly renderInput;
40
+ constructor(item: T, opt?: boolean, customValidateFunctions?: ((src: Src) => false | string)[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null, renderInput?: FieldRender | null);
37
41
  describe(description: string | null): ArraySchema<T, Src>;
38
42
  validate(validationFunction: (src: Src) => false | string): ArraySchema<T, Src>;
39
43
  protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
@@ -44,14 +48,22 @@ export declare class ArraySchema<T extends Schema<SelectorSource>, Src extends S
44
48
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
45
49
  protected executeSerialize(): SerializedArraySchema;
46
50
  protected executePreview(sourcePath: SourcePath | ModuleFilePath, src: Src, scope?: PreviewScope): ReifiedPreview;
51
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
52
+ protected declaresItemPreview(): boolean;
47
53
  /**
48
- * What the editor shows for each ITEM of this array: a title, and optionally a
49
- * subtitle and an image.
54
+ * How this ARRAY ITSELF is shown where a preview of it is needed — when it
55
+ * is the item of another container, in search, in references. What its rows
56
+ * show is the ITEM schema's `preview`, not this. Never how the field is
57
+ * edited (that is `render`). See `preview.ts`.
58
+ */
59
+ preview(select: ItemPreviewInput<Src>): ArraySchema<T, Src>;
60
+ /**
61
+ * How this field is laid out in the editor when it is the item of an array
62
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
63
+ * instead of a preview row that navigates to it.
50
64
  *
51
- * `select` is your own code over the item's source, so it is run on demand for
52
- * the rows that are actually being looked at — see `PreviewScope`.
65
+ * Static configuration, not a callback — see `render.ts`.
53
66
  */
54
- preview(select: ArrayPreviewInput<T>): ArraySchema<T, Src>;
67
+ render(input: FieldRender): ArraySchema<T, Src>;
55
68
  }
56
69
  export declare const array: <S extends Schema<SelectorSource>>(schema: S) => ArraySchema<S, SelectorOfSchema<S>[]>;
57
- export {};
@@ -1,9 +1,14 @@
1
1
  import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
- import { ReifiedPreview } from "../preview.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
3
4
  import { SourcePath } from "../val/index.js";
4
5
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
5
6
  export type SerializedBooleanSchema = {
6
7
  type: "boolean";
8
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
9
+ render?: FieldRender;
10
+ /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
11
+ preview?: true;
7
12
  opt: boolean;
8
13
  customValidate?: boolean;
9
14
  readonly?: boolean;
@@ -16,7 +21,9 @@ export declare class BooleanSchema<Src extends boolean | null> extends Schema<Sr
16
21
  private readonly isReadonly;
17
22
  private readonly isHidden;
18
23
  private readonly description?;
19
- constructor(opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined);
24
+ private readonly renderInput;
25
+ private readonly previewInput;
26
+ constructor(opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
20
27
  describe(description: string | null): BooleanSchema<Src>;
21
28
  validate(validationFunction: (src: Src) => false | string): BooleanSchema<Src>;
22
29
  protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
@@ -25,6 +32,22 @@ export declare class BooleanSchema<Src extends boolean | null> extends Schema<Sr
25
32
  readonly(): BooleanSchema<Src>;
26
33
  hidden(): BooleanSchema<Src>;
27
34
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
35
+ /**
36
+ * How this field is laid out in the editor when it is the item of an array
37
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
38
+ * instead of a preview row that navigates to it.
39
+ *
40
+ * Static configuration, not a callback — see `render.ts`.
41
+ */
42
+ render(input: FieldRender): BooleanSchema<Src>;
43
+ /**
44
+ * How this VALUE is shown where a preview of it is needed — a row in a
45
+ * sortable list, a reference dropdown, a search hit. Never how the field
46
+ * itself is edited (that is `render`). See `preview.ts`.
47
+ */
48
+ preview(select: ItemPreviewInput<Src>): BooleanSchema<Src>;
49
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
50
+ protected declaresItemPreview(): boolean;
28
51
  protected executeSerialize(): SerializedSchema;
29
52
  protected executePreview(): ReifiedPreview;
30
53
  }
@@ -1,5 +1,6 @@
1
1
  import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
- import { ReifiedPreview } from "../preview.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
3
4
  import { SourcePath } from "../val/index.js";
4
5
  import { ColorFormat } from "./colorFormat.js";
5
6
  import { RawString } from "./string.js";
@@ -28,6 +29,10 @@ export type ColorOptions = {
28
29
  };
29
30
  export type SerializedColorSchema = {
30
31
  type: "color";
32
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
33
+ render?: FieldRender;
34
+ /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
35
+ preview?: true;
31
36
  options?: ColorOptions;
32
37
  opt: boolean;
33
38
  customValidate?: boolean;
@@ -42,7 +47,9 @@ export declare class ColorSchema<Src extends string | null> extends Schema<Src>
42
47
  private readonly isReadonly;
43
48
  private readonly isHidden;
44
49
  private readonly description?;
45
- constructor(options?: ColorOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined);
50
+ private readonly renderInput;
51
+ private readonly previewInput;
52
+ constructor(options?: ColorOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
46
53
  describe(description: string | null): ColorSchema<Src>;
47
54
  validate(validationFunction: (src: Src) => false | string): ColorSchema<Src>;
48
55
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
@@ -51,6 +58,22 @@ export declare class ColorSchema<Src extends string | null> extends Schema<Src>
51
58
  nullable(): ColorSchema<Src | null>;
52
59
  readonly(): ColorSchema<Src>;
53
60
  hidden(): ColorSchema<Src>;
61
+ /**
62
+ * How this field is laid out in the editor when it is the item of an array
63
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
64
+ * instead of a preview row that navigates to it.
65
+ *
66
+ * Static configuration, not a callback — see `render.ts`.
67
+ */
68
+ render(input: FieldRender): ColorSchema<Src>;
69
+ /**
70
+ * How this VALUE is shown where a preview of it is needed — a row in a
71
+ * sortable list, a reference dropdown, a search hit. Never how the field
72
+ * itself is edited (that is `render`). See `preview.ts`.
73
+ */
74
+ preview(select: ItemPreviewInput<Src>): ColorSchema<Src>;
75
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
76
+ protected declaresItemPreview(): boolean;
54
77
  protected executeSerialize(): SerializedSchema;
55
78
  protected executePreview(): ReifiedPreview;
56
79
  }
@@ -1,5 +1,6 @@
1
1
  import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
- import { ReifiedPreview } from "../preview.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
3
4
  import { SourcePath } from "../val/index.js";
4
5
  import { RawString } from "./string.js";
5
6
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
@@ -21,6 +22,10 @@ type DateOptions = {
21
22
  };
22
23
  export type SerializedDateSchema = {
23
24
  type: "date";
25
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
26
+ render?: FieldRender;
27
+ /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
28
+ preview?: true;
24
29
  options?: DateOptions;
25
30
  opt: boolean;
26
31
  customValidate?: boolean;
@@ -35,7 +40,9 @@ export declare class DateSchema<Src extends string | null> extends Schema<Src> {
35
40
  private readonly isReadonly;
36
41
  private readonly isHidden;
37
42
  private readonly description?;
38
- constructor(options?: DateOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined);
43
+ private readonly renderInput;
44
+ private readonly previewInput;
45
+ constructor(options?: DateOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
39
46
  describe(description: string | null): DateSchema<Src>;
40
47
  validate(validationFunction: (src: Src) => false | string): DateSchema<Src>;
41
48
  protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
@@ -46,6 +53,22 @@ export declare class DateSchema<Src extends string | null> extends Schema<Src> {
46
53
  readonly(): DateSchema<Src>;
47
54
  hidden(): DateSchema<Src>;
48
55
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
56
+ /**
57
+ * How this field is laid out in the editor when it is the item of an array
58
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
59
+ * instead of a preview row that navigates to it.
60
+ *
61
+ * Static configuration, not a callback — see `render.ts`.
62
+ */
63
+ render(input: FieldRender): DateSchema<Src>;
64
+ /**
65
+ * How this VALUE is shown where a preview of it is needed — a row in a
66
+ * sortable list, a reference dropdown, a search hit. Never how the field
67
+ * itself is edited (that is `render`). See `preview.ts`.
68
+ */
69
+ preview(select: ItemPreviewInput<Src>): DateSchema<Src>;
70
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
71
+ protected declaresItemPreview(): boolean;
49
72
  protected executeSerialize(): SerializedSchema;
50
73
  protected executePreview(): ReifiedPreview;
51
74
  }
@@ -1,5 +1,6 @@
1
1
  import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
- import { ReifiedPreview } from "../preview.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
3
4
  import { SourcePath } from "../val/index.js";
4
5
  import { RawString } from "./string.js";
5
6
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
@@ -25,6 +26,10 @@ type DateTimeOptions = {
25
26
  };
26
27
  export type SerializedDateTimeSchema = {
27
28
  type: "dateTime";
29
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
30
+ render?: FieldRender;
31
+ /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
32
+ preview?: true;
28
33
  options?: DateTimeOptions;
29
34
  opt: boolean;
30
35
  customValidate?: boolean;
@@ -39,7 +44,9 @@ export declare class DateTimeSchema<Src extends string | null> extends Schema<Sr
39
44
  private readonly isReadonly;
40
45
  private readonly isHidden;
41
46
  private readonly description?;
42
- constructor(options?: DateTimeOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined);
47
+ private readonly renderInput;
48
+ private readonly previewInput;
49
+ constructor(options?: DateTimeOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
43
50
  describe(description: string | null): DateTimeSchema<Src>;
44
51
  validate(validationFunction: (src: Src) => false | string): DateTimeSchema<Src>;
45
52
  protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
@@ -50,6 +57,22 @@ export declare class DateTimeSchema<Src extends string | null> extends Schema<Sr
50
57
  readonly(): DateTimeSchema<Src>;
51
58
  hidden(): DateTimeSchema<Src>;
52
59
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
60
+ /**
61
+ * How this field is laid out in the editor when it is the item of an array
62
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
63
+ * instead of a preview row that navigates to it.
64
+ *
65
+ * Static configuration, not a callback — see `render.ts`.
66
+ */
67
+ render(input: FieldRender): DateTimeSchema<Src>;
68
+ /**
69
+ * How this VALUE is shown where a preview of it is needed — a row in a
70
+ * sortable list, a reference dropdown, a search hit. Never how the field
71
+ * itself is edited (that is `render`). See `preview.ts`.
72
+ */
73
+ preview(select: ItemPreviewInput<Src>): DateTimeSchema<Src>;
74
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
75
+ protected declaresItemPreview(): boolean;
53
76
  protected executeSerialize(): SerializedSchema;
54
77
  protected executePreview(): ReifiedPreview;
55
78
  }
@@ -4,13 +4,18 @@ import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema }
4
4
  import { ModulePath, SourcePath } from "../val/index.js";
5
5
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
6
6
  import { ValModule } from "../index.js";
7
- import { ReifiedPreview } from "../preview.js";
7
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
8
+ import { FieldRender } from "../render.js";
8
9
  import { FilesEntryMetadata } from "./files.js";
9
10
  export type FileOptions = {
10
11
  accept?: string;
11
12
  };
12
13
  export type SerializedFileSchema = {
13
14
  type: "file";
15
+ /** Static layout config, carried whole in the serialized schema — see `render.ts`. */
16
+ render?: FieldRender;
17
+ /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
18
+ preview?: true;
14
19
  options?: FileOptions;
15
20
  remote?: boolean;
16
21
  opt: boolean;
@@ -29,7 +34,9 @@ export declare class FileSchema<Src extends FileSource | null> extends Schema<Sr
29
34
  private readonly isReadonly;
30
35
  private readonly isHidden;
31
36
  private readonly description?;
32
- constructor(options?: FileOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string, FilesEntryMetadata>>, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined);
37
+ private readonly renderInput;
38
+ private readonly previewInput;
39
+ constructor(options?: FileOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string, FilesEntryMetadata>>, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
33
40
  describe(description: string | null): FileSchema<Src>;
34
41
  remote(): FileSchema<Src>;
35
42
  validate(validationFunction: CustomValidateFunction<Src>): FileSchema<Src>;
@@ -44,6 +51,22 @@ export declare class FileSchema<Src extends FileSource | null> extends Schema<Sr
44
51
  readonly(): FileSchema<Src>;
45
52
  hidden(): FileSchema<Src>;
46
53
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
54
+ /**
55
+ * How this field is laid out in the editor when it is the item of an array
56
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
57
+ * instead of a preview row that navigates to it.
58
+ *
59
+ * Static configuration, not a callback — see `render.ts`.
60
+ */
61
+ render(input: FieldRender): FileSchema<Src>;
62
+ /**
63
+ * How this VALUE is shown where a preview of it is needed — a row in a
64
+ * sortable list, a reference dropdown, a search hit. Never how the field
65
+ * itself is edited (that is `render`). See `preview.ts`.
66
+ */
67
+ preview(select: ItemPreviewInput<Src>): FileSchema<Src>;
68
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
69
+ protected declaresItemPreview(): boolean;
47
70
  protected executeSerialize(): SerializedSchema;
48
71
  protected executePreview(): ReifiedPreview;
49
72
  }