@valbuild/core 0.110.0 → 0.111.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.
@@ -51,6 +51,7 @@ export { type SerializedImageSchema, ImageSchema } from "./schema/image.js";
51
51
  export { type SerializedFileSchema, FileSchema } from "./schema/file.js";
52
52
  export { type SerializedDateSchema, DateSchema } from "./schema/date.js";
53
53
  export { type SerializedColorSchema, type ColorOptions, ColorSchema, } from "./schema/color.js";
54
+ export { type SerializedCodeSchema, type CodeOptions, type CodeLanguage, CodeSchema, CODE_LANGUAGES, } from "./schema/code.js";
54
55
  export { type ColorFormat, type ParsedColor, COLOR_FORMATS, DEFAULT_COLOR_FORMAT, } from "./schema/colorFormat.js";
55
56
  export { type SerializedDateTimeSchema, DateTimeSchema, } from "./schema/datetime.js";
56
57
  export { type SerializedKeyOfSchema, KeyOfSchema } from "./schema/keyOf.js";
@@ -60,7 +61,7 @@ export { type SerializedUnionSchema, UnionSchema, type SerializedStringUnionSche
60
61
  export { type SerializedLiteralSchema, LiteralSchema } from "./schema/literal.js";
61
62
  export { deserializeSchema } from "./schema/deserialize.js";
62
63
  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, isInlineRender, } from "./render.js";
64
+ export { type InlineRender, type FieldRender, isInlineRender } from "./render.js";
64
65
  export type { ValRouter, RouteValidationError } from "./router.js";
65
66
  export { getSourcePathFromRoute } from "./getSourcePathFromRoute.js";
66
67
  export declare const FATAL_ERROR_TYPES: readonly ["no-schema", "no-source", "invalid-id", "no-module", "invalid-patch"];
@@ -13,6 +13,7 @@ import { file } from "./schema/file.js";
13
13
  import { files } from "./schema/files.js";
14
14
  import { date } from "./schema/date.js";
15
15
  import { datetime } from "./schema/datetime.js";
16
+ import { code } from "./schema/code.js";
16
17
  import { color } from "./schema/color.js";
17
18
  import { route } from "./schema/route.js";
18
19
  import { router } from "./schema/router.js";
@@ -206,6 +207,23 @@ export type InitSchema = {
206
207
  *
207
208
  */
208
209
  readonly color: typeof color;
210
+ /**
211
+ * Define a string edited in a code editor.
212
+ *
213
+ * Pass a `language` to syntax highlight it; leave it out for a plain
214
+ * monospaced editor. The value is a plain string, and — unlike `s.string()` —
215
+ * it is never stega encoded, so the code reaches your app as it was written.
216
+ *
217
+ * @example
218
+ * const schema = s.code({ language: "typescript" });
219
+ * export default c.define("/example.val.ts", schema, "const a = 1;");
220
+ *
221
+ * @example
222
+ * const schema = s.code();
223
+ * export default c.define("/example.val.ts", schema, "no highlighting here");
224
+ *
225
+ */
226
+ readonly code: typeof code;
209
227
  /**
210
228
  * Define a string that references a route path in your application.
211
229
  *
@@ -317,6 +335,7 @@ export declare function initSchema(): {
317
335
  date: (options?: Record<string, never>) => import("./index.js").DateSchema<import("./index.js").RawString>;
318
336
  datetime: (options?: Record<string, never>) => import("./index.js").DateTimeSchema<import("./index.js").RawString>;
319
337
  color: (options?: import("./index.js").ColorOptions) => import("./index.js").ColorSchema<import("./index.js").RawString>;
338
+ code: (options?: import("./index.js").CodeOptions) => import("./index.js").CodeSchema<import("./index.js").RawString>;
320
339
  route: <T extends string>(options?: Record<string, never>) => import("./index.js").RouteSchema<T>;
321
340
  router: typeof router;
322
341
  images: <Accept extends `image/${string}`>(options: import("./schema/images.js").ImagesOptions<Accept>) => import("./index.js").RecordSchema<import("./index.js").ObjectSchema<{
@@ -1,10 +1,14 @@
1
1
  import type { SerializedSchema } from "./schema/index.js";
2
2
  /**
3
3
  * A RENDER is how the FIELD ITSELF is laid out in the editor, and it applies
4
- * only when you are looking at the field: `s.string().render({ as: "textarea"
5
- * })`, `.render({ as: "code", language })`, `.render({ as: "inline" })` on an
4
+ * only when you are looking at the field: `.render({ as: "inline" })` on an
6
5
  * array/record item.
7
6
  *
7
+ * It is deliberately the ONE thing a render can say. What a string looks like
8
+ * when it holds more than a line is the schema's own business — `.multiline()`
9
+ * for a text box, `s.code({ language })` for a code editor — not a layout
10
+ * bolted onto `s.string()` from outside.
11
+ *
8
12
  * A PREVIEW (`preview.ts`) is the other thing: how the VALUE is shown wherever
9
13
  * a preview of it is needed — a list row, a reference dropdown, a search hit —
10
14
  * that is, wherever the value is navigable to rather than open. The two never
@@ -25,13 +29,6 @@ import type { SerializedSchema } from "./schema/index.js";
25
29
  * `render` its own execute/store pair again. It is NOT to re-merge the two:
26
30
  * conflating them is what this file was split up to undo.
27
31
  */
28
- /**
29
- * The list is the declaration and {@link CodeLanguage} is derived from it, so
30
- * that a validator elsewhere (`shared`'s zod schema) can enumerate the same
31
- * languages without a second copy that drifts. Same shape as `COLOR_FORMATS`.
32
- */
33
- 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"];
34
- export type CodeLanguage = (typeof CODE_LANGUAGES)[number];
35
32
  /**
36
33
  * `{ as: "inline" }` on a field that is the ITEM of an array or record: the
37
34
  * container renders the field itself inside each (sortable) row, instead of a
@@ -49,21 +46,10 @@ export type InlineRender = {
49
46
  as: "inline";
50
47
  };
51
48
  /**
52
- * What `.render(...)` takes on every field except `s.string()`, and what the
53
- * serialized schema carries verbatim.
49
+ * What `.render(...)` takes on every field, and what the serialized schema
50
+ * carries verbatim.
54
51
  */
55
52
  export type FieldRender = InlineRender;
56
- /**
57
- * What `s.string().render(...)` takes, and what the serialized schema carries
58
- * verbatim. A string has editor layouts of its own (textarea, code) in
59
- * addition to the container-facing `inline`.
60
- */
61
- export type StringRender = {
62
- as: "textarea";
63
- } | {
64
- as: "code";
65
- language: CodeLanguage;
66
- } | InlineRender;
67
53
  /**
68
54
  * Is this item schema edited INSIDE its list row, rather than behind a
69
55
  * clickable preview row that navigates to it?
@@ -0,0 +1,85 @@
1
+ import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
+ import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
+ import { FieldRender } from "../render.js";
4
+ import { SourcePath } from "../val/index.js";
5
+ import { RawString } from "./string.js";
6
+ import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
7
+ /**
8
+ * The list is the declaration and {@link CodeLanguage} is derived from it, so
9
+ * that a validator elsewhere (`shared`'s zod schema) can enumerate the same
10
+ * languages without a second copy that drifts. Same shape as `COLOR_FORMATS`.
11
+ */
12
+ 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"];
13
+ export type CodeLanguage = (typeof CODE_LANGUAGES)[number];
14
+ export type CodeOptions = {
15
+ /**
16
+ * The language to syntax highlight the editor with.
17
+ *
18
+ * Omit it for a plain monospaced editor with no highlighting.
19
+ *
20
+ * @example
21
+ * "typescript"
22
+ * "json"
23
+ * "markdown"
24
+ */
25
+ language?: CodeLanguage;
26
+ };
27
+ export type SerializedCodeSchema = {
28
+ type: "code";
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;
33
+ options?: CodeOptions;
34
+ opt: boolean;
35
+ customValidate?: boolean;
36
+ readonly?: boolean;
37
+ hidden?: boolean;
38
+ description?: string;
39
+ };
40
+ /**
41
+ * A string edited in a code editor.
42
+ *
43
+ * Its own schema type rather than a layout on `s.string()`: the language is
44
+ * part of what the content IS, not of how one field happens to be drawn, and
45
+ * being a type is what lets the value stay out of stega encoding — invisible
46
+ * characters woven into source code are not something a consumer can render.
47
+ */
48
+ export declare class CodeSchema<Src extends string | null> extends Schema<Src> {
49
+ private readonly options?;
50
+ private readonly opt;
51
+ private readonly customValidateFunctions;
52
+ private readonly isReadonly;
53
+ private readonly isHidden;
54
+ private readonly description?;
55
+ private readonly renderInput;
56
+ private readonly previewInput;
57
+ constructor(options?: CodeOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, renderInput?: FieldRender | null, previewInput?: ItemPreviewInput<Src> | null);
58
+ describe(description: string | null): CodeSchema<Src>;
59
+ validate(validationFunction: (src: Src) => false | string): CodeSchema<Src>;
60
+ protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
61
+ protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
62
+ protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
63
+ nullable(): CodeSchema<Src | null>;
64
+ readonly(): CodeSchema<Src>;
65
+ hidden(): CodeSchema<Src>;
66
+ /**
67
+ * How this field is laid out in the editor when it is the item of an array
68
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
69
+ * instead of a preview row that navigates to it.
70
+ *
71
+ * Static configuration, not a callback — see `render.ts`.
72
+ */
73
+ render(input: FieldRender): CodeSchema<Src>;
74
+ /**
75
+ * How this VALUE is shown where a preview of it is needed — a row in a
76
+ * sortable list, a reference dropdown, a search hit. Never how the field
77
+ * itself is edited (that is `render`). See `preview.ts`.
78
+ */
79
+ preview(select: ItemPreviewInput<Src>): CodeSchema<Src>;
80
+ protected executePreviewItem(src: NonNullable<Src>): PreviewItem | null;
81
+ protected declaresItemPreview(): boolean;
82
+ protected executeSerialize(): SerializedSchema;
83
+ protected executePreview(): ReifiedPreview;
84
+ }
85
+ export declare const code: (options?: CodeOptions) => CodeSchema<RawString>;
@@ -12,6 +12,7 @@ import { SerializedRecordSchema } from "./record.js";
12
12
  import { SerializedRichTextSchema } from "./richtext.js";
13
13
  import { RawString, SerializedStringSchema } from "./string.js";
14
14
  import { SerializedUnionSchema } from "./union.js";
15
+ import { SerializedCodeSchema } from "./code.js";
15
16
  import { SerializedColorSchema } from "./color.js";
16
17
  import { SerializedDateSchema } from "./date.js";
17
18
  import { SerializedDateTimeSchema } from "./datetime.js";
@@ -20,7 +21,7 @@ import { ValidationError, ValidationErrors } from "./validation/ValidationError.
20
21
  import { FileSource } from "../source/media.js";
21
22
  import { GenericRichTextSourceNode, RichTextSource } from "../source/richtext.js";
22
23
  import { ReifiedPreview, PreviewScope, PreviewItem } from "../preview.js";
23
- export type SerializedSchema = SerializedStringSchema | SerializedLiteralSchema | SerializedBooleanSchema | SerializedNumberSchema | SerializedObjectSchema | SerializedArraySchema | SerializedUnionSchema | SerializedRichTextSchema | SerializedRecordSchema | SerializedKeyOfSchema | SerializedFileSchema | SerializedDateSchema | SerializedDateTimeSchema | SerializedColorSchema | SerializedRouteSchema | SerializedImageSchema;
24
+ export type SerializedSchema = SerializedStringSchema | SerializedLiteralSchema | SerializedBooleanSchema | SerializedNumberSchema | SerializedObjectSchema | SerializedArraySchema | SerializedUnionSchema | SerializedRichTextSchema | SerializedRecordSchema | SerializedKeyOfSchema | SerializedFileSchema | SerializedDateSchema | SerializedDateTimeSchema | SerializedColorSchema | SerializedCodeSchema | SerializedRouteSchema | SerializedImageSchema;
24
25
  type Primitives = number | string | boolean | null | FileSource;
25
26
  export type AssertError = {
26
27
  message: string;
@@ -1,6 +1,6 @@
1
1
  import { Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
2
2
  import { ItemPreviewInput, PreviewItem, ReifiedPreview } from "../preview.js";
3
- import { StringRender } from "../render.js";
3
+ import { FieldRender } from "../render.js";
4
4
  import { SourcePath } from "../val/index.js";
5
5
  import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
6
6
  type StringOptions = {
@@ -20,7 +20,17 @@ export type SerializedStringSchema = {
20
20
  * off the schema it already has. See `render.ts` for what that assumption
21
21
  * buys, and what to do if a render ever needs to stop being static.
22
22
  */
23
- render?: StringRender;
23
+ render?: FieldRender;
24
+ /**
25
+ * Set by `.multiline()`: the field is a growing text box rather than a
26
+ * single-line input.
27
+ *
28
+ * A property of the schema rather than a `render` variant, because it says
29
+ * what the string IS — text that may hold line breaks — and not merely how one
30
+ * field is drawn. It is read the same way a render is, straight off the
31
+ * serialized schema where the field is drawn.
32
+ */
33
+ multiline?: boolean;
24
34
  /** Set when this schema declares a `preview`. The closure itself cannot serialize. */
25
35
  preview?: true;
26
36
  options?: {
@@ -54,7 +64,8 @@ export declare class StringSchema<Src extends string | null> extends Schema<Src>
54
64
  private readonly isHidden;
55
65
  private readonly description?;
56
66
  private readonly previewInput;
57
- constructor(options?: StringOptions | undefined, opt?: boolean, isRaw?: boolean, customValidateFunctions?: ((src: Src) => false | string)[], renderInput?: StringRender | null, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null);
67
+ private readonly isMultiline;
68
+ constructor(options?: StringOptions | undefined, opt?: boolean, isRaw?: boolean, customValidateFunctions?: ((src: Src) => false | string)[], renderInput?: FieldRender | null, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null, isMultiline?: boolean);
58
69
  describe(description: string | null): StringSchema<Src>;
59
70
  /**
60
71
  * @deprecated Use `minLength` instead
@@ -77,13 +88,27 @@ export declare class StringSchema<Src extends string | null> extends Schema<Src>
77
88
  protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
78
89
  protected executeSerialize(): SerializedSchema;
79
90
  /**
80
- * How this field is laid out in the editor: a textarea, or a code editor for
81
- * the given language.
91
+ * This string holds text that may run to several lines: the editor gives it a
92
+ * growing text box instead of a single-line input.
93
+ *
94
+ * Nothing else changes — the value is still a plain string, and no validation
95
+ * is added or removed. For code, use `s.code({ language })` instead, which is
96
+ * its own schema type.
97
+ *
98
+ * @example
99
+ * const schema = s.string().multiline();
100
+ * export default c.define("/example.val.ts", schema, "Line one\nLine two");
101
+ */
102
+ multiline(): StringSchema<Src>;
103
+ /**
104
+ * How this field is laid out in the editor when it is the item of an array or
105
+ * record: `{ as: "inline" }` renders the field itself inside each row,
106
+ * instead of a preview row that navigates to it.
82
107
  *
83
108
  * Static configuration, not a callback — see `render.ts`. What a CONTAINER
84
109
  * shows for its items is a `preview`, which is a different thing entirely.
85
110
  */
86
- render(input: StringRender): StringSchema<Src>;
111
+ render(input: FieldRender): StringSchema<Src>;
87
112
  /**
88
113
  * How this VALUE is shown where a preview of it is needed — a row in a
89
114
  * sortable list, a reference dropdown, a search hit. Never how the field