@valbuild/core 0.143.0 → 0.145.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 +60 -0
- package/dist/declarations/src/index.d.ts +16 -4
- package/dist/declarations/src/initSchema.d.ts +107 -26
- package/dist/declarations/src/initVal.d.ts +2 -2
- package/dist/declarations/src/mimeType/font.d.ts +2 -2
- package/dist/declarations/src/render.d.ts +39 -6
- package/dist/declarations/src/schema/file.d.ts +4 -4
- package/dist/declarations/src/schema/filedir.d.ts +83 -0
- package/dist/declarations/src/schema/font.d.ts +4 -4
- package/dist/declarations/src/schema/fontdir.d.ts +63 -0
- package/dist/declarations/src/schema/hasRemoteFileSchema.d.ts +3 -3
- package/dist/declarations/src/schema/image.d.ts +4 -4
- package/dist/declarations/src/schema/{imageset.d.ts → imagedir.d.ts} +63 -29
- package/dist/declarations/src/schema/number.d.ts +45 -5
- package/dist/declarations/src/schema/numberRules.d.ts +27 -0
- package/dist/declarations/src/schema/record.d.ts +17 -6
- package/dist/declarations/src/schema/video.d.ts +7 -7
- package/dist/declarations/src/schema/{videoset.d.ts → videodir.d.ts} +55 -27
- package/dist/declarations/src/source/media.d.ts +26 -3
- package/dist/{index-02a1ba06.esm.js → index-307b907e.esm.js} +601 -122
- package/dist/{index-46c72f01.cjs.prod.js → index-93763025.cjs.prod.js} +601 -122
- package/dist/{index-aac8c69c.cjs.dev.js → index-ee601322.cjs.dev.js} +601 -122
- package/dist/valbuild-core.cjs.dev.js +1 -1
- package/dist/valbuild-core.cjs.prod.js +1 -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
- package/dist/declarations/src/schema/fileset.d.ts +0 -57
- package/dist/declarations/src/schema/fontset.d.ts +0 -40
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { filedir } from "./filedir.js";
|
|
2
|
+
import type { MediaDir } from "./record.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for `s.fontdir(dir, options)`: everything but the directory, which
|
|
5
|
+
* is the first argument.
|
|
6
|
+
*/
|
|
7
|
+
export type FontdirOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* The accepted font types. Defaults to every web font format:
|
|
10
|
+
* `"font/woff2,font/woff,font/ttf,font/otf"`. Narrow it to `"font/woff2"` to
|
|
11
|
+
* keep the site's fonts to the one format every current browser reads and
|
|
12
|
+
* that is smallest on the wire.
|
|
13
|
+
*/
|
|
14
|
+
accept?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Options for the deprecated `s.fontset(options)`, which took the directory
|
|
18
|
+
* as `dir`.
|
|
19
|
+
*
|
|
20
|
+
* @deprecated Use `s.fontdir(dir, options)` and `FontdirOptions`.
|
|
21
|
+
*/
|
|
22
|
+
export type FontsetOptions = FontdirOptions & {
|
|
23
|
+
/**
|
|
24
|
+
* The directory where fonts should be stored.
|
|
25
|
+
* Must start with "/public" (e.g., "/public/val/fonts")
|
|
26
|
+
*/
|
|
27
|
+
dir: MediaDir;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Define a directory of fonts.
|
|
31
|
+
*
|
|
32
|
+
* A fontdir IS a filedir — the same source, the same `s.font(fontsVal)` field
|
|
33
|
+
* to pick from it, the same checks and fixes — with `accept` defaulting to the
|
|
34
|
+
* web font formats. What a font gets that any other file does not is decided
|
|
35
|
+
* by its mime type rather than by the directory: the Studio previews any file
|
|
36
|
+
* it knows is a font, wherever it is shown.
|
|
37
|
+
*
|
|
38
|
+
* Remote is off by default: call `.remote()` on the result to allow remote files.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const schema = s.fontdir("/public/val/fonts");
|
|
43
|
+
* export default c.define("/content/fonts.val.ts", schema, {
|
|
44
|
+
* "/public/val/fonts/inter_a1b2c.woff2": {
|
|
45
|
+
* mimeType: "font/woff2",
|
|
46
|
+
* },
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const fontdir: (dir: MediaDir, options?: FontdirOptions) => ReturnType<typeof filedir>;
|
|
51
|
+
/**
|
|
52
|
+
* Define a collection of fonts.
|
|
53
|
+
*
|
|
54
|
+
* @deprecated Use `s.fontdir(dir, options)`: the directory moved out of the
|
|
55
|
+
* options and into the first argument, and nothing else changed.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // was: s.fontset({ dir: "/public/val/fonts" })
|
|
60
|
+
* const schema = s.fontdir("/public/val/fonts");
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const fontset: (options: FontsetOptions) => ReturnType<typeof filedir>;
|
|
@@ -5,7 +5,7 @@ import type { SerializedSchema } from "./index.js";
|
|
|
5
5
|
* The one answer to that question. There used to be two — `hasRemoteFileSchema`
|
|
6
6
|
* in the server, gating whether `/save` demands remote credentials, and
|
|
7
7
|
* `findRequiredRemoteFiles` in the Studio, gating the `/remote/settings` fetch —
|
|
8
|
-
* and they disagreed about `s.
|
|
8
|
+
* and they disagreed about `s.imagedir(dir, { ... }).remote()`: the Studio's version
|
|
9
9
|
* counted a remote media record, the server's did not, because a media
|
|
10
10
|
* collection serializes as a `record` of metadata rather than as an image
|
|
11
11
|
* schema.
|
|
@@ -43,8 +43,8 @@ export declare function hasRemoteFileSchema(schema: SerializedSchema): boolean;
|
|
|
43
43
|
*
|
|
44
44
|
* It is a walk over the SERIALIZED schema for the reasons given above, and for
|
|
45
45
|
* one more that is specific to this question: the two cases most likely to be
|
|
46
|
-
* missed are invisible to a value type. A media collection (`s.
|
|
47
|
-
* `s.
|
|
46
|
+
* missed are invisible to a value type. A media collection (`s.imagedir()` /
|
|
47
|
+
* `s.filedir()`) serializes as a record of metadata with no image schema inside
|
|
48
48
|
* it, and a richtext inline image lives in a constructor argument. A check
|
|
49
49
|
* written against the item TYPE would silently pass both — and the gallery case
|
|
50
50
|
* already has a data-loss incident attached to it (see above).
|
|
@@ -4,7 +4,7 @@ import { ModulePath, SourcePath } from "../val/index.js";
|
|
|
4
4
|
import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
|
|
5
5
|
import { ValModule } from "../index.js";
|
|
6
6
|
import { ItemPreviewInput, PreviewItem } from "../preview.js";
|
|
7
|
-
import { AltSource,
|
|
7
|
+
import { AltSource, ImagedirEntryMetadata } from "./imagedir.js";
|
|
8
8
|
/**
|
|
9
9
|
* How an uploaded image is re-encoded in the browser, before it is uploaded.
|
|
10
10
|
*
|
|
@@ -77,7 +77,7 @@ export declare class ImageSchema<Src extends ImageSource | null> extends Schema<
|
|
|
77
77
|
private readonly isHidden;
|
|
78
78
|
private readonly description?;
|
|
79
79
|
private readonly previewInput;
|
|
80
|
-
constructor(options?: ImageOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string,
|
|
80
|
+
constructor(options?: ImageOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string, ImagedirEntryMetadata<AltSource>>>, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null);
|
|
81
81
|
/**
|
|
82
82
|
* Describe this field.
|
|
83
83
|
*
|
|
@@ -204,7 +204,7 @@ export declare class ImageSchema<Src extends ImageSource | null> extends Schema<
|
|
|
204
204
|
* An image picked from a gallery. Its dimensions and mime type live in the
|
|
205
205
|
* gallery, so the field carries only what a person typed.
|
|
206
206
|
*/
|
|
207
|
-
export declare function image(galleryModule: ValModule<Record<string,
|
|
207
|
+
export declare function image(galleryModule: ValModule<Record<string, ImagedirEntryMetadata<AltSource>>>, galleryOptions?: GalleryImageOptions): ImageSchema<GalleryImageSource>;
|
|
208
208
|
/** An image of its own, carrying its own dimensions and mime type. */
|
|
209
209
|
export declare function image(options?: ImageOptions): ImageSchema<ImageSource>;
|
|
210
210
|
/**
|
|
@@ -212,5 +212,5 @@ export declare function image(options?: ImageOptions): ImageSchema<ImageSource>;
|
|
|
212
212
|
* `val.config.ts`): the same schema, with `.remote()` already applied. See
|
|
213
213
|
* `initSchema`.
|
|
214
214
|
*/
|
|
215
|
-
export declare function remoteImage(galleryModule: ValModule<Record<string,
|
|
215
|
+
export declare function remoteImage(galleryModule: ValModule<Record<string, ImagedirEntryMetadata<AltSource>>>, galleryOptions?: GalleryImageOptions): ImageSchema<GalleryImageSource>;
|
|
216
216
|
export declare function remoteImage(options?: ImageOptions): ImageSchema<ImageSource>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Schema } from "./index.js";
|
|
2
2
|
import type { SelectorOfSchema } from "./index.js";
|
|
3
|
-
import type { SerializedRecordSchema } from "./record.js";
|
|
3
|
+
import type { MediaDir, SerializedRecordSchema } from "./record.js";
|
|
4
4
|
import { RecordSchema } from "./record.js";
|
|
5
5
|
import { ObjectSchema } from "./object.js";
|
|
6
6
|
import { StringSchema } from "./string.js";
|
|
@@ -22,18 +22,32 @@ export type AltSourceOf<Alt extends AltSchema> = SelectorOfSchema<Alt>;
|
|
|
22
22
|
/** Every `alt` value any `AltSchema` can produce. */
|
|
23
23
|
export type AltSource = AltSourceOf<AltSchema>;
|
|
24
24
|
/**
|
|
25
|
-
* Options for s.
|
|
25
|
+
* Options for `s.imagedir(dir, options)`: everything but the directory, which
|
|
26
|
+
* is the first argument.
|
|
26
27
|
*/
|
|
27
|
-
export type
|
|
28
|
+
export type ImagedirOptions<Accept extends `image/${string}`, Alt extends AltSchema = StringSchema<string | null>> = ImagedirOptionsBase<Accept> & ImagedirAltOption<Alt>;
|
|
29
|
+
/**
|
|
30
|
+
* Options for the deprecated `s.imageset(options)`, which took the directory
|
|
31
|
+
* as `dir`.
|
|
32
|
+
*
|
|
33
|
+
* @deprecated Use `s.imagedir(dir, options)` and `ImagedirOptions`.
|
|
34
|
+
*/
|
|
35
|
+
export type ImagesetOptions<Accept extends `image/${string}`, Alt extends AltSchema = StringSchema<string | null>> = ImagedirOptions<Accept, Alt> & {
|
|
36
|
+
/**
|
|
37
|
+
* The directory where images should be stored.
|
|
38
|
+
* Must start with "/public" (e.g., "/public/val/images")
|
|
39
|
+
*/
|
|
40
|
+
dir: MediaDir;
|
|
41
|
+
};
|
|
28
42
|
/**
|
|
29
43
|
* `alt` is optional only when it is the default schema.
|
|
30
44
|
*
|
|
31
45
|
* Naming a different `Alt` and then leaving `alt` out would make the fallback
|
|
32
|
-
* in `
|
|
46
|
+
* in `imagedir()` a lie — `Alt` would say `s.string()` while the value was a
|
|
33
47
|
* nullable one. Requiring it in that case is what makes the fallback sound:
|
|
34
48
|
* the branch that uses it is reachable only when `Alt` IS the default.
|
|
35
49
|
*/
|
|
36
|
-
type
|
|
50
|
+
type ImagedirAltOption<Alt extends AltSchema> = [
|
|
37
51
|
StringSchema<string | null>
|
|
38
52
|
] extends [Alt] ? {
|
|
39
53
|
/**
|
|
@@ -47,27 +61,23 @@ type ImagesetAltOption<Alt extends AltSchema> = [
|
|
|
47
61
|
/** Alt text schema — required, because it is not the default one. */
|
|
48
62
|
alt: Alt;
|
|
49
63
|
};
|
|
50
|
-
|
|
64
|
+
/**
|
|
65
|
+
* The options argument of `s.imagedir()`: optional only when `alt` is, for
|
|
66
|
+
* the reason `ImagedirAltOption` gives — leaving the whole object out leaves
|
|
67
|
+
* `alt` out with it.
|
|
68
|
+
*/
|
|
69
|
+
type ImagedirOptionsArg<Accept extends `image/${string}`, Alt extends AltSchema> = [StringSchema<string | null>] extends [Alt] ? [options?: ImagedirOptions<Accept, Alt>] : [options: ImagedirOptions<Accept, Alt>];
|
|
70
|
+
type ImagedirOptionsBase<Accept extends `image/${string}`> = {
|
|
51
71
|
/**
|
|
52
72
|
* The accepted mime type pattern. Must be an image type (e.g., "image/png", "image/webp", "image/*")
|
|
53
73
|
* @default "image/*"
|
|
54
74
|
*/
|
|
55
75
|
accept?: Accept;
|
|
56
|
-
/**
|
|
57
|
-
* The directory where images should be stored.
|
|
58
|
-
* Must start with "/public" (e.g., "/public/val/images")
|
|
59
|
-
*
|
|
60
|
-
* Required, and deliberately so: it decides where every uploaded file in this
|
|
61
|
-
* collection lands, and it used to default to "/public/val" — which meant a
|
|
62
|
-
* gallery that had simply not said where it wanted its files silently shared a
|
|
63
|
-
* directory with every other one.
|
|
64
|
-
*/
|
|
65
|
-
dir: "/public" | `/public/${string}`;
|
|
66
76
|
/**
|
|
67
77
|
* Re-encode uploads in the browser before they are uploaded.
|
|
68
78
|
*
|
|
69
79
|
* Off unless set. A field backed by this gallery (`s.image(galleryVal)`)
|
|
70
|
-
* inherits it, the same way it inherits `accept` and
|
|
80
|
+
* inherits it, the same way it inherits `accept` and the directory.
|
|
71
81
|
*/
|
|
72
82
|
encode?: ImageEncodeOption;
|
|
73
83
|
};
|
|
@@ -76,10 +86,10 @@ type ImagesetOptionsBase<Accept extends `image/${string}`> = {
|
|
|
76
86
|
*
|
|
77
87
|
* `alt` follows the schema's `alt` option, so it defaults to `string | null`
|
|
78
88
|
* and becomes `string` under `s.string()` or `Record<string, string>` under
|
|
79
|
-
* `s.record(s.string())`. Write `
|
|
89
|
+
* `s.record(s.string())`. Write `ImagedirEntryMetadata<AltSource>` where a
|
|
80
90
|
* gallery of any alt shape is acceptable.
|
|
81
91
|
*/
|
|
82
|
-
export type
|
|
92
|
+
export type ImagedirEntryMetadata<Alt extends AltSource = string | null> = {
|
|
83
93
|
width: number;
|
|
84
94
|
height: number;
|
|
85
95
|
mimeType: string;
|
|
@@ -89,31 +99,37 @@ export type ImagesetEntryMetadata<Alt extends AltSource = string | null> = {
|
|
|
89
99
|
y: number;
|
|
90
100
|
};
|
|
91
101
|
};
|
|
92
|
-
|
|
93
|
-
type
|
|
102
|
+
/** @deprecated Use `ImagedirEntryMetadata`. */
|
|
103
|
+
export type ImagesetEntryMetadata<Alt extends AltSource = string | null> = ImagedirEntryMetadata<Alt>;
|
|
104
|
+
export type SerializedImagedirSchema = SerializedRecordSchema;
|
|
105
|
+
/** @deprecated Use `SerializedImagedirSchema`. */
|
|
106
|
+
export type SerializedImagesetSchema = SerializedImagedirSchema;
|
|
107
|
+
type ImagedirItemProps<Alt extends AltSchema> = {
|
|
94
108
|
width: NumberSchema<number>;
|
|
95
109
|
height: NumberSchema<number>;
|
|
96
110
|
mimeType: StringSchema<string>;
|
|
97
111
|
alt: Alt;
|
|
98
112
|
};
|
|
99
|
-
type
|
|
113
|
+
type ImagedirItemSrc<Alt extends AltSchema> = {
|
|
100
114
|
width: number;
|
|
101
115
|
height: number;
|
|
102
116
|
mimeType: string;
|
|
103
117
|
alt: AltSourceOf<Alt>;
|
|
104
118
|
};
|
|
119
|
+
type ImagedirSchema<Alt extends AltSchema> = RecordSchema<ObjectSchema<ImagedirItemProps<Alt>, ImagedirItemSrc<Alt>>, Schema<string>, Record<string, ImagedirEntryMetadata<AltSourceOf<Alt>>>>;
|
|
105
120
|
/**
|
|
106
|
-
* Define a
|
|
121
|
+
* Define a directory of images: a whole module that holds many images, keyed
|
|
122
|
+
* by their file path, that fields pick from with `s.image(galleryVal)`.
|
|
107
123
|
*
|
|
108
|
-
*
|
|
109
|
-
* to be inferred. The rest defaults: any
|
|
110
|
-
*
|
|
124
|
+
* The directory is the first argument and is required — it decides where
|
|
125
|
+
* uploads land, so it is not something to be inferred. The rest defaults: any
|
|
126
|
+
* image type (`"image/*"`), nullable alt text, remote disabled. Call
|
|
127
|
+
* `.remote()` on the result to allow remote images.
|
|
111
128
|
*
|
|
112
129
|
* @example
|
|
113
130
|
* ```typescript
|
|
114
|
-
* const schema = s.
|
|
131
|
+
* const schema = s.imagedir("/public/val/images", {
|
|
115
132
|
* accept: "image/webp",
|
|
116
|
-
* dir: "/public/val/images",
|
|
117
133
|
* alt: s.string().minLength(4),
|
|
118
134
|
* });
|
|
119
135
|
* export default c.define("/content/images.val.ts", schema, {
|
|
@@ -126,5 +142,23 @@ type ImagesetItemSrc<Alt extends AltSchema> = {
|
|
|
126
142
|
* });
|
|
127
143
|
* ```
|
|
128
144
|
*/
|
|
129
|
-
export declare const
|
|
145
|
+
export declare const imagedir: <Accept extends `image/${string}`, Alt extends AltSchema = StringSchema<string | null>>(dir: MediaDir, ...[options]: ImagedirOptionsArg<Accept, Alt>) => ImagedirSchema<Alt>;
|
|
146
|
+
/**
|
|
147
|
+
* `s.imagedir()` with `.remote()` applied: what `s.imagedir` is under
|
|
148
|
+
* `files: { remote: true }`.
|
|
149
|
+
*/
|
|
150
|
+
export declare const remoteImagedir: <Accept extends `image/${string}`, Alt extends AltSchema = StringSchema<string | null>>(dir: MediaDir, ...[options]: ImagedirOptionsArg<Accept, Alt>) => ImagedirSchema<Alt>;
|
|
151
|
+
/**
|
|
152
|
+
* Define a collection of images.
|
|
153
|
+
*
|
|
154
|
+
* @deprecated Use `s.imagedir(dir, options)`: the directory moved out of the
|
|
155
|
+
* options and into the first argument, and nothing else changed.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* // was: s.imageset({ dir: "/public/val/images", accept: "image/webp" })
|
|
160
|
+
* const schema = s.imagedir("/public/val/images", { accept: "image/webp" });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export declare const imageset: <Accept extends `image/${string}`, Alt extends AltSchema = StringSchema<string | null>>(options: ImagesetOptions<Accept, Alt>) => ImagedirSchema<Alt>;
|
|
130
164
|
export {};
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
|
|
2
2
|
import { ItemPreviewInput, PreviewItem } from "../preview.js";
|
|
3
|
+
import { NumberRender } from "../render.js";
|
|
3
4
|
import { SourcePath } from "../val/index.js";
|
|
4
5
|
import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import { NumberRules } from "./numberRules.js";
|
|
7
|
+
/**
|
|
8
|
+
* What the value has to be. `integer` is what makes a number schema an
|
|
9
|
+
* `s.int()`: the source is a number either way, so an int is a number schema
|
|
10
|
+
* with one more rule rather than a schema type of its own (which every walk
|
|
11
|
+
* over a schema would have had to learn).
|
|
12
|
+
*/
|
|
13
|
+
type NumberOptions = NumberRules;
|
|
9
14
|
export type SerializedNumberSchema = {
|
|
10
15
|
type: "number";
|
|
11
16
|
/** Set when this schema declares a `preview`. The closure itself cannot serialize. */
|
|
12
17
|
preview?: true;
|
|
13
18
|
options?: NumberOptions;
|
|
19
|
+
/** How the field is edited. Static config — see `render.ts`. */
|
|
20
|
+
render?: NumberRender;
|
|
14
21
|
opt: boolean;
|
|
15
22
|
customValidate?: boolean;
|
|
16
23
|
readonly?: boolean;
|
|
@@ -25,7 +32,8 @@ export declare class NumberSchema<Src extends number | null> extends Schema<Src>
|
|
|
25
32
|
private readonly isHidden;
|
|
26
33
|
private readonly description?;
|
|
27
34
|
private readonly previewInput;
|
|
28
|
-
|
|
35
|
+
private readonly renderInput;
|
|
36
|
+
constructor(options?: NumberOptions | undefined, opt?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null, renderInput?: NumberRender | null);
|
|
29
37
|
/**
|
|
30
38
|
* Describe this field.
|
|
31
39
|
*
|
|
@@ -86,6 +94,37 @@ export declare class NumberSchema<Src extends number | null> extends Schema<Src>
|
|
|
86
94
|
* export default c.define("/example.val.ts", schema, 3);
|
|
87
95
|
*/
|
|
88
96
|
min(min: number): NumberSchema<Src>;
|
|
97
|
+
/**
|
|
98
|
+
* Validate that the number is on a grid of `step`: one of `min`, `min + step`,
|
|
99
|
+
* `min + 2 * step` and so on, counted from 0 when there is no `.min()`.
|
|
100
|
+
*
|
|
101
|
+
* A slider rendered on this field moves in the same steps unless its render
|
|
102
|
+
* says otherwise (and then its step has to be a multiple of this one).
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* const schema = s.int().min(0).max(100).step(5);
|
|
106
|
+
* export default c.define("/example.val.ts", schema, 40);
|
|
107
|
+
*/
|
|
108
|
+
step(step: number): NumberSchema<Src>;
|
|
109
|
+
/**
|
|
110
|
+
* Choose how this field is edited. `{ as: "slider", min, max }` edits it with
|
|
111
|
+
* a slider from `min` to `max`, next to a box for typing an exact value.
|
|
112
|
+
*
|
|
113
|
+
* `min` and `max` are required — a slider without ends is not a slider — and
|
|
114
|
+
* they are the slider's, not validation: use `.min()` / `.max()` for what the
|
|
115
|
+
* value may be. The slider can only produce values this schema accepts, so
|
|
116
|
+
* its range must lie inside `.min()`/`.max()`, its `step` (which defaults to
|
|
117
|
+
* `.step()`, then 1) must be a multiple of `.step()`, and on `s.int()` all of
|
|
118
|
+
* them must be whole numbers. A schema that breaks this throws here.
|
|
119
|
+
*
|
|
120
|
+
* Static configuration, not a callback — see `render.ts`. A second
|
|
121
|
+
* `.render(...)` replaces the first.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const schema = s.int().render({ as: "slider", min: 0, max: 100, step: 5 });
|
|
125
|
+
* export default c.define("/example.val.ts", schema, 40);
|
|
126
|
+
*/
|
|
127
|
+
render(input: NumberRender): NumberSchema<Src>;
|
|
89
128
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
90
129
|
/**
|
|
91
130
|
* How this VALUE is shown where a preview of it is needed — a row in a
|
|
@@ -104,4 +143,5 @@ export declare class NumberSchema<Src extends number | null> extends Schema<Src>
|
|
|
104
143
|
protected executeSerialize(): SerializedSchema;
|
|
105
144
|
}
|
|
106
145
|
export declare const number: (options?: NumberOptions) => NumberSchema<number>;
|
|
146
|
+
export declare const int: () => NumberSchema<number>;
|
|
107
147
|
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a number schema accepts, in one place, so the validator and the
|
|
3
|
+
* Studio's "Round to …" / "Set to …" buttons cannot disagree about it.
|
|
4
|
+
*
|
|
5
|
+
* A button that offers a value the validator then rejects is worse than no
|
|
6
|
+
* button, which is exactly what two copies of this arithmetic would drift into.
|
|
7
|
+
*/
|
|
8
|
+
export type NumberRules = {
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
/** Whole numbers only — `s.int()`. */
|
|
12
|
+
integer?: boolean;
|
|
13
|
+
/** Allowed values are `origin + n * step`, where the origin is `min` or 0. */
|
|
14
|
+
step?: number;
|
|
15
|
+
};
|
|
16
|
+
/** Where the step grid starts: the schema's `min`, or 0 when it has none. */
|
|
17
|
+
export declare function stepOrigin(rules: NumberRules): number;
|
|
18
|
+
/** Is `value` one of `origin + n * step`? */
|
|
19
|
+
export declare function isOnStep(value: number, origin: number, step: number): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The allowed value closest to `value`: inside `min`/`max`, on the step grid,
|
|
22
|
+
* and whole when the schema is an int.
|
|
23
|
+
*
|
|
24
|
+
* Returns `null` when the rules leave nothing to snap to — a `min` above
|
|
25
|
+
* `max`, or a range too narrow to hold a single step or a single whole number.
|
|
26
|
+
*/
|
|
27
|
+
export declare function nearestAllowedNumber(value: number, rules: NumberRules): number | null;
|
|
@@ -20,8 +20,19 @@ type MediaOptions = {
|
|
|
20
20
|
/** Videos only: whether uploads become HLS streams. See `video.ts`. */
|
|
21
21
|
stream?: VideoStreamOption;
|
|
22
22
|
};
|
|
23
|
-
/** What a media collection (`s.
|
|
23
|
+
/** What a media collection (`s.imagedir`, `s.filedir`, `s.videodir`) holds. */
|
|
24
24
|
export type MediaCollectionType = "files" | "images" | "videos";
|
|
25
|
+
/**
|
|
26
|
+
* Where a media collection keeps its files: the first argument of
|
|
27
|
+
* `s.imagedir()`, `s.filedir()`, `s.fontdir()` and `s.videodir()`.
|
|
28
|
+
*
|
|
29
|
+
* Required, and deliberately so: it decides where every uploaded file in the
|
|
30
|
+
* collection lands. It used to default to "/public/val", which meant a
|
|
31
|
+
* collection that had simply not said where it wanted its files silently
|
|
32
|
+
* shared a directory with every other one. It is the first argument rather
|
|
33
|
+
* than an option because it is the one thing every collection has to say.
|
|
34
|
+
*/
|
|
35
|
+
export type MediaDir = "/public" | `/public/${string}`;
|
|
25
36
|
export type SerializedRecordSchema = {
|
|
26
37
|
type: "record";
|
|
27
38
|
item: SerializedSchema;
|
|
@@ -258,7 +269,7 @@ RO extends boolean = false> extends Schema<Src> {
|
|
|
258
269
|
* Allow the files in this gallery to be stored on Val's remote content host
|
|
259
270
|
* instead of in your repository.
|
|
260
271
|
*
|
|
261
|
-
* For `s.
|
|
272
|
+
* For `s.imagedir()` and `s.filedir()`, which are records of media. Remote is off
|
|
262
273
|
* until this is called.
|
|
263
274
|
*
|
|
264
275
|
* Each entry is then keyed by its URL on the content host rather than by a
|
|
@@ -267,7 +278,7 @@ RO extends boolean = false> extends Schema<Src> {
|
|
|
267
278
|
* upload it and rewrite the key.
|
|
268
279
|
*
|
|
269
280
|
* @example
|
|
270
|
-
* const schema = s.
|
|
281
|
+
* const schema = s.imagedir("/public/val/images").remote();
|
|
271
282
|
* export default c.define("/content/images.val.ts", schema, {
|
|
272
283
|
* "https://remote.val.build/file/p/my-project/b/01/v/1.0.0/h/8f2a1c/f/3b9d70/p/public/val/images/hero.webp":
|
|
273
284
|
* {
|
|
@@ -286,7 +297,7 @@ RO extends boolean = false> extends Schema<Src> {
|
|
|
286
297
|
* which lets the runtime, the Studio and validation work one entry at a time
|
|
287
298
|
* so a record/router can scale to many thousands of entries.
|
|
288
299
|
*
|
|
289
|
-
* Not supported on image/file galleries (`s.
|
|
300
|
+
* Not supported on image/file galleries (`s.imagedir()` / `s.filedir()`).
|
|
290
301
|
*
|
|
291
302
|
* Only supported on a module's ROOT record/router — a `.jsonValues()` record
|
|
292
303
|
* nested inside an object/array/record is rejected at startup with a module
|
|
@@ -313,7 +324,7 @@ RO extends boolean = false> extends Schema<Src> {
|
|
|
313
324
|
* bucket — instead of in the module.
|
|
314
325
|
*
|
|
315
326
|
* Available on every record-derived schema, which is `s.record()`,
|
|
316
|
-
* `s.router()`, `s.
|
|
327
|
+
* `s.router()`, `s.imagedir()` and `s.filedir()` alike: a router is a
|
|
317
328
|
* `RecordSchema` with a `ValRouter`, a gallery one with media options, so all
|
|
318
329
|
* four get external storage from this one method.
|
|
319
330
|
*
|
|
@@ -396,7 +407,7 @@ RO extends boolean = false> extends Schema<Src> {
|
|
|
396
407
|
* draws each entry's own editor in place, labelled by its key, instead of a
|
|
397
408
|
* preview row that navigates to it. It reaches the direct entries only.
|
|
398
409
|
*
|
|
399
|
-
* Not for `s.router(...)`, `s.
|
|
410
|
+
* Not for `s.router(...)`, `s.imagedir(...)` or `s.filedir(...)`: pages and
|
|
400
411
|
* media have UIs of their own, so this throws on them.
|
|
401
412
|
*
|
|
402
413
|
* Static configuration, not a callback — see `render.ts`.
|
|
@@ -2,8 +2,8 @@ import { GalleryVideoSource, VideoSource } from "../source/media.js";
|
|
|
2
2
|
import { CustomValidateFunction, Schema, SchemaAssertResult, SerializedSchema } from "./index.js";
|
|
3
3
|
import { SourcePath } from "../val/index.js";
|
|
4
4
|
import type { ValModule } from "../module.js";
|
|
5
|
-
import type { AltSource } from "./
|
|
6
|
-
import type {
|
|
5
|
+
import type { AltSource } from "./imagedir.js";
|
|
6
|
+
import type { VideodirEntryMetadata } from "./videodir.js";
|
|
7
7
|
import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
|
|
8
8
|
import { ItemPreviewInput, PreviewItem } from "../preview.js";
|
|
9
9
|
import { FieldRender } from "../render.js";
|
|
@@ -67,7 +67,7 @@ export type VideoGallery = {
|
|
|
67
67
|
* set, not its contents, so whether the set has the entry is a question
|
|
68
68
|
* for the set's own module — which the Studio validates anyway.
|
|
69
69
|
*/
|
|
70
|
-
entries: Record<string,
|
|
70
|
+
entries: Record<string, VideodirEntryMetadata<AltSource>> | null;
|
|
71
71
|
remote: boolean;
|
|
72
72
|
};
|
|
73
73
|
export type SerializedVideoSchema = {
|
|
@@ -80,7 +80,7 @@ export type SerializedVideoSchema = {
|
|
|
80
80
|
opt: boolean;
|
|
81
81
|
remote?: boolean;
|
|
82
82
|
customValidate?: boolean;
|
|
83
|
-
/** The `s.
|
|
83
|
+
/** The `s.videodir()` module this field picks from, if it is set-backed. */
|
|
84
84
|
referencedModule?: string;
|
|
85
85
|
readonly?: boolean;
|
|
86
86
|
hidden?: boolean;
|
|
@@ -230,11 +230,11 @@ export declare class VideoSchema<Src extends GalleryVideoSource | null> extends
|
|
|
230
230
|
*/
|
|
231
231
|
export declare function filesOfVideoSource(src: GalleryVideoSource): string[];
|
|
232
232
|
/**
|
|
233
|
-
* A video picked from a set (`s.
|
|
233
|
+
* A video picked from a set (`s.videodir()`). What is true of the file —
|
|
234
234
|
* its type, size and length — lives in the set; the field carries what one
|
|
235
235
|
* page chose about it.
|
|
236
236
|
*/
|
|
237
|
-
export declare function video(videosetModule: ValModule<Record<string,
|
|
237
|
+
export declare function video(videosetModule: ValModule<Record<string, VideodirEntryMetadata<AltSource>>>, galleryOptions?: GalleryVideoOptions): VideoSchema<GalleryVideoSource>;
|
|
238
238
|
/**
|
|
239
239
|
* Define a video: an `.mp4` / `.webm` file, or an HLS stream the Studio makes
|
|
240
240
|
* from an upload when `stream` is set.
|
|
@@ -245,5 +245,5 @@ export declare function video(options?: VideoOptions): VideoSchema<VideoSource>;
|
|
|
245
245
|
* `val.config.ts`): the same schema, with `.remote()` already applied. See
|
|
246
246
|
* `initSchema`.
|
|
247
247
|
*/
|
|
248
|
-
export declare function remoteVideo(videosetModule: ValModule<Record<string,
|
|
248
|
+
export declare function remoteVideo(videosetModule: ValModule<Record<string, VideodirEntryMetadata<AltSource>>>, galleryOptions?: GalleryVideoOptions): VideoSchema<GalleryVideoSource>;
|
|
249
249
|
export declare function remoteVideo(options?: VideoOptions): VideoSchema<VideoSource>;
|