@valbuild/core 0.141.0 → 0.144.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 +67 -0
- package/dist/declarations/src/index.d.ts +13 -4
- package/dist/declarations/src/initSchema.d.ts +108 -18
- package/dist/declarations/src/initVal.d.ts +2 -2
- package/dist/declarations/src/mimeType/font.d.ts +36 -0
- package/dist/declarations/src/mimeType/index.d.ts +1 -0
- package/dist/declarations/src/render.d.ts +1 -1
- 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 +16 -0
- 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/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-13cf45b1.cjs.prod.js → index-2d194c90.cjs.prod.js} +504 -79
- package/dist/{index-fae161b5.cjs.dev.js → index-8b22b2c1.cjs.dev.js} +504 -79
- package/dist/{index-a6c53286.esm.js → index-aa16dd90.esm.js} +503 -80
- 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
- package/dist/declarations/src/schema/fileset.d.ts +0 -57
|
@@ -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 {};
|
|
@@ -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>;
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import { Schema } from "./index.js";
|
|
2
|
-
import type { SerializedRecordSchema } from "./record.js";
|
|
2
|
+
import type { MediaDir, SerializedRecordSchema } from "./record.js";
|
|
3
3
|
import { RecordSchema } from "./record.js";
|
|
4
4
|
import { ObjectSchema } from "./object.js";
|
|
5
5
|
import { StringSchema } from "./string.js";
|
|
6
6
|
import { NumberSchema } from "./number.js";
|
|
7
|
-
import type { AltSchema, AltSource, AltSourceOf } from "./
|
|
7
|
+
import type { AltSchema, AltSource, AltSourceOf } from "./imagedir.js";
|
|
8
8
|
import type { SerializedVideoSchema, VideoStreamOption } from "./video.js";
|
|
9
9
|
import type { MediaHotspot, VideoCaptionSource, VideoPosterSource } from "../source/media.js";
|
|
10
10
|
/**
|
|
11
|
-
* Options for s.
|
|
11
|
+
* Options for `s.videodir(dir, options)`: everything but the directory, which
|
|
12
|
+
* is the first argument.
|
|
12
13
|
*/
|
|
13
|
-
export type
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
export type VideodirOptions<Accept extends `video/${string}`, Alt extends AltSchema = StringSchema<string | null>> = VideodirOptionsBase<Accept> & VideodirAltOption<Alt>;
|
|
15
|
+
/**
|
|
16
|
+
* Options for the deprecated `s.videoset(options)`, which took the directory
|
|
17
|
+
* as `dir`.
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Use `s.videodir(dir, options)` and `VideodirOptions`.
|
|
20
|
+
*/
|
|
21
|
+
export type VideosetOptions<Accept extends `video/${string}`, Alt extends AltSchema = StringSchema<string | null>> = VideodirOptions<Accept, Alt> & {
|
|
22
|
+
/** The directory where videos are stored. Must start with "/public". */
|
|
23
|
+
dir: MediaDir;
|
|
24
|
+
};
|
|
25
|
+
/** See `ImagedirAltOption`: `alt` is optional only when it is the default. */
|
|
26
|
+
type VideodirAltOption<Alt extends AltSchema> = [
|
|
16
27
|
StringSchema<string | null>
|
|
17
28
|
] extends [Alt] ? {
|
|
18
29
|
/**
|
|
@@ -26,25 +37,20 @@ type VideosetAltOption<Alt extends AltSchema> = [
|
|
|
26
37
|
/** Description schema — required, because it is not the default one. */
|
|
27
38
|
alt: Alt;
|
|
28
39
|
};
|
|
29
|
-
|
|
40
|
+
/** See `ImagedirOptionsArg`: the options are optional only when `alt` is. */
|
|
41
|
+
type VideodirOptionsArg<Accept extends `video/${string}`, Alt extends AltSchema> = [StringSchema<string | null>] extends [Alt] ? [options?: VideodirOptions<Accept, Alt>] : [options: VideodirOptions<Accept, Alt>];
|
|
42
|
+
type VideodirOptionsBase<Accept extends `video/${string}`> = {
|
|
30
43
|
/**
|
|
31
44
|
* What may be UPLOADED, in `<input accept>` syntax. Must be a video type.
|
|
32
45
|
* Not checked against an HLS stream: see `VideoOptions.accept`.
|
|
33
46
|
* @default "video/*"
|
|
34
47
|
*/
|
|
35
48
|
accept?: Accept;
|
|
36
|
-
/**
|
|
37
|
-
* The directory where videos are stored. Must start with "/public".
|
|
38
|
-
*
|
|
39
|
-
* Required for the same reason it is on `s.imageset()`: it decides where
|
|
40
|
-
* every upload in the set lands, and a default is a directory shared with
|
|
41
|
-
* every other set that did not say.
|
|
42
|
-
*/
|
|
43
|
-
dir: "/public" | `/public/${string}`;
|
|
44
49
|
/**
|
|
45
50
|
* Turn every upload into an HLS stream, in the browser. See
|
|
46
|
-
* `VideoStreamOptions`. A field backed by this
|
|
47
|
-
* inherits it, as it inherits `accept` and
|
|
51
|
+
* `VideoStreamOptions`. A field backed by this directory
|
|
52
|
+
* (`s.video(videosVal)`) inherits it, as it inherits `accept` and the
|
|
53
|
+
* directory.
|
|
48
54
|
*/
|
|
49
55
|
stream?: VideoStreamOption;
|
|
50
56
|
};
|
|
@@ -63,7 +69,7 @@ type VideosetOptionsBase<Accept extends `video/${string}`> = {
|
|
|
63
69
|
* The poster is also the set's thumbnail of the entry: there is no separate
|
|
64
70
|
* still for the gallery, because two stills of one video would disagree.
|
|
65
71
|
*/
|
|
66
|
-
export type
|
|
72
|
+
export type VideodirEntryMetadata<Alt extends AltSource = string | null> = {
|
|
67
73
|
mimeType: string;
|
|
68
74
|
width: number;
|
|
69
75
|
height: number;
|
|
@@ -81,34 +87,38 @@ export type VideosetEntryMetadata<Alt extends AltSource = string | null> = {
|
|
|
81
87
|
/** Overridden as a whole: a field with its own tracks has none of these. */
|
|
82
88
|
captions?: readonly VideoCaptionSource[];
|
|
83
89
|
};
|
|
84
|
-
|
|
85
|
-
type
|
|
90
|
+
/** @deprecated Use `VideodirEntryMetadata`. */
|
|
91
|
+
export type VideosetEntryMetadata<Alt extends AltSource = string | null> = VideodirEntryMetadata<Alt>;
|
|
92
|
+
export type SerializedVideodirSchema = SerializedRecordSchema;
|
|
93
|
+
/** @deprecated Use `SerializedVideodirSchema`. */
|
|
94
|
+
export type SerializedVideosetSchema = SerializedVideodirSchema;
|
|
95
|
+
type VideodirItemProps<Alt extends AltSchema> = {
|
|
86
96
|
mimeType: StringSchema<string>;
|
|
87
97
|
width: NumberSchema<number>;
|
|
88
98
|
height: NumberSchema<number>;
|
|
89
99
|
duration: NumberSchema<number>;
|
|
90
100
|
alt: Alt;
|
|
91
101
|
};
|
|
92
|
-
type
|
|
102
|
+
type VideodirItemSrc<Alt extends AltSchema> = {
|
|
93
103
|
mimeType: string;
|
|
94
104
|
width: number;
|
|
95
105
|
height: number;
|
|
96
106
|
duration: number;
|
|
97
107
|
alt: AltSourceOf<Alt>;
|
|
98
108
|
};
|
|
109
|
+
type VideodirSchema<Alt extends AltSchema> = RecordSchema<ObjectSchema<VideodirItemProps<Alt>, VideodirItemSrc<Alt>>, Schema<string>, Record<string, VideodirEntryMetadata<AltSourceOf<Alt>>>>;
|
|
99
110
|
/**
|
|
100
|
-
* Define a
|
|
111
|
+
* Define a directory of videos — the video twin of `s.imagedir()`.
|
|
101
112
|
*
|
|
102
113
|
* A field picks from it with `s.video(videosVal)`. An entry may hold the
|
|
103
114
|
* description, poster, start and end, focal point and captions as defaults,
|
|
104
115
|
* and a field overrides any of them by setting its own. Uploading in such a
|
|
105
|
-
* field adds to the
|
|
106
|
-
*
|
|
116
|
+
* field adds to the directory. Call `.remote()` on the result to store the
|
|
117
|
+
* videos on Val Remote.
|
|
107
118
|
*
|
|
108
119
|
* @example
|
|
109
120
|
* ```typescript
|
|
110
|
-
* const schema = s.
|
|
111
|
-
* dir: "/public/val/videos",
|
|
121
|
+
* const schema = s.videodir("/public/val/videos", {
|
|
112
122
|
* stream: { type: "hls" },
|
|
113
123
|
* });
|
|
114
124
|
* export default c.define("/content/videos.val.ts", schema, {
|
|
@@ -123,7 +133,25 @@ type VideosetItemSrc<Alt extends AltSchema> = {
|
|
|
123
133
|
* });
|
|
124
134
|
* ```
|
|
125
135
|
*/
|
|
126
|
-
export declare const
|
|
136
|
+
export declare const videodir: <Accept extends `video/${string}`, Alt extends AltSchema = StringSchema<string | null>>(dir: MediaDir, ...[options]: VideodirOptionsArg<Accept, Alt>) => VideodirSchema<Alt>;
|
|
137
|
+
/**
|
|
138
|
+
* `s.videodir()` with `.remote()` applied: what `s.videodir` is under
|
|
139
|
+
* `files: { remote: true }`.
|
|
140
|
+
*/
|
|
141
|
+
export declare const remoteVideodir: <Accept extends `video/${string}`, Alt extends AltSchema = StringSchema<string | null>>(dir: MediaDir, ...[options]: VideodirOptionsArg<Accept, Alt>) => VideodirSchema<Alt>;
|
|
142
|
+
/**
|
|
143
|
+
* Define a collection of videos.
|
|
144
|
+
*
|
|
145
|
+
* @deprecated Use `s.videodir(dir, options)`: the directory moved out of the
|
|
146
|
+
* options and into the first argument, and nothing else changed.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // was: s.videoset({ dir: "/public/val/videos", stream: { type: "hls" } })
|
|
151
|
+
* const schema = s.videodir("/public/val/videos", { stream: { type: "hls" } });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare const videoset: <Accept extends `video/${string}`, Alt extends AltSchema = StringSchema<string | null>>(options: VideosetOptions<Accept, Alt>) => VideodirSchema<Alt>;
|
|
127
155
|
/**
|
|
128
156
|
* The video schema a set's entry is hashed against, for a remote ref.
|
|
129
157
|
*
|
|
@@ -81,7 +81,7 @@ export type VideoCaptionSource = {
|
|
|
81
81
|
* What a video FIELD authors, on top of the file it names: the description,
|
|
82
82
|
* the crop, the poster, the trim and the caption tracks.
|
|
83
83
|
*
|
|
84
|
-
* This is the whole value of a field picked from an `s.
|
|
84
|
+
* This is the whole value of a field picked from an `s.videodir()`
|
|
85
85
|
* (`s.video(videosetVal)`) — the mime type, size and length live in the set,
|
|
86
86
|
* keyed by `path`, and repeating them here is how two copies of one fact get
|
|
87
87
|
* to disagree. The poster, captions and times stay with the FIELD: one video
|
|
@@ -112,7 +112,7 @@ export type GalleryVideoSource = {
|
|
|
112
112
|
/**
|
|
113
113
|
* What one page chooses about a video — as opposed to what is true of the
|
|
114
114
|
* file. A field (`s.video()`) carries these for itself; the entry of a set
|
|
115
|
-
* (`s.
|
|
115
|
+
* (`s.videodir()`) carries them as DEFAULTS, which every field picked from the
|
|
116
116
|
* set starts from and may override key by key. See {@link fillFromGallery}.
|
|
117
117
|
*/
|
|
118
118
|
export type VideoDefaults = Pick<GalleryVideoSource, "hotspot" | "posterTime" | "poster" | "startTime" | "endTime" | "captions">;
|
|
@@ -211,6 +211,27 @@ export type ResolvedVideo<S extends GalleryVideoSource = VideoSource> = Omit<S,
|
|
|
211
211
|
* the poster's and the captions', which are not where an edit lands.
|
|
212
212
|
*/
|
|
213
213
|
export declare function resolveVideo<S extends GalleryVideoSource>(src: S, videoUrl?: (src: S) => string): ResolvedVideo<S>;
|
|
214
|
+
/**
|
|
215
|
+
* The key of a gallery (an `s.imagedir()`, `s.filedir()` or `s.videodir()`)
|
|
216
|
+
* that a field's `path` names, or `null` when it names none.
|
|
217
|
+
*
|
|
218
|
+
* Usually the path IS the key. It is not for an image uploaded THROUGH an
|
|
219
|
+
* `s.image(remoteGallery)` field in the Studio, which stores the remote ref in
|
|
220
|
+
* the field and keys the entry by the local path inside it — so a path that is
|
|
221
|
+
* not a key falls back to that embedded path. Exact first, because a gallery
|
|
222
|
+
* can hold both shapes for one file, and the field then names the entry that
|
|
223
|
+
* IS its path.
|
|
224
|
+
*
|
|
225
|
+
* One implementation of the question, asked by everything that has to agree on
|
|
226
|
+
* the answer: reading a field (`galleryEntryOf`), validating it (`ImageSchema`
|
|
227
|
+
* and `FileSchema` ask whether the gallery has it), the Studio's reference
|
|
228
|
+
* scans and renames, and `val validate --fix` when it renames a key and has to
|
|
229
|
+
* find the fields that hold it.
|
|
230
|
+
*
|
|
231
|
+
* The embedded path is tried with its leading slash (how a key is written) and
|
|
232
|
+
* without (how `splitRemoteRef` returns it).
|
|
233
|
+
*/
|
|
234
|
+
export declare function galleryKeyOf(path: string, isKey: (key: string) => boolean): string | null;
|
|
214
235
|
/**
|
|
215
236
|
* What a gallery entry holds as a DEFAULT for the fields picked from it, in
|
|
216
237
|
* the groups a field overrides together.
|
|
@@ -226,7 +247,9 @@ export declare const GALLERY_DEFAULT_GROUPS: readonly (readonly string[])[];
|
|
|
226
247
|
* gallery-backed or the gallery has no such entry.
|
|
227
248
|
*
|
|
228
249
|
* The double lookup is load-bearing: a remote gallery keys its entries by the
|
|
229
|
-
* remote URL while the file itself stays on disk under its local path
|
|
250
|
+
* remote URL while the file itself stays on disk under its local path, and an
|
|
251
|
+
* upload through the field does it the other way round (see
|
|
252
|
+
* {@link galleryKeyOf}).
|
|
230
253
|
*/
|
|
231
254
|
export declare function galleryEntryOf(src: {
|
|
232
255
|
readonly path: string;
|