@valbuild/core 0.120.0 → 0.124.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 +123 -0
- package/dist/declarations/src/index.d.ts +12 -1
- package/dist/declarations/src/initSchema.d.ts +27 -0
- package/dist/declarations/src/initVal.d.ts +13 -8
- package/dist/declarations/src/module.d.ts +18 -1
- package/dist/declarations/src/schema/array.d.ts +2 -2
- package/dist/declarations/src/schema/boolean.d.ts +2 -2
- package/dist/declarations/src/schema/code.d.ts +2 -2
- package/dist/declarations/src/schema/color.d.ts +2 -2
- package/dist/declarations/src/schema/date.d.ts +2 -2
- package/dist/declarations/src/schema/datetime.d.ts +2 -2
- package/dist/declarations/src/schema/file.d.ts +2 -2
- package/dist/declarations/src/schema/files.d.ts +2 -5
- package/dist/declarations/src/schema/hasRemoteFileSchema.d.ts +21 -3
- package/dist/declarations/src/schema/image.d.ts +2 -2
- package/dist/declarations/src/schema/images.d.ts +1 -6
- package/dist/declarations/src/schema/index.d.ts +12 -3
- package/dist/declarations/src/schema/keyOf.d.ts +2 -2
- package/dist/declarations/src/schema/literal.d.ts +2 -2
- package/dist/declarations/src/schema/number.d.ts +2 -2
- package/dist/declarations/src/schema/object.d.ts +2 -2
- package/dist/declarations/src/schema/record.d.ts +80 -4
- package/dist/declarations/src/schema/richtext.d.ts +2 -2
- package/dist/declarations/src/schema/route.d.ts +2 -2
- package/dist/declarations/src/schema/settings.d.ts +102 -0
- package/dist/declarations/src/schema/string.d.ts +2 -2
- package/dist/declarations/src/schema/union.d.ts +2 -2
- package/dist/declarations/src/schema/validation/ValidationFix.d.ts +1 -1
- package/dist/declarations/src/selector/index.d.ts +4 -2
- package/dist/declarations/src/settingsModule.d.ts +60 -0
- package/dist/declarations/src/source/external.d.ts +91 -0
- package/dist/declarations/src/source/externalRef.d.ts +46 -0
- package/dist/declarations/src/source/index.d.ts +4 -2
- package/dist/declarations/src/source/settings.d.ts +94 -0
- package/dist/{index-861944d8.cjs.prod.js → index-22a40d42.cjs.prod.js} +1324 -446
- package/dist/{index-2f65e194.esm.js → index-9c14df37.esm.js} +1318 -447
- package/dist/{index-01f673d2.cjs.dev.js → index-fcd087bd.cjs.dev.js} +1324 -446
- package/dist/valbuild-core.cjs.dev.js +8 -1
- package/dist/valbuild-core.cjs.prod.js +8 -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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,128 @@
|
|
|
1
1
|
# @valbuild/core
|
|
2
2
|
|
|
3
|
+
## 0.124.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#622](https://github.com/valbuild/val/pull/622) [`aa89fc2`](https://github.com/valbuild/val/commit/aa89fc26de7028b3c5a1666b99afc03b39e92769) Thanks [@freekh](https://github.com/freekh)! - **Breaking:** `s.images()` and `s.files()` no longer take a `remote` option. Use
|
|
8
|
+
`.remote()`, the same way `s.image()` and `s.file()` already did.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
// before
|
|
12
|
+
s.images({ directory: "/public/val/images", remote: true });
|
|
13
|
+
s.files({
|
|
14
|
+
directory: "/public/val/docs",
|
|
15
|
+
accept: "application/pdf",
|
|
16
|
+
remote: true,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// after
|
|
20
|
+
s.images({ directory: "/public/val/images" }).remote();
|
|
21
|
+
s.files({
|
|
22
|
+
directory: "/public/val/docs",
|
|
23
|
+
accept: "application/pdf",
|
|
24
|
+
}).remote();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Behaviour is unchanged — remote is still off unless asked for. This only makes
|
|
28
|
+
remote one thing spelled one way across all four media schemas, instead of an
|
|
29
|
+
option on the two collections and a method on the two fields. `remote: false`
|
|
30
|
+
has no replacement because it was the default; drop it.
|
|
31
|
+
|
|
32
|
+
## 0.121.0
|
|
33
|
+
|
|
34
|
+
### Minor Changes
|
|
35
|
+
|
|
36
|
+
- [#605](https://github.com/valbuild/val/pull/605) [`6794d29`](https://github.com/valbuild/val/commit/6794d2980bc81284ab7f2cc667f01cc21c9e3a79) Thanks [@freekh](https://github.com/freekh)! - `s.settings()`: the project's settings, as content.
|
|
37
|
+
|
|
38
|
+
A settings module is one per project, at the root of the content tree:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// settings.val.ts
|
|
42
|
+
export default c.define("/settings.val.ts", s.settings(), {});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Register it in `val.modules.ts` like any other module, and it shows up in the
|
|
46
|
+
Studio under the cog at the foot of the left rail. Everything in it is content:
|
|
47
|
+
it is edited as a draft, it appears in the publish diff, and it is the same for
|
|
48
|
+
everyone working on the project.
|
|
49
|
+
|
|
50
|
+
Every key is optional, at every level, so `{}` is a complete settings module —
|
|
51
|
+
and stays one as sections are added. What it holds today is the assistant:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export default c.define("/settings.val.ts", s.settings(), {
|
|
55
|
+
assistant: {
|
|
56
|
+
enabled: true,
|
|
57
|
+
context: "A CMS for developers, run by a team of four in Oslo.",
|
|
58
|
+
tone: "Plain and direct. British English, sentence case in headings.",
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`context` is background the assistant would otherwise guess at; `tone` is how it
|
|
64
|
+
should write when it writes content. Both are sent with every message it makes.
|
|
65
|
+
|
|
66
|
+
`enabled` decides whether editors have an assistant, and it has **three** states
|
|
67
|
+
rather than two:
|
|
68
|
+
|
|
69
|
+
- `true` — they do.
|
|
70
|
+
- `false` — they do not, and every trace of it goes: no button in the top bar,
|
|
71
|
+
no row in the quick actions, no panel, nothing sent.
|
|
72
|
+
- unset — nobody has decided. The assistant is still **shown**, and asks to be
|
|
73
|
+
turned on before it is used. Hiding an assistant nobody has decided about
|
|
74
|
+
means nobody discovers it; quietly enabling one means a project starts sending
|
|
75
|
+
its content to a model because it did not know to say no.
|
|
76
|
+
|
|
77
|
+
A project with no settings module at all has an assistant, as before: there is
|
|
78
|
+
nowhere to record a decision, and nowhere for the prompt to write the answer.
|
|
79
|
+
|
|
80
|
+
**Breaking: `ai.chat` is gone from `val.config.ts`.** Whether the assistant is
|
|
81
|
+
available is a decision about the project's content, made by the people who edit
|
|
82
|
+
it, so it moved to settings — turning the chat on used to take a developer, a
|
|
83
|
+
deploy and a code review of a boolean. Remove the whole block:
|
|
84
|
+
|
|
85
|
+
```diff
|
|
86
|
+
const { s, c, val, config } = initVal({
|
|
87
|
+
- ai: {
|
|
88
|
+
- chat: {
|
|
89
|
+
- experimental: { enable: true },
|
|
90
|
+
- suggestions: ["Summarize", "Fix typos at this page"],
|
|
91
|
+
- title: "Ask me anything",
|
|
92
|
+
- description: "Val can answer questions about the content.",
|
|
93
|
+
- },
|
|
94
|
+
- },
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`experimental.enable` becomes `assistant.enabled` in the settings module.
|
|
99
|
+
`suggestions`, `title` and `description` are removed with nothing replacing
|
|
100
|
+
them: the assistant now opens with its own copy. A project that had the chat
|
|
101
|
+
enabled and wants it to stay on for everyone should write
|
|
102
|
+
`assistant: { enabled: true }` — otherwise editors are offered it and asked.
|
|
103
|
+
|
|
104
|
+
`ai.commitMessages` stays in `val.config.ts`, and is unaffected.
|
|
105
|
+
|
|
106
|
+
Two settings modules, or one in a subdirectory, is a module error: the dev
|
|
107
|
+
server refuses to serve sources, `npx val validate` reports it against the file,
|
|
108
|
+
and the Studio says so rather than picking one.
|
|
109
|
+
|
|
110
|
+
### Patch Changes
|
|
111
|
+
|
|
112
|
+
- [#607](https://github.com/valbuild/val/pull/607) [`2bcbee1`](https://github.com/valbuild/val/commit/2bcbee1be682c2bbd5b7bc7d152ddd4204162fd2) Thanks [@freekh](https://github.com/freekh)! - `.readonly()` and `.hidden()` now take the flag as an argument, so a schema can
|
|
113
|
+
decide these from a variable instead of only from whether the call was written at
|
|
114
|
+
all:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
s.string().readonly(!canEdit);
|
|
118
|
+
s.image().hidden(hideMedia);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The argument defaults to `true`, so `.readonly()` and `.readonly(true)` are the
|
|
122
|
+
same thing and nothing about existing schemas changes. Passing `false` leaves the
|
|
123
|
+
field editable or visible, which is also what a schema is without the call - it
|
|
124
|
+
is there so the flag can come from a variable.
|
|
125
|
+
|
|
3
126
|
## 0.120.0
|
|
4
127
|
|
|
5
128
|
### Minor Changes
|
|
@@ -3,13 +3,14 @@ export { modules, type ValModules } from "./modules.js";
|
|
|
3
3
|
export { extractValModules, computeValModuleShas, type ExtractedValModules, type ValModuleShaEntry, type ValModuleShas, type ExtractedModuleError, } from "./extractValModules.js";
|
|
4
4
|
export type { InitVal, ValConfig, ValConstructor, ContentConstructor, } from "./initVal.js";
|
|
5
5
|
export { Schema, type SerializedSchema, type SelectorOfSchema } from "./schema/index.js";
|
|
6
|
-
export { hasRemoteFileSchema } from "./schema/hasRemoteFileSchema.js";
|
|
6
|
+
export { hasRemoteFileSchema, hasMediaSchema, } from "./schema/hasRemoteFileSchema.js";
|
|
7
7
|
export type { ImageMetadata, ImageEncodeOption, ImageEncodeOptions, } from "./schema/image.js";
|
|
8
8
|
export type { FileMetadata } from "./schema/file.js";
|
|
9
9
|
export type { ValModule, SerializedModule, InferValModuleType } from "./module.js";
|
|
10
10
|
export type { SourceObject, SourcePrimitive, Source } from "./source/index.js";
|
|
11
11
|
export type { FileSource } from "./source/media.js";
|
|
12
12
|
export type { JsonSource, JsonOf, JsonImportThunk } from "./source/json.js";
|
|
13
|
+
export type { ExternalRecordSrc, ExternalRecordWritableSrc, ExternalItemOf, ExternalLabelOf, ExternalReadonlyOf, } from "./source/external.js";
|
|
13
14
|
export type { RemoteRef } from "./source/remote.js";
|
|
14
15
|
export { DEFAULT_VAL_REMOTE_HOST } from "./schema/remote.js";
|
|
15
16
|
export type { RawString } from "./schema/string.js";
|
|
@@ -35,6 +36,8 @@ import { getMimeType, mimeTypeToFileExt, filenameToMimeType, mimeTypeMatchesAcce
|
|
|
35
36
|
import { type ImageMetadata } from "./schema/image.js";
|
|
36
37
|
import { type FileMetadata } from "./schema/file.js";
|
|
37
38
|
import { isJson, getJsonImport, resolveJsonValues } from "./source/json.js";
|
|
39
|
+
import { isExternal, hasInlineExternalEntries } from "./source/external.js";
|
|
40
|
+
import { createExternalFileRef, splitExternalFileRef, isExternalFileRef } from "./source/externalRef.js";
|
|
38
41
|
import { createRemoteRef } from "./source/remote.js";
|
|
39
42
|
import { getValidationBasis, getValidationHash } from "./remote/validationBasis.js";
|
|
40
43
|
import { getFileHash, hashToRemoteFileHash } from "./remote/fileHash.js";
|
|
@@ -50,6 +53,9 @@ export { type SerializedBooleanSchema, BooleanSchema } from "./schema/boolean.js
|
|
|
50
53
|
export { type SerializedImageSchema, ImageSchema } from "./schema/image.js";
|
|
51
54
|
export { type SerializedFileSchema, FileSchema } from "./schema/file.js";
|
|
52
55
|
export { type SerializedDateSchema, DateSchema } from "./schema/date.js";
|
|
56
|
+
export { type SerializedSettingsSchema, SettingsSchema, } from "./schema/settings.js";
|
|
57
|
+
export { type SettingsSource, type AssistantSettingsSource, type AssistantAvailability, ASSISTANT_SETTINGS_MAX_LENGTH, assistantAvailability, } from "./source/settings.js";
|
|
58
|
+
export { type ResolvedSettingsModule, SETTINGS_MODULE_CONVENTION, isRootModuleFilePath, resolveSettingsModule, } from "./settingsModule.js";
|
|
53
59
|
export { type SerializedColorSchema, type ColorOptions, ColorSchema, } from "./schema/color.js";
|
|
54
60
|
export { type SerializedCodeSchema, type CodeOptions, type CodeLanguage, CodeSchema, CODE_LANGUAGES, } from "./schema/code.js";
|
|
55
61
|
export { type ColorFormat, type ParsedColor, COLOR_FORMATS, DEFAULT_COLOR_FORMAT, } from "./schema/colorFormat.js";
|
|
@@ -108,6 +114,11 @@ declare const Internal: {
|
|
|
108
114
|
isJson: typeof isJson;
|
|
109
115
|
getJsonImport: typeof getJsonImport;
|
|
110
116
|
resolveJsonValues: typeof resolveJsonValues;
|
|
117
|
+
isExternal: typeof isExternal;
|
|
118
|
+
hasInlineExternalEntries: typeof hasInlineExternalEntries;
|
|
119
|
+
createExternalFileRef: typeof createExternalFileRef;
|
|
120
|
+
splitExternalFileRef: typeof splitExternalFileRef;
|
|
121
|
+
isExternalFileRef: typeof isExternalFileRef;
|
|
111
122
|
createValPathOfItem: typeof createValPathOfItem;
|
|
112
123
|
getSHA256Hash: (bits: Uint8Array) => string;
|
|
113
124
|
initSchema: typeof initSchema;
|
|
@@ -18,6 +18,7 @@ import { color } from "./schema/color.js";
|
|
|
18
18
|
import { route } from "./schema/route.js";
|
|
19
19
|
import { router } from "./schema/router.js";
|
|
20
20
|
import { images } from "./schema/images.js";
|
|
21
|
+
import { settings } from "./schema/settings.js";
|
|
21
22
|
export type InitSchema = {
|
|
22
23
|
/**
|
|
23
24
|
* Define a string.
|
|
@@ -299,6 +300,31 @@ export type InitSchema = {
|
|
|
299
300
|
* ```
|
|
300
301
|
*/
|
|
301
302
|
readonly files: typeof files;
|
|
303
|
+
/**
|
|
304
|
+
* Define the project's settings.
|
|
305
|
+
*
|
|
306
|
+
* One per project, at the root of the content tree — a module file path with
|
|
307
|
+
* no directory segment, `/settings.val.ts` by convention. Every section is
|
|
308
|
+
* optional, so `{}` is a complete settings module and stays one as sections
|
|
309
|
+
* are added.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```typescript
|
|
313
|
+
* export default c.define("/settings.val.ts", s.settings(), {});
|
|
314
|
+
* ```
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```typescript
|
|
318
|
+
* export default c.define("/settings.val.ts", s.settings(), {
|
|
319
|
+
* assistant: {
|
|
320
|
+
* enabled: true,
|
|
321
|
+
* context: "A CMS for developers. British English throughout.",
|
|
322
|
+
* tone: "Plain and direct. Sentence case in headings.",
|
|
323
|
+
* },
|
|
324
|
+
* });
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
readonly settings: typeof settings;
|
|
302
328
|
};
|
|
303
329
|
export declare function initSchema(): {
|
|
304
330
|
string: <T extends string>(options?: Record<string, never>) => import("./index.js").StringSchema<T>;
|
|
@@ -349,4 +375,5 @@ export declare function initSchema(): {
|
|
|
349
375
|
mimeType: string;
|
|
350
376
|
alt: string | null;
|
|
351
377
|
}>, import("./schema/index.js").Schema<string>, Record<string, import("./schema/images.js").ImagesEntryMetadata>>;
|
|
378
|
+
settings: typeof settings;
|
|
352
379
|
};
|
|
@@ -2,9 +2,11 @@ import { define } from "./module.js";
|
|
|
2
2
|
import { InitSchema } from "./initSchema.js";
|
|
3
3
|
import { getValPath as getPath } from "./val/index.js";
|
|
4
4
|
import { json } from "./source/json.js";
|
|
5
|
+
import { external } from "./source/external.js";
|
|
5
6
|
export type ContentConstructor = {
|
|
6
7
|
define: typeof define;
|
|
7
8
|
json: typeof json;
|
|
9
|
+
external: typeof external;
|
|
8
10
|
};
|
|
9
11
|
export type ValConstructor = {
|
|
10
12
|
unstable_getPath: typeof getPath;
|
|
@@ -20,17 +22,20 @@ export type ValConfig = {
|
|
|
20
22
|
gitBranch?: string;
|
|
21
23
|
defaultTheme?: "dark" | "light";
|
|
22
24
|
ai?: {
|
|
25
|
+
/**
|
|
26
|
+
* The AI commit-message summariser.
|
|
27
|
+
*
|
|
28
|
+
* Still config, and deliberately: it is about how the repository is
|
|
29
|
+
* written to rather than about the content, and it is getting settings of
|
|
30
|
+
* its own. The ASSISTANT is not here — it is `s.settings()`, under
|
|
31
|
+
* `assistant.enabled`, because whether editors have a chat is a decision
|
|
32
|
+
* about the
|
|
33
|
+
* project's content, made by the people who edit it, and published like any
|
|
34
|
+
* other content change.
|
|
35
|
+
*/
|
|
23
36
|
commitMessages?: {
|
|
24
37
|
disabled?: boolean;
|
|
25
38
|
};
|
|
26
|
-
chat?: {
|
|
27
|
-
experimental?: {
|
|
28
|
-
enable?: boolean;
|
|
29
|
-
};
|
|
30
|
-
suggestions?: string[];
|
|
31
|
-
title?: string;
|
|
32
|
-
description?: string;
|
|
33
|
-
};
|
|
34
39
|
};
|
|
35
40
|
};
|
|
36
41
|
export type InitVal = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Schema, SelectorOfSchema, SerializedSchema } from "./schema/index.js";
|
|
2
2
|
import { GenericSelector, SelectorOf, SelectorSource } from "./selector/index.js";
|
|
3
3
|
import { Source } from "./source/index.js";
|
|
4
|
+
import { ExternalRecordSrc } from "./source/external.js";
|
|
4
5
|
import { ModuleFilePath, ModulePath, SourcePath } from "./val/index.js";
|
|
5
6
|
import { Json } from "./Json.js";
|
|
6
7
|
import { RawString } from "./schema/string.js";
|
|
@@ -15,8 +16,24 @@ export type ReplaceRawStringWithString<T extends SelectorSource> = SelectorSourc
|
|
|
15
16
|
} ? {
|
|
16
17
|
[key in keyof T]: ReplaceRawStringWithString<T[key]>;
|
|
17
18
|
} : T extends SelectorSource[] ? ReplaceRawStringWithString<T[number]>[] : T;
|
|
19
|
+
/**
|
|
20
|
+
* What may be WRITTEN as an external record's source, on top of the marker.
|
|
21
|
+
*
|
|
22
|
+
* Entries inline in the `.val.ts` are accepted on purpose — the same call
|
|
23
|
+
* `.jsonValues()` makes for the same reason: pasting content straight into the
|
|
24
|
+
* module is the natural first thing to write, and a type error there is a dead
|
|
25
|
+
* end, because the author cannot see what to write instead. Validation reports
|
|
26
|
+
* them as an `external:upload` fix, and they are readable at runtime meanwhile.
|
|
27
|
+
*
|
|
28
|
+
* Widened HERE rather than in the schema's own source type so that the MODULE
|
|
29
|
+
* stays typed on the marker alone. An adapter is bound to a module, and a module
|
|
30
|
+
* whose type were "marker or plain record" would be indistinguishable from an
|
|
31
|
+
* ordinary record — which would let `entry()` accept a module that is not
|
|
32
|
+
* external at all.
|
|
33
|
+
*/
|
|
34
|
+
type InlineEntriesFor<S> = S extends ExternalRecordSrc<infer Item, string, boolean> ? Record<string, Item> : never;
|
|
18
35
|
export declare function define<T extends Schema<SelectorSource>>(id: string, // TODO: `/${string}`
|
|
19
|
-
schema: T, source: ReplaceRawStringWithString<SelectorOfSchema<T>>): ValModule<SelectorOfSchema<T>>;
|
|
36
|
+
schema: T, source: ReplaceRawStringWithString<SelectorOfSchema<T>> | InlineEntriesFor<SelectorOfSchema<T>>): ValModule<SelectorOfSchema<T>>;
|
|
20
37
|
export declare function getSource<T extends Source>(valModule: ValModule<T>): T;
|
|
21
38
|
/**
|
|
22
39
|
* Whether `value` is a Val module, i.e. something {@link define} produced.
|
|
@@ -43,8 +43,8 @@ export declare class ArraySchema<T extends Schema<SelectorSource>, Src extends S
|
|
|
43
43
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
44
44
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
45
45
|
nullable(): ArraySchema<T, Src | null>;
|
|
46
|
-
readonly(): ArraySchema<T, Src>;
|
|
47
|
-
hidden(): ArraySchema<T, Src>;
|
|
46
|
+
readonly(isReadonly?: boolean): ArraySchema<T, Src>;
|
|
47
|
+
hidden(isHidden?: boolean): ArraySchema<T, Src>;
|
|
48
48
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
49
49
|
protected executeSerialize(): SerializedArraySchema;
|
|
50
50
|
protected executePreview(sourcePath: SourcePath | ModuleFilePath, src: Src, scope?: PreviewScope): ReifiedPreview;
|
|
@@ -29,8 +29,8 @@ export declare class BooleanSchema<Src extends boolean | null> extends Schema<Sr
|
|
|
29
29
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
30
30
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
31
31
|
nullable(): BooleanSchema<Src | null>;
|
|
32
|
-
readonly(): BooleanSchema<Src>;
|
|
33
|
-
hidden(): BooleanSchema<Src>;
|
|
32
|
+
readonly(isReadonly?: boolean): BooleanSchema<Src>;
|
|
33
|
+
hidden(isHidden?: boolean): BooleanSchema<Src>;
|
|
34
34
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
35
35
|
/**
|
|
36
36
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -61,8 +61,8 @@ export declare class CodeSchema<Src extends string | null> extends Schema<Src> {
|
|
|
61
61
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
62
62
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
63
63
|
nullable(): CodeSchema<Src | null>;
|
|
64
|
-
readonly(): CodeSchema<Src>;
|
|
65
|
-
hidden(): CodeSchema<Src>;
|
|
64
|
+
readonly(isReadonly?: boolean): CodeSchema<Src>;
|
|
65
|
+
hidden(isHidden?: boolean): CodeSchema<Src>;
|
|
66
66
|
/**
|
|
67
67
|
* How this field is laid out in the editor when it is the item of an array
|
|
68
68
|
* or record: `{ as: "inline" }` renders the field itself inside each row,
|
|
@@ -56,8 +56,8 @@ export declare class ColorSchema<Src extends string | null> extends Schema<Src>
|
|
|
56
56
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
57
57
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
58
58
|
nullable(): ColorSchema<Src | null>;
|
|
59
|
-
readonly(): ColorSchema<Src>;
|
|
60
|
-
hidden(): ColorSchema<Src>;
|
|
59
|
+
readonly(isReadonly?: boolean): ColorSchema<Src>;
|
|
60
|
+
hidden(isHidden?: boolean): ColorSchema<Src>;
|
|
61
61
|
/**
|
|
62
62
|
* How this field is laid out in the editor when it is the item of an array
|
|
63
63
|
* or record: `{ as: "inline" }` renders the field itself inside each row,
|
|
@@ -50,8 +50,8 @@ export declare class DateSchema<Src extends string | null> extends Schema<Src> {
|
|
|
50
50
|
from(from: string): DateSchema<Src>;
|
|
51
51
|
to(to: string): DateSchema<Src>;
|
|
52
52
|
nullable(): DateSchema<Src | null>;
|
|
53
|
-
readonly(): DateSchema<Src>;
|
|
54
|
-
hidden(): DateSchema<Src>;
|
|
53
|
+
readonly(isReadonly?: boolean): DateSchema<Src>;
|
|
54
|
+
hidden(isHidden?: boolean): DateSchema<Src>;
|
|
55
55
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
56
56
|
/**
|
|
57
57
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -54,8 +54,8 @@ export declare class DateTimeSchema<Src extends string | null> extends Schema<Sr
|
|
|
54
54
|
from(from: string): DateTimeSchema<Src>;
|
|
55
55
|
to(to: string): DateTimeSchema<Src>;
|
|
56
56
|
nullable(): DateTimeSchema<Src | null>;
|
|
57
|
-
readonly(): DateTimeSchema<Src>;
|
|
58
|
-
hidden(): DateTimeSchema<Src>;
|
|
57
|
+
readonly(isReadonly?: boolean): DateTimeSchema<Src>;
|
|
58
|
+
hidden(isHidden?: boolean): DateTimeSchema<Src>;
|
|
59
59
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
60
60
|
/**
|
|
61
61
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -48,8 +48,8 @@ export declare class FileSchema<Src extends FileSource | null> extends Schema<Sr
|
|
|
48
48
|
private galleryEntries;
|
|
49
49
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
50
50
|
nullable(): FileSchema<Src | null>;
|
|
51
|
-
readonly(): FileSchema<Src>;
|
|
52
|
-
hidden(): FileSchema<Src>;
|
|
51
|
+
readonly(isReadonly?: boolean): FileSchema<Src>;
|
|
52
|
+
hidden(isHidden?: boolean): FileSchema<Src>;
|
|
53
53
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
54
54
|
/**
|
|
55
55
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -21,11 +21,6 @@ export type FilesOptions = {
|
|
|
21
21
|
* a directory with every other one.
|
|
22
22
|
*/
|
|
23
23
|
directory: "/public" | `/public/${string}`;
|
|
24
|
-
/**
|
|
25
|
-
* Whether remote files are allowed
|
|
26
|
-
* @default false
|
|
27
|
-
*/
|
|
28
|
-
remote?: boolean;
|
|
29
24
|
};
|
|
30
25
|
/**
|
|
31
26
|
* Metadata for a file entry in the files record
|
|
@@ -43,6 +38,8 @@ type FilesItemSrc = {
|
|
|
43
38
|
/**
|
|
44
39
|
* Define a collection of files.
|
|
45
40
|
*
|
|
41
|
+
* Remote is off by default: call `.remote()` on the result to allow remote files.
|
|
42
|
+
*
|
|
46
43
|
* @example
|
|
47
44
|
* ```typescript
|
|
48
45
|
* const schema = s.files({
|
|
@@ -5,9 +5,10 @@ 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.images({
|
|
9
|
-
* remote media record, the server's did not, because a media
|
|
10
|
-
* serializes as a `record` of metadata rather than as an image
|
|
8
|
+
* and they disagreed about `s.images({ ... }).remote()`: the Studio's version
|
|
9
|
+
* counted a remote media record, the server's did not, because a media
|
|
10
|
+
* collection serializes as a `record` of metadata rather than as an image
|
|
11
|
+
* schema.
|
|
11
12
|
*
|
|
12
13
|
* The server's answer was the wrong one, and silently so. With it false,
|
|
13
14
|
* `/save` runs `saveOrUploadFiles` in `skip-remote` mode, and that mode does not
|
|
@@ -32,3 +33,20 @@ import type { SerializedSchema } from "./index.js";
|
|
|
32
33
|
* instead would reintroduce exactly the silent skip described above.
|
|
33
34
|
*/
|
|
34
35
|
export declare function hasRemoteFileSchema(schema: SerializedSchema): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Does this schema hold any media at all — remote or not?
|
|
38
|
+
*
|
|
39
|
+
* The sibling of {@link hasRemoteFileSchema}, and the same walk minus the
|
|
40
|
+
* `remote` predicate. It answers the question an external record has to ask
|
|
41
|
+
* before it will accept a binding: an item schema containing media needs a
|
|
42
|
+
* `putFile`/`getFile` pair, and without one that is a schema error.
|
|
43
|
+
*
|
|
44
|
+
* It is a walk over the SERIALIZED schema for the reasons given above, and for
|
|
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.images()` /
|
|
47
|
+
* `s.files()`) serializes as a record of metadata with no image schema inside
|
|
48
|
+
* it, and a richtext inline image lives in a constructor argument. A check
|
|
49
|
+
* written against the item TYPE would silently pass both — and the gallery case
|
|
50
|
+
* already has a data-loss incident attached to it (see above).
|
|
51
|
+
*/
|
|
52
|
+
export declare function hasMediaSchema(schema: SerializedSchema): boolean;
|
|
@@ -93,8 +93,8 @@ export declare class ImageSchema<Src extends ImageSource | null> extends Schema<
|
|
|
93
93
|
private galleryEntries;
|
|
94
94
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
95
95
|
nullable(): ImageSchema<Src | null>;
|
|
96
|
-
readonly(): ImageSchema<Src>;
|
|
97
|
-
hidden(): ImageSchema<Src>;
|
|
96
|
+
readonly(isReadonly?: boolean): ImageSchema<Src>;
|
|
97
|
+
hidden(isHidden?: boolean): ImageSchema<Src>;
|
|
98
98
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
99
99
|
/**
|
|
100
100
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -35,11 +35,6 @@ export type ImagesOptions<Accept extends `image/${string}`> = {
|
|
|
35
35
|
* - s.record(s.string(), s.string()) for locale-based alt text
|
|
36
36
|
*/
|
|
37
37
|
alt?: AltSchema;
|
|
38
|
-
/**
|
|
39
|
-
* Whether remote images are allowed
|
|
40
|
-
* @default false
|
|
41
|
-
*/
|
|
42
|
-
remote?: boolean;
|
|
43
38
|
/**
|
|
44
39
|
* Re-encode uploads in the browser before they are uploaded.
|
|
45
40
|
*
|
|
@@ -79,7 +74,7 @@ type ImagesItemSrc = {
|
|
|
79
74
|
*
|
|
80
75
|
* `directory` is required — it decides where uploads land, so it is not something
|
|
81
76
|
* to be inferred. The rest defaults: any image type (`"image/*"`), nullable alt
|
|
82
|
-
* text, remote disabled.
|
|
77
|
+
* text, remote disabled. Call `.remote()` on the result to allow remote images.
|
|
83
78
|
*
|
|
84
79
|
* @example
|
|
85
80
|
* ```typescript
|
|
@@ -17,11 +17,12 @@ import { SerializedColorSchema } from "./color.js";
|
|
|
17
17
|
import { SerializedDateSchema } from "./date.js";
|
|
18
18
|
import { SerializedDateTimeSchema } from "./datetime.js";
|
|
19
19
|
import { SerializedRouteSchema } from "./route.js";
|
|
20
|
+
import { SerializedSettingsSchema } from "./settings.js";
|
|
20
21
|
import { ValidationError, ValidationErrors } from "./validation/ValidationError.js";
|
|
21
22
|
import { FileSource } from "../source/media.js";
|
|
22
23
|
import { GenericRichTextSourceNode, RichTextSource } from "../source/richtext.js";
|
|
23
24
|
import { ReifiedPreview, PreviewScope, PreviewItem } from "../preview.js";
|
|
24
|
-
export type SerializedSchema = SerializedStringSchema | SerializedLiteralSchema | SerializedBooleanSchema | SerializedNumberSchema | SerializedObjectSchema | SerializedArraySchema | SerializedUnionSchema | SerializedRichTextSchema | SerializedRecordSchema | SerializedKeyOfSchema | SerializedFileSchema | SerializedDateSchema | SerializedDateTimeSchema | SerializedColorSchema | SerializedCodeSchema | SerializedRouteSchema | SerializedImageSchema;
|
|
25
|
+
export type SerializedSchema = SerializedStringSchema | SerializedLiteralSchema | SerializedBooleanSchema | SerializedNumberSchema | SerializedObjectSchema | SerializedArraySchema | SerializedUnionSchema | SerializedRichTextSchema | SerializedRecordSchema | SerializedKeyOfSchema | SerializedFileSchema | SerializedDateSchema | SerializedDateTimeSchema | SerializedColorSchema | SerializedCodeSchema | SerializedRouteSchema | SerializedSettingsSchema | SerializedImageSchema;
|
|
25
26
|
type Primitives = number | string | boolean | null | FileSource;
|
|
26
27
|
export type AssertError = {
|
|
27
28
|
message: string;
|
|
@@ -97,15 +98,23 @@ export declare abstract class Schema<Src extends SelectorSource> {
|
|
|
97
98
|
*
|
|
98
99
|
* This is a UI-only flag: the field is rendered disabled in the editor, but
|
|
99
100
|
* the value is not otherwise validated or enforced differently.
|
|
101
|
+
*
|
|
102
|
+
* The flag defaults to `true`, so `.readonly()` and `.readonly(true)` are the
|
|
103
|
+
* same thing. `.readonly(false)` leaves the field editable, which is what a
|
|
104
|
+
* schema is anyway - pass it when the decision comes from a variable.
|
|
100
105
|
*/
|
|
101
|
-
abstract readonly(): Schema<Src>;
|
|
106
|
+
abstract readonly(isReadonly?: boolean): Schema<Src>;
|
|
102
107
|
/**
|
|
103
108
|
* Hide this field from the Val editor.
|
|
104
109
|
*
|
|
105
110
|
* This is a UI-only flag: the field is not rendered in the editor, but the
|
|
106
111
|
* value is still stored, validated and serialized as normal.
|
|
112
|
+
*
|
|
113
|
+
* The flag defaults to `true`, so `.hidden()` and `.hidden(true)` are the
|
|
114
|
+
* same thing. `.hidden(false)` leaves the field visible, which is what a
|
|
115
|
+
* schema is anyway - pass it when the decision comes from a variable.
|
|
107
116
|
*/
|
|
108
|
-
abstract hidden(): Schema<Src>;
|
|
117
|
+
abstract hidden(isHidden?: boolean): Schema<Src>;
|
|
109
118
|
protected abstract executeSerialize(): SerializedSchema;
|
|
110
119
|
/**
|
|
111
120
|
* @param scope Which paths the caller needs a preview for. Absent means the
|
|
@@ -47,8 +47,8 @@ export declare class KeyOfSchema<Sel extends GenericSelector<SourceObject>, Src
|
|
|
47
47
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
48
48
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
49
49
|
nullable(): KeyOfSchema<Sel, Src | null>;
|
|
50
|
-
readonly(): KeyOfSchema<Sel, Src>;
|
|
51
|
-
hidden(): KeyOfSchema<Sel, Src>;
|
|
50
|
+
readonly(isReadonly?: boolean): KeyOfSchema<Sel, Src>;
|
|
51
|
+
hidden(isHidden?: boolean): KeyOfSchema<Sel, Src>;
|
|
52
52
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
53
53
|
/**
|
|
54
54
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -31,8 +31,8 @@ export declare class LiteralSchema<Src extends string | null> extends Schema<Src
|
|
|
31
31
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
32
32
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
33
33
|
nullable(): LiteralSchema<Src | null>;
|
|
34
|
-
readonly(): LiteralSchema<Src>;
|
|
35
|
-
hidden(): LiteralSchema<Src>;
|
|
34
|
+
readonly(isReadonly?: boolean): LiteralSchema<Src>;
|
|
35
|
+
hidden(isHidden?: boolean): LiteralSchema<Src>;
|
|
36
36
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
37
37
|
/**
|
|
38
38
|
* How this field is laid out in the editor when it is the item of an array
|
|
@@ -35,8 +35,8 @@ export declare class NumberSchema<Src extends number | null> extends Schema<Src>
|
|
|
35
35
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
36
36
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
37
37
|
nullable(): NumberSchema<Src | null>;
|
|
38
|
-
readonly(): NumberSchema<Src>;
|
|
39
|
-
hidden(): NumberSchema<Src>;
|
|
38
|
+
readonly(isReadonly?: boolean): NumberSchema<Src>;
|
|
39
|
+
hidden(isHidden?: boolean): NumberSchema<Src>;
|
|
40
40
|
max(max: number): NumberSchema<Src>;
|
|
41
41
|
min(min: number): NumberSchema<Src>;
|
|
42
42
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
@@ -55,8 +55,8 @@ export declare class ObjectSchema<Props extends ObjectSchemaProps, Src extends O
|
|
|
55
55
|
protected executeValidate(path: SourcePath, src: Src): ValidationErrors;
|
|
56
56
|
protected executeAssert(path: SourcePath, src: unknown): SchemaAssertResult<Src>;
|
|
57
57
|
nullable(): ObjectSchema<Props, Src | null>;
|
|
58
|
-
readonly(): ObjectSchema<Props, Src>;
|
|
59
|
-
hidden(): ObjectSchema<Props, Src>;
|
|
58
|
+
readonly(isReadonly?: boolean): ObjectSchema<Props, Src>;
|
|
59
|
+
hidden(isHidden?: boolean): ObjectSchema<Props, Src>;
|
|
60
60
|
protected executeCustomValidateAt(path: SourcePath, src: Src): ValidationError[];
|
|
61
61
|
/**
|
|
62
62
|
* How this field is laid out in the editor when it is the item of an array
|