@valbuild/server 0.139.2 → 0.140.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 +58 -0
- package/dist/declarations/src/ValOps.d.ts +38 -3
- package/dist/declarations/src/patch/jsonValuesPatch.d.ts +25 -0
- package/dist/declarations/src/valServerConfig.d.ts +9 -0
- package/dist/valbuild-server.cjs.dev.js +471 -18
- package/dist/valbuild-server.cjs.prod.js +471 -18
- package/dist/valbuild-server.esm.js +472 -19
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @valbuild/server
|
|
2
2
|
|
|
3
|
+
## 0.140.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#769](https://github.com/valbuild/val/pull/769) [`cb93874`](https://github.com/valbuild/val/commit/cb938748aec15fd0ac3814c1696a2dd78ad63c27) Thanks [@freekh](https://github.com/freekh)! - The project name in the Studio's top bar is now a project switcher, for projects connected to Val Build. It shows the project you are in, the projects you pinned and the five you opened most recently, and searches every project in your organisations. Choosing one opens its Studio.
|
|
8
|
+
|
|
9
|
+
The top bar also gets a **Share** button (an icon on a phone). It shows who is in the project's organisation. Owners can create invite links for a role (each works once and expires after 7 days), see and revoke pending links, and change members' roles. Everyone else can see the members and which owners to ask.
|
|
10
|
+
|
|
11
|
+
The assistant can be set up from the Studio too. Settings › Assistant shows the AI key this project runs on and whether it works. From there you can add a key, update it, remove it, or choose one that already exists: the organisation's, your own, or another project's. The assistant's empty state offers the same when no key is set up. Every key is checked with the provider before it is saved, and once a key is saved the assistant turns on without a reload.
|
|
12
|
+
|
|
13
|
+
The panels are served by Val's content server (`content.val.build/wc/v1/project-switcher.js`, `members.js` and `ai-setup.js`), beside the API they read and write, so they can improve without a Val release. The Studio draws the project name and the Share button itself, and loads the switcher and Share panels only when the button is first hovered or clicked, so opening the Studio fetches nothing extra. If a panel cannot load, for example offline or under a strict Content Security Policy, the click opens the same page in Val Build instead, and the AI setup is a link to the project's AI keys there. If your app sets a CSP, allow `script-src https://content.val.build` to get them.
|
|
14
|
+
|
|
15
|
+
They reach Val Build through a new route on your app's Val server, `/api/val/admin/proxy/*`, which adds the editor's existing Val Build session. That route forwards only to the Studio API on Val's content server (`/v1/studio/*` on `VAL_CONTENT_URL`, `https://content.val.build` by default), and only with the `x-val-studio` header that a cross-site request cannot send.
|
|
16
|
+
|
|
17
|
+
In local development they appear once you have run `val login`, and use that login. Without one the Studio keeps the plain project name, as before; it does not load them just to say you are not logged in.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#793](https://github.com/valbuild/val/pull/793) [`092e6a7`](https://github.com/valbuild/val/commit/092e6a7f78bcfcf4c6cecaf34407fdfc580ebbc1) Thanks [@freekh](https://github.com/freekh)! - A draft page on TanStack Start is now rendered as the draft by the server, so it no longer shows the published text first and the draft a moment later — most noticeable when you reload right after publishing.
|
|
22
|
+
|
|
23
|
+
Read the request's draft in your site layout's loader and pass it to `ValProvider`:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// src/val/server.ts
|
|
27
|
+
export const { fetchValDraft /* , fetchVal, ... */ } = initValContent(
|
|
28
|
+
config,
|
|
29
|
+
valModules,
|
|
30
|
+
{ draftMode },
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// src/routes/_site.tsx
|
|
34
|
+
const getValDraft = createServerFn().handler(() => fetchValDraft());
|
|
35
|
+
|
|
36
|
+
export const Route = createFileRoute("/_site")({
|
|
37
|
+
loader: () => (typeof document === "undefined" ? getValDraft() : null),
|
|
38
|
+
component: SiteLayout,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
function SiteLayout() {
|
|
42
|
+
const draft = Route.useLoaderData();
|
|
43
|
+
return (
|
|
44
|
+
<ValProvider config={config} suspend draft={draft}>
|
|
45
|
+
{/* ... */}
|
|
46
|
+
</ValProvider>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Visitors pay one cookie lookup and nothing else. Without `draft`, pages behave as before. Edited `.jsonValues()` entries are rendered as the draft too; the others render from the build, as they do for visitors.
|
|
52
|
+
|
|
53
|
+
Also: a draft's `.jsonValues()` entries now include changes that were published after the build being served, instead of showing the old value until the next build is live.
|
|
54
|
+
|
|
55
|
+
Also: a renamed or duplicated `.jsonValues()` entry now has its content in the draft, on the page and when the Studio reads the entry, instead of failing to load until it is published.
|
|
56
|
+
|
|
57
|
+
- Updated dependencies [[`cb93874`](https://github.com/valbuild/val/commit/cb938748aec15fd0ac3814c1696a2dd78ad63c27)]:
|
|
58
|
+
- @valbuild/ui@0.140.0
|
|
59
|
+
- @valbuild/shared@0.140.0
|
|
60
|
+
|
|
3
61
|
## 0.139.2
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
|
@@ -845,8 +845,10 @@ export type PatchReadError = {
|
|
|
845
845
|
* 1. this module's, since the chain is branch-wide;
|
|
846
846
|
* 2. this caller's, when they asked to be scoped. `undefined` is "everything",
|
|
847
847
|
* which is what every unscoped caller gets and must keep getting;
|
|
848
|
-
* 3.
|
|
849
|
-
* and
|
|
848
|
+
* 3. a patch published after this build is kept whatever the scope: it is
|
|
849
|
+
* nobody's to hold back, and this build does not have it. One already in
|
|
850
|
+
* the build is dropped. `draftOverlay` decides which is which, from
|
|
851
|
+
* `commits`.
|
|
850
852
|
*
|
|
851
853
|
* Filtered here rather than by asking `fetchPatches` for a list, and that is
|
|
852
854
|
* load-bearing: both implementations read an empty `patchIds` as "no filter"
|
|
@@ -862,7 +864,40 @@ export declare function scopedModulePatches<T extends {
|
|
|
862
864
|
appliedAt: {
|
|
863
865
|
commitSha: CommitSha;
|
|
864
866
|
} | null;
|
|
865
|
-
}>(patches: T[], moduleFilePath: ModuleFilePath, patchIds: PatchId[] | undefined
|
|
867
|
+
}>(patches: T[], moduleFilePath: ModuleFilePath, patchIds: PatchId[] | undefined,
|
|
868
|
+
/** The commits content says came after this build: see `draftOverlay`. */
|
|
869
|
+
commits?: Pick<ValCommit, "commitSha">[]): T[];
|
|
870
|
+
/**
|
|
871
|
+
* The patches a DRAFT applies on top of this build's own source: the pending
|
|
872
|
+
* ones, and the ones published AFTER this build, in chain order -- with
|
|
873
|
+
* `appliedAt` cleared on the latter, because this build has none of them.
|
|
874
|
+
*
|
|
875
|
+
* Content places every caller at its own build (`getApplicablePatchesAndCommits`
|
|
876
|
+
* in valbuild/home: "the earliest the caller has not seen") and returns the
|
|
877
|
+
* commits after it as `commits`. A patch applied at one of those was
|
|
878
|
+
* published after this build and is not in it, so a draft has to apply it --
|
|
879
|
+
* skipping it showed the build's old value from the publish until the next
|
|
880
|
+
* build went live. `/sources/~` already applies them (`getSources` walks every
|
|
881
|
+
* patch it is given); the `.jsonValues()` entry path skipped them.
|
|
882
|
+
*
|
|
883
|
+
* A patch applied at a commit NOT in that list is already in this build --
|
|
884
|
+
* content returns one only because it was asked for by id -- and is dropped:
|
|
885
|
+
* applying it again would apply it twice. Without `commits` (a store that
|
|
886
|
+
* does not report them) every applied patch is dropped, as before. Only
|
|
887
|
+
* `ValOpsHttp` ever reports `appliedAt`; `fs` and memory stores report `null`.
|
|
888
|
+
*
|
|
889
|
+
* Chain order, not published-first, because that is the order the Studio
|
|
890
|
+
* applies them in, and a draft page starts from the server's answer and is
|
|
891
|
+
* then kept up to date by the Studio's: the two must agree.
|
|
892
|
+
*
|
|
893
|
+
* For the reads that render a draft only. What to COMMIT still keys on
|
|
894
|
+
* `appliedAt`: a published patch must never be published again.
|
|
895
|
+
*/
|
|
896
|
+
export declare function draftOverlay<T extends {
|
|
897
|
+
appliedAt: {
|
|
898
|
+
commitSha: CommitSha;
|
|
899
|
+
} | null;
|
|
900
|
+
}>(patches: T[], commits: Pick<ValCommit, "commitSha">[] | undefined): T[];
|
|
866
901
|
export type OrderedPatches = {
|
|
867
902
|
patches: {
|
|
868
903
|
path: ModuleFilePath;
|
|
@@ -165,7 +165,32 @@ export declare function applyJsonValuesEntryPatches(args: {
|
|
|
165
165
|
patchId: PatchId;
|
|
166
166
|
patch: Patch;
|
|
167
167
|
}[];
|
|
168
|
+
/**
|
|
169
|
+
* The committed content of the OTHER entries of the record, for a
|
|
170
|
+
* whole-entry `move` or `copy` into this key: its content is the source
|
|
171
|
+
* entry's at that point in the chain, which is a different `*.val.json`.
|
|
172
|
+
*
|
|
173
|
+
* `undefined` for an entry the caller did not load, and then such an op is
|
|
174
|
+
* an error, as it is when this is not given at all. `{ content: undefined }`
|
|
175
|
+
* is an entry the committed source does not have.
|
|
176
|
+
*/
|
|
177
|
+
baseContentOf?: (entryKey: string) => {
|
|
178
|
+
content: JSONValue | undefined;
|
|
179
|
+
} | undefined;
|
|
180
|
+
/**
|
|
181
|
+
* Replay only the ops before this one: patch index, then op index in it.
|
|
182
|
+
* How a move's source is read as it stood when the move was made.
|
|
183
|
+
*/
|
|
184
|
+
stopBefore?: {
|
|
185
|
+
patch: number;
|
|
186
|
+
op: number;
|
|
187
|
+
};
|
|
168
188
|
}): JsonEntryResolution;
|
|
189
|
+
/**
|
|
190
|
+
* The entry a path names when it names a WHOLE entry of the root
|
|
191
|
+
* `.jsonValues()` record, and `undefined` for anything else.
|
|
192
|
+
*/
|
|
193
|
+
export declare function wholeEntryKey(serializedSchema: SerializedSchema | undefined, path: string[]): string | undefined;
|
|
169
194
|
/**
|
|
170
195
|
* Resolves an EXISTING entry's `*.val.json` path (relative to rootDir) from the
|
|
171
196
|
* `import(...)` path recorded in the `.val.ts` thunk (from
|
|
@@ -118,5 +118,14 @@ export type ResolveRemoteFileAuthResult = {
|
|
|
118
118
|
errorCode: "project-not-configured" | "pat-error" | "api-key-missing";
|
|
119
119
|
message: string;
|
|
120
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* The personal access token `val login` wrote for this project, or null when
|
|
123
|
+
* there is none (or it does not parse). Only `fs` mode has a working directory
|
|
124
|
+
* to read it from, so every other mode answers null.
|
|
125
|
+
*
|
|
126
|
+
* Unlike `resolveRemoteFileAuth` this never answers with the api key: the
|
|
127
|
+
* caller wants to act as the DEVELOPER, and an api key is the project.
|
|
128
|
+
*/
|
|
129
|
+
export declare function readValLoginToken(options: ValServerConfig): Promise<string | null>;
|
|
121
130
|
export declare function resolveRemoteFileAuth(options: ValServerConfig): Promise<ResolveRemoteFileAuthResult>;
|
|
122
131
|
export {};
|