@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# @valbuild/core
|
|
2
2
|
|
|
3
|
+
## 0.145.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#851](https://github.com/valbuild/val/pull/851) [`b6cb939`](https://github.com/valbuild/val/commit/b6cb9395d8bdcd5182e9c6ba84f5284930de2fa5) Thanks [@freekh](https://github.com/freekh)! - New `s.int()` for whole numbers, `.step()` on `s.int()` and `s.number()`, and a slider for both:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
s.object({
|
|
11
|
+
columns: s.int().min(1).max(6),
|
|
12
|
+
opacity: s
|
|
13
|
+
.int()
|
|
14
|
+
.min(0)
|
|
15
|
+
.max(100)
|
|
16
|
+
.step(5)
|
|
17
|
+
.render({ as: "slider", min: 0, max: 100 }),
|
|
18
|
+
lineHeight: s.number().render({ as: "slider", min: 1, max: 2, step: 0.1 }),
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `.min()`, `.max()` and `.step()` are rules the validator checks. A step is counted from `min`, or from 0 when there is none.
|
|
23
|
+
- `.render({ as: "slider", min, max, step? })` is how the field is edited: a slider, with a box beside it for typing an exact value. `min` and `max` are required. The slider's step defaults to the schema's `.step()`, then to 1.
|
|
24
|
+
- The slider can only produce values the schema accepts. A slider outside `.min()`/`.max()`, with a step that is not a multiple of `.step()`, or with decimals on an `s.int()` throws where the schema is defined.
|
|
25
|
+
- A value outside the slider's range is still valid content. The field says it is out of the slider's reach and offers "Set to" the nearest stop. A value that breaks a rule offers "Round to" the nearest allowed value.
|
|
26
|
+
- Fixed: `.min(0)` and `.max(0)` on `s.number()` were ignored.
|
|
27
|
+
- A new item of a number schema starts at the nearest allowed value instead of `0`, so `s.int().min(1)` starts at 1.
|
|
28
|
+
|
|
29
|
+
## 0.144.0
|
|
30
|
+
|
|
31
|
+
### Minor Changes
|
|
32
|
+
|
|
33
|
+
- [#826](https://github.com/valbuild/val/pull/826) [`860ab2b`](https://github.com/valbuild/val/commit/860ab2b87333daf95a48215b0e4a1b44f441c878) Thanks [@freekh](https://github.com/freekh)! - New names for the media collections: `s.imagedir()`, `s.filedir()`, `s.fontdir()` and `s.videodir()`. The directory the uploads land in is now the first argument instead of the `dir` option:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// before
|
|
37
|
+
s.imageset({ dir: "/public/val/images", accept: "image/webp" });
|
|
38
|
+
s.fileset({ dir: "/public/val/docs", accept: "application/pdf" });
|
|
39
|
+
s.fontset({ dir: "/public/val/fonts" });
|
|
40
|
+
s.videoset({ dir: "/public/val/videos", stream: { type: "hls" } });
|
|
41
|
+
|
|
42
|
+
// after
|
|
43
|
+
s.imagedir("/public/val/images", { accept: "image/webp" });
|
|
44
|
+
s.filedir("/public/val/docs", { accept: "application/pdf" });
|
|
45
|
+
s.fontdir("/public/val/fonts");
|
|
46
|
+
s.videodir("/public/val/videos", { stream: { type: "hls" } });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Every other option is unchanged, and so is the content: a module only needs its schema call changed. The options object can now be left out entirely where nothing else is set, as in `s.fontdir("/public/val/fonts")`.
|
|
50
|
+
|
|
51
|
+
`s.imageset()`, `s.fileset()`, `s.fontset()` and `s.videoset()` still work and build exactly the same schema, but are deprecated and will be removed in a later release. The exported `VideosetEntryMetadata`, `VideosetOptions` and `SerializedVideosetSchema` types are deprecated in favour of `VideodirEntryMetadata`, `VideodirOptions` and `SerializedVideodirSchema`, and the image, file and font equivalents (`ImagedirOptions`, `ImagedirEntryMetadata`, `FiledirOptions`, `FiledirEntryMetadata`, `FontdirOptions`, `MediaDir`, …) are now exported too.
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- [#788](https://github.com/valbuild/val/pull/788) [`a84271c`](https://github.com/valbuild/val/commit/a84271c534822071c1e428cf9990602459682d25) Thanks [@freekh](https://github.com/freekh)! - Fixes to `npx val validate` for `s.imagedir()` and `s.filedir()`, and the `s.image(galleryVal)` / `s.file(filesVal)` fields that use them:
|
|
56
|
+
|
|
57
|
+
- **`--fix` now updates every field that uses an uploaded image or file.** When `--fix` moves an entry of an `s.imagedir(dir).remote()` or `s.filedir(dir, options).remote()` to Val Remote, the entry's key changes from the local path to the remote URL. Fields that held the old path were left pointing at it, and reported "The gallery does not have an image at …" with nothing to fix it. Now `s.image(galleryVal)` and `s.file(filesVal)` fields, and images in rich text (`s.richtext({ img: s.image(galleryVal) })`), are updated in the same run. The VS Code extension's "upload to Val Remote" updates them in the same edit, including fields inside `.jsonValues()` entries, which live in their own `*.val.json` files.
|
|
58
|
+
- **A field that uses an image or file from a `.remote()` gallery is no longer reported as "Expected local image, but found remote".** The gallery decides whether its files are on Val Remote; the field only has to name a file the gallery has. Before, `--fix` would download the file and point the field at a path the gallery did not have.
|
|
59
|
+
- **Images uploaded through a field into a `.remote()` gallery.** When you upload an image through an `s.image(galleryVal)` field in Val Studio, the field stores the remote URL and the gallery stores the image under its local path. Validation now accepts this, and `useVal` / `fetchVal` now fill in the image's `width`, `height` and `mimeType` from the gallery for it, as they do for every other gallery image.
|
|
60
|
+
- **Errors in a gallery's keys are reported.** A remote URL in a gallery that is not `.remote()`, a remote URL that is not valid, or one outside the gallery's `dir` was silently ignored by `npx val validate`. It is now reported as an error. `--fix` does not change it: you decide whether the key or the gallery's options are wrong.
|
|
61
|
+
- **A file is no longer reported as valid when it still has an error.** When `--fix` fixed one error in a file and another error was left, the file could be printed as "✔ valid".
|
|
62
|
+
|
|
3
63
|
## 0.143.0
|
|
4
64
|
|
|
5
65
|
### Minor Changes
|
|
@@ -7,8 +7,12 @@ export { hasRemoteFileSchema, hasMediaSchema, } from "./schema/hasRemoteFileSche
|
|
|
7
7
|
export type { ImageMetadata, ImageEncodeOption, ImageEncodeOptions, } from "./schema/image.js";
|
|
8
8
|
export type { FileMetadata } from "./schema/file.js";
|
|
9
9
|
export type { GalleryVideoOptions, VideoMetadata, VideoOptions, VideoStreamOption, VideoStreamOptions, } from "./schema/video.js";
|
|
10
|
-
import { videosetEntryVideoSchema } from "./schema/
|
|
11
|
-
export type { VideosetEntryMetadata, VideosetOptions, SerializedVideosetSchema, } from "./schema/
|
|
10
|
+
import { videosetEntryVideoSchema } from "./schema/videodir.js";
|
|
11
|
+
export type { VideodirEntryMetadata, VideodirOptions, SerializedVideodirSchema, VideosetEntryMetadata, VideosetOptions, SerializedVideosetSchema, } from "./schema/videodir.js";
|
|
12
|
+
export type { ImagedirEntryMetadata, ImagedirOptions, SerializedImagedirSchema, } from "./schema/imagedir.js";
|
|
13
|
+
export type { FiledirEntryMetadata, FiledirOptions, SerializedFiledirSchema, } from "./schema/filedir.js";
|
|
14
|
+
export type { FontdirOptions } from "./schema/fontdir.js";
|
|
15
|
+
export type { MediaDir } from "./schema/record.js";
|
|
12
16
|
export type { ValModule, SerializedModule, InferValModuleType } from "./module.js";
|
|
13
17
|
export type { SourceObject, SourcePrimitive, Source } from "./source/index.js";
|
|
14
18
|
export type { FileSource } from "./source/media.js";
|
|
@@ -47,13 +51,15 @@ import { getValidationBasis, getValidationHash } from "./remote/validationBasis.
|
|
|
47
51
|
import { getFileHash, hashToRemoteFileHash } from "./remote/fileHash.js";
|
|
48
52
|
import { splitRemoteRef } from "./remote/splitRemoteRef.js";
|
|
49
53
|
import { galleriesOf } from "./source/galleries.js";
|
|
50
|
-
import { fillFromGallery, galleryEntryOf, isHlsVideo, isRemoteMediaPath, mediaUrl, resolveMedia, resolveVideo } from "./source/media.js";
|
|
54
|
+
import { fillFromGallery, galleryEntryOf, galleryKeyOf, isHlsVideo, isRemoteMediaPath, mediaUrl, resolveMedia, resolveVideo } from "./source/media.js";
|
|
51
55
|
import { colorToHex, convertColor, detectColorFormat, formatColor, parseColor } from "./schema/colorFormat.js";
|
|
52
56
|
export { type SerializedArraySchema, ArraySchema } from "./schema/array.js";
|
|
53
57
|
export { type SerializedObjectSchema, ObjectSchema } from "./schema/object.js";
|
|
54
58
|
export { type SerializedRecordSchema, type MediaCollectionType, RecordSchema, } from "./schema/record.js";
|
|
55
59
|
export { type SerializedStringSchema, StringSchema } from "./schema/string.js";
|
|
56
60
|
export { type SerializedNumberSchema, NumberSchema } from "./schema/number.js";
|
|
61
|
+
import { nearestAllowedNumber, isOnStep, stepOrigin } from "./schema/numberRules.js";
|
|
62
|
+
export type { NumberRules } from "./schema/numberRules.js";
|
|
57
63
|
export { type SerializedBooleanSchema, BooleanSchema } from "./schema/boolean.js";
|
|
58
64
|
export { type SerializedImageSchema, ImageSchema } from "./schema/image.js";
|
|
59
65
|
export { type SerializedFileSchema, FileSchema } from "./schema/file.js";
|
|
@@ -85,7 +91,7 @@ export { type SerializedUnionSchema, type UnionSchema, type SerializedStringUnio
|
|
|
85
91
|
export { type SerializedLiteralSchema, LiteralSchema } from "./schema/literal.js";
|
|
86
92
|
export { deserializeSchema } from "./schema/deserialize.js";
|
|
87
93
|
export { type PreviewItem, type ItemPreviewInput, type RecordPreview, type ArrayPreview, type ReifiedPreview, type PreviewScope, previewScope, } from "./preview.js";
|
|
88
|
-
export { type InlineRender, type FieldRender, isInlineRender } from "./render.js";
|
|
94
|
+
export { type InlineRender, type FieldRender, type SliderRender, type NumberRender, isInlineRender, } from "./render.js";
|
|
89
95
|
export type { ValRouter, ExternalPageRouter, RouteValidationError, } from "./router.js";
|
|
90
96
|
export { parseNextJsRoutePattern, parseTanStackRoutePattern, tanStackSegmentsOfRoutePath, validateUrlAgainstPattern, } from "./router.js";
|
|
91
97
|
export { getSourcePathFromRoute, isPageRouter } from "./getSourcePathFromRoute.js";
|
|
@@ -148,6 +154,7 @@ declare const Internal: {
|
|
|
148
154
|
fillFromGallery: typeof fillFromGallery;
|
|
149
155
|
galleriesOf: typeof galleriesOf;
|
|
150
156
|
galleryEntryOf: typeof galleryEntryOf;
|
|
157
|
+
galleryKeyOf: typeof galleryKeyOf;
|
|
151
158
|
GALLERY_DEFAULT_GROUPS: readonly (readonly string[])[];
|
|
152
159
|
isHlsVideo: typeof isHlsVideo;
|
|
153
160
|
HLS_MIME_TYPE: string;
|
|
@@ -168,6 +175,11 @@ declare const Internal: {
|
|
|
168
175
|
rejectScheme: typeof rejectScheme;
|
|
169
176
|
schemeOf: typeof schemeOf;
|
|
170
177
|
UNSAFE_URL_SCHEMES: readonly ["javascript", "data", "vbscript", "file", "blob"];
|
|
178
|
+
number: {
|
|
179
|
+
nearestAllowedNumber: typeof nearestAllowedNumber;
|
|
180
|
+
isOnStep: typeof isOnStep;
|
|
181
|
+
stepOrigin: typeof stepOrigin;
|
|
182
|
+
};
|
|
171
183
|
color: {
|
|
172
184
|
parseColor: typeof parseColor;
|
|
173
185
|
formatColor: typeof formatColor;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { array } from "./schema/array.js";
|
|
2
|
-
import { number } from "./schema/number.js";
|
|
2
|
+
import { int, number } from "./schema/number.js";
|
|
3
3
|
import { object } from "./schema/object.js";
|
|
4
4
|
import { string } from "./schema/string.js";
|
|
5
5
|
import { boolean } from "./schema/boolean.js";
|
|
@@ -15,8 +15,8 @@ import { record } from "./schema/record.js";
|
|
|
15
15
|
import { file } from "./schema/file.js";
|
|
16
16
|
import { font } from "./schema/font.js";
|
|
17
17
|
import { video } from "./schema/video.js";
|
|
18
|
-
import { fileset } from "./schema/
|
|
19
|
-
import { fontset } from "./schema/
|
|
18
|
+
import { filedir, fileset } from "./schema/filedir.js";
|
|
19
|
+
import { fontdir, fontset } from "./schema/fontdir.js";
|
|
20
20
|
import { date } from "./schema/date.js";
|
|
21
21
|
import { datetime } from "./schema/datetime.js";
|
|
22
22
|
import { code } from "./schema/code.js";
|
|
@@ -24,8 +24,8 @@ import { color } from "./schema/color.js";
|
|
|
24
24
|
import { locale } from "./schema/locale.js";
|
|
25
25
|
import { route } from "./schema/route.js";
|
|
26
26
|
import { router } from "./schema/router.js";
|
|
27
|
-
import { imageset } from "./schema/
|
|
28
|
-
import { videoset } from "./schema/
|
|
27
|
+
import { imagedir, imageset } from "./schema/imagedir.js";
|
|
28
|
+
import { videodir, videoset } from "./schema/videodir.js";
|
|
29
29
|
import { settings } from "./schema/settings.js";
|
|
30
30
|
export type InitSchema = {
|
|
31
31
|
/**
|
|
@@ -74,6 +74,28 @@ export type InitSchema = {
|
|
|
74
74
|
*
|
|
75
75
|
*/
|
|
76
76
|
readonly number: typeof number;
|
|
77
|
+
/**
|
|
78
|
+
* Define a whole number. The source is an ordinary `number`; `s.int()` adds
|
|
79
|
+
* the rule that it has no decimals.
|
|
80
|
+
*
|
|
81
|
+
* Takes `.min()`, `.max()` and `.step()` for what the value may be, and
|
|
82
|
+
* `.render({ as: "slider", min, max })` to edit it with a slider.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const schema = s.object({
|
|
86
|
+
* columns: s.int().min(1).max(6),
|
|
87
|
+
* opacity: s.int().min(0).max(100).step(5).render({
|
|
88
|
+
* as: "slider",
|
|
89
|
+
* min: 0,
|
|
90
|
+
* max: 100,
|
|
91
|
+
* }),
|
|
92
|
+
* });
|
|
93
|
+
* export default c.define("/example.val.ts", schema, {
|
|
94
|
+
* columns: 3,
|
|
95
|
+
* opacity: 40,
|
|
96
|
+
* });
|
|
97
|
+
*/
|
|
98
|
+
readonly int: typeof int;
|
|
77
99
|
/**
|
|
78
100
|
* Define one of several object shapes, told apart by a tag field.
|
|
79
101
|
*
|
|
@@ -153,7 +175,7 @@ export type InitSchema = {
|
|
|
153
175
|
*
|
|
154
176
|
* @example
|
|
155
177
|
* // Backed by a gallery: width, height and mimeType live there.
|
|
156
|
-
* import galleryVal from "./gallery.val"; // an s.
|
|
178
|
+
* import galleryVal from "./gallery.val"; // an s.imagedir() module
|
|
157
179
|
* const schema = s.image(galleryVal);
|
|
158
180
|
* export default c.define("/example.val.ts", schema, {
|
|
159
181
|
* path: "/public/val/example.png",
|
|
@@ -222,13 +244,13 @@ export type InitSchema = {
|
|
|
222
244
|
*/
|
|
223
245
|
readonly file: typeof file;
|
|
224
246
|
/**
|
|
225
|
-
* A font picked from an `s.
|
|
247
|
+
* A font picked from an `s.fontdir()`: `s.file(fontsVal)` for fonts, which
|
|
226
248
|
* refuses a module that is not a font set. The Studio shows it in its parent
|
|
227
249
|
* as the font's "A" and file name, and opens it on the set to pick from.
|
|
228
250
|
*
|
|
229
251
|
* @example
|
|
230
252
|
* ```typescript
|
|
231
|
-
* import fontsVal from "./fonts.val"; // an s.
|
|
253
|
+
* import fontsVal from "./fonts.val"; // an s.fontdir() module
|
|
232
254
|
* const schema = s.object({ headingFont: s.font(fontsVal) });
|
|
233
255
|
* // source: { headingFont: { path: "/public/val/fonts/inter_a1b2c.woff2" } }
|
|
234
256
|
* ```
|
|
@@ -261,7 +283,7 @@ export type InitSchema = {
|
|
|
261
283
|
*
|
|
262
284
|
* @example
|
|
263
285
|
* // Picked from a set: mimeType, width, height and duration live there.
|
|
264
|
-
* import videosVal from "./videos.val"; // an s.
|
|
286
|
+
* import videosVal from "./videos.val"; // an s.videodir() module
|
|
265
287
|
* const schema = s.video(videosVal);
|
|
266
288
|
* export default c.define("/example.val.ts", schema, {
|
|
267
289
|
* path: "/public/val/videos/intro_51df2.mp4",
|
|
@@ -377,13 +399,16 @@ export type InitSchema = {
|
|
|
377
399
|
*/
|
|
378
400
|
readonly router: typeof router;
|
|
379
401
|
/**
|
|
380
|
-
* Define a
|
|
402
|
+
* Define a directory of images: a whole module of images, keyed by file
|
|
403
|
+
* path, that fields pick from with `s.image(galleryVal)`.
|
|
404
|
+
*
|
|
405
|
+
* The first argument is the directory uploads land in, and must start with
|
|
406
|
+
* `/public`.
|
|
381
407
|
*
|
|
382
408
|
* @example
|
|
383
409
|
* ```typescript
|
|
384
|
-
* const schema = s.
|
|
410
|
+
* const schema = s.imagedir("/public/val/images", {
|
|
385
411
|
* accept: "image/webp",
|
|
386
|
-
* dir: "/public/val/images",
|
|
387
412
|
* alt: s.string().minLength(4),
|
|
388
413
|
* });
|
|
389
414
|
* export default c.define("/content/images.val.ts", schema, {
|
|
@@ -396,15 +421,18 @@ export type InitSchema = {
|
|
|
396
421
|
* });
|
|
397
422
|
* ```
|
|
398
423
|
*/
|
|
399
|
-
readonly
|
|
424
|
+
readonly imagedir: typeof imagedir;
|
|
400
425
|
/**
|
|
401
|
-
* Define a
|
|
426
|
+
* Define a directory of files: a whole module of files, keyed by file path,
|
|
427
|
+
* that fields pick from with `s.file(filesVal)`.
|
|
428
|
+
*
|
|
429
|
+
* The first argument is the directory uploads land in, and must start with
|
|
430
|
+
* `/public`.
|
|
402
431
|
*
|
|
403
432
|
* @example
|
|
404
433
|
* ```typescript
|
|
405
|
-
* const schema = s.
|
|
434
|
+
* const schema = s.filedir("/public/val/documents", {
|
|
406
435
|
* accept: "application/pdf",
|
|
407
|
-
* dir: "/public/val/documents",
|
|
408
436
|
* });
|
|
409
437
|
* export default c.define("/content/documents.val.ts", schema, {
|
|
410
438
|
* "/public/val/documents/report.pdf": {
|
|
@@ -413,15 +441,15 @@ export type InitSchema = {
|
|
|
413
441
|
* });
|
|
414
442
|
* ```
|
|
415
443
|
*/
|
|
416
|
-
readonly
|
|
444
|
+
readonly filedir: typeof filedir;
|
|
417
445
|
/**
|
|
418
|
-
* Define a
|
|
446
|
+
* Define a directory of fonts: an `s.filedir()` that accepts the web font
|
|
419
447
|
* formats, and whose files the Studio previews as type. A field picks from
|
|
420
|
-
* it with `s.
|
|
448
|
+
* it with `s.font(fontsVal)`.
|
|
421
449
|
*
|
|
422
450
|
* @example
|
|
423
451
|
* ```typescript
|
|
424
|
-
* const schema = s.
|
|
452
|
+
* const schema = s.fontdir("/public/val/fonts");
|
|
425
453
|
* export default c.define("/content/fonts.val.ts", schema, {
|
|
426
454
|
* "/public/val/fonts/inter_a1b2c.woff2": {
|
|
427
455
|
* mimeType: "font/woff2",
|
|
@@ -429,15 +457,14 @@ export type InitSchema = {
|
|
|
429
457
|
* });
|
|
430
458
|
* ```
|
|
431
459
|
*/
|
|
432
|
-
readonly
|
|
460
|
+
readonly fontdir: typeof fontdir;
|
|
433
461
|
/**
|
|
434
|
-
* Define a
|
|
462
|
+
* Define a directory of videos. A field picks from it with
|
|
435
463
|
* `s.video(videosVal)`.
|
|
436
464
|
*
|
|
437
465
|
* @example
|
|
438
466
|
* ```typescript
|
|
439
|
-
* const schema = s.
|
|
440
|
-
* dir: "/public/val/videos",
|
|
467
|
+
* const schema = s.videodir("/public/val/videos", {
|
|
441
468
|
* stream: { type: "hls" },
|
|
442
469
|
* });
|
|
443
470
|
* export default c.define("/content/videos.val.ts", schema, {
|
|
@@ -451,6 +478,60 @@ export type InitSchema = {
|
|
|
451
478
|
* });
|
|
452
479
|
* ```
|
|
453
480
|
*/
|
|
481
|
+
readonly videodir: typeof videodir;
|
|
482
|
+
/**
|
|
483
|
+
* Define a collection of images.
|
|
484
|
+
*
|
|
485
|
+
* @deprecated Use `s.imagedir(dir, options)`: the directory moved out of the
|
|
486
|
+
* options and into the first argument.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript
|
|
490
|
+
* // was: s.imageset({ dir: "/public/val/images", accept: "image/webp" })
|
|
491
|
+
* const schema = s.imagedir("/public/val/images", { accept: "image/webp" });
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
readonly imageset: typeof imageset;
|
|
495
|
+
/**
|
|
496
|
+
* Define a collection of files.
|
|
497
|
+
*
|
|
498
|
+
* @deprecated Use `s.filedir(dir, options)`: the directory moved out of the
|
|
499
|
+
* options and into the first argument.
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* ```typescript
|
|
503
|
+
* // was: s.fileset({ dir: "/public/val/documents", accept: "application/pdf" })
|
|
504
|
+
* const schema = s.filedir("/public/val/documents", {
|
|
505
|
+
* accept: "application/pdf",
|
|
506
|
+
* });
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
readonly fileset: typeof fileset;
|
|
510
|
+
/**
|
|
511
|
+
* Define a collection of fonts.
|
|
512
|
+
*
|
|
513
|
+
* @deprecated Use `s.fontdir(dir, options)`: the directory moved out of the
|
|
514
|
+
* options and into the first argument.
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```typescript
|
|
518
|
+
* // was: s.fontset({ dir: "/public/val/fonts" })
|
|
519
|
+
* const schema = s.fontdir("/public/val/fonts");
|
|
520
|
+
* ```
|
|
521
|
+
*/
|
|
522
|
+
readonly fontset: typeof fontset;
|
|
523
|
+
/**
|
|
524
|
+
* Define a collection of videos.
|
|
525
|
+
*
|
|
526
|
+
* @deprecated Use `s.videodir(dir, options)`: the directory moved out of the
|
|
527
|
+
* options and into the first argument.
|
|
528
|
+
*
|
|
529
|
+
* @example
|
|
530
|
+
* ```typescript
|
|
531
|
+
* // was: s.videoset({ dir: "/public/val/videos", stream: { type: "hls" } })
|
|
532
|
+
* const schema = s.videodir("/public/val/videos", { stream: { type: "hls" } });
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
454
535
|
readonly videoset: typeof videoset;
|
|
455
536
|
/**
|
|
456
537
|
* Define the project's settings.
|
|
@@ -482,8 +563,8 @@ export type InitSchemaOptions = {
|
|
|
482
563
|
/**
|
|
483
564
|
* Every media schema is remote: `files.remote` in `val.config.ts`.
|
|
484
565
|
*
|
|
485
|
-
* `s.image()`, `s.file()`, `s.video()`, `s.
|
|
486
|
-
* `s.
|
|
566
|
+
* `s.image()`, `s.file()`, `s.video()`, `s.imagedir()`, `s.filedir()`,
|
|
567
|
+
* `s.fontdir()` and `s.videodir()` (and their deprecated `*set` names) come back with `.remote()` already applied, and so does the
|
|
487
568
|
* image `s.richtext({ img: true })` builds for itself. Nothing downstream
|
|
488
569
|
* needs to know: the Studio, the MCP tools, validation and publishing all
|
|
489
570
|
* read `remote` off the schema, exactly as they do for a `.remote()` written
|
|
@@ -80,8 +80,8 @@ export type ValConfig = {
|
|
|
80
80
|
* Store every image, file and video on Val's remote content host instead
|
|
81
81
|
* of in the repository.
|
|
82
82
|
*
|
|
83
|
-
* `s.image()`, `s.file()`, `s.video()`, `s.
|
|
84
|
-
* `s.
|
|
83
|
+
* `s.image()`, `s.file()`, `s.video()`, `s.imagedir()`, `s.filedir()`,
|
|
84
|
+
* `s.fontdir()`, `s.videodir()` and `s.richtext({ img: true })` all behave as though
|
|
85
85
|
* `.remote()` had been written on them. Required for a project in the Val
|
|
86
86
|
* app, which has no repository for the bytes to go into: there the Val
|
|
87
87
|
* server refuses to start without it.
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* `application/octet-stream` once the file is a data URL. That is why an upload
|
|
9
9
|
* asks the BYTES ({@link sniffFontMimeType}) rather than trusting the picker.
|
|
10
10
|
*/
|
|
11
|
-
/** The formats `s.
|
|
11
|
+
/** The formats `s.fontdir()` accepts unless told otherwise, best first. */
|
|
12
12
|
export declare const FONT_MIME_TYPES: readonly ["font/woff2", "font/woff", "font/ttf", "font/otf"];
|
|
13
|
-
/** `s.
|
|
13
|
+
/** `s.fontdir()`'s `accept` when none is given. */
|
|
14
14
|
export declare const DEFAULT_FONT_ACCEPT: string;
|
|
15
15
|
/**
|
|
16
16
|
* The extension of each font type, for a file input: a picker matches an
|
|
@@ -27,11 +27,12 @@ import type { SerializedSchema } from "./schema/index.js";
|
|
|
27
27
|
*/
|
|
28
28
|
/**
|
|
29
29
|
* A RENDER is how a field is laid out in the editor, and it applies only when
|
|
30
|
-
* you are looking at the field.
|
|
31
|
-
* children, never by a child about itself: `s.array(item).render({ as: "inline" })`
|
|
32
|
-
* and `s.record(item).render({ as: "inline" })`.
|
|
33
|
-
*
|
|
34
|
-
* `KeyOfSchema.render`).
|
|
30
|
+
* you are looking at the field. On a list it is declared by the CONTAINER about
|
|
31
|
+
* its children, never by a child about itself: `s.array(item).render({ as: "inline" })`
|
|
32
|
+
* and `s.record(item).render({ as: "inline" })`. Two other schemas take a
|
|
33
|
+
* render, each meaning something of its own: `s.keyOf(...)` (see
|
|
34
|
+
* `KeyOfSchema.render`) and `s.number()` / `s.int()`, whose `{ as: "slider" }`
|
|
35
|
+
* is a different input for the same value (see {@link SliderRender}).
|
|
35
36
|
*
|
|
36
37
|
* Why the container: inline is a property of the LIST — "my items are edited in
|
|
37
38
|
* their rows" — and the item schema is the wrong place to say it. An item can be
|
|
@@ -75,7 +76,7 @@ import type { SerializedSchema } from "./schema/index.js";
|
|
|
75
76
|
* `s.array(s.object({ tags: s.array(s.string()) })).render({ as: "inline" })`
|
|
76
77
|
* the objects are inline and `tags` keeps its own default.
|
|
77
78
|
*
|
|
78
|
-
* Not available on `s.router(...)`, `s.
|
|
79
|
+
* Not available on `s.router(...)`, `s.imagedir(...)` or `s.filedir(...)`:
|
|
79
80
|
* pages and media have UIs of their own, and `RecordSchema.render` throws there.
|
|
80
81
|
*
|
|
81
82
|
* On `s.keyOf(...)` the same value means something else: the selected entry's
|
|
@@ -89,6 +90,38 @@ export type InlineRender = {
|
|
|
89
90
|
* What `.render(...)` takes, and what the serialized schema carries verbatim.
|
|
90
91
|
*/
|
|
91
92
|
export type FieldRender = InlineRender;
|
|
93
|
+
/**
|
|
94
|
+
* `{ as: "slider", min, max }` on `s.int()` or `s.number()`: the value is
|
|
95
|
+
* edited with a slider from `min` to `max`, next to a box that takes a typed
|
|
96
|
+
* value.
|
|
97
|
+
*
|
|
98
|
+
* `min` and `max` are REQUIRED, because a slider without ends is not a slider.
|
|
99
|
+
* They are the slider's own and are not validation: a value outside them is
|
|
100
|
+
* still valid content (if the schema allows it), and the field says it is out
|
|
101
|
+
* of the slider's reach and offers to bring it back. What the schema accepts is
|
|
102
|
+
* `.min()`, `.max()` and `.step()` on the schema itself.
|
|
103
|
+
*
|
|
104
|
+
* The one rule tying the two together: **the slider may only produce values
|
|
105
|
+
* the schema accepts.** So its range has to lie inside the schema's, its step
|
|
106
|
+
* has to be a multiple of the schema's step and its `min` on the schema's grid,
|
|
107
|
+
* and on `s.int()` all of them have to be whole numbers. A schema that breaks
|
|
108
|
+
* that throws where it is defined — see `NumberSchema`.
|
|
109
|
+
*
|
|
110
|
+
* `step` defaults to the schema's `.step()`, and to 1 when there is none.
|
|
111
|
+
*
|
|
112
|
+
* Unlike `inline` this is about the field itself — no list reads it, and
|
|
113
|
+
* {@link isInlineRender} answers `false` for it.
|
|
114
|
+
*/
|
|
115
|
+
export type SliderRender = {
|
|
116
|
+
as: "slider";
|
|
117
|
+
min: number;
|
|
118
|
+
max: number;
|
|
119
|
+
step?: number;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* What `s.number().render(...)` and `s.int().render(...)` take.
|
|
123
|
+
*/
|
|
124
|
+
export type NumberRender = SliderRender;
|
|
92
125
|
/**
|
|
93
126
|
* Does this CONTAINER edit its items inside their list rows, rather than behind
|
|
94
127
|
* clickable preview rows that navigate to them?
|
|
@@ -5,7 +5,7 @@ import { ModulePath, SourcePath } from "../val/index.js";
|
|
|
5
5
|
import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
|
|
6
6
|
import { ValModule } from "../index.js";
|
|
7
7
|
import { ItemPreviewInput, PreviewItem } from "../preview.js";
|
|
8
|
-
import {
|
|
8
|
+
import { FiledirEntryMetadata } from "./filedir.js";
|
|
9
9
|
export type FileOptions = {
|
|
10
10
|
accept?: string;
|
|
11
11
|
};
|
|
@@ -32,7 +32,7 @@ export declare class FileSchema<Src extends FileSource | null> extends Schema<Sr
|
|
|
32
32
|
private readonly isHidden;
|
|
33
33
|
private readonly description?;
|
|
34
34
|
private readonly previewInput;
|
|
35
|
-
constructor(options?: FileOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string,
|
|
35
|
+
constructor(options?: FileOptions | undefined, opt?: boolean, isRemote?: boolean, customValidateFunctions?: CustomValidateFunction<Src>[], moduleMetadata?: Record<ModulePath, Record<string, FiledirEntryMetadata>>, isReadonly?: boolean, isHidden?: boolean, description?: string | undefined, previewInput?: ItemPreviewInput<Src> | null);
|
|
36
36
|
/**
|
|
37
37
|
* Describe this field.
|
|
38
38
|
*
|
|
@@ -135,7 +135,7 @@ export declare class FileSchema<Src extends FileSource | null> extends Schema<Sr
|
|
|
135
135
|
* A file picked from a gallery. Its mime type lives in the gallery, so the
|
|
136
136
|
* field carries only the path.
|
|
137
137
|
*/
|
|
138
|
-
export declare function file(galleryModule: ValModule<Record<string,
|
|
138
|
+
export declare function file(galleryModule: ValModule<Record<string, FiledirEntryMetadata>>): FileSchema<GalleryFileSource>;
|
|
139
139
|
/** A file of its own, carrying its own mime type. */
|
|
140
140
|
export declare function file(options?: FileOptions): FileSchema<FileSource>;
|
|
141
141
|
/**
|
|
@@ -143,5 +143,5 @@ export declare function file(options?: FileOptions): FileSchema<FileSource>;
|
|
|
143
143
|
* `val.config.ts`): the same schema, with `.remote()` already applied. See
|
|
144
144
|
* `initSchema`.
|
|
145
145
|
*/
|
|
146
|
-
export declare function remoteFile(galleryModule: ValModule<Record<string,
|
|
146
|
+
export declare function remoteFile(galleryModule: ValModule<Record<string, FiledirEntryMetadata>>): FileSchema<GalleryFileSource>;
|
|
147
147
|
export declare function remoteFile(options?: FileOptions): FileSchema<FileSource>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Schema } from "./index.js";
|
|
2
|
+
import type { MediaDir, SerializedRecordSchema } from "./record.js";
|
|
3
|
+
import { RecordSchema } from "./record.js";
|
|
4
|
+
import { ObjectSchema } from "./object.js";
|
|
5
|
+
import { StringSchema } from "./string.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for `s.filedir(dir, options)`: everything but the directory, which
|
|
8
|
+
* is the first argument.
|
|
9
|
+
*/
|
|
10
|
+
export type FiledirOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* The accepted mime type pattern (e.g., "application/pdf", "text/*", "*\/*")
|
|
13
|
+
*/
|
|
14
|
+
accept: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Options for the deprecated `s.fileset(options)`, which took the directory
|
|
18
|
+
* as `dir`.
|
|
19
|
+
*
|
|
20
|
+
* @deprecated Use `s.filedir(dir, options)` and `FiledirOptions`.
|
|
21
|
+
*/
|
|
22
|
+
export type FilesetOptions = FiledirOptions & {
|
|
23
|
+
/**
|
|
24
|
+
* The directory where files should be stored.
|
|
25
|
+
* Must start with "/public" (e.g., "/public/val/files")
|
|
26
|
+
*/
|
|
27
|
+
dir: MediaDir;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Metadata for a file entry in the files record
|
|
31
|
+
*/
|
|
32
|
+
export type FiledirEntryMetadata = {
|
|
33
|
+
mimeType: string;
|
|
34
|
+
};
|
|
35
|
+
/** @deprecated Use `FiledirEntryMetadata`. */
|
|
36
|
+
export type FilesetEntryMetadata = FiledirEntryMetadata;
|
|
37
|
+
export type SerializedFiledirSchema = SerializedRecordSchema;
|
|
38
|
+
/** @deprecated Use `SerializedFiledirSchema`. */
|
|
39
|
+
export type SerializedFilesetSchema = SerializedFiledirSchema;
|
|
40
|
+
type FiledirItemProps = {
|
|
41
|
+
mimeType: StringSchema<string>;
|
|
42
|
+
};
|
|
43
|
+
type FiledirItemSrc = {
|
|
44
|
+
mimeType: string;
|
|
45
|
+
};
|
|
46
|
+
type FiledirSchema = RecordSchema<ObjectSchema<FiledirItemProps, FiledirItemSrc>, Schema<string>, Record<string, FiledirEntryMetadata>>;
|
|
47
|
+
/**
|
|
48
|
+
* Define a directory of files: a whole module that holds many files, keyed by
|
|
49
|
+
* their file path, that fields pick from with `s.file(filesVal)`.
|
|
50
|
+
*
|
|
51
|
+
* The directory is the first argument and is required — it decides where
|
|
52
|
+
* uploads land. Remote is off by default: call `.remote()` on the result to
|
|
53
|
+
* allow remote files.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const schema = s.filedir("/public/val/documents", {
|
|
58
|
+
* accept: "application/pdf",
|
|
59
|
+
* });
|
|
60
|
+
* export default c.define("/content/documents.val.ts", schema, {
|
|
61
|
+
* "/public/val/documents/report.pdf": {
|
|
62
|
+
* mimeType: "application/pdf",
|
|
63
|
+
* },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare const filedir: (dir: MediaDir, options: FiledirOptions) => FiledirSchema;
|
|
68
|
+
/**
|
|
69
|
+
* Define a collection of files.
|
|
70
|
+
*
|
|
71
|
+
* @deprecated Use `s.filedir(dir, options)`: the directory moved out of the
|
|
72
|
+
* options and into the first argument, and nothing else changed.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* // was: s.fileset({ dir: "/public/val/documents", accept: "application/pdf" })
|
|
77
|
+
* const schema = s.filedir("/public/val/documents", {
|
|
78
|
+
* accept: "application/pdf",
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare const fileset: (options: FilesetOptions) => FiledirSchema;
|
|
83
|
+
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ValModule } from "../index.js";
|
|
2
2
|
import { FileSchema } from "./file.js";
|
|
3
|
-
import {
|
|
3
|
+
import { FiledirEntryMetadata } from "./filedir.js";
|
|
4
4
|
import { GalleryFileSource } from "../source/media.js";
|
|
5
5
|
/**
|
|
6
|
-
* A font picked from an `s.
|
|
6
|
+
* A font picked from an `s.fontdir()`.
|
|
7
7
|
*
|
|
8
8
|
* The same field `s.file(fontsVal)` is — it stores `{ path }` and serializes
|
|
9
9
|
* identically — with one thing more: it refuses a set that is not a font set,
|
|
@@ -11,6 +11,6 @@ import { GalleryFileSource } from "../source/media.js";
|
|
|
11
11
|
* Studio does with it (a specimen in its parent, the set to pick from when
|
|
12
12
|
* opened) it does for any file field backed by a font set.
|
|
13
13
|
*/
|
|
14
|
-
export declare function font(fontsetModule: ValModule<Record<string,
|
|
14
|
+
export declare function font(fontsetModule: ValModule<Record<string, FiledirEntryMetadata>>): FileSchema<GalleryFileSource>;
|
|
15
15
|
/** `s.font()` with `.remote()` applied: see `files.remote` in `initSchema`. */
|
|
16
|
-
export declare function remoteFont(fontsetModule: ValModule<Record<string,
|
|
16
|
+
export declare function remoteFont(fontsetModule: ValModule<Record<string, FiledirEntryMetadata>>): FileSchema<GalleryFileSource>;
|