@valbuild/shared 0.123.3 → 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,50 @@
1
1
  # @valbuild/shared
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 [[`aa89fc2`](https://github.com/valbuild/val/commit/aa89fc26de7028b3c5a1666b99afc03b39e92769)]:
46
+ - @valbuild/core@0.124.0
47
+
3
48
  ## 0.123.3
4
49
 
5
50
  ### Patch Changes
@@ -1329,6 +1329,80 @@ export declare const Api: {
1329
1329
  * actually mounts. A file at a fixed commit cannot change, so the response is
1330
1330
  * immutable and the browser's own cache handles flipping between commits.
1331
1331
  */
1332
+ /**
1333
+ * One `.jsonValues()` entry's content, as it was at a commit.
1334
+ *
1335
+ * The history pane's counterpart to `/json`. A `.jsonValues()` record's
1336
+ * source is only `{_type:"json"}` markers - the content is per entry, fetched
1337
+ * on demand - so without this the commit pane rendered every entry as an
1338
+ * empty field, which is a claim that the author left it blank.
1339
+ *
1340
+ * One entry per request, deliberately: the store fetches an entry when
1341
+ * something reads inside it, so a batch would mean guessing which entries the
1342
+ * pane is about to show. Authenticated for the same reasons as
1343
+ * `/history/files` below.
1344
+ */
1345
+ "/history/json": {
1346
+ GET: {
1347
+ req: {
1348
+ query: {
1349
+ commit_sha: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>;
1350
+ path: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>;
1351
+ key: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>;
1352
+ };
1353
+ cookies: {
1354
+ val_session: z.ZodOptional<z.ZodString>;
1355
+ };
1356
+ };
1357
+ res: z.ZodUnion<readonly [z.ZodObject<{
1358
+ status: z.ZodLiteral<401>;
1359
+ json: z.ZodObject<{
1360
+ message: z.ZodString;
1361
+ }, z.core.$strip>;
1362
+ }, z.core.$strip>, z.ZodObject<{
1363
+ status: z.ZodLiteral<404>;
1364
+ json: z.ZodObject<{
1365
+ message: z.ZodString;
1366
+ }, z.core.$strip>;
1367
+ }, z.core.$strip>, z.ZodObject<{
1368
+ status: z.ZodLiteral<400>;
1369
+ json: z.ZodIntersection<z.ZodObject<{
1370
+ message: z.ZodString;
1371
+ }, z.core.$strip>, z.ZodObject<{
1372
+ kind: z.ZodOptional<z.ZodString>;
1373
+ }, z.core.$strip>>;
1374
+ }, z.core.$strip>, z.ZodObject<{
1375
+ status: z.ZodLiteral<500>;
1376
+ json: z.ZodIntersection<z.ZodObject<{
1377
+ message: z.ZodString;
1378
+ }, z.core.$strip>, z.ZodObject<{
1379
+ kind: z.ZodOptional<z.ZodString>;
1380
+ }, z.core.$strip>>;
1381
+ }, z.core.$strip>, z.ZodObject<{
1382
+ status: z.ZodLiteral<200>;
1383
+ json: z.ZodObject<{
1384
+ path: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1385
+ key: z.ZodString;
1386
+ content: z.ZodUnknown;
1387
+ }, z.core.$strip>;
1388
+ }, z.core.$strip>]>;
1389
+ };
1390
+ };
1391
+ /**
1392
+ * A binary file as it was at a commit.
1393
+ *
1394
+ * AUTHENTICATED, unlike `/files` below - and the difference is not an
1395
+ * oversight in either direction. See the comment on `/files`: what makes it
1396
+ * safe to leave open is that a `patch_id` is an unguessable UUID, and what
1397
+ * makes leaving it open NECESSARY is that a draft image is fetched by the
1398
+ * app's own backend during Next image optimisation, with no cookies.
1399
+ *
1400
+ * Neither holds here. A commit sha is published - `git log`, the GitHub UI,
1401
+ * every PR - so it is not a secret to stand in for a credential. And nothing
1402
+ * fetches these server-side: they are read by the Studio, in a browser that
1403
+ * has the session cookie, for the history pane and for staging a restore.
1404
+ * So this one asks.
1405
+ */
1332
1406
  "/history/files": {
1333
1407
  GET: {
1334
1408
  req: {
@@ -1337,6 +1411,9 @@ export declare const Api: {
1337
1411
  path: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>;
1338
1412
  remote: z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>>;
1339
1413
  };
1414
+ cookies: {
1415
+ val_session: z.ZodOptional<z.ZodString>;
1416
+ };
1340
1417
  };
1341
1418
  res: z.ZodUnion<readonly [z.ZodObject<{
1342
1419
  status: z.ZodLiteral<401>;
@@ -2463,6 +2463,66 @@ var Api = {
2463
2463
  * actually mounts. A file at a fixed commit cannot change, so the response is
2464
2464
  * immutable and the browser's own cache handles flipping between commits.
2465
2465
  */
2466
+ /**
2467
+ * One `.jsonValues()` entry's content, as it was at a commit.
2468
+ *
2469
+ * The history pane's counterpart to `/json`. A `.jsonValues()` record's
2470
+ * source is only `{_type:"json"}` markers - the content is per entry, fetched
2471
+ * on demand - so without this the commit pane rendered every entry as an
2472
+ * empty field, which is a claim that the author left it blank.
2473
+ *
2474
+ * One entry per request, deliberately: the store fetches an entry when
2475
+ * something reads inside it, so a batch would mean guessing which entries the
2476
+ * pane is about to show. Authenticated for the same reasons as
2477
+ * `/history/files` below.
2478
+ */
2479
+ "/history/json": {
2480
+ GET: {
2481
+ req: {
2482
+ query: {
2483
+ commit_sha: onlyOneStringQueryParam,
2484
+ path: onlyOneStringQueryParam,
2485
+ key: onlyOneStringQueryParam
2486
+ },
2487
+ cookies: {
2488
+ val_session: zod.z.string().optional()
2489
+ }
2490
+ },
2491
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2492
+ status: zod.z.literal(400),
2493
+ json: GenericError.and(zod.z.object({
2494
+ kind: zod.z.string().optional()
2495
+ }))
2496
+ }), zod.z.object({
2497
+ status: zod.z.literal(500),
2498
+ json: GenericError.and(zod.z.object({
2499
+ kind: zod.z.string().optional()
2500
+ }))
2501
+ }), zod.z.object({
2502
+ status: zod.z.literal(200),
2503
+ json: zod.z.object({
2504
+ path: ModuleFilePath,
2505
+ key: zod.z.string(),
2506
+ content: zod.z.unknown()
2507
+ })
2508
+ })])
2509
+ }
2510
+ },
2511
+ /**
2512
+ * A binary file as it was at a commit.
2513
+ *
2514
+ * AUTHENTICATED, unlike `/files` below - and the difference is not an
2515
+ * oversight in either direction. See the comment on `/files`: what makes it
2516
+ * safe to leave open is that a `patch_id` is an unguessable UUID, and what
2517
+ * makes leaving it open NECESSARY is that a draft image is fetched by the
2518
+ * app's own backend during Next image optimisation, with no cookies.
2519
+ *
2520
+ * Neither holds here. A commit sha is published - `git log`, the GitHub UI,
2521
+ * every PR - so it is not a secret to stand in for a credential. And nothing
2522
+ * fetches these server-side: they are read by the Studio, in a browser that
2523
+ * has the session cookie, for the history pane and for staging a restore.
2524
+ * So this one asks.
2525
+ */
2466
2526
  "/history/files": {
2467
2527
  GET: {
2468
2528
  req: {
@@ -2470,6 +2530,9 @@ var Api = {
2470
2530
  commit_sha: onlyOneStringQueryParam,
2471
2531
  path: onlyOneStringQueryParam,
2472
2532
  remote: onlyOneStringQueryParam.optional()
2533
+ },
2534
+ cookies: {
2535
+ val_session: zod.z.string().optional()
2473
2536
  }
2474
2537
  },
2475
2538
  res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
@@ -2463,6 +2463,66 @@ var Api = {
2463
2463
  * actually mounts. A file at a fixed commit cannot change, so the response is
2464
2464
  * immutable and the browser's own cache handles flipping between commits.
2465
2465
  */
2466
+ /**
2467
+ * One `.jsonValues()` entry's content, as it was at a commit.
2468
+ *
2469
+ * The history pane's counterpart to `/json`. A `.jsonValues()` record's
2470
+ * source is only `{_type:"json"}` markers - the content is per entry, fetched
2471
+ * on demand - so without this the commit pane rendered every entry as an
2472
+ * empty field, which is a claim that the author left it blank.
2473
+ *
2474
+ * One entry per request, deliberately: the store fetches an entry when
2475
+ * something reads inside it, so a batch would mean guessing which entries the
2476
+ * pane is about to show. Authenticated for the same reasons as
2477
+ * `/history/files` below.
2478
+ */
2479
+ "/history/json": {
2480
+ GET: {
2481
+ req: {
2482
+ query: {
2483
+ commit_sha: onlyOneStringQueryParam,
2484
+ path: onlyOneStringQueryParam,
2485
+ key: onlyOneStringQueryParam
2486
+ },
2487
+ cookies: {
2488
+ val_session: zod.z.string().optional()
2489
+ }
2490
+ },
2491
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2492
+ status: zod.z.literal(400),
2493
+ json: GenericError.and(zod.z.object({
2494
+ kind: zod.z.string().optional()
2495
+ }))
2496
+ }), zod.z.object({
2497
+ status: zod.z.literal(500),
2498
+ json: GenericError.and(zod.z.object({
2499
+ kind: zod.z.string().optional()
2500
+ }))
2501
+ }), zod.z.object({
2502
+ status: zod.z.literal(200),
2503
+ json: zod.z.object({
2504
+ path: ModuleFilePath,
2505
+ key: zod.z.string(),
2506
+ content: zod.z.unknown()
2507
+ })
2508
+ })])
2509
+ }
2510
+ },
2511
+ /**
2512
+ * A binary file as it was at a commit.
2513
+ *
2514
+ * AUTHENTICATED, unlike `/files` below - and the difference is not an
2515
+ * oversight in either direction. See the comment on `/files`: what makes it
2516
+ * safe to leave open is that a `patch_id` is an unguessable UUID, and what
2517
+ * makes leaving it open NECESSARY is that a draft image is fetched by the
2518
+ * app's own backend during Next image optimisation, with no cookies.
2519
+ *
2520
+ * Neither holds here. A commit sha is published - `git log`, the GitHub UI,
2521
+ * every PR - so it is not a secret to stand in for a credential. And nothing
2522
+ * fetches these server-side: they are read by the Studio, in a browser that
2523
+ * has the session cookie, for the history pane and for staging a restore.
2524
+ * So this one asks.
2525
+ */
2466
2526
  "/history/files": {
2467
2527
  GET: {
2468
2528
  req: {
@@ -2470,6 +2530,9 @@ var Api = {
2470
2530
  commit_sha: onlyOneStringQueryParam,
2471
2531
  path: onlyOneStringQueryParam,
2472
2532
  remote: onlyOneStringQueryParam.optional()
2533
+ },
2534
+ cookies: {
2535
+ val_session: zod.z.string().optional()
2473
2536
  }
2474
2537
  },
2475
2538
  res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
@@ -2456,6 +2456,66 @@ var Api = {
2456
2456
  * actually mounts. A file at a fixed commit cannot change, so the response is
2457
2457
  * immutable and the browser's own cache handles flipping between commits.
2458
2458
  */
2459
+ /**
2460
+ * One `.jsonValues()` entry's content, as it was at a commit.
2461
+ *
2462
+ * The history pane's counterpart to `/json`. A `.jsonValues()` record's
2463
+ * source is only `{_type:"json"}` markers - the content is per entry, fetched
2464
+ * on demand - so without this the commit pane rendered every entry as an
2465
+ * empty field, which is a claim that the author left it blank.
2466
+ *
2467
+ * One entry per request, deliberately: the store fetches an entry when
2468
+ * something reads inside it, so a batch would mean guessing which entries the
2469
+ * pane is about to show. Authenticated for the same reasons as
2470
+ * `/history/files` below.
2471
+ */
2472
+ "/history/json": {
2473
+ GET: {
2474
+ req: {
2475
+ query: {
2476
+ commit_sha: onlyOneStringQueryParam,
2477
+ path: onlyOneStringQueryParam,
2478
+ key: onlyOneStringQueryParam
2479
+ },
2480
+ cookies: {
2481
+ val_session: z.string().optional()
2482
+ }
2483
+ },
2484
+ res: z.union([unauthorizedResponse, notFoundResponse, z.object({
2485
+ status: z.literal(400),
2486
+ json: GenericError.and(z.object({
2487
+ kind: z.string().optional()
2488
+ }))
2489
+ }), z.object({
2490
+ status: z.literal(500),
2491
+ json: GenericError.and(z.object({
2492
+ kind: z.string().optional()
2493
+ }))
2494
+ }), z.object({
2495
+ status: z.literal(200),
2496
+ json: z.object({
2497
+ path: ModuleFilePath,
2498
+ key: z.string(),
2499
+ content: z.unknown()
2500
+ })
2501
+ })])
2502
+ }
2503
+ },
2504
+ /**
2505
+ * A binary file as it was at a commit.
2506
+ *
2507
+ * AUTHENTICATED, unlike `/files` below - and the difference is not an
2508
+ * oversight in either direction. See the comment on `/files`: what makes it
2509
+ * safe to leave open is that a `patch_id` is an unguessable UUID, and what
2510
+ * makes leaving it open NECESSARY is that a draft image is fetched by the
2511
+ * app's own backend during Next image optimisation, with no cookies.
2512
+ *
2513
+ * Neither holds here. A commit sha is published - `git log`, the GitHub UI,
2514
+ * every PR - so it is not a secret to stand in for a credential. And nothing
2515
+ * fetches these server-side: they are read by the Studio, in a browser that
2516
+ * has the session cookie, for the history pane and for staging a restore.
2517
+ * So this one asks.
2518
+ */
2459
2519
  "/history/files": {
2460
2520
  GET: {
2461
2521
  req: {
@@ -2463,6 +2523,9 @@ var Api = {
2463
2523
  commit_sha: onlyOneStringQueryParam,
2464
2524
  path: onlyOneStringQueryParam,
2465
2525
  remote: onlyOneStringQueryParam.optional()
2526
+ },
2527
+ cookies: {
2528
+ val_session: z.string().optional()
2466
2529
  }
2467
2530
  },
2468
2531
  res: z.union([unauthorizedResponse, notFoundResponse, z.object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/shared",
3
- "version": "0.123.3",
3
+ "version": "0.124.0",
4
4
  "private": false,
5
5
  "description": "Val shared types and utilities",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "flexsearch": "^0.8.212",
38
38
  "zod": "^4.4.3",
39
39
  "zod-validation-error": "^5.0.0",
40
- "@valbuild/core": "0.121.0"
40
+ "@valbuild/core": "0.124.0"
41
41
  },
42
42
  "files": [
43
43
  "CHANGELOG.md",