@valbuild/server 0.123.2 → 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 CHANGED
@@ -1,5 +1,74 @@
1
1
  # @valbuild/server
2
2
 
3
+ ## 0.124.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#639](https://github.com/valbuild/val/pull/639) [`ad7fff4`](https://github.com/valbuild/val/commit/ad7fff4cc8cea98c506cf7ff9b4e8d6e5ffa4055) Thanks [@freekh](https://github.com/freekh)! - Show `.jsonValues()` entries in the history pane
8
+
9
+ A `.jsonValues()` record keeps each entry's content in its own `*.val.json`
10
+ file; the module's own content is just markers pointing at them. The history
11
+ pane had no way to fetch those files for a past commit, so every entry rendered
12
+ as an **empty field** — which reads as "the author left this blank", about
13
+ content that was simply stored somewhere else.
14
+
15
+ Entries now load in the history pane the same way they load in the Studio: one
16
+ at a time, when you open one. A commit with a thousand support pages costs
17
+ nothing until you look at one of them.
18
+
19
+ An entry that cannot be read says so instead of rendering blank — including the
20
+ case where the key did not exist yet at that commit, which is a real answer
21
+ rather than an error.
22
+
23
+ ### Patch Changes
24
+
25
+ - [#639](https://github.com/valbuild/val/pull/639) [`ad7fff4`](https://github.com/valbuild/val/commit/ad7fff4cc8cea98c506cf7ff9b4e8d6e5ffa4055) Thanks [@freekh](https://github.com/freekh)! - Require a session to read a file from history
26
+
27
+ `GET /api/val/history/files` served a file at a given commit to anyone who
28
+ asked. It followed the reasoning of `/api/val/files`, which is deliberately
29
+ open — and neither half of that reasoning applies to it:
30
+
31
+ - `/files` stands on `patch_id` being an unguessable UUID. A **commit sha is
32
+ published** — `git log`, the GitHub UI, every pull request — so it is no
33
+ substitute for a credential.
34
+ - `/files` also _cannot_ require auth: draft images are fetched by the app's own
35
+ backend during Next image optimisation, with no cookies to send. Nothing
36
+ fetches history files server-side; both callers are the Studio, in a browser
37
+ that already holds the session.
38
+
39
+ So history files now require a session. `/files` is unchanged, and the reason
40
+ the two differ is written down in `architecture/media.md` so it is not "fixed"
41
+ in either direction later.
42
+
43
+ No action needed: the Studio sends its session cookie automatically.
44
+
45
+ - Updated dependencies [[`5674237`](https://github.com/valbuild/val/commit/56742371a75b4fdcbff8b1afccff8fcc1ebf8078), [`ad7fff4`](https://github.com/valbuild/val/commit/ad7fff4cc8cea98c506cf7ff9b4e8d6e5ffa4055), [`ad7fff4`](https://github.com/valbuild/val/commit/ad7fff4cc8cea98c506cf7ff9b4e8d6e5ffa4055), [`aa89fc2`](https://github.com/valbuild/val/commit/aa89fc26de7028b3c5a1666b99afc03b39e92769)]:
46
+ - @valbuild/ui@0.124.0
47
+ - @valbuild/shared@0.124.0
48
+ - @valbuild/core@0.124.0
49
+
50
+ ## 0.123.3
51
+
52
+ ### Patch Changes
53
+
54
+ - [#623](https://github.com/valbuild/val/pull/623) [`4c9369b`](https://github.com/valbuild/val/commit/4c9369bad3f17e96868262e78a4f47361d85319e) Thanks [@freekh](https://github.com/freekh)! - Add the editor quick fix for a `.jsonValues()` entry written inline: **Val: move entry into its own .val.json**.
55
+
56
+ The language server already reported the problem — "Entry '…' is written inline … Run 'val validate --fix' to move it" — but offered no way to act on it, so the only remedy was to leave the editor and run the CLI. It now offers a quick fix that creates the `*.val.json` with the entry's content and rewrites the `.val.ts` to `c.json(() => import("./…"))`, in one undoable step.
57
+
58
+ The fix is computed from the same code `val validate --fix` runs, so the two write the same files, and it is computed against the buffer you are looking at rather than what is on disk — an unsaved module can be fixed without saving first. It refuses, rather than overwriting, when a file or an unsaved buffer already occupies the target path.
59
+
60
+ Requires an editor that honours file creation inside a workspace edit; VS Code does. In an editor that does not announce it, no action is offered rather than one that would rewrite the module to import a file that never got created.
61
+
62
+ - [#621](https://github.com/valbuild/val/pull/621) [`fb1baff`](https://github.com/valbuild/val/commit/fb1baffead5228d8a86a51af65178b88738d5a64) Thanks [@freekh](https://github.com/freekh)! - Fix `.jsonValues()` validation being silently skipped when the CLI is run through `npx` / `pnpm dlx`.
63
+
64
+ `npx @valbuild/cli validate` reported a `.jsonValues()` module whose entries were still written inline in the `.val.ts` as **valid**, and `--fix` moved nothing into `*.val.json`. Running the CLI installed in the project (`./node_modules/.bin/val validate --fix`) worked, which made this look like a schema or path problem rather than a tooling one.
65
+
66
+ The cause: the project's `*.val.ts` are evaluated with a `require` rooted at the project, so their schemas come from the project's `@valbuild/core`, while `npx`/`dlx` runs the CLI's own second copy. The entry check guarded on `schema instanceof RecordSchema`, which is false across those two copies, and it failed open — the whole check returned "no errors". The guard is now structural, so it holds whichever copy built the schema. If you gate CI on `npx @valbuild/cli validate`, that gate was green for the wrong reason.
67
+
68
+ - Updated dependencies [[`accf4f8`](https://github.com/valbuild/val/commit/accf4f852fe3400d762cc14e80316da741a69a9a), [`356eb11`](https://github.com/valbuild/val/commit/356eb11b5f6a0a02dfec80580c6fccac75d28402), [`aef45ce`](https://github.com/valbuild/val/commit/aef45ce3ef269f1b6221de44a56df0f6a0d9dbbd)]:
69
+ - @valbuild/shared@0.123.3
70
+ - @valbuild/ui@0.123.3
71
+
3
72
  ## 0.123.2
4
73
 
5
74
  ### Patch Changes
@@ -486,6 +486,17 @@ export declare abstract class ValOps {
486
486
  abstract getCommitAffectedFiles(commitSha: string): Promise<result.Result<AffectedFile[], HistoryError>>;
487
487
  /** One file's bytes as they were at one commit. */
488
488
  abstract getFileAtCommit(commitSha: string, filePath: string, remote: boolean): Promise<result.Result<Buffer, HistoryError>>;
489
+ /**
490
+ * Where a module lives in the REPOSITORY, as `getFileAtCommit` wants it.
491
+ *
492
+ * A `ModuleFilePath` is project-relative (`/app/page.val.ts`); a git path is
493
+ * repository-relative and carries the project root in front of it
494
+ * (`examples/next/app/page.val.ts`). Only the ops know that root, which is
495
+ * why this is here rather than computed by the history functions - and why a
496
+ * history function that needs to read a module's own file at a commit has to
497
+ * ask instead of concatenating.
498
+ */
499
+ abstract gitPathOfModule(moduleFilePath: ModuleFilePath): result.Result<string, HistoryError>;
489
500
  }
490
501
  export type WithGenericError<T extends Record<string, unknown>> = (T & {
491
502
  error?: undefined;
@@ -172,4 +172,5 @@ export declare class ValOpsFS extends ValOps {
172
172
  }, HistoryError>>;
173
173
  getCommitAffectedFiles(): Promise<result.Result<AffectedFile[], HistoryError>>;
174
174
  getFileAtCommit(): Promise<result.Result<Buffer, HistoryError>>;
175
+ gitPathOfModule(_moduleFilePath: ModuleFilePath): result.Result<string, HistoryError>;
175
176
  }
@@ -310,6 +310,15 @@ export declare class ValOpsHttp extends ValOps {
310
310
  complete: boolean;
311
311
  }, HistoryError>>;
312
312
  getCommitAffectedFiles(commitSha: string): Promise<result.Result<AffectedFile[], HistoryError>>;
313
+ /**
314
+ * `root` in front, and never a doubled or missing slash.
315
+ *
316
+ * `root` is "" for a project at the repository root and something like
317
+ * `examples/next` otherwise; a ModuleFilePath always starts with "/". Joining
318
+ * them by hand at each call site is how one of these ends up with "//" in the
319
+ * middle, which GitHub answers with a 404 that reads like a missing file.
320
+ */
321
+ gitPathOfModule(moduleFilePath: ModuleFilePath): result.Result<string, HistoryError>;
313
322
  getFileAtCommit(commitSha: string, filePath: string, remote: boolean): Promise<result.Result<Buffer, HistoryError>>;
314
323
  }
315
324
  export {};
@@ -1,17 +1,61 @@
1
1
  import type { Json, ModuleFilePath } from "@valbuild/core";
2
+ import { result } from "@valbuild/core/fp";
2
3
  import { ValSourceFileHandler } from "./ValSourceFileHandler.js";
4
+ /**
5
+ * The two files an extraction touches, as text — nothing written yet.
6
+ *
7
+ * Both paths are project-relative in the `ModuleFilePath` style (a leading
8
+ * slash), because that is what the callers already hold and what
9
+ * {@link getNewJsonEntryPaths} derives. Join them onto the project root to get
10
+ * somewhere to write.
11
+ */
12
+ export type JsonValuesEntryExtraction = {
13
+ /** The `*.val.json` to CREATE. It must not already exist — see the note below. */
14
+ jsonPath: string;
15
+ jsonContent: string;
16
+ /** The `.val.ts` to rewrite, and its complete new text. */
17
+ valTsPath: string;
18
+ valTsContent: string;
19
+ };
20
+ /**
21
+ * Works out what moving ONE inline `.jsonValues()` entry into its own
22
+ * `*.val.json` would change, without changing anything.
23
+ *
24
+ * This is the whole fix for `jsonValues:extract-entry`, minus the writing. It
25
+ * is split out because the two callers cannot share a way of applying it: the
26
+ * CLI writes both files ({@link extractJsonValuesEntry}), while the editor has
27
+ * to hand the same two changes back as a `WorkspaceEdit` so they go through the
28
+ * undo stack and respect an unsaved buffer. Anything that lived in only one of
29
+ * those would be a fix that behaves differently depending on where it was
30
+ * invoked from, which is exactly the drift `codeActions.ts` exists to prevent.
31
+ *
32
+ * It does NOT check whether `jsonPath` already exists: that needs a filesystem,
33
+ * and the editor's answer ("is there a buffer or a file here?") is not the
34
+ * CLI's. Every caller must check before writing — overwriting an unrelated file
35
+ * is not a fix.
36
+ *
37
+ * Root-only, like the rest of the `.jsonValues()` machinery: the entry is looked
38
+ * up in the module's root record/router object literal.
39
+ */
40
+ export declare function planJsonValuesEntryExtraction({ moduleFilePath, entryKey, content, valTsPath, valTsText, }: {
41
+ moduleFilePath: ModuleFilePath;
42
+ entryKey: string;
43
+ /** The entry's value, as it is written inline in the `.val.ts`. */
44
+ content: Json;
45
+ /** Where the `.val.ts` lives, for error messages. */
46
+ valTsPath: string;
47
+ /** Its text — the editor's version of it, where there is an editor. */
48
+ valTsText: string;
49
+ }): result.Result<JsonValuesEntryExtraction, string>;
3
50
  /**
4
51
  * Moves ONE `.jsonValues()` entry that was written inline in the `.val.ts` into
5
52
  * its own `*.val.json`, replacing the inline value with
6
53
  * `c.json(() => import("./<key>.val.json"))`.
7
54
  *
8
- * This is the fix for the `jsonValues:extract-entry` validation error. It is not
9
- * expressible as a patch (a patch edits one `.val.ts` and cannot create the
55
+ * The `val validate --fix` half of {@link planJsonValuesEntryExtraction}. It is
56
+ * not expressible as a patch (a patch edits one `.val.ts` and cannot create the
10
57
  * backing JSON file), so it writes both files directly — JSON first, so a
11
58
  * failure part-way through never leaves the module pointing at a file that does
12
59
  * not exist.
13
- *
14
- * Root-only, like the rest of the `.jsonValues()` machinery: the entry is looked
15
- * up in the module's root record/router object literal.
16
60
  */
17
61
  export declare function extractJsonValuesEntry(moduleFilePath: ModuleFilePath, rootDir: string, entryKey: string, content: Json, sourceFileHandler: ValSourceFileHandler): void;
@@ -36,7 +36,8 @@ export { createModulePathMap, createJsonEntryPathMap, getModulePathRange, } from
36
36
  export { findJsonEntryFilePath } from "./jsonEntryLocation.js";
37
37
  export { classifyJsonValuesOp, rebaseContentOp } from "./patch/jsonValuesPatch.js";
38
38
  export type { JsonValuesOpClass } from "./patch/jsonValuesPatch.js";
39
- export { extractJsonValuesEntry } from "./extractJsonValuesEntry.js";
39
+ export { extractJsonValuesEntry, planJsonValuesEntryExtraction, } from "./extractJsonValuesEntry.js";
40
+ export type { JsonValuesEntryExtraction } from "./extractJsonValuesEntry.js";
40
41
  export type { ModulePathMap } from "./modulePathMap.js";
41
42
  export { ValOpsFS } from "./ValOpsFS.js";
42
43
  export { ValOpsHttp } from "./ValOpsHttp.js";