@valbuild/next 0.120.3 → 0.121.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
CHANGED
|
@@ -1,5 +1,117 @@
|
|
|
1
1
|
# @valbuild/next
|
|
2
2
|
|
|
3
|
+
## 0.121.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#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.
|
|
8
|
+
|
|
9
|
+
A settings module is one per project, at the root of the content tree:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// settings.val.ts
|
|
13
|
+
export default c.define("/settings.val.ts", s.settings(), {});
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Register it in `val.modules.ts` like any other module, and it shows up in the
|
|
17
|
+
Studio under the cog at the foot of the left rail. Everything in it is content:
|
|
18
|
+
it is edited as a draft, it appears in the publish diff, and it is the same for
|
|
19
|
+
everyone working on the project.
|
|
20
|
+
|
|
21
|
+
Every key is optional, at every level, so `{}` is a complete settings module —
|
|
22
|
+
and stays one as sections are added. What it holds today is the assistant:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
export default c.define("/settings.val.ts", s.settings(), {
|
|
26
|
+
assistant: {
|
|
27
|
+
enabled: true,
|
|
28
|
+
context: "A CMS for developers, run by a team of four in Oslo.",
|
|
29
|
+
tone: "Plain and direct. British English, sentence case in headings.",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`context` is background the assistant would otherwise guess at; `tone` is how it
|
|
35
|
+
should write when it writes content. Both are sent with every message it makes.
|
|
36
|
+
|
|
37
|
+
`enabled` decides whether editors have an assistant, and it has **three** states
|
|
38
|
+
rather than two:
|
|
39
|
+
|
|
40
|
+
- `true` — they do.
|
|
41
|
+
- `false` — they do not, and every trace of it goes: no button in the top bar,
|
|
42
|
+
no row in the quick actions, no panel, nothing sent.
|
|
43
|
+
- unset — nobody has decided. The assistant is still **shown**, and asks to be
|
|
44
|
+
turned on before it is used. Hiding an assistant nobody has decided about
|
|
45
|
+
means nobody discovers it; quietly enabling one means a project starts sending
|
|
46
|
+
its content to a model because it did not know to say no.
|
|
47
|
+
|
|
48
|
+
A project with no settings module at all has an assistant, as before: there is
|
|
49
|
+
nowhere to record a decision, and nowhere for the prompt to write the answer.
|
|
50
|
+
|
|
51
|
+
**Breaking: `ai.chat` is gone from `val.config.ts`.** Whether the assistant is
|
|
52
|
+
available is a decision about the project's content, made by the people who edit
|
|
53
|
+
it, so it moved to settings — turning the chat on used to take a developer, a
|
|
54
|
+
deploy and a code review of a boolean. Remove the whole block:
|
|
55
|
+
|
|
56
|
+
```diff
|
|
57
|
+
const { s, c, val, config } = initVal({
|
|
58
|
+
- ai: {
|
|
59
|
+
- chat: {
|
|
60
|
+
- experimental: { enable: true },
|
|
61
|
+
- suggestions: ["Summarize", "Fix typos at this page"],
|
|
62
|
+
- title: "Ask me anything",
|
|
63
|
+
- description: "Val can answer questions about the content.",
|
|
64
|
+
- },
|
|
65
|
+
- },
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`experimental.enable` becomes `assistant.enabled` in the settings module.
|
|
70
|
+
`suggestions`, `title` and `description` are removed with nothing replacing
|
|
71
|
+
them: the assistant now opens with its own copy. A project that had the chat
|
|
72
|
+
enabled and wants it to stay on for everyone should write
|
|
73
|
+
`assistant: { enabled: true }` — otherwise editors are offered it and asked.
|
|
74
|
+
|
|
75
|
+
`ai.commitMessages` stays in `val.config.ts`, and is unaffected.
|
|
76
|
+
|
|
77
|
+
Two settings modules, or one in a subdirectory, is a module error: the dev
|
|
78
|
+
server refuses to serve sources, `npx val validate` reports it against the file,
|
|
79
|
+
and the Studio says so rather than picking one.
|
|
80
|
+
|
|
81
|
+
### Patch Changes
|
|
82
|
+
|
|
83
|
+
- [#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
|
|
84
|
+
decide these from a variable instead of only from whether the call was written at
|
|
85
|
+
all:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
s.string().readonly(!canEdit);
|
|
89
|
+
s.image().hidden(hideMedia);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The argument defaults to `true`, so `.readonly()` and `.readonly(true)` are the
|
|
93
|
+
same thing and nothing about existing schemas changes. Passing `false` leaves the
|
|
94
|
+
field editable or visible, which is also what a schema is without the call - it
|
|
95
|
+
is there so the flag can come from a variable.
|
|
96
|
+
|
|
97
|
+
- Updated dependencies [[`105479b`](https://github.com/valbuild/val/commit/105479b84a08846f1fe5971916f6a54275198d12), [`55ec736`](https://github.com/valbuild/val/commit/55ec73651394908b6f440e360d181b95a91c0a93), [`2bcc6fd`](https://github.com/valbuild/val/commit/2bcc6fdff8d668123e07e3c5e81ac6fa1436e47b), [`2bcbee1`](https://github.com/valbuild/val/commit/2bcbee1be682c2bbd5b7bc7d152ddd4204162fd2), [`6794d29`](https://github.com/valbuild/val/commit/6794d2980bc81284ab7f2cc667f01cc21c9e3a79), [`2db27d5`](https://github.com/valbuild/val/commit/2db27d555441bee2dd31817acc8c92b7b718ee55)]:
|
|
98
|
+
- @valbuild/ui@0.121.0
|
|
99
|
+
- @valbuild/shared@0.121.0
|
|
100
|
+
- @valbuild/server@0.121.0
|
|
101
|
+
- @valbuild/core@0.121.0
|
|
102
|
+
- @valbuild/react@0.121.0
|
|
103
|
+
- @valbuild/language-server@0.121.0
|
|
104
|
+
|
|
105
|
+
## 0.120.4
|
|
106
|
+
|
|
107
|
+
### Patch Changes
|
|
108
|
+
|
|
109
|
+
- Updated dependencies [[`6df3cae`](https://github.com/valbuild/val/commit/6df3caec1cc043a07b532d3174583b8218d4871d)]:
|
|
110
|
+
- @valbuild/ui@0.120.4
|
|
111
|
+
- @valbuild/react@0.120.4
|
|
112
|
+
- @valbuild/server@0.120.4
|
|
113
|
+
- @valbuild/language-server@0.120.4
|
|
114
|
+
|
|
3
115
|
## 0.120.3
|
|
4
116
|
|
|
5
117
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
- [Number](#number)
|
|
49
49
|
- [Boolean](#boolean)
|
|
50
50
|
- [Nullable](#nullable)
|
|
51
|
+
- [Read-only and hidden fields](#read-only-and-hidden-fields)
|
|
51
52
|
- [Array](#array)
|
|
52
53
|
- [Record](#record)
|
|
53
54
|
- [Router](#router)
|
|
@@ -384,6 +385,24 @@ import { s } from "./val.config";
|
|
|
384
385
|
s.string().nullable(); // <- Schema<string | null>
|
|
385
386
|
```
|
|
386
387
|
|
|
388
|
+
## Read-only and hidden fields
|
|
389
|
+
|
|
390
|
+
`.readonly()` renders a field disabled in the Val editor, and `.hidden()` leaves
|
|
391
|
+
it out of the editor entirely. Both are UI-only: the value is still stored,
|
|
392
|
+
validated and serialized as normal.
|
|
393
|
+
|
|
394
|
+
Both take an optional flag which defaults to `true`, so `.readonly()` and
|
|
395
|
+
`.readonly(true)` are the same thing. Pass it when the decision comes from a
|
|
396
|
+
variable rather than being written out:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
import { s } from "./val.config";
|
|
400
|
+
|
|
401
|
+
s.string().readonly(); // same as .readonly(true)
|
|
402
|
+
s.string().readonly(!canEdit);
|
|
403
|
+
s.image().hidden(hideMedia);
|
|
404
|
+
```
|
|
405
|
+
|
|
387
406
|
## Description
|
|
388
407
|
|
|
389
408
|
All schema types can be given a human-readable description with `.describe(text)`. Descriptions are shown in the Val editor UI as muted helper text under the field label, helping editors understand what a field is for without leaving the page.
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"next",
|
|
13
13
|
"react"
|
|
14
14
|
],
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.121.0",
|
|
16
16
|
"main": "dist/valbuild-next.cjs.js",
|
|
17
17
|
"module": "dist/valbuild-next.esm.js",
|
|
18
18
|
"exports": {
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"client-only": "^0.0.1",
|
|
49
49
|
"server-only": "^0.0.1",
|
|
50
|
-
"@valbuild/
|
|
51
|
-
"@valbuild/
|
|
52
|
-
"@valbuild/server": "0.
|
|
53
|
-
"@valbuild/
|
|
54
|
-
"@valbuild/core": "0.
|
|
55
|
-
"@valbuild/
|
|
50
|
+
"@valbuild/react": "0.121.0",
|
|
51
|
+
"@valbuild/shared": "0.121.0",
|
|
52
|
+
"@valbuild/server": "0.121.0",
|
|
53
|
+
"@valbuild/ui": "0.121.0",
|
|
54
|
+
"@valbuild/core": "0.121.0",
|
|
55
|
+
"@valbuild/language-server": "0.121.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@testing-library/react": "^16.3.3",
|
|
@@ -92,7 +92,22 @@ var initFetchValStega = function initFetchValStega(config, valApiEndpoints, valS
|
|
|
92
92
|
validate_binary_files: false,
|
|
93
93
|
exclude_patches: false,
|
|
94
94
|
// RSC pre-render uses the legacy "server applies patches" path.
|
|
95
|
-
apply_patches: undefined
|
|
95
|
+
apply_patches: undefined,
|
|
96
|
+
/*
|
|
97
|
+
* The caller's own staged work, and nobody else's.
|
|
98
|
+
*
|
|
99
|
+
* A draft render cannot name its group ids — it has no client
|
|
100
|
+
* state — so it asks for "mine" and the server resolves them from
|
|
101
|
+
* the session. Without this a preview shows base + every pending
|
|
102
|
+
* patch on the branch, so one person's half-finished edit appears
|
|
103
|
+
* in another person's draft.
|
|
104
|
+
*
|
|
105
|
+
* `patch_id` stays `undefined`: naming an explicit list is for a
|
|
106
|
+
* caller that already knows what it wants, and it would override
|
|
107
|
+
* the resolution rather than intersect with it.
|
|
108
|
+
*/
|
|
109
|
+
patch_id: undefined,
|
|
110
|
+
own_patch_groups_only: true
|
|
96
111
|
},
|
|
97
112
|
cookies: defineProperty._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies = cookies) === null || _cookies === void 0 || (_cookies = _cookies.get(internal.VAL_SESSION_COOKIE)) === null || _cookies === void 0 ? void 0 : _cookies.value)
|
|
98
113
|
});
|
|
@@ -408,7 +423,16 @@ function _loadDraftJsonEntry() {
|
|
|
408
423
|
// single-entry shape
|
|
409
424
|
offset: undefined,
|
|
410
425
|
limit: undefined,
|
|
411
|
-
apply_patches: true
|
|
426
|
+
apply_patches: true,
|
|
427
|
+
/*
|
|
428
|
+
* Scoped the same way the module content beside it is.
|
|
429
|
+
*
|
|
430
|
+
* A draft page renders both, and this call was unscoped — so one page
|
|
431
|
+
* showed base + the caller's group for its modules and base + EVERY
|
|
432
|
+
* pending patch on the branch for any `jsonValues` entry, including other
|
|
433
|
+
* authors' half-finished edits. See the same flag on `/sources/~` above.
|
|
434
|
+
*/
|
|
435
|
+
own_patch_groups_only: true
|
|
412
436
|
},
|
|
413
437
|
cookies: defineProperty._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies3 = cookies) === null || _cookies3 === void 0 || (_cookies3 = _cookies3.get(internal.VAL_SESSION_COOKIE)) === null || _cookies3 === void 0 ? void 0 : _cookies3.value)
|
|
414
438
|
});
|
|
@@ -92,7 +92,22 @@ var initFetchValStega = function initFetchValStega(config, valApiEndpoints, valS
|
|
|
92
92
|
validate_binary_files: false,
|
|
93
93
|
exclude_patches: false,
|
|
94
94
|
// RSC pre-render uses the legacy "server applies patches" path.
|
|
95
|
-
apply_patches: undefined
|
|
95
|
+
apply_patches: undefined,
|
|
96
|
+
/*
|
|
97
|
+
* The caller's own staged work, and nobody else's.
|
|
98
|
+
*
|
|
99
|
+
* A draft render cannot name its group ids — it has no client
|
|
100
|
+
* state — so it asks for "mine" and the server resolves them from
|
|
101
|
+
* the session. Without this a preview shows base + every pending
|
|
102
|
+
* patch on the branch, so one person's half-finished edit appears
|
|
103
|
+
* in another person's draft.
|
|
104
|
+
*
|
|
105
|
+
* `patch_id` stays `undefined`: naming an explicit list is for a
|
|
106
|
+
* caller that already knows what it wants, and it would override
|
|
107
|
+
* the resolution rather than intersect with it.
|
|
108
|
+
*/
|
|
109
|
+
patch_id: undefined,
|
|
110
|
+
own_patch_groups_only: true
|
|
96
111
|
},
|
|
97
112
|
cookies: defineProperty._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies = cookies) === null || _cookies === void 0 || (_cookies = _cookies.get(internal.VAL_SESSION_COOKIE)) === null || _cookies === void 0 ? void 0 : _cookies.value)
|
|
98
113
|
});
|
|
@@ -408,7 +423,16 @@ function _loadDraftJsonEntry() {
|
|
|
408
423
|
// single-entry shape
|
|
409
424
|
offset: undefined,
|
|
410
425
|
limit: undefined,
|
|
411
|
-
apply_patches: true
|
|
426
|
+
apply_patches: true,
|
|
427
|
+
/*
|
|
428
|
+
* Scoped the same way the module content beside it is.
|
|
429
|
+
*
|
|
430
|
+
* A draft page renders both, and this call was unscoped — so one page
|
|
431
|
+
* showed base + the caller's group for its modules and base + EVERY
|
|
432
|
+
* pending patch on the branch for any `jsonValues` entry, including other
|
|
433
|
+
* authors' half-finished edits. See the same flag on `/sources/~` above.
|
|
434
|
+
*/
|
|
435
|
+
own_patch_groups_only: true
|
|
412
436
|
},
|
|
413
437
|
cookies: defineProperty._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies3 = cookies) === null || _cookies3 === void 0 || (_cookies3 = _cookies3.get(internal.VAL_SESSION_COOKIE)) === null || _cookies3 === void 0 ? void 0 : _cookies3.value)
|
|
414
438
|
});
|
|
@@ -88,7 +88,22 @@ var initFetchValStega = function initFetchValStega(config, valApiEndpoints, valS
|
|
|
88
88
|
validate_binary_files: false,
|
|
89
89
|
exclude_patches: false,
|
|
90
90
|
// RSC pre-render uses the legacy "server applies patches" path.
|
|
91
|
-
apply_patches: undefined
|
|
91
|
+
apply_patches: undefined,
|
|
92
|
+
/*
|
|
93
|
+
* The caller's own staged work, and nobody else's.
|
|
94
|
+
*
|
|
95
|
+
* A draft render cannot name its group ids — it has no client
|
|
96
|
+
* state — so it asks for "mine" and the server resolves them from
|
|
97
|
+
* the session. Without this a preview shows base + every pending
|
|
98
|
+
* patch on the branch, so one person's half-finished edit appears
|
|
99
|
+
* in another person's draft.
|
|
100
|
+
*
|
|
101
|
+
* `patch_id` stays `undefined`: naming an explicit list is for a
|
|
102
|
+
* caller that already knows what it wants, and it would override
|
|
103
|
+
* the resolution rather than intersect with it.
|
|
104
|
+
*/
|
|
105
|
+
patch_id: undefined,
|
|
106
|
+
own_patch_groups_only: true
|
|
92
107
|
},
|
|
93
108
|
cookies: _defineProperty({}, VAL_SESSION_COOKIE, (_cookies = cookies) === null || _cookies === void 0 || (_cookies = _cookies.get(VAL_SESSION_COOKIE)) === null || _cookies === void 0 ? void 0 : _cookies.value)
|
|
94
109
|
});
|
|
@@ -404,7 +419,16 @@ function _loadDraftJsonEntry() {
|
|
|
404
419
|
// single-entry shape
|
|
405
420
|
offset: undefined,
|
|
406
421
|
limit: undefined,
|
|
407
|
-
apply_patches: true
|
|
422
|
+
apply_patches: true,
|
|
423
|
+
/*
|
|
424
|
+
* Scoped the same way the module content beside it is.
|
|
425
|
+
*
|
|
426
|
+
* A draft page renders both, and this call was unscoped — so one page
|
|
427
|
+
* showed base + the caller's group for its modules and base + EVERY
|
|
428
|
+
* pending patch on the branch for any `jsonValues` entry, including other
|
|
429
|
+
* authors' half-finished edits. See the same flag on `/sources/~` above.
|
|
430
|
+
*/
|
|
431
|
+
own_patch_groups_only: true
|
|
408
432
|
},
|
|
409
433
|
cookies: _defineProperty({}, VAL_SESSION_COOKIE, (_cookies3 = cookies) === null || _cookies3 === void 0 || (_cookies3 = _cookies3.get(VAL_SESSION_COOKIE)) === null || _cookies3 === void 0 ? void 0 : _cookies3.value)
|
|
410
434
|
});
|