@valbuild/shared 0.99.1 → 0.100.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.
@@ -19,6 +19,12 @@ type CookieValue = EnableCookieValue | {
19
19
  expires: Date;
20
20
  };
21
21
  };
22
+ /**
23
+ * Upper bound on how many `.jsonValues()` entries one `/json` request may ask
24
+ * for. Callers page through bigger sets; the Studio chunks its key windows to
25
+ * this. Shared so client and server agree on the limit.
26
+ */
27
+ export declare const JSON_ENTRIES_BATCH_MAX = 100;
22
28
  export declare const Api: {
23
29
  "/draft/enable": {
24
30
  GET: {
@@ -395,6 +401,7 @@ export declare const Api: {
395
401
  schemaSha: z.ZodString;
396
402
  baseSha: z.ZodString;
397
403
  patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
404
+ jsonEntriesSha: z.ZodOptional<z.ZodString>;
398
405
  }, z.core.$strip>>;
399
406
  cookies: {
400
407
  val_session: z.ZodOptional<z.ZodString>;
@@ -434,6 +441,7 @@ export declare const Api: {
434
441
  }, z.core.$strip>;
435
442
  profileId: z.ZodNullable<z.ZodString>;
436
443
  mode: z.ZodUnion<readonly [z.ZodLiteral<"http">, z.ZodLiteral<"fs">]>;
444
+ jsonEntriesSha: z.ZodOptional<z.ZodString>;
437
445
  }, z.core.$strip>, z.ZodObject<{
438
446
  type: z.ZodLiteral<"use-websocket">;
439
447
  url: z.ZodString;
@@ -819,7 +827,7 @@ export declare const Api: {
819
827
  message: z.ZodString;
820
828
  value: z.ZodOptional<z.ZodUnknown>;
821
829
  fatal: z.ZodOptional<z.ZodBoolean>;
822
- fixes: z.ZodOptional<z.ZodArray<z.ZodType<"image:add-metadata" | "image:check-metadata" | "image:upload-remote" | "image:download-remote" | "image:check-remote" | "images:check-remote" | "images:upload-remote" | "file:add-metadata" | "file:check-metadata" | "file:upload-remote" | "file:download-remote" | "file:check-remote" | "files:check-remote" | "files:upload-remote" | "keyof:check-keys" | "router:check-route" | "images:check-unique-folder" | "files:check-unique-folder" | "images:check-all-files" | "files:check-all-files", unknown, z.core.$ZodTypeInternals<"image:add-metadata" | "image:check-metadata" | "image:upload-remote" | "image:download-remote" | "image:check-remote" | "images:check-remote" | "images:upload-remote" | "file:add-metadata" | "file:check-metadata" | "file:upload-remote" | "file:download-remote" | "file:check-remote" | "files:check-remote" | "files:upload-remote" | "keyof:check-keys" | "router:check-route" | "images:check-unique-folder" | "files:check-unique-folder" | "images:check-all-files" | "files:check-all-files", unknown>>>>;
830
+ fixes: z.ZodOptional<z.ZodArray<z.ZodType<"image:add-metadata" | "image:check-metadata" | "image:upload-remote" | "image:download-remote" | "image:check-remote" | "images:check-remote" | "images:upload-remote" | "file:add-metadata" | "file:check-metadata" | "file:upload-remote" | "file:download-remote" | "file:check-remote" | "files:check-remote" | "files:upload-remote" | "keyof:check-keys" | "router:check-route" | "images:check-unique-folder" | "files:check-unique-folder" | "images:check-all-files" | "files:check-all-files" | "jsonValues:extract-entry", unknown, z.core.$ZodTypeInternals<"image:add-metadata" | "image:check-metadata" | "image:upload-remote" | "image:download-remote" | "image:check-remote" | "images:check-remote" | "images:upload-remote" | "file:add-metadata" | "file:check-metadata" | "file:upload-remote" | "file:download-remote" | "file:check-remote" | "files:check-remote" | "files:upload-remote" | "keyof:check-keys" | "router:check-route" | "images:check-unique-folder" | "files:check-unique-folder" | "images:check-all-files" | "files:check-all-files" | "jsonValues:extract-entry", unknown>>>>;
823
831
  }, z.core.$strip>>>>;
824
832
  }, z.core.$strip>>;
825
833
  }, z.core.$strip>;
@@ -963,6 +971,68 @@ export declare const Api: {
963
971
  }, z.core.$strip>]>;
964
972
  };
965
973
  };
974
+ "/json": {
975
+ GET: {
976
+ req: {
977
+ query: {
978
+ path: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>;
979
+ key: z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>>;
980
+ keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
981
+ offset: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>, z.ZodTransform<number, string>>>;
982
+ limit: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>>, z.ZodTransform<number, string>>>;
983
+ apply_patches: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<string, string[]>> & z.ZodType<"true" | "false", string[], z.core.$ZodTypeInternals<"true" | "false", string[]>>, z.ZodTransform<boolean, "true" | "false">>>;
984
+ };
985
+ cookies: {
986
+ val_session: z.ZodOptional<z.ZodString>;
987
+ };
988
+ };
989
+ res: z.ZodUnion<readonly [z.ZodObject<{
990
+ status: z.ZodLiteral<401>;
991
+ json: z.ZodObject<{
992
+ message: z.ZodString;
993
+ }, z.core.$strip>;
994
+ }, z.core.$strip>, z.ZodObject<{
995
+ status: z.ZodLiteral<404>;
996
+ json: z.ZodObject<{
997
+ message: z.ZodString;
998
+ }, z.core.$strip>;
999
+ }, z.core.$strip>, z.ZodObject<{
1000
+ status: z.ZodLiteral<200>;
1001
+ json: z.ZodObject<{
1002
+ path: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1003
+ key: z.ZodString;
1004
+ content: z.ZodAny;
1005
+ }, z.core.$strip>;
1006
+ }, z.core.$strip>, z.ZodObject<{
1007
+ status: z.ZodLiteral<200>;
1008
+ json: z.ZodObject<{
1009
+ path: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1010
+ entries: z.ZodArray<z.ZodObject<{
1011
+ key: z.ZodString;
1012
+ content: z.ZodAny;
1013
+ }, z.core.$strip>>;
1014
+ missing: z.ZodArray<z.ZodString>;
1015
+ errors: z.ZodArray<z.ZodObject<{
1016
+ key: z.ZodString;
1017
+ message: z.ZodString;
1018
+ }, z.core.$strip>>;
1019
+ offset: z.ZodOptional<z.ZodNumber>;
1020
+ limit: z.ZodOptional<z.ZodNumber>;
1021
+ total: z.ZodOptional<z.ZodNumber>;
1022
+ }, z.core.$strip>;
1023
+ }, z.core.$strip>, z.ZodObject<{
1024
+ status: z.ZodLiteral<400>;
1025
+ json: z.ZodObject<{
1026
+ message: z.ZodString;
1027
+ }, z.core.$strip>;
1028
+ }, z.core.$strip>, z.ZodObject<{
1029
+ status: z.ZodLiteral<500>;
1030
+ json: z.ZodObject<{
1031
+ message: z.ZodString;
1032
+ }, z.core.$strip>;
1033
+ }, z.core.$strip>]>;
1034
+ };
1035
+ };
966
1036
  "/ai/initialize": {
967
1037
  POST: {
968
1038
  req: {
@@ -1209,7 +1279,7 @@ type DefinedObject<T> = Pick<T, DefinedKeys<T>>;
1209
1279
  *
1210
1280
  * Do not change this without updating the ValRouter query parsing logic
1211
1281
  * */
1212
- export type ValidQueryParamTypes = boolean | string | string[] | undefined;
1282
+ export type ValidQueryParamTypes = boolean | number | string | string[] | undefined;
1213
1283
  export type ApiEndpoint = {
1214
1284
  req: {
1215
1285
  path?: z.ZodString | z.ZodOptional<z.ZodString>;
@@ -1245,7 +1245,7 @@ var ValConfig = zod.z.object({
1245
1245
  gitCommit: zod.z.string().optional(),
1246
1246
  gitBranch: zod.z.string().optional()
1247
1247
  });
1248
- var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("router:check-route"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files")]);
1248
+ var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("router:check-route"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("jsonValues:extract-entry")]);
1249
1249
  var ValidationError = zod.z.object({
1250
1250
  message: zod.z.string(),
1251
1251
  value: zod.z.unknown().optional(),
@@ -1294,6 +1294,18 @@ var onlyOneBooleanQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1294
1294
  }, "Value must be true or false").transform(function (arg) {
1295
1295
  return arg === "true";
1296
1296
  });
1297
+ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1298
+ return /^\d+$/.test(arg);
1299
+ }, "Value must be a non-negative whole number").transform(function (arg) {
1300
+ return parseInt(arg, 10);
1301
+ });
1302
+
1303
+ /**
1304
+ * Upper bound on how many `.jsonValues()` entries one `/json` request may ask
1305
+ * for. Callers page through bigger sets; the Studio chunks its key windows to
1306
+ * this. Shared so client and server agree on the limit.
1307
+ */
1308
+ var JSON_ENTRIES_BATCH_MAX = 100;
1297
1309
  var Api = {
1298
1310
  "/draft/enable": {
1299
1311
  GET: {
@@ -1606,7 +1618,14 @@ var Api = {
1606
1618
  sourcesSha: zod.z.string(),
1607
1619
  schemaSha: zod.z.string(),
1608
1620
  baseSha: zod.z.string(),
1609
- patches: zod.z.array(zod.z.string()).optional()
1621
+ patches: zod.z.array(zod.z.string()).optional(),
1622
+ /**
1623
+ * Fingerprint of the `.jsonValues()` entry files the client last saw.
1624
+ * FS mode only: no other sha can see an entry file change, since a
1625
+ * jsonValues module's source is markers and the content sits behind a
1626
+ * thunk that `JSON.stringify` drops.
1627
+ */
1628
+ jsonEntriesSha: zod.z.string().optional()
1610
1629
  }).nullable(),
1611
1630
  cookies: {
1612
1631
  val_session: zod.z.string().optional()
@@ -1631,7 +1650,8 @@ var Api = {
1631
1650
  patches: zod.z.array(PatchId),
1632
1651
  config: ValConfig,
1633
1652
  profileId: zod.z.string().nullable(),
1634
- mode: zod.z.union([zod.z.literal("http"), zod.z.literal("fs")])
1653
+ mode: zod.z.union([zod.z.literal("http"), zod.z.literal("fs")]),
1654
+ jsonEntriesSha: zod.z.string().optional()
1635
1655
  }), zod.z.object({
1636
1656
  type: zod.z.literal("use-websocket"),
1637
1657
  url: zod.z.string(),
@@ -1993,6 +2013,88 @@ var Api = {
1993
2013
  })])
1994
2014
  }
1995
2015
  },
2016
+ // Loads the content of `.jsonValues()` record/router entries, so the Studio can
2017
+ // lazily load just the entries it needs (instead of the whole record), and so
2018
+ // the runtime can read draft edits in draft mode.
2019
+ //
2020
+ // Three request shapes, exactly one of which must be used:
2021
+ // 1. `key=<k>` — ONE entry; responds `{path, key, content}`.
2022
+ // 2. `keys=<k>&keys=<k2>&…` — a BATCH; responds `{path, entries, missing, errors}`.
2023
+ // 3. `offset=<n>&limit=<n>` — a PAGE of every entry, in module key order;
2024
+ // responds as (2) plus `{offset, limit, total}`.
2025
+ // (2) and (3) are what make loading many entries one round trip instead of N:
2026
+ // the server resolves sources and pending patches ONCE per request, not per entry.
2027
+ //
2028
+ // Batch failures are per entry, never whole-request: a key with no entry lands in
2029
+ // `missing`, a key whose `*.val.json` fails to load lands in `errors`. Only a
2030
+ // missing/non-record MODULE is a 404.
2031
+ //
2032
+ // `apply_patches` defaults to TRUE (as on `/sources/~`): the server replays
2033
+ // pending patches for the entry. The Studio passes `false` explicitly, because
2034
+ // it owns in-flight client patches the server has not seen yet and applies
2035
+ // them itself — letting the server apply them too would double-apply.
2036
+ //
2037
+ // Shape (3) REQUIRES `apply_patches=false`. Enumerating "every entry" from the
2038
+ // base source would silently omit draft-added keys, and the only all-mode caller
2039
+ // (the Studio) derives its key set from its own patched source anyway. Callers
2040
+ // that need draft-aware enumeration pass explicit `keys`.
2041
+ "/json": {
2042
+ GET: {
2043
+ req: {
2044
+ query: {
2045
+ path: onlyOneStringQueryParam,
2046
+ key: onlyOneStringQueryParam.optional(),
2047
+ keys: zod.z.array(zod.z.string()).max(JSON_ENTRIES_BATCH_MAX).optional(),
2048
+ offset: onlyOneIntQueryParam.optional(),
2049
+ limit: onlyOneIntQueryParam.refine(function (arg) {
2050
+ return arg > 0 && arg <= JSON_ENTRIES_BATCH_MAX;
2051
+ }, "limit must be between 1 and ".concat(JSON_ENTRIES_BATCH_MAX)).optional(),
2052
+ apply_patches: onlyOneBooleanQueryParam.optional()
2053
+ },
2054
+ cookies: _defineProperty({}, VAL_SESSION_COOKIE, zod.z.string().optional())
2055
+ },
2056
+ res: zod.z.union([unauthorizedResponse, notFoundResponse,
2057
+ // Shape (1): single `key`.
2058
+ zod.z.object({
2059
+ status: zod.z.literal(200),
2060
+ json: zod.z.object({
2061
+ path: ModuleFilePath,
2062
+ key: zod.z.string(),
2063
+ // The entry's JSON content (or null if the entry has no value).
2064
+ content: zod.z.any()
2065
+ })
2066
+ }),
2067
+ // Shapes (2) and (3): `keys` or `offset`+`limit`.
2068
+ zod.z.object({
2069
+ status: zod.z.literal(200),
2070
+ json: zod.z.object({
2071
+ path: ModuleFilePath,
2072
+ entries: zod.z.array(zod.z.object({
2073
+ key: zod.z.string(),
2074
+ // The entry's JSON content (or null if the entry has no value).
2075
+ content: zod.z.any()
2076
+ })),
2077
+ // Requested keys that have no entry (neither committed nor drafted).
2078
+ missing: zod.z.array(zod.z.string()),
2079
+ // Requested keys whose content could not be loaded.
2080
+ errors: zod.z.array(zod.z.object({
2081
+ key: zod.z.string(),
2082
+ message: zod.z.string()
2083
+ })),
2084
+ // All-mode only: the resolved window and the record's total key count.
2085
+ offset: zod.z.number().optional(),
2086
+ limit: zod.z.number().optional(),
2087
+ total: zod.z.number().optional()
2088
+ })
2089
+ }), zod.z.object({
2090
+ status: zod.z.literal(400),
2091
+ json: GenericError
2092
+ }), zod.z.object({
2093
+ status: zod.z.literal(500),
2094
+ json: GenericError
2095
+ })])
2096
+ }
2097
+ },
1996
2098
  "/ai/initialize": {
1997
2099
  POST: {
1998
2100
  req: {
@@ -2180,6 +2282,8 @@ var Api = {
2180
2282
  *
2181
2283
  * Do not change this without updating the ValRouter query parsing logic
2182
2284
  * */
2285
+ // `number` is allowed because the client stringifies every query value before it
2286
+ // goes on the URL (see createValClient), so a numeric param round-trips fine.
2183
2287
 
2184
2288
  function _typeof(o) {
2185
2289
  "@babel/helpers - typeof";
@@ -3173,6 +3277,7 @@ exports.DEFAULT_ERROR_MESSAGE = DEFAULT_ERROR_MESSAGE;
3173
3277
  exports.DateOptions = DateOptions;
3174
3278
  exports.FileOptions = FileOptions;
3175
3279
  exports.ImageOptions = ImageOptions;
3280
+ exports.JSON_ENTRIES_BATCH_MAX = JSON_ENTRIES_BATCH_MAX;
3176
3281
  exports.ParentRef = ParentRef$1;
3177
3282
  exports.Patch = Patch;
3178
3283
  exports.PatchBlock = PatchBlock;
@@ -1245,7 +1245,7 @@ var ValConfig = zod.z.object({
1245
1245
  gitCommit: zod.z.string().optional(),
1246
1246
  gitBranch: zod.z.string().optional()
1247
1247
  });
1248
- var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("router:check-route"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files")]);
1248
+ var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("router:check-route"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("jsonValues:extract-entry")]);
1249
1249
  var ValidationError = zod.z.object({
1250
1250
  message: zod.z.string(),
1251
1251
  value: zod.z.unknown().optional(),
@@ -1294,6 +1294,18 @@ var onlyOneBooleanQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1294
1294
  }, "Value must be true or false").transform(function (arg) {
1295
1295
  return arg === "true";
1296
1296
  });
1297
+ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1298
+ return /^\d+$/.test(arg);
1299
+ }, "Value must be a non-negative whole number").transform(function (arg) {
1300
+ return parseInt(arg, 10);
1301
+ });
1302
+
1303
+ /**
1304
+ * Upper bound on how many `.jsonValues()` entries one `/json` request may ask
1305
+ * for. Callers page through bigger sets; the Studio chunks its key windows to
1306
+ * this. Shared so client and server agree on the limit.
1307
+ */
1308
+ var JSON_ENTRIES_BATCH_MAX = 100;
1297
1309
  var Api = {
1298
1310
  "/draft/enable": {
1299
1311
  GET: {
@@ -1606,7 +1618,14 @@ var Api = {
1606
1618
  sourcesSha: zod.z.string(),
1607
1619
  schemaSha: zod.z.string(),
1608
1620
  baseSha: zod.z.string(),
1609
- patches: zod.z.array(zod.z.string()).optional()
1621
+ patches: zod.z.array(zod.z.string()).optional(),
1622
+ /**
1623
+ * Fingerprint of the `.jsonValues()` entry files the client last saw.
1624
+ * FS mode only: no other sha can see an entry file change, since a
1625
+ * jsonValues module's source is markers and the content sits behind a
1626
+ * thunk that `JSON.stringify` drops.
1627
+ */
1628
+ jsonEntriesSha: zod.z.string().optional()
1610
1629
  }).nullable(),
1611
1630
  cookies: {
1612
1631
  val_session: zod.z.string().optional()
@@ -1631,7 +1650,8 @@ var Api = {
1631
1650
  patches: zod.z.array(PatchId),
1632
1651
  config: ValConfig,
1633
1652
  profileId: zod.z.string().nullable(),
1634
- mode: zod.z.union([zod.z.literal("http"), zod.z.literal("fs")])
1653
+ mode: zod.z.union([zod.z.literal("http"), zod.z.literal("fs")]),
1654
+ jsonEntriesSha: zod.z.string().optional()
1635
1655
  }), zod.z.object({
1636
1656
  type: zod.z.literal("use-websocket"),
1637
1657
  url: zod.z.string(),
@@ -1993,6 +2013,88 @@ var Api = {
1993
2013
  })])
1994
2014
  }
1995
2015
  },
2016
+ // Loads the content of `.jsonValues()` record/router entries, so the Studio can
2017
+ // lazily load just the entries it needs (instead of the whole record), and so
2018
+ // the runtime can read draft edits in draft mode.
2019
+ //
2020
+ // Three request shapes, exactly one of which must be used:
2021
+ // 1. `key=<k>` — ONE entry; responds `{path, key, content}`.
2022
+ // 2. `keys=<k>&keys=<k2>&…` — a BATCH; responds `{path, entries, missing, errors}`.
2023
+ // 3. `offset=<n>&limit=<n>` — a PAGE of every entry, in module key order;
2024
+ // responds as (2) plus `{offset, limit, total}`.
2025
+ // (2) and (3) are what make loading many entries one round trip instead of N:
2026
+ // the server resolves sources and pending patches ONCE per request, not per entry.
2027
+ //
2028
+ // Batch failures are per entry, never whole-request: a key with no entry lands in
2029
+ // `missing`, a key whose `*.val.json` fails to load lands in `errors`. Only a
2030
+ // missing/non-record MODULE is a 404.
2031
+ //
2032
+ // `apply_patches` defaults to TRUE (as on `/sources/~`): the server replays
2033
+ // pending patches for the entry. The Studio passes `false` explicitly, because
2034
+ // it owns in-flight client patches the server has not seen yet and applies
2035
+ // them itself — letting the server apply them too would double-apply.
2036
+ //
2037
+ // Shape (3) REQUIRES `apply_patches=false`. Enumerating "every entry" from the
2038
+ // base source would silently omit draft-added keys, and the only all-mode caller
2039
+ // (the Studio) derives its key set from its own patched source anyway. Callers
2040
+ // that need draft-aware enumeration pass explicit `keys`.
2041
+ "/json": {
2042
+ GET: {
2043
+ req: {
2044
+ query: {
2045
+ path: onlyOneStringQueryParam,
2046
+ key: onlyOneStringQueryParam.optional(),
2047
+ keys: zod.z.array(zod.z.string()).max(JSON_ENTRIES_BATCH_MAX).optional(),
2048
+ offset: onlyOneIntQueryParam.optional(),
2049
+ limit: onlyOneIntQueryParam.refine(function (arg) {
2050
+ return arg > 0 && arg <= JSON_ENTRIES_BATCH_MAX;
2051
+ }, "limit must be between 1 and ".concat(JSON_ENTRIES_BATCH_MAX)).optional(),
2052
+ apply_patches: onlyOneBooleanQueryParam.optional()
2053
+ },
2054
+ cookies: _defineProperty({}, VAL_SESSION_COOKIE, zod.z.string().optional())
2055
+ },
2056
+ res: zod.z.union([unauthorizedResponse, notFoundResponse,
2057
+ // Shape (1): single `key`.
2058
+ zod.z.object({
2059
+ status: zod.z.literal(200),
2060
+ json: zod.z.object({
2061
+ path: ModuleFilePath,
2062
+ key: zod.z.string(),
2063
+ // The entry's JSON content (or null if the entry has no value).
2064
+ content: zod.z.any()
2065
+ })
2066
+ }),
2067
+ // Shapes (2) and (3): `keys` or `offset`+`limit`.
2068
+ zod.z.object({
2069
+ status: zod.z.literal(200),
2070
+ json: zod.z.object({
2071
+ path: ModuleFilePath,
2072
+ entries: zod.z.array(zod.z.object({
2073
+ key: zod.z.string(),
2074
+ // The entry's JSON content (or null if the entry has no value).
2075
+ content: zod.z.any()
2076
+ })),
2077
+ // Requested keys that have no entry (neither committed nor drafted).
2078
+ missing: zod.z.array(zod.z.string()),
2079
+ // Requested keys whose content could not be loaded.
2080
+ errors: zod.z.array(zod.z.object({
2081
+ key: zod.z.string(),
2082
+ message: zod.z.string()
2083
+ })),
2084
+ // All-mode only: the resolved window and the record's total key count.
2085
+ offset: zod.z.number().optional(),
2086
+ limit: zod.z.number().optional(),
2087
+ total: zod.z.number().optional()
2088
+ })
2089
+ }), zod.z.object({
2090
+ status: zod.z.literal(400),
2091
+ json: GenericError
2092
+ }), zod.z.object({
2093
+ status: zod.z.literal(500),
2094
+ json: GenericError
2095
+ })])
2096
+ }
2097
+ },
1996
2098
  "/ai/initialize": {
1997
2099
  POST: {
1998
2100
  req: {
@@ -2180,6 +2282,8 @@ var Api = {
2180
2282
  *
2181
2283
  * Do not change this without updating the ValRouter query parsing logic
2182
2284
  * */
2285
+ // `number` is allowed because the client stringifies every query value before it
2286
+ // goes on the URL (see createValClient), so a numeric param round-trips fine.
2183
2287
 
2184
2288
  function _typeof(o) {
2185
2289
  "@babel/helpers - typeof";
@@ -3173,6 +3277,7 @@ exports.DEFAULT_ERROR_MESSAGE = DEFAULT_ERROR_MESSAGE;
3173
3277
  exports.DateOptions = DateOptions;
3174
3278
  exports.FileOptions = FileOptions;
3175
3279
  exports.ImageOptions = ImageOptions;
3280
+ exports.JSON_ENTRIES_BATCH_MAX = JSON_ENTRIES_BATCH_MAX;
3176
3281
  exports.ParentRef = ParentRef$1;
3177
3282
  exports.Patch = Patch;
3178
3283
  exports.PatchBlock = PatchBlock;
@@ -1241,7 +1241,7 @@ var ValConfig = z.object({
1241
1241
  gitCommit: z.string().optional(),
1242
1242
  gitBranch: z.string().optional()
1243
1243
  });
1244
- var ValidationFixZ = z.union([z.literal("image:add-metadata"), z.literal("image:check-metadata"), z.literal("image:check-remote"), z.literal("image:upload-remote"), z.literal("image:download-remote"), z.literal("images:check-remote"), z.literal("images:upload-remote"), z.literal("file:add-metadata"), z.literal("file:check-metadata"), z.literal("file:check-remote"), z.literal("file:upload-remote"), z.literal("file:download-remote"), z.literal("files:check-remote"), z.literal("files:upload-remote"), z.literal("keyof:check-keys"), z.literal("router:check-route"), z.literal("images:check-unique-folder"), z.literal("files:check-unique-folder"), z.literal("images:check-all-files"), z.literal("files:check-all-files")]);
1244
+ var ValidationFixZ = z.union([z.literal("image:add-metadata"), z.literal("image:check-metadata"), z.literal("image:check-remote"), z.literal("image:upload-remote"), z.literal("image:download-remote"), z.literal("images:check-remote"), z.literal("images:upload-remote"), z.literal("file:add-metadata"), z.literal("file:check-metadata"), z.literal("file:check-remote"), z.literal("file:upload-remote"), z.literal("file:download-remote"), z.literal("files:check-remote"), z.literal("files:upload-remote"), z.literal("keyof:check-keys"), z.literal("router:check-route"), z.literal("images:check-unique-folder"), z.literal("files:check-unique-folder"), z.literal("images:check-all-files"), z.literal("files:check-all-files"), z.literal("jsonValues:extract-entry")]);
1245
1245
  var ValidationError = z.object({
1246
1246
  message: z.string(),
1247
1247
  value: z.unknown().optional(),
@@ -1290,6 +1290,18 @@ var onlyOneBooleanQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1290
1290
  }, "Value must be true or false").transform(function (arg) {
1291
1291
  return arg === "true";
1292
1292
  });
1293
+ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1294
+ return /^\d+$/.test(arg);
1295
+ }, "Value must be a non-negative whole number").transform(function (arg) {
1296
+ return parseInt(arg, 10);
1297
+ });
1298
+
1299
+ /**
1300
+ * Upper bound on how many `.jsonValues()` entries one `/json` request may ask
1301
+ * for. Callers page through bigger sets; the Studio chunks its key windows to
1302
+ * this. Shared so client and server agree on the limit.
1303
+ */
1304
+ var JSON_ENTRIES_BATCH_MAX = 100;
1293
1305
  var Api = {
1294
1306
  "/draft/enable": {
1295
1307
  GET: {
@@ -1602,7 +1614,14 @@ var Api = {
1602
1614
  sourcesSha: z.string(),
1603
1615
  schemaSha: z.string(),
1604
1616
  baseSha: z.string(),
1605
- patches: z.array(z.string()).optional()
1617
+ patches: z.array(z.string()).optional(),
1618
+ /**
1619
+ * Fingerprint of the `.jsonValues()` entry files the client last saw.
1620
+ * FS mode only: no other sha can see an entry file change, since a
1621
+ * jsonValues module's source is markers and the content sits behind a
1622
+ * thunk that `JSON.stringify` drops.
1623
+ */
1624
+ jsonEntriesSha: z.string().optional()
1606
1625
  }).nullable(),
1607
1626
  cookies: {
1608
1627
  val_session: z.string().optional()
@@ -1627,7 +1646,8 @@ var Api = {
1627
1646
  patches: z.array(PatchId),
1628
1647
  config: ValConfig,
1629
1648
  profileId: z.string().nullable(),
1630
- mode: z.union([z.literal("http"), z.literal("fs")])
1649
+ mode: z.union([z.literal("http"), z.literal("fs")]),
1650
+ jsonEntriesSha: z.string().optional()
1631
1651
  }), z.object({
1632
1652
  type: z.literal("use-websocket"),
1633
1653
  url: z.string(),
@@ -1989,6 +2009,88 @@ var Api = {
1989
2009
  })])
1990
2010
  }
1991
2011
  },
2012
+ // Loads the content of `.jsonValues()` record/router entries, so the Studio can
2013
+ // lazily load just the entries it needs (instead of the whole record), and so
2014
+ // the runtime can read draft edits in draft mode.
2015
+ //
2016
+ // Three request shapes, exactly one of which must be used:
2017
+ // 1. `key=<k>` — ONE entry; responds `{path, key, content}`.
2018
+ // 2. `keys=<k>&keys=<k2>&…` — a BATCH; responds `{path, entries, missing, errors}`.
2019
+ // 3. `offset=<n>&limit=<n>` — a PAGE of every entry, in module key order;
2020
+ // responds as (2) plus `{offset, limit, total}`.
2021
+ // (2) and (3) are what make loading many entries one round trip instead of N:
2022
+ // the server resolves sources and pending patches ONCE per request, not per entry.
2023
+ //
2024
+ // Batch failures are per entry, never whole-request: a key with no entry lands in
2025
+ // `missing`, a key whose `*.val.json` fails to load lands in `errors`. Only a
2026
+ // missing/non-record MODULE is a 404.
2027
+ //
2028
+ // `apply_patches` defaults to TRUE (as on `/sources/~`): the server replays
2029
+ // pending patches for the entry. The Studio passes `false` explicitly, because
2030
+ // it owns in-flight client patches the server has not seen yet and applies
2031
+ // them itself — letting the server apply them too would double-apply.
2032
+ //
2033
+ // Shape (3) REQUIRES `apply_patches=false`. Enumerating "every entry" from the
2034
+ // base source would silently omit draft-added keys, and the only all-mode caller
2035
+ // (the Studio) derives its key set from its own patched source anyway. Callers
2036
+ // that need draft-aware enumeration pass explicit `keys`.
2037
+ "/json": {
2038
+ GET: {
2039
+ req: {
2040
+ query: {
2041
+ path: onlyOneStringQueryParam,
2042
+ key: onlyOneStringQueryParam.optional(),
2043
+ keys: z.array(z.string()).max(JSON_ENTRIES_BATCH_MAX).optional(),
2044
+ offset: onlyOneIntQueryParam.optional(),
2045
+ limit: onlyOneIntQueryParam.refine(function (arg) {
2046
+ return arg > 0 && arg <= JSON_ENTRIES_BATCH_MAX;
2047
+ }, "limit must be between 1 and ".concat(JSON_ENTRIES_BATCH_MAX)).optional(),
2048
+ apply_patches: onlyOneBooleanQueryParam.optional()
2049
+ },
2050
+ cookies: _defineProperty({}, VAL_SESSION_COOKIE, z.string().optional())
2051
+ },
2052
+ res: z.union([unauthorizedResponse, notFoundResponse,
2053
+ // Shape (1): single `key`.
2054
+ z.object({
2055
+ status: z.literal(200),
2056
+ json: z.object({
2057
+ path: ModuleFilePath,
2058
+ key: z.string(),
2059
+ // The entry's JSON content (or null if the entry has no value).
2060
+ content: z.any()
2061
+ })
2062
+ }),
2063
+ // Shapes (2) and (3): `keys` or `offset`+`limit`.
2064
+ z.object({
2065
+ status: z.literal(200),
2066
+ json: z.object({
2067
+ path: ModuleFilePath,
2068
+ entries: z.array(z.object({
2069
+ key: z.string(),
2070
+ // The entry's JSON content (or null if the entry has no value).
2071
+ content: z.any()
2072
+ })),
2073
+ // Requested keys that have no entry (neither committed nor drafted).
2074
+ missing: z.array(z.string()),
2075
+ // Requested keys whose content could not be loaded.
2076
+ errors: z.array(z.object({
2077
+ key: z.string(),
2078
+ message: z.string()
2079
+ })),
2080
+ // All-mode only: the resolved window and the record's total key count.
2081
+ offset: z.number().optional(),
2082
+ limit: z.number().optional(),
2083
+ total: z.number().optional()
2084
+ })
2085
+ }), z.object({
2086
+ status: z.literal(400),
2087
+ json: GenericError
2088
+ }), z.object({
2089
+ status: z.literal(500),
2090
+ json: GenericError
2091
+ })])
2092
+ }
2093
+ },
1992
2094
  "/ai/initialize": {
1993
2095
  POST: {
1994
2096
  req: {
@@ -2176,6 +2278,8 @@ var Api = {
2176
2278
  *
2177
2279
  * Do not change this without updating the ValRouter query parsing logic
2178
2280
  * */
2281
+ // `number` is allowed because the client stringifies every query value before it
2282
+ // goes on the URL (see createValClient), so a numeric param round-trips fine.
2179
2283
 
2180
2284
  function _typeof(o) {
2181
2285
  "@babel/helpers - typeof";
@@ -3164,4 +3268,4 @@ function resolveSchemaSourceFixes(validationErrors, snapshot) {
3164
3268
  return result;
3165
3269
  }
3166
3270
 
3167
- export { Api, DEFAULT_ERROR_MESSAGE, DateOptions, FileOptions, ImageOptions, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchId, PatchJSON, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RichTextOptions, SerializedArraySchema, SerializedBooleanSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedStringSchema, SerializedUnionSchema, SharedValConfig, VAL_AI_SESSION_STORAGE_KEY, VAL_CONFIG_SESSION_STORAGE_KEY, VAL_ENABLE_COOKIE_NAME, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_THEME_SESSION_STORAGE_KEY, ValCommit, ValDeployment, createRegExpFromPattern, createValClient, filterRoutesByPatterns, findSimilar, getErrorMessageFromUnknownJson, getNextAppRouterSitemapTree, getNextAppRouterSourceFolder, getPatternFromModuleFilePath, getRoutesOf, getRoutesWithModulePaths, levenshtein, parseRoutePattern, remirrorToRichTextSource, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, richTextToRemirror, urlOf, validateRoutePatterns };
3271
+ export { Api, DEFAULT_ERROR_MESSAGE, DateOptions, FileOptions, ImageOptions, JSON_ENTRIES_BATCH_MAX, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchId, PatchJSON, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RichTextOptions, SerializedArraySchema, SerializedBooleanSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedStringSchema, SerializedUnionSchema, SharedValConfig, VAL_AI_SESSION_STORAGE_KEY, VAL_CONFIG_SESSION_STORAGE_KEY, VAL_ENABLE_COOKIE_NAME, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_THEME_SESSION_STORAGE_KEY, ValCommit, ValDeployment, createRegExpFromPattern, createValClient, filterRoutesByPatterns, findSimilar, getErrorMessageFromUnknownJson, getNextAppRouterSitemapTree, getNextAppRouterSourceFolder, getPatternFromModuleFilePath, getRoutesOf, getRoutesWithModulePaths, levenshtein, parseRoutePattern, remirrorToRichTextSource, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, richTextToRemirror, urlOf, validateRoutePatterns };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/shared",
3
- "version": "0.99.1",
3
+ "version": "0.100.0",
4
4
  "private": false,
5
5
  "description": "Val shared types and utilities",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "zod": "^4.3.5",
33
33
  "zod-validation-error": "^5.0.0",
34
- "@valbuild/core": "0.99.1"
34
+ "@valbuild/core": "0.100.0"
35
35
  },
36
36
  "files": [
37
37
  "dist",