@valbuild/shared 0.144.9 → 0.145.1

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,48 @@
1
1
  # @valbuild/shared
2
2
 
3
+ ## 0.145.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#860](https://github.com/valbuild/val/pull/860) [`a45f595`](https://github.com/valbuild/val/commit/a45f595a5e20b009d4110bbef8ebdc08b2d731d7) Thanks [@freekh](https://github.com/freekh)! - `val publish` and the Studio now tell Val Build which version of the platform's React and TanStack a build was made against. If the platform is updated while a build is running — a project's CI can take several minutes — that build is no longer published onto a platform it was never checked against: the publish stops with a message saying the platform was updated and to build again, and the next build is checked against what it will run on. A build published with `val publish --artifacts` was made elsewhere and does not say, and publishes as before.
8
+
9
+ ## 0.145.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#859](https://github.com/valbuild/val/pull/859) [`f085be0`](https://github.com/valbuild/val/commit/f085be0eb5bdc195e9d8cdb15dd5f8acfdabe23c) Thanks [@freekh](https://github.com/freekh)! - An edit Val Build refuses to save because of the project's plan — the Free plan's 1,000 changes a week are used, or a Hosted trial has ended — is now kept in the Studio instead of being reverted.
14
+
15
+ - `PUT /patches` answers such a save with a `403` of type `plan-refused`, carrying Val Build's reason and fix as data and which patches of the request it did save. It used to answer `400 patch-error`, which the Studio reads as a bad patch and drops.
16
+ - The Studio keeps the refused edits and any made after them, shows the plan notice with **Upgrade** or **Add a card** beside it, and saves them by itself once the plan allows it: as soon as Val Build says editing is open again (an owner added a card, the week moved on), and otherwise by trying again now and then. A publish or a restore that meets held edits says why, in Val Build's words, instead of suggesting the connection.
17
+ - The MCP write tools answer a refused write as `forbidden`, with Val Build's sentence, instead of `internal`.
18
+
19
+ ### Patch Changes
20
+
21
+ - [#851](https://github.com/valbuild/val/pull/851) [`b6cb939`](https://github.com/valbuild/val/commit/b6cb9395d8bdcd5182e9c6ba84f5284930de2fa5) Thanks [@freekh](https://github.com/freekh)! - New `s.int()` for whole numbers, `.step()` on `s.int()` and `s.number()`, and a slider for both:
22
+
23
+ ```ts
24
+ s.object({
25
+ columns: s.int().min(1).max(6),
26
+ opacity: s
27
+ .int()
28
+ .min(0)
29
+ .max(100)
30
+ .step(5)
31
+ .render({ as: "slider", min: 0, max: 100 }),
32
+ lineHeight: s.number().render({ as: "slider", min: 1, max: 2, step: 0.1 }),
33
+ });
34
+ ```
35
+
36
+ - `.min()`, `.max()` and `.step()` are rules the validator checks. A step is counted from `min`, or from 0 when there is none.
37
+ - `.render({ as: "slider", min, max, step? })` is how the field is edited: a slider, with a box beside it for typing an exact value. `min` and `max` are required. The slider's step defaults to the schema's `.step()`, then to 1.
38
+ - The slider can only produce values the schema accepts. A slider outside `.min()`/`.max()`, with a step that is not a multiple of `.step()`, or with decimals on an `s.int()` throws where the schema is defined.
39
+ - A value outside the slider's range is still valid content. The field says it is out of the slider's reach and offers "Set to" the nearest stop. A value that breaks a rule offers "Round to" the nearest allowed value.
40
+ - Fixed: `.min(0)` and `.max(0)` on `s.number()` were ignored.
41
+ - A new item of a number schema starts at the nearest allowed value instead of `0`, so `s.int().min(1)` starts at 1.
42
+
43
+ - Updated dependencies [[`b6cb939`](https://github.com/valbuild/val/commit/b6cb9395d8bdcd5182e9c6ba84f5284930de2fa5)]:
44
+ - @valbuild/core@0.145.0
45
+
3
46
  ## 0.144.9
4
47
 
5
48
  ### Patch Changes
@@ -1,6 +1,21 @@
1
1
  import { z } from "zod";
2
2
  import { type ModuleFilePath } from "@valbuild/core";
3
3
  declare const ModuleFilePath: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
4
+ /**
5
+ * Why Val Build refused a write for the project's plan, as data: the `error` of
6
+ * its 403 (`refusalError` in valbuild/home's `billing/projectLimits.ts`).
7
+ *
8
+ * Every field but `code` is optional and every field is a plain string, so a
9
+ * newer Val Build that adds a code or a fix still parses: the Studio says an
10
+ * unknown one with Billing beside it rather than failing to read the answer.
11
+ */
12
+ export declare const PlanRefusalError: z.ZodObject<{
13
+ code: z.ZodString;
14
+ fix: z.ZodOptional<z.ZodString>;
15
+ until: z.ZodOptional<z.ZodString>;
16
+ billingUrl: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ export type PlanRefusalErrorT = z.infer<typeof PlanRefusalError>;
4
19
  /**
5
20
  * The header a request to `/admin/proxy` must carry. A cross-site form or
6
21
  * `<img>` cannot set a custom header, so without it the proxy cannot be driven
@@ -818,6 +833,28 @@ export declare const Api: {
818
833
  }, z.core.$strip>;
819
834
  }, z.core.$strip>>>;
820
835
  }, z.core.$strip>;
836
+ }, z.core.$strip>, z.ZodObject<{
837
+ status: z.ZodLiteral<403>;
838
+ json: z.ZodObject<{
839
+ type: z.ZodLiteral<"plan-refused">;
840
+ message: z.ZodString;
841
+ error: z.ZodObject<{
842
+ code: z.ZodString;
843
+ fix: z.ZodOptional<z.ZodString>;
844
+ until: z.ZodOptional<z.ZodString>;
845
+ billingUrl: z.ZodOptional<z.ZodString>;
846
+ }, z.core.$strip>;
847
+ newPatchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
848
+ parentRef: z.ZodUnion<readonly [z.ZodObject<{
849
+ type: z.ZodLiteral<"head">;
850
+ headBaseSha: z.ZodString;
851
+ }, z.core.$strip>, z.ZodObject<{
852
+ type: z.ZodLiteral<"patch">;
853
+ patchId: z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>;
854
+ }, z.core.$strip>]>;
855
+ patchGroupId: z.ZodOptional<z.ZodString>;
856
+ headVersion: z.ZodOptional<z.ZodNumber>;
857
+ }, z.core.$strip>;
821
858
  }, z.core.$strip>, z.ZodObject<{
822
859
  status: z.ZodLiteral<200>;
823
860
  json: z.ZodObject<{
@@ -1057,7 +1094,7 @@ export declare const Api: {
1057
1094
  status: z.ZodLiteral<200>;
1058
1095
  json: z.ZodObject<{
1059
1096
  schemaSha: z.ZodString;
1060
- schemas: z.ZodRecord<z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>, z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
1097
+ schemas: z.ZodRecord<z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>, z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
1061
1098
  }, z.core.$strip>;
1062
1099
  }, z.core.$strip>]>;
1063
1100
  };
@@ -1489,7 +1526,7 @@ export declare const Api: {
1489
1526
  }, z.core.$strip>;
1490
1527
  modules: z.ZodRecord<z.ZodString, z.ZodObject<{
1491
1528
  source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
1492
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
1529
+ schema: z.ZodNullable<z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
1493
1530
  patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
1494
1531
  changedPaths: z.ZodArray<z.ZodString>;
1495
1532
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -1609,7 +1646,7 @@ export declare const Api: {
1609
1646
  moduleFilePath: z.ZodString;
1610
1647
  module: z.ZodNullable<z.ZodObject<{
1611
1648
  source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
1612
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
1649
+ schema: z.ZodNullable<z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
1613
1650
  patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
1614
1651
  changedPaths: z.ZodArray<z.ZodString>;
1615
1652
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -50,9 +50,11 @@ export type ContentPublishApi = {
50
50
  *
51
51
  * ## What is deliberately not here
52
52
  *
53
- * No loader URL, no `vendorRev`, no `x-platform-project`. This service holds
54
- * the operator relationship with the build platform and calls it; a publisher
55
- * talks to this API and nothing else. The one exception is the presigned
53
+ * No loader URL, no `x-platform-project`. This service holds the operator
54
+ * relationship with the build platform and calls it; a publisher talks to
55
+ * this API and nothing else. A publisher does say which base layer it built
56
+ * against (`baseRev` below) -- a fact about its build, which this service
57
+ * forwards -- but never addresses the platform itself. The one exception is the presigned
56
58
  * upload URL, which points at object storage -- bytes do not travel through
57
59
  * here.
58
60
  *
@@ -73,6 +75,18 @@ export type ContentPublishApi = {
73
75
  branch: string | null;
74
76
  /** Which dependency layer this was built against, sent or not. */
75
77
  layerRev: string | null;
78
+ /**
79
+ * Which BASE layer -- the platform's React and TanStack -- this was
80
+ * built against: `base.rev` of the build target the build used.
81
+ *
82
+ * Content forwards it to the build platform as the build's own, and
83
+ * the platform refuses a new build whose base layer it no longer
84
+ * serves: one deployed while the build ran, which the build's layer
85
+ * was never checked against. Left out when it is not known -- a build
86
+ * made elsewhere and published with `--artifacts` -- which publishes
87
+ * as every build did before.
88
+ */
89
+ baseRev?: string | null;
76
90
  /**
77
91
  * Whether the app links its own CSS.
78
92
  *
@@ -88,6 +88,11 @@ declare const buildTargetResponse: z.ZodObject<{
88
88
  flightServer: z.ZodString;
89
89
  serverFnBase: z.ZodString;
90
90
  }, z.core.$strip>;
91
+ pins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
92
+ exports: z.ZodOptional<z.ZodObject<{
93
+ worker: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
94
+ browser: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
95
+ }, z.core.$strip>>;
91
96
  }, z.core.$strip>;
92
97
  project: z.ZodObject<{
93
98
  rev: z.ZodNullable<z.ZodString>;
@@ -177,6 +182,11 @@ declare const updateTargetResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
177
182
  flightServer: z.ZodString;
178
183
  serverFnBase: z.ZodString;
179
184
  }, z.core.$strip>;
185
+ pins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
186
+ exports: z.ZodOptional<z.ZodObject<{
187
+ worker: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
188
+ browser: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
189
+ }, z.core.$strip>>;
180
190
  }, z.core.$strip>;
181
191
  project: z.ZodObject<{
182
192
  rev: z.ZodNullable<z.ZodString>;
@@ -65,7 +65,7 @@ export declare const BinaryFileRef: z.ZodObject<{
65
65
  export type BinaryFileRef = z.infer<typeof BinaryFileRef>;
66
66
  export declare const HistoricalModule: z.ZodObject<{
67
67
  source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
68
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
68
+ schema: z.ZodNullable<z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
69
69
  patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
70
70
  changedPaths: z.ZodArray<z.ZodString>;
71
71
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -110,7 +110,7 @@ export declare const HistoricalPatchSet: z.ZodObject<{
110
110
  }, z.core.$strip>;
111
111
  modules: z.ZodRecord<z.ZodString, z.ZodObject<{
112
112
  source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
113
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
113
+ schema: z.ZodNullable<z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
114
114
  patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
115
115
  changedPaths: z.ZodArray<z.ZodString>;
116
116
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -1086,8 +1086,8 @@ var _excluded = ["directory"];
1086
1086
 
1087
1087
  // A render is static config, so unlike a `preview` it travels WHOLE — this
1088
1088
  // is the field the editor reads the layout from. See `core/src/render.ts`.
1089
- // Only array, record and keyOf carry one, and `{ as: "inline" }` is all it
1090
- // says. A stale `render` on any other schema is stripped here, harmlessly.
1089
+ // Array, record and keyOf carry `{ as: "inline" }`; number carries
1090
+ // `{ as: "slider", ... }`. A stale `render` on any other schema is stripped here, harmlessly.
1091
1091
  // NB: these z.objects STRIP unknown keys, so a render variant that is not
1092
1092
  // declared here is silently dropped in transit — add it here when it is added
1093
1093
  // to `render.ts`.
@@ -1095,6 +1095,13 @@ var InlineRender = zod.z.object({
1095
1095
  as: zod.z.literal("inline")
1096
1096
  });
1097
1097
  var FieldRender = InlineRender.optional();
1098
+ // The other render, and the only one a leaf takes: `s.number()` / `s.int()`.
1099
+ var NumberRender = zod.z.object({
1100
+ as: zod.z.literal("slider"),
1101
+ min: zod.z.number(),
1102
+ max: zod.z.number(),
1103
+ step: zod.z.number().optional()
1104
+ }).optional();
1098
1105
 
1099
1106
  /**
1100
1107
  * The fields EVERY serialized schema carries, in one place.
@@ -1154,8 +1161,11 @@ var SerializedNumberSchema = zod.z.object(getSitemapTree._objectSpread2(getSitem
1154
1161
  type: zod.z.literal("number"),
1155
1162
  options: zod.z.object({
1156
1163
  max: zod.z.number().optional(),
1157
- min: zod.z.number().optional()
1164
+ min: zod.z.number().optional(),
1165
+ integer: zod.z["boolean"]().optional(),
1166
+ step: zod.z.number().optional()
1158
1167
  }).optional(),
1168
+ render: NumberRender,
1159
1169
  opt: zod.z["boolean"]()
1160
1170
  }));
1161
1171
  var SerializedObjectSchema = zod.z.lazy(function () {
@@ -1628,7 +1638,22 @@ var notFoundResponse = zod.z.object({
1628
1638
  var GenericError = zod.z.object({
1629
1639
  message: zod.z.string()
1630
1640
  });
1631
-
1641
+ /**
1642
+ * Why Val Build refused a write for the project's plan, as data: the `error` of
1643
+ * its 403 (`refusalError` in valbuild/home's `billing/projectLimits.ts`).
1644
+ *
1645
+ * Every field but `code` is optional and every field is a plain string, so a
1646
+ * newer Val Build that adds a code or a fix still parses: the Studio says an
1647
+ * unknown one with Billing beside it rather than failing to read the answer.
1648
+ */
1649
+ var PlanRefusalError = zod.z.object({
1650
+ code: zod.z.string(),
1651
+ fix: zod.z.string().optional(),
1652
+ /** When it lifts by itself, as an ISO time, if it does. */
1653
+ until: zod.z.string().optional(),
1654
+ /** The organization's Billing in Val Build. */
1655
+ billingUrl: zod.z.string().optional()
1656
+ });
1632
1657
  /**
1633
1658
  * The header a request to `/admin/proxy` must carry. A cross-site form or
1634
1659
  * `<img>` cannot set a custom header, so without it the proxy cannot be driven
@@ -2625,6 +2650,29 @@ var Api = {
2625
2650
  error: GenericError
2626
2651
  })))
2627
2652
  })
2653
+ }),
2654
+ /*
2655
+ * Val Build refused the write for the project's plan: the Free week's
2656
+ * changes are used, or a trial is over. Not the 400 above, because the
2657
+ * patches are fine -- they are kept, and saved once the plan allows.
2658
+ * `message` is Val Build's own sentence and `error` the same as data,
2659
+ * so the Studio can put the fix beside it.
2660
+ *
2661
+ * The patches of the batch BEFORE the refused one were saved (the Free
2662
+ * week can run out mid-batch), so this carries what a 200 does about
2663
+ * them: the client marks those saved and keeps the rest.
2664
+ */
2665
+ zod.z.object({
2666
+ status: zod.z.literal(403),
2667
+ json: zod.z.object({
2668
+ type: zod.z.literal("plan-refused"),
2669
+ message: zod.z.string(),
2670
+ error: PlanRefusalError,
2671
+ newPatchIds: zod.z.array(PatchId),
2672
+ parentRef: ParentRef,
2673
+ patchGroupId: zod.z.string().optional(),
2674
+ headVersion: zod.z.number().optional()
2675
+ })
2628
2676
  }), zod.z.object({
2629
2677
  status: zod.z.literal(200),
2630
2678
  json: zod.z.object({
@@ -5569,7 +5617,11 @@ function emptyOf(schema, context) {
5569
5617
  } else if (schema.type === "boolean") {
5570
5618
  return false;
5571
5619
  } else if (schema.type === "number") {
5572
- return 0;
5620
+ var _Internal$number$near, _schema$options;
5621
+ // 0, unless the schema rules it out: an `s.int().min(1)` starts at 1
5622
+ // rather than as an error. `null` means the schema allows nothing at all,
5623
+ // which validation will say; 0 is as good a start as any for that.
5624
+ return (_Internal$number$near = core.Internal.number.nearestAllowedNumber(0, (_schema$options = schema.options) !== null && _schema$options !== void 0 ? _schema$options : {})) !== null && _Internal$number$near !== void 0 ? _Internal$number$near : 0;
5573
5625
  } else if (schema.type === "keyOf") {
5574
5626
  if (schema.values === "string") {
5575
5627
  return ""; // TODO: figure out this: user code might very well fail in this case
@@ -5611,14 +5663,14 @@ function emptyOf(schema, context) {
5611
5663
  } else if (schema.type === "dateTime") {
5612
5664
  return clampDateTimeString(new Date().toISOString(), schema.options);
5613
5665
  } else if (schema.type === "color") {
5614
- var _schema$options$forma, _schema$options;
5666
+ var _schema$options$forma, _schema$options2;
5615
5667
  // Mid grey: visible against both a light and a dark canvas
5616
5668
  return core.Internal.color.formatColor({
5617
5669
  r: 128,
5618
5670
  g: 128,
5619
5671
  b: 128,
5620
5672
  a: 1
5621
- }, (_schema$options$forma = (_schema$options = schema.options) === null || _schema$options === void 0 ? void 0 : _schema$options.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : core.DEFAULT_COLOR_FORMAT);
5673
+ }, (_schema$options$forma = (_schema$options2 = schema.options) === null || _schema$options2 === void 0 ? void 0 : _schema$options2.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : core.DEFAULT_COLOR_FORMAT);
5622
5674
  } else if (schema.type === "code") {
5623
5675
  return ""; // An empty editor: no language has a sensible starting snippet
5624
5676
  } else if (schema.type === "view") {
@@ -7809,7 +7861,20 @@ var buildTargetResponse = zod.z.object({
7809
7861
  rscRuntimePath: zod.z.string(),
7810
7862
  flightServer: zod.z.string(),
7811
7863
  serverFnBase: zod.z.string()
7812
- })
7864
+ }),
7865
+ /*
7866
+ * What the base layer is built from and what its chunks export, which
7867
+ * `val publish` checks a project's layer against (`BuildTarget.base` in
7868
+ * @valbuild/tanstack-build). Declared, because `z.object` DROPS a key it
7869
+ * does not name: left out, they never reached the build, and every
7870
+ * publish skipped both checks while saying the platform had not sent them.
7871
+ * Optional, for a platform that predates them.
7872
+ */
7873
+ pins: zod.z.record(zod.z.string(), zod.z.string()).optional(),
7874
+ exports: zod.z.object({
7875
+ worker: zod.z.record(zod.z.string(), zod.z.array(zod.z.string())),
7876
+ browser: zod.z.record(zod.z.string(), zod.z.array(zod.z.string()))
7877
+ }).optional()
7813
7878
  }),
7814
7879
  project: zod.z.object({
7815
7880
  rev: zod.z.string().nullable(),
@@ -8069,6 +8134,7 @@ exports.PatchBlock = PatchBlock;
8069
8134
  exports.PatchGroup = PatchGroup;
8070
8135
  exports.PatchId = PatchId;
8071
8136
  exports.PatchJSON = PatchJSON;
8137
+ exports.PlanRefusalError = PlanRefusalError;
8072
8138
  exports.PublishProtocolError = PublishProtocolError;
8073
8139
  exports.RAMP_STEPS = RAMP_STEPS;
8074
8140
  exports.RemirrorBr = RemirrorBr;
@@ -1086,8 +1086,8 @@ var _excluded = ["directory"];
1086
1086
 
1087
1087
  // A render is static config, so unlike a `preview` it travels WHOLE — this
1088
1088
  // is the field the editor reads the layout from. See `core/src/render.ts`.
1089
- // Only array, record and keyOf carry one, and `{ as: "inline" }` is all it
1090
- // says. A stale `render` on any other schema is stripped here, harmlessly.
1089
+ // Array, record and keyOf carry `{ as: "inline" }`; number carries
1090
+ // `{ as: "slider", ... }`. A stale `render` on any other schema is stripped here, harmlessly.
1091
1091
  // NB: these z.objects STRIP unknown keys, so a render variant that is not
1092
1092
  // declared here is silently dropped in transit — add it here when it is added
1093
1093
  // to `render.ts`.
@@ -1095,6 +1095,13 @@ var InlineRender = zod.z.object({
1095
1095
  as: zod.z.literal("inline")
1096
1096
  });
1097
1097
  var FieldRender = InlineRender.optional();
1098
+ // The other render, and the only one a leaf takes: `s.number()` / `s.int()`.
1099
+ var NumberRender = zod.z.object({
1100
+ as: zod.z.literal("slider"),
1101
+ min: zod.z.number(),
1102
+ max: zod.z.number(),
1103
+ step: zod.z.number().optional()
1104
+ }).optional();
1098
1105
 
1099
1106
  /**
1100
1107
  * The fields EVERY serialized schema carries, in one place.
@@ -1154,8 +1161,11 @@ var SerializedNumberSchema = zod.z.object(getSitemapTree._objectSpread2(getSitem
1154
1161
  type: zod.z.literal("number"),
1155
1162
  options: zod.z.object({
1156
1163
  max: zod.z.number().optional(),
1157
- min: zod.z.number().optional()
1164
+ min: zod.z.number().optional(),
1165
+ integer: zod.z["boolean"]().optional(),
1166
+ step: zod.z.number().optional()
1158
1167
  }).optional(),
1168
+ render: NumberRender,
1159
1169
  opt: zod.z["boolean"]()
1160
1170
  }));
1161
1171
  var SerializedObjectSchema = zod.z.lazy(function () {
@@ -1628,7 +1638,22 @@ var notFoundResponse = zod.z.object({
1628
1638
  var GenericError = zod.z.object({
1629
1639
  message: zod.z.string()
1630
1640
  });
1631
-
1641
+ /**
1642
+ * Why Val Build refused a write for the project's plan, as data: the `error` of
1643
+ * its 403 (`refusalError` in valbuild/home's `billing/projectLimits.ts`).
1644
+ *
1645
+ * Every field but `code` is optional and every field is a plain string, so a
1646
+ * newer Val Build that adds a code or a fix still parses: the Studio says an
1647
+ * unknown one with Billing beside it rather than failing to read the answer.
1648
+ */
1649
+ var PlanRefusalError = zod.z.object({
1650
+ code: zod.z.string(),
1651
+ fix: zod.z.string().optional(),
1652
+ /** When it lifts by itself, as an ISO time, if it does. */
1653
+ until: zod.z.string().optional(),
1654
+ /** The organization's Billing in Val Build. */
1655
+ billingUrl: zod.z.string().optional()
1656
+ });
1632
1657
  /**
1633
1658
  * The header a request to `/admin/proxy` must carry. A cross-site form or
1634
1659
  * `<img>` cannot set a custom header, so without it the proxy cannot be driven
@@ -2625,6 +2650,29 @@ var Api = {
2625
2650
  error: GenericError
2626
2651
  })))
2627
2652
  })
2653
+ }),
2654
+ /*
2655
+ * Val Build refused the write for the project's plan: the Free week's
2656
+ * changes are used, or a trial is over. Not the 400 above, because the
2657
+ * patches are fine -- they are kept, and saved once the plan allows.
2658
+ * `message` is Val Build's own sentence and `error` the same as data,
2659
+ * so the Studio can put the fix beside it.
2660
+ *
2661
+ * The patches of the batch BEFORE the refused one were saved (the Free
2662
+ * week can run out mid-batch), so this carries what a 200 does about
2663
+ * them: the client marks those saved and keeps the rest.
2664
+ */
2665
+ zod.z.object({
2666
+ status: zod.z.literal(403),
2667
+ json: zod.z.object({
2668
+ type: zod.z.literal("plan-refused"),
2669
+ message: zod.z.string(),
2670
+ error: PlanRefusalError,
2671
+ newPatchIds: zod.z.array(PatchId),
2672
+ parentRef: ParentRef,
2673
+ patchGroupId: zod.z.string().optional(),
2674
+ headVersion: zod.z.number().optional()
2675
+ })
2628
2676
  }), zod.z.object({
2629
2677
  status: zod.z.literal(200),
2630
2678
  json: zod.z.object({
@@ -5569,7 +5617,11 @@ function emptyOf(schema, context) {
5569
5617
  } else if (schema.type === "boolean") {
5570
5618
  return false;
5571
5619
  } else if (schema.type === "number") {
5572
- return 0;
5620
+ var _Internal$number$near, _schema$options;
5621
+ // 0, unless the schema rules it out: an `s.int().min(1)` starts at 1
5622
+ // rather than as an error. `null` means the schema allows nothing at all,
5623
+ // which validation will say; 0 is as good a start as any for that.
5624
+ return (_Internal$number$near = core.Internal.number.nearestAllowedNumber(0, (_schema$options = schema.options) !== null && _schema$options !== void 0 ? _schema$options : {})) !== null && _Internal$number$near !== void 0 ? _Internal$number$near : 0;
5573
5625
  } else if (schema.type === "keyOf") {
5574
5626
  if (schema.values === "string") {
5575
5627
  return ""; // TODO: figure out this: user code might very well fail in this case
@@ -5611,14 +5663,14 @@ function emptyOf(schema, context) {
5611
5663
  } else if (schema.type === "dateTime") {
5612
5664
  return clampDateTimeString(new Date().toISOString(), schema.options);
5613
5665
  } else if (schema.type === "color") {
5614
- var _schema$options$forma, _schema$options;
5666
+ var _schema$options$forma, _schema$options2;
5615
5667
  // Mid grey: visible against both a light and a dark canvas
5616
5668
  return core.Internal.color.formatColor({
5617
5669
  r: 128,
5618
5670
  g: 128,
5619
5671
  b: 128,
5620
5672
  a: 1
5621
- }, (_schema$options$forma = (_schema$options = schema.options) === null || _schema$options === void 0 ? void 0 : _schema$options.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : core.DEFAULT_COLOR_FORMAT);
5673
+ }, (_schema$options$forma = (_schema$options2 = schema.options) === null || _schema$options2 === void 0 ? void 0 : _schema$options2.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : core.DEFAULT_COLOR_FORMAT);
5622
5674
  } else if (schema.type === "code") {
5623
5675
  return ""; // An empty editor: no language has a sensible starting snippet
5624
5676
  } else if (schema.type === "view") {
@@ -7809,7 +7861,20 @@ var buildTargetResponse = zod.z.object({
7809
7861
  rscRuntimePath: zod.z.string(),
7810
7862
  flightServer: zod.z.string(),
7811
7863
  serverFnBase: zod.z.string()
7812
- })
7864
+ }),
7865
+ /*
7866
+ * What the base layer is built from and what its chunks export, which
7867
+ * `val publish` checks a project's layer against (`BuildTarget.base` in
7868
+ * @valbuild/tanstack-build). Declared, because `z.object` DROPS a key it
7869
+ * does not name: left out, they never reached the build, and every
7870
+ * publish skipped both checks while saying the platform had not sent them.
7871
+ * Optional, for a platform that predates them.
7872
+ */
7873
+ pins: zod.z.record(zod.z.string(), zod.z.string()).optional(),
7874
+ exports: zod.z.object({
7875
+ worker: zod.z.record(zod.z.string(), zod.z.array(zod.z.string())),
7876
+ browser: zod.z.record(zod.z.string(), zod.z.array(zod.z.string()))
7877
+ }).optional()
7813
7878
  }),
7814
7879
  project: zod.z.object({
7815
7880
  rev: zod.z.string().nullable(),
@@ -8069,6 +8134,7 @@ exports.PatchBlock = PatchBlock;
8069
8134
  exports.PatchGroup = PatchGroup;
8070
8135
  exports.PatchId = PatchId;
8071
8136
  exports.PatchJSON = PatchJSON;
8137
+ exports.PlanRefusalError = PlanRefusalError;
8072
8138
  exports.PublishProtocolError = PublishProtocolError;
8073
8139
  exports.RAMP_STEPS = RAMP_STEPS;
8074
8140
  exports.RemirrorBr = RemirrorBr;
@@ -1079,8 +1079,8 @@ var _excluded = ["directory"];
1079
1079
 
1080
1080
  // A render is static config, so unlike a `preview` it travels WHOLE — this
1081
1081
  // is the field the editor reads the layout from. See `core/src/render.ts`.
1082
- // Only array, record and keyOf carry one, and `{ as: "inline" }` is all it
1083
- // says. A stale `render` on any other schema is stripped here, harmlessly.
1082
+ // Array, record and keyOf carry `{ as: "inline" }`; number carries
1083
+ // `{ as: "slider", ... }`. A stale `render` on any other schema is stripped here, harmlessly.
1084
1084
  // NB: these z.objects STRIP unknown keys, so a render variant that is not
1085
1085
  // declared here is silently dropped in transit — add it here when it is added
1086
1086
  // to `render.ts`.
@@ -1088,6 +1088,13 @@ var InlineRender = z.object({
1088
1088
  as: z.literal("inline")
1089
1089
  });
1090
1090
  var FieldRender = InlineRender.optional();
1091
+ // The other render, and the only one a leaf takes: `s.number()` / `s.int()`.
1092
+ var NumberRender = z.object({
1093
+ as: z.literal("slider"),
1094
+ min: z.number(),
1095
+ max: z.number(),
1096
+ step: z.number().optional()
1097
+ }).optional();
1091
1098
 
1092
1099
  /**
1093
1100
  * The fields EVERY serialized schema carries, in one place.
@@ -1147,8 +1154,11 @@ var SerializedNumberSchema = z.object(_objectSpread2(_objectSpread2({}, commonSc
1147
1154
  type: z.literal("number"),
1148
1155
  options: z.object({
1149
1156
  max: z.number().optional(),
1150
- min: z.number().optional()
1157
+ min: z.number().optional(),
1158
+ integer: z["boolean"]().optional(),
1159
+ step: z.number().optional()
1151
1160
  }).optional(),
1161
+ render: NumberRender,
1152
1162
  opt: z["boolean"]()
1153
1163
  }));
1154
1164
  var SerializedObjectSchema = z.lazy(function () {
@@ -1621,7 +1631,22 @@ var notFoundResponse = z.object({
1621
1631
  var GenericError = z.object({
1622
1632
  message: z.string()
1623
1633
  });
1624
-
1634
+ /**
1635
+ * Why Val Build refused a write for the project's plan, as data: the `error` of
1636
+ * its 403 (`refusalError` in valbuild/home's `billing/projectLimits.ts`).
1637
+ *
1638
+ * Every field but `code` is optional and every field is a plain string, so a
1639
+ * newer Val Build that adds a code or a fix still parses: the Studio says an
1640
+ * unknown one with Billing beside it rather than failing to read the answer.
1641
+ */
1642
+ var PlanRefusalError = z.object({
1643
+ code: z.string(),
1644
+ fix: z.string().optional(),
1645
+ /** When it lifts by itself, as an ISO time, if it does. */
1646
+ until: z.string().optional(),
1647
+ /** The organization's Billing in Val Build. */
1648
+ billingUrl: z.string().optional()
1649
+ });
1625
1650
  /**
1626
1651
  * The header a request to `/admin/proxy` must carry. A cross-site form or
1627
1652
  * `<img>` cannot set a custom header, so without it the proxy cannot be driven
@@ -2618,6 +2643,29 @@ var Api = {
2618
2643
  error: GenericError
2619
2644
  })))
2620
2645
  })
2646
+ }),
2647
+ /*
2648
+ * Val Build refused the write for the project's plan: the Free week's
2649
+ * changes are used, or a trial is over. Not the 400 above, because the
2650
+ * patches are fine -- they are kept, and saved once the plan allows.
2651
+ * `message` is Val Build's own sentence and `error` the same as data,
2652
+ * so the Studio can put the fix beside it.
2653
+ *
2654
+ * The patches of the batch BEFORE the refused one were saved (the Free
2655
+ * week can run out mid-batch), so this carries what a 200 does about
2656
+ * them: the client marks those saved and keeps the rest.
2657
+ */
2658
+ z.object({
2659
+ status: z.literal(403),
2660
+ json: z.object({
2661
+ type: z.literal("plan-refused"),
2662
+ message: z.string(),
2663
+ error: PlanRefusalError,
2664
+ newPatchIds: z.array(PatchId),
2665
+ parentRef: ParentRef,
2666
+ patchGroupId: z.string().optional(),
2667
+ headVersion: z.number().optional()
2668
+ })
2621
2669
  }), z.object({
2622
2670
  status: z.literal(200),
2623
2671
  json: z.object({
@@ -5562,7 +5610,11 @@ function emptyOf(schema, context) {
5562
5610
  } else if (schema.type === "boolean") {
5563
5611
  return false;
5564
5612
  } else if (schema.type === "number") {
5565
- return 0;
5613
+ var _Internal$number$near, _schema$options;
5614
+ // 0, unless the schema rules it out: an `s.int().min(1)` starts at 1
5615
+ // rather than as an error. `null` means the schema allows nothing at all,
5616
+ // which validation will say; 0 is as good a start as any for that.
5617
+ return (_Internal$number$near = Internal.number.nearestAllowedNumber(0, (_schema$options = schema.options) !== null && _schema$options !== void 0 ? _schema$options : {})) !== null && _Internal$number$near !== void 0 ? _Internal$number$near : 0;
5566
5618
  } else if (schema.type === "keyOf") {
5567
5619
  if (schema.values === "string") {
5568
5620
  return ""; // TODO: figure out this: user code might very well fail in this case
@@ -5604,14 +5656,14 @@ function emptyOf(schema, context) {
5604
5656
  } else if (schema.type === "dateTime") {
5605
5657
  return clampDateTimeString(new Date().toISOString(), schema.options);
5606
5658
  } else if (schema.type === "color") {
5607
- var _schema$options$forma, _schema$options;
5659
+ var _schema$options$forma, _schema$options2;
5608
5660
  // Mid grey: visible against both a light and a dark canvas
5609
5661
  return Internal.color.formatColor({
5610
5662
  r: 128,
5611
5663
  g: 128,
5612
5664
  b: 128,
5613
5665
  a: 1
5614
- }, (_schema$options$forma = (_schema$options = schema.options) === null || _schema$options === void 0 ? void 0 : _schema$options.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : DEFAULT_COLOR_FORMAT);
5666
+ }, (_schema$options$forma = (_schema$options2 = schema.options) === null || _schema$options2 === void 0 ? void 0 : _schema$options2.format) !== null && _schema$options$forma !== void 0 ? _schema$options$forma : DEFAULT_COLOR_FORMAT);
5615
5667
  } else if (schema.type === "code") {
5616
5668
  return ""; // An empty editor: no language has a sensible starting snippet
5617
5669
  } else if (schema.type === "view") {
@@ -7802,7 +7854,20 @@ var buildTargetResponse = z.object({
7802
7854
  rscRuntimePath: z.string(),
7803
7855
  flightServer: z.string(),
7804
7856
  serverFnBase: z.string()
7805
- })
7857
+ }),
7858
+ /*
7859
+ * What the base layer is built from and what its chunks export, which
7860
+ * `val publish` checks a project's layer against (`BuildTarget.base` in
7861
+ * @valbuild/tanstack-build). Declared, because `z.object` DROPS a key it
7862
+ * does not name: left out, they never reached the build, and every
7863
+ * publish skipped both checks while saying the platform had not sent them.
7864
+ * Optional, for a platform that predates them.
7865
+ */
7866
+ pins: z.record(z.string(), z.string()).optional(),
7867
+ exports: z.object({
7868
+ worker: z.record(z.string(), z.array(z.string())),
7869
+ browser: z.record(z.string(), z.array(z.string()))
7870
+ }).optional()
7806
7871
  }),
7807
7872
  project: z.object({
7808
7873
  rev: z.string().nullable(),
@@ -8016,4 +8081,4 @@ function parse(schema, body, call) {
8016
8081
  return parsed.data;
8017
8082
  }
8018
8083
 
8019
- export { AA_LARGE, AA_TEXT, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, ModuleComparison, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchGroup, PatchId, PatchJSON, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SerializedVideoSchema, SharedValConfig, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_STUDIO_HEADER, ValCommit, ValDeployment, VideoOptions, VideoStreamOption, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, explainIncompatible, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, indexModule, isMimeTypeAccepted, isRemoteSchema, isSchemaSourceFixError, isSkippedSource, keyOfRecordPath, levenshtein, localeAt, memoizePerRequest, newestCommitSha, parseArtifacts, parseBuildTarget, parseCancel, parseDeclare, parseDiscard, parseJob, parseNewestCiRun, parsePress, parseProblems, parseProjectSource, parsePromote, parsePublishToken, parseRenew, parseRequestStatus, parseStatus, parseUpdateTarget, parseVerify, partitionValidationErrors, performSearch, relativeLuminance, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextImageSchema, richTextToRemirror, safeParsePatch, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
8084
+ export { AA_LARGE, AA_TEXT, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, ModuleComparison, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchGroup, PatchId, PatchJSON, PlanRefusalError, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SerializedVideoSchema, SharedValConfig, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_STUDIO_HEADER, ValCommit, ValDeployment, VideoOptions, VideoStreamOption, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, explainIncompatible, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, indexModule, isMimeTypeAccepted, isRemoteSchema, isSchemaSourceFixError, isSkippedSource, keyOfRecordPath, levenshtein, localeAt, memoizePerRequest, newestCommitSha, parseArtifacts, parseBuildTarget, parseCancel, parseDeclare, parseDiscard, parseJob, parseNewestCiRun, parsePress, parseProblems, parseProjectSource, parsePromote, parsePublishToken, parseRenew, parseRequestStatus, parseStatus, parseUpdateTarget, parseVerify, partitionValidationErrors, performSearch, relativeLuminance, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextImageSchema, richTextToRemirror, safeParsePatch, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/shared",
3
- "version": "0.144.9",
3
+ "version": "0.145.1",
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.144.0"
40
+ "@valbuild/core": "0.145.0"
41
41
  },
42
42
  "files": [
43
43
  "CHANGELOG.md",