@valbuild/core 0.137.0 → 0.138.2

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,34 @@
1
1
  # @valbuild/core
2
2
 
3
+ ## 0.138.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#760](https://github.com/valbuild/val/pull/760) [`cf3bbc8`](https://github.com/valbuild/val/commit/cf3bbc8fc89ff349aac5ab101d0b4f28164583e6) Thanks [@freekh](https://github.com/freekh)! - Files and images can now be renamed in the Studio, for local files and remote ones.
8
+
9
+ - **Rename a file in a gallery** from its properties: click the pencil next to the file name. Every field that uses the file is updated to the new name in the same step, including images inside rich text, and the dialog says how many places will change before you save.
10
+ - **Rename the file of an image or file field** with the new **Rename** button. A field that picks its file from a gallery sends you to the gallery instead, because other fields may use the same file.
11
+ - **You choose the name, Val keeps the rest.** The short hash at the end of the name (`_a1b2c`) and the file extension stay as they are, so two different files can never end up with the same name. The name is cleaned up the same way an upload's is: lower case, and characters that do not belong in a URL are dropped.
12
+ - **Renaming a local file moves it.** The file is saved under the new name and the old file is deleted when you publish, so nothing is left behind to clean up. If another field uses the same file without going through a gallery, pick the file again in that field.
13
+ - **Renaming a remote file is instant.** Remote files are stored by their content, so a published remote file only gets a new address and nothing is uploaded again.
14
+ - **Gallery images used in rich text now count as references.** A gallery file used only inside rich text could be deleted, which left the text pointing at nothing. It is now listed under the file's references and blocks the delete like any other use.
15
+
16
+ ## 0.138.0
17
+
18
+ ### Minor Changes
19
+
20
+ - [#751](https://github.com/valbuild/val/pull/751) [`5876fe0`](https://github.com/valbuild/val/commit/5876fe075fdee1f76f1cdaa2488ac52c58c894a8) Thanks [@freekh](https://github.com/freekh)! - Publishing no longer asks for a commit message by default.
21
+
22
+ - **Publish publishes.** In HTTP mode, pressing Publish goes straight to publishing, just as Save already did in local development. Where an AI model is available it writes the commit message (the button reads "Preparing" meanwhile, for up to 15 seconds). Otherwise the message is built from what changed, and names the exact path when a single field changed, e.g. `Update hero.title in /content/home.val.ts`. When several things changed, the message body lists the changed modules and their fields: up to six modules and five fields each, then how many more.
23
+ - **`studio.commitMessage: "required"`** in `s.settings()` brings the box back, redesigned. Editors can turn it on from the Studio too: Settings → Studio → "Ask for a commit message". It opens empty rather than pre-filled, so a message cannot be published unread. The AI fills it in when it can, and Publish stays disabled until there is a message. Nothing publishes on its own: the countdown that published while the AI was still writing is gone.
24
+ - **The overlay menu stays open** while the commit message popover is open, or a publish is under way. Before, moving onto the popover collapsed the menu and the popover moved with it.
25
+
26
+ ### Patch Changes
27
+
28
+ - [#752](https://github.com/valbuild/val/pull/752) [`57af895`](https://github.com/valbuild/val/commit/57af8959cc46519a405b1ed7441623f8bf2e6d27) Thanks [@freekh](https://github.com/freekh)! - `s.date()` now reports a value that is not a real `YYYY-MM-DD` day as a validation error. It used to check only `from` / `to`, and compared those as plain strings, so a typo like `"19f81-12-30"` passed a `.from("1900-01-01").to("2024-01-01")` range without a word. Impossible days such as `"2023-02-29"` are rejected too, and a `from` / `to` bound that is not a valid date is reported as a schema error.
29
+
30
+ The Studio's date field no longer shows a year below 100 (`"0050-01-01"`) as empty: it was read as 1950 and discarded.
31
+
3
32
  ## 0.137.0
4
33
 
5
34
  ### Patch Changes
@@ -39,6 +39,7 @@ import { isJson, getJsonImport, resolveJsonValues } from "./source/json.js";
39
39
  import { isExternal, hasInlineExternalEntries } from "./source/external.js";
40
40
  import { createExternalFileRef, splitExternalFileRef, isExternalFileRef } from "./source/externalRef.js";
41
41
  import { createRemoteRef } from "./source/remote.js";
42
+ import { createRenamedFilename } from "./source/filename.js";
42
43
  import { getValidationBasis, getValidationHash } from "./remote/validationBasis.js";
43
44
  import { getFileHash, hashToRemoteFileHash } from "./remote/fileHash.js";
44
45
  import { splitRemoteRef } from "./remote/splitRemoteRef.js";
@@ -54,7 +55,7 @@ export { type SerializedImageSchema, ImageSchema } from "./schema/image.js";
54
55
  export { type SerializedFileSchema, FileSchema } from "./schema/file.js";
55
56
  export { type SerializedDateSchema, DateSchema } from "./schema/date.js";
56
57
  export { type SerializedSettingsSchema, SettingsSchema, } from "./schema/settings.js";
57
- export { type SettingsSource, type AssistantSettingsSource, type LocalesSettingsSource, type AssistantAvailability, type ThemeSettingsSource, type StudioSettingsSource, type ThemeRadius, ASSISTANT_SETTINGS_MAX_LENGTH, THEME_LOGO_DIRECTORY, THEME_RADIUS_STEPS, THEME_RADIUS_LENGTHS, assistantAvailability, } from "./source/settings.js";
58
+ export { type SettingsSource, type AssistantSettingsSource, type LocalesSettingsSource, type AssistantAvailability, type ThemeSettingsSource, type StudioSettingsSource, type StudioCommitMessageMode, type ThemeRadius, ASSISTANT_SETTINGS_MAX_LENGTH, THEME_LOGO_DIRECTORY, THEME_RADIUS_STEPS, THEME_RADIUS_LENGTHS, assistantAvailability, } from "./source/settings.js";
58
59
  export { type ResolvedSettingsModule, SETTINGS_MODULE_CONVENTION, isRootModuleFilePath, resolveSettingsModule, } from "./settingsModule.js";
59
60
  export { type Locale, localeTagError, localeOfValue } from "./locale.js";
60
61
  export { type SerializedLocaleSchema, LocaleSchema } from "./schema/locale.js";
@@ -233,5 +234,6 @@ declare const Internal: {
233
234
  VAL_STATE_COOKIE: "val_state";
234
235
  VAL_SESSION_COOKIE: "val_session";
235
236
  createFilename: (data: string | null, filename: string | null, metadata: FileMetadata | ImageMetadata | undefined, sha256: string) => string | null;
237
+ createRenamedFilename: typeof createRenamedFilename;
236
238
  };
237
239
  export { Internal };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * How Val names a media file: a cleaned-up base name, the first five hex of the
3
+ * content's SHA-256, and the extension — `hero-mountains_a1b2c.jpg`.
4
+ *
5
+ * Two producers need this and must agree: an upload (`createFilename`, which
6
+ * has the bytes) and a rename (`createRenamedFilename`, which keeps the bytes
7
+ * and only changes what is in front of the hash). If they disagreed, renaming a
8
+ * file to the name it was uploaded with would give it a different name.
9
+ */
10
+ /** The `_a1b2c` a Val filename ends in, before the extension. */
11
+ export declare const FILENAME_HASH_SUFFIX_LENGTH = 5;
12
+ /**
13
+ * The part of a filename a person chose, made safe for a URL path.
14
+ *
15
+ * Lower case, with everything `encodeURIComponent` would escape dropped rather
16
+ * than escaped — a path segment that needs decoding is a path segment that gets
17
+ * decoded twice somewhere. Can return the empty string, for a name made only of
18
+ * such characters; a caller that needs a name has to refuse that.
19
+ */
20
+ export declare function sanitizeFilenameBase(base: string): string;
21
+ /**
22
+ * `base` with a trailing `_<hashPrefix>` removed, so a name that already carries
23
+ * the hash does not get it twice (`photo_a1b2c` + `a1b2c` → `photo_a1b2c`, not
24
+ * `photo_a1b2c_a1b2c`).
25
+ */
26
+ export declare function stripHashSuffix(base: string, hashPrefix: string): string;
27
+ /**
28
+ * The name a file gets when it is renamed to `newBase`.
29
+ *
30
+ * The hash and the extension are not the editor's to change: the hash keeps two
31
+ * different files from ever sharing a name, and the extension is part of a
32
+ * remote file's validation hash and of how its bytes are served. So they are
33
+ * passed in, and only the base comes from the person.
34
+ *
35
+ * Returns `null` when nothing usable is left of `newBase` after cleaning it.
36
+ */
37
+ export declare function createRenamedFilename(newBase: string, sha256: string, ext: string): string | null;
@@ -52,7 +52,21 @@ export type StudioSettingsSource = {
52
52
  * that browser and is not here.
53
53
  */
54
54
  tour?: boolean | null;
55
+ /**
56
+ * Whether publishing asks for a commit message.
57
+ *
58
+ * Unset means `"automatic"`: pressing Publish publishes, with a summary the
59
+ * AI writes where one is available and one assembled from what changed where
60
+ * it is not. Nobody is shown a box. `"required"` opens the box on every
61
+ * publish and will not publish it empty — the AI still fills it in, where
62
+ * there is one, but a person has to read it and press Publish.
63
+ *
64
+ * Only the HTTP (remote) mode commits, so this changes nothing in local
65
+ * development, where Save writes to disk.
66
+ */
67
+ commitMessage?: StudioCommitMessageMode | null;
55
68
  };
69
+ export type StudioCommitMessageMode = "automatic" | "required";
56
70
  /**
57
71
  * How the Studio looks in this project.
58
72
  *
@@ -8756,7 +8756,8 @@ function settings() {
8756
8756
  }).nullable().describe("The project's own mark, shown where Val's is in the Studio. A square-ish mark rather than a wordmark: the slot is 32px wide.")
8757
8757
  }),
8758
8758
  studio: new SettingsSchema({
8759
- tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it.")
8759
+ tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it."),
8760
+ commitMessage: enumSchema("automatic", "required").nullable().describe("Whether publishing asks for a commit message. Unset is the same as 'automatic': Publish publishes straight away, with a message the AI writes (or one listing what changed). 'required' asks every time, and will not publish an empty one.")
8760
8761
  }),
8761
8762
  locales: new SettingsSchema({
8762
8763
  // Nullable because the source type is, and because the Studio writes
@@ -10928,7 +10929,7 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10928
10929
  }, {
10929
10930
  key: "executeValidate",
10930
10931
  value: function executeValidate(path, src) {
10931
- var _this$options, _this$options2, _this$options3, _this$options4;
10932
+ var _this$options, _this$options2, _this$options3, _this$options4, _this$options5, _this$options6;
10932
10933
  var errors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
10933
10934
  path: path
10934
10935
  });
@@ -10942,7 +10943,31 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10942
10943
  });
10943
10944
  return _defineProperty({}, path, errors);
10944
10945
  }
10945
- if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.from && (_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.to) {
10946
+ // The bounds below are compared as strings, which only orders days when
10947
+ // every side is a real `YYYY-MM-DD`: "19f81-12-30" sorts between
10948
+ // "1900-01-01" and "2024-01-01" and would pass them.
10949
+ if (!isCalendarDay(src)) {
10950
+ errors.push({
10951
+ message: "Value '".concat(src, "' is not a valid date (expected YYYY-MM-DD)"),
10952
+ value: src
10953
+ });
10954
+ return _defineProperty({}, path, errors);
10955
+ }
10956
+ var bounds = [["From", (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.from], ["To", (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.to]];
10957
+ for (var _i = 0, _bounds = bounds; _i < _bounds.length; _i++) {
10958
+ var _bounds$_i = _slicedToArray(_bounds[_i], 2),
10959
+ name = _bounds$_i[0],
10960
+ bound = _bounds$_i[1];
10961
+ if (bound !== undefined && !isCalendarDay(bound)) {
10962
+ errors.push({
10963
+ message: "".concat(name, " date '").concat(bound, "' is not a valid date (expected YYYY-MM-DD)"),
10964
+ value: src,
10965
+ typeError: true
10966
+ });
10967
+ return _defineProperty({}, path, errors);
10968
+ }
10969
+ }
10970
+ if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from && (_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10946
10971
  if (this.options.from > this.options.to) {
10947
10972
  errors.push({
10948
10973
  message: "From date ".concat(this.options.from, " is after to date ").concat(this.options.to),
@@ -10955,14 +10980,14 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10955
10980
  value: src
10956
10981
  });
10957
10982
  }
10958
- } else if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from) {
10983
+ } else if ((_this$options5 = this.options) !== null && _this$options5 !== void 0 && _this$options5.from) {
10959
10984
  if (src < this.options.from) {
10960
10985
  errors.push({
10961
10986
  message: "Date is before the minimum date ".concat(this.options.from),
10962
10987
  value: src
10963
10988
  });
10964
10989
  }
10965
- } else if ((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10990
+ } else if ((_this$options6 = this.options) !== null && _this$options6 !== void 0 && _this$options6.to) {
10966
10991
  if (src > this.options.to) {
10967
10992
  errors.push({
10968
10993
  message: "Date is after the maximum date ".concat(this.options.to),
@@ -11132,6 +11157,27 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
11132
11157
  }
11133
11158
  }]);
11134
11159
  }(Schema);
11160
+ var CALENDAR_DAY = /^(\d{4})-(\d{2})-(\d{2})$/;
11161
+
11162
+ /**
11163
+ * Whether `value` is a `YYYY-MM-DD` day that exists on the calendar — so
11164
+ * "2023-02-29" and "2024-13-01" are not, even though they have the shape.
11165
+ */
11166
+ function isCalendarDay(value) {
11167
+ var match = CALENDAR_DAY.exec(value);
11168
+ if (!match) {
11169
+ return false;
11170
+ }
11171
+ var year = Number(match[1]);
11172
+ var month = Number(match[2]);
11173
+ var day = Number(match[3]);
11174
+ // Out-of-range fields roll over (Feb 30 -> Mar 2) instead of failing, so a
11175
+ // day is real only if it survives the round trip. setUTCFullYear, not
11176
+ // Date.UTC: the latter maps years 0-99 to 1900-1999.
11177
+ var date = new Date(0);
11178
+ date.setUTCFullYear(year, month - 1, day);
11179
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
11180
+ }
11135
11181
  var date = function date(options) {
11136
11182
  return new DateSchema(options);
11137
11183
  };
@@ -13311,6 +13357,63 @@ function createRemoteRef(remoteHost, _ref) {
13311
13357
  return "".concat(remoteHost, "/file/p/").concat(publicProjectId, "/b/").concat(bucket, "/v/").concat(coreVersion, "/h/").concat(validationHash, "/f/").concat(fileHash, "/p/").concat(filePath);
13312
13358
  }
13313
13359
 
13360
+ /**
13361
+ * How Val names a media file: a cleaned-up base name, the first five hex of the
13362
+ * content's SHA-256, and the extension — `hero-mountains_a1b2c.jpg`.
13363
+ *
13364
+ * Two producers need this and must agree: an upload (`createFilename`, which
13365
+ * has the bytes) and a rename (`createRenamedFilename`, which keeps the bytes
13366
+ * and only changes what is in front of the hash). If they disagreed, renaming a
13367
+ * file to the name it was uploaded with would give it a different name.
13368
+ */
13369
+
13370
+ /** The `_a1b2c` a Val filename ends in, before the extension. */
13371
+ var FILENAME_HASH_SUFFIX_LENGTH = 5;
13372
+
13373
+ /**
13374
+ * The part of a filename a person chose, made safe for a URL path.
13375
+ *
13376
+ * Lower case, with everything `encodeURIComponent` would escape dropped rather
13377
+ * than escaped — a path segment that needs decoding is a path segment that gets
13378
+ * decoded twice somewhere. Can return the empty string, for a name made only of
13379
+ * such characters; a caller that needs a name has to refuse that.
13380
+ */
13381
+ function sanitizeFilenameBase(base) {
13382
+ return encodeURIComponent(base).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
13383
+ }
13384
+
13385
+ /**
13386
+ * `base` with a trailing `_<hashPrefix>` removed, so a name that already carries
13387
+ * the hash does not get it twice (`photo_a1b2c` + `a1b2c` → `photo_a1b2c`, not
13388
+ * `photo_a1b2c_a1b2c`).
13389
+ */
13390
+ function stripHashSuffix(base, hashPrefix) {
13391
+ var pos = base.lastIndexOf("_");
13392
+ if (pos !== -1 && base.slice(pos + 1) === hashPrefix) {
13393
+ return base.slice(0, pos);
13394
+ }
13395
+ return base;
13396
+ }
13397
+
13398
+ /**
13399
+ * The name a file gets when it is renamed to `newBase`.
13400
+ *
13401
+ * The hash and the extension are not the editor's to change: the hash keeps two
13402
+ * different files from ever sharing a name, and the extension is part of a
13403
+ * remote file's validation hash and of how its bytes are served. So they are
13404
+ * passed in, and only the base comes from the person.
13405
+ *
13406
+ * Returns `null` when nothing usable is left of `newBase` after cleaning it.
13407
+ */
13408
+ function createRenamedFilename(newBase, sha256, ext) {
13409
+ var hashPrefix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
13410
+ var cleaned = sanitizeFilenameBase(stripHashSuffix(newBase.trim(), hashPrefix));
13411
+ if (cleaned === "") {
13412
+ return null;
13413
+ }
13414
+ return ext === "" ? "".concat(cleaned, "_").concat(hashPrefix) : "".concat(cleaned, "_").concat(hashPrefix, ".").concat(ext);
13415
+ }
13416
+
13314
13417
  /**
13315
13418
  * The validation basis is used in remote refs to determine if the remote content needs to be re-validated.
13316
13419
  *
@@ -14339,7 +14442,7 @@ function isPageRouter(routerId) {
14339
14442
 
14340
14443
  var corePackageJson = {
14341
14444
  name: "@valbuild/core",
14342
- version: "0.137.0",
14445
+ version: "0.138.2",
14343
14446
  "private": false,
14344
14447
  description: "Val - supercharged hard-coded content",
14345
14448
  repository: {
@@ -14526,21 +14629,17 @@ var Internal = {
14526
14629
  if (!data) {
14527
14630
  return filename;
14528
14631
  }
14529
- var shaSuffix = sha256.slice(0, 5);
14632
+ var shaSuffix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
14530
14633
  var mimeType = (_Internal$getMimeType = Internal.getMimeType(data)) !== null && _Internal$getMimeType !== void 0 ? _Internal$getMimeType : "unknown";
14531
14634
  var newExt = (_Internal$mimeTypeToF = Internal.mimeTypeToFileExt(mimeType)) !== null && _Internal$mimeTypeToF !== void 0 ? _Internal$mimeTypeToF : "unknown"; // Don't trust the file extension
14532
14635
  if (filename) {
14533
14636
  var cleanFilename = filename.split(".").slice(0, -1).join(".") || filename; // remove extension if it exists
14534
- var maybeShaSuffixPos = cleanFilename.lastIndexOf("_");
14535
- var currentShaSuffix = cleanFilename.slice(maybeShaSuffixPos + 1, cleanFilename.length);
14536
- if (currentShaSuffix === shaSuffix) {
14537
- cleanFilename = cleanFilename.slice(0, maybeShaSuffixPos);
14538
- }
14539
- var escapedFilename = encodeURIComponent(cleanFilename).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
14637
+ var escapedFilename = sanitizeFilenameBase(stripHashSuffix(cleanFilename, shaSuffix));
14540
14638
  return "".concat(escapedFilename, "_").concat(shaSuffix, ".").concat(newExt);
14541
14639
  }
14542
14640
  return "".concat(sha256, ".").concat(newExt);
14543
- }
14641
+ },
14642
+ createRenamedFilename: createRenamedFilename
14544
14643
  };
14545
14644
  function tryJsonParse(str) {
14546
14645
  try {
@@ -8758,7 +8758,8 @@ function settings() {
8758
8758
  }).nullable().describe("The project's own mark, shown where Val's is in the Studio. A square-ish mark rather than a wordmark: the slot is 32px wide.")
8759
8759
  }),
8760
8760
  studio: new SettingsSchema({
8761
- tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it.")
8761
+ tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it."),
8762
+ commitMessage: enumSchema("automatic", "required").nullable().describe("Whether publishing asks for a commit message. Unset is the same as 'automatic': Publish publishes straight away, with a message the AI writes (or one listing what changed). 'required' asks every time, and will not publish an empty one.")
8762
8763
  }),
8763
8764
  locales: new SettingsSchema({
8764
8765
  // Nullable because the source type is, and because the Studio writes
@@ -10930,7 +10931,7 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10930
10931
  }, {
10931
10932
  key: "executeValidate",
10932
10933
  value: function executeValidate(path, src) {
10933
- var _this$options, _this$options2, _this$options3, _this$options4;
10934
+ var _this$options, _this$options2, _this$options3, _this$options4, _this$options5, _this$options6;
10934
10935
  var errors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
10935
10936
  path: path
10936
10937
  });
@@ -10944,7 +10945,31 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10944
10945
  });
10945
10946
  return _defineProperty({}, path, errors);
10946
10947
  }
10947
- if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.from && (_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.to) {
10948
+ // The bounds below are compared as strings, which only orders days when
10949
+ // every side is a real `YYYY-MM-DD`: "19f81-12-30" sorts between
10950
+ // "1900-01-01" and "2024-01-01" and would pass them.
10951
+ if (!isCalendarDay(src)) {
10952
+ errors.push({
10953
+ message: "Value '".concat(src, "' is not a valid date (expected YYYY-MM-DD)"),
10954
+ value: src
10955
+ });
10956
+ return _defineProperty({}, path, errors);
10957
+ }
10958
+ var bounds = [["From", (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.from], ["To", (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.to]];
10959
+ for (var _i = 0, _bounds = bounds; _i < _bounds.length; _i++) {
10960
+ var _bounds$_i = _slicedToArray(_bounds[_i], 2),
10961
+ name = _bounds$_i[0],
10962
+ bound = _bounds$_i[1];
10963
+ if (bound !== undefined && !isCalendarDay(bound)) {
10964
+ errors.push({
10965
+ message: "".concat(name, " date '").concat(bound, "' is not a valid date (expected YYYY-MM-DD)"),
10966
+ value: src,
10967
+ typeError: true
10968
+ });
10969
+ return _defineProperty({}, path, errors);
10970
+ }
10971
+ }
10972
+ if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from && (_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10948
10973
  if (this.options.from > this.options.to) {
10949
10974
  errors.push({
10950
10975
  message: "From date ".concat(this.options.from, " is after to date ").concat(this.options.to),
@@ -10957,14 +10982,14 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10957
10982
  value: src
10958
10983
  });
10959
10984
  }
10960
- } else if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from) {
10985
+ } else if ((_this$options5 = this.options) !== null && _this$options5 !== void 0 && _this$options5.from) {
10961
10986
  if (src < this.options.from) {
10962
10987
  errors.push({
10963
10988
  message: "Date is before the minimum date ".concat(this.options.from),
10964
10989
  value: src
10965
10990
  });
10966
10991
  }
10967
- } else if ((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10992
+ } else if ((_this$options6 = this.options) !== null && _this$options6 !== void 0 && _this$options6.to) {
10968
10993
  if (src > this.options.to) {
10969
10994
  errors.push({
10970
10995
  message: "Date is after the maximum date ".concat(this.options.to),
@@ -11134,6 +11159,27 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
11134
11159
  }
11135
11160
  }]);
11136
11161
  }(Schema);
11162
+ var CALENDAR_DAY = /^(\d{4})-(\d{2})-(\d{2})$/;
11163
+
11164
+ /**
11165
+ * Whether `value` is a `YYYY-MM-DD` day that exists on the calendar — so
11166
+ * "2023-02-29" and "2024-13-01" are not, even though they have the shape.
11167
+ */
11168
+ function isCalendarDay(value) {
11169
+ var match = CALENDAR_DAY.exec(value);
11170
+ if (!match) {
11171
+ return false;
11172
+ }
11173
+ var year = Number(match[1]);
11174
+ var month = Number(match[2]);
11175
+ var day = Number(match[3]);
11176
+ // Out-of-range fields roll over (Feb 30 -> Mar 2) instead of failing, so a
11177
+ // day is real only if it survives the round trip. setUTCFullYear, not
11178
+ // Date.UTC: the latter maps years 0-99 to 1900-1999.
11179
+ var date = new Date(0);
11180
+ date.setUTCFullYear(year, month - 1, day);
11181
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
11182
+ }
11137
11183
  var date = function date(options) {
11138
11184
  return new DateSchema(options);
11139
11185
  };
@@ -13313,6 +13359,63 @@ function createRemoteRef(remoteHost, _ref) {
13313
13359
  return "".concat(remoteHost, "/file/p/").concat(publicProjectId, "/b/").concat(bucket, "/v/").concat(coreVersion, "/h/").concat(validationHash, "/f/").concat(fileHash, "/p/").concat(filePath);
13314
13360
  }
13315
13361
 
13362
+ /**
13363
+ * How Val names a media file: a cleaned-up base name, the first five hex of the
13364
+ * content's SHA-256, and the extension — `hero-mountains_a1b2c.jpg`.
13365
+ *
13366
+ * Two producers need this and must agree: an upload (`createFilename`, which
13367
+ * has the bytes) and a rename (`createRenamedFilename`, which keeps the bytes
13368
+ * and only changes what is in front of the hash). If they disagreed, renaming a
13369
+ * file to the name it was uploaded with would give it a different name.
13370
+ */
13371
+
13372
+ /** The `_a1b2c` a Val filename ends in, before the extension. */
13373
+ var FILENAME_HASH_SUFFIX_LENGTH = 5;
13374
+
13375
+ /**
13376
+ * The part of a filename a person chose, made safe for a URL path.
13377
+ *
13378
+ * Lower case, with everything `encodeURIComponent` would escape dropped rather
13379
+ * than escaped — a path segment that needs decoding is a path segment that gets
13380
+ * decoded twice somewhere. Can return the empty string, for a name made only of
13381
+ * such characters; a caller that needs a name has to refuse that.
13382
+ */
13383
+ function sanitizeFilenameBase(base) {
13384
+ return encodeURIComponent(base).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
13385
+ }
13386
+
13387
+ /**
13388
+ * `base` with a trailing `_<hashPrefix>` removed, so a name that already carries
13389
+ * the hash does not get it twice (`photo_a1b2c` + `a1b2c` → `photo_a1b2c`, not
13390
+ * `photo_a1b2c_a1b2c`).
13391
+ */
13392
+ function stripHashSuffix(base, hashPrefix) {
13393
+ var pos = base.lastIndexOf("_");
13394
+ if (pos !== -1 && base.slice(pos + 1) === hashPrefix) {
13395
+ return base.slice(0, pos);
13396
+ }
13397
+ return base;
13398
+ }
13399
+
13400
+ /**
13401
+ * The name a file gets when it is renamed to `newBase`.
13402
+ *
13403
+ * The hash and the extension are not the editor's to change: the hash keeps two
13404
+ * different files from ever sharing a name, and the extension is part of a
13405
+ * remote file's validation hash and of how its bytes are served. So they are
13406
+ * passed in, and only the base comes from the person.
13407
+ *
13408
+ * Returns `null` when nothing usable is left of `newBase` after cleaning it.
13409
+ */
13410
+ function createRenamedFilename(newBase, sha256, ext) {
13411
+ var hashPrefix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
13412
+ var cleaned = sanitizeFilenameBase(stripHashSuffix(newBase.trim(), hashPrefix));
13413
+ if (cleaned === "") {
13414
+ return null;
13415
+ }
13416
+ return ext === "" ? "".concat(cleaned, "_").concat(hashPrefix) : "".concat(cleaned, "_").concat(hashPrefix, ".").concat(ext);
13417
+ }
13418
+
13316
13419
  /**
13317
13420
  * The validation basis is used in remote refs to determine if the remote content needs to be re-validated.
13318
13421
  *
@@ -14341,7 +14444,7 @@ function isPageRouter(routerId) {
14341
14444
 
14342
14445
  var corePackageJson = {
14343
14446
  name: "@valbuild/core",
14344
- version: "0.137.0",
14447
+ version: "0.138.2",
14345
14448
  "private": false,
14346
14449
  description: "Val - supercharged hard-coded content",
14347
14450
  repository: {
@@ -14528,21 +14631,17 @@ var Internal = {
14528
14631
  if (!data) {
14529
14632
  return filename;
14530
14633
  }
14531
- var shaSuffix = sha256.slice(0, 5);
14634
+ var shaSuffix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
14532
14635
  var mimeType = (_Internal$getMimeType = Internal.getMimeType(data)) !== null && _Internal$getMimeType !== void 0 ? _Internal$getMimeType : "unknown";
14533
14636
  var newExt = (_Internal$mimeTypeToF = Internal.mimeTypeToFileExt(mimeType)) !== null && _Internal$mimeTypeToF !== void 0 ? _Internal$mimeTypeToF : "unknown"; // Don't trust the file extension
14534
14637
  if (filename) {
14535
14638
  var cleanFilename = filename.split(".").slice(0, -1).join(".") || filename; // remove extension if it exists
14536
- var maybeShaSuffixPos = cleanFilename.lastIndexOf("_");
14537
- var currentShaSuffix = cleanFilename.slice(maybeShaSuffixPos + 1, cleanFilename.length);
14538
- if (currentShaSuffix === shaSuffix) {
14539
- cleanFilename = cleanFilename.slice(0, maybeShaSuffixPos);
14540
- }
14541
- var escapedFilename = encodeURIComponent(cleanFilename).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
14639
+ var escapedFilename = sanitizeFilenameBase(stripHashSuffix(cleanFilename, shaSuffix));
14542
14640
  return "".concat(escapedFilename, "_").concat(shaSuffix, ".").concat(newExt);
14543
14641
  }
14544
14642
  return "".concat(sha256, ".").concat(newExt);
14545
- }
14643
+ },
14644
+ createRenamedFilename: createRenamedFilename
14546
14645
  };
14547
14646
  function tryJsonParse(str) {
14548
14647
  try {
@@ -8758,7 +8758,8 @@ function settings() {
8758
8758
  }).nullable().describe("The project's own mark, shown where Val's is in the Studio. A square-ish mark rather than a wordmark: the slot is 32px wide.")
8759
8759
  }),
8760
8760
  studio: new SettingsSchema({
8761
- tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it.")
8761
+ tour: _boolean().nullable().describe("Whether editors are offered the guided tour of the Studio. Unset means yes. Off hides the offer for everyone on this project — the tour stays in Quick actions for anyone who wants it."),
8762
+ commitMessage: enumSchema("automatic", "required").nullable().describe("Whether publishing asks for a commit message. Unset is the same as 'automatic': Publish publishes straight away, with a message the AI writes (or one listing what changed). 'required' asks every time, and will not publish an empty one.")
8762
8763
  }),
8763
8764
  locales: new SettingsSchema({
8764
8765
  // Nullable because the source type is, and because the Studio writes
@@ -10930,7 +10931,7 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10930
10931
  }, {
10931
10932
  key: "executeValidate",
10932
10933
  value: function executeValidate(path, src) {
10933
- var _this$options, _this$options2, _this$options3, _this$options4;
10934
+ var _this$options, _this$options2, _this$options3, _this$options4, _this$options5, _this$options6;
10934
10935
  var errors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
10935
10936
  path: path
10936
10937
  });
@@ -10944,7 +10945,31 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10944
10945
  });
10945
10946
  return _defineProperty({}, path, errors);
10946
10947
  }
10947
- if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.from && (_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.to) {
10948
+ // The bounds below are compared as strings, which only orders days when
10949
+ // every side is a real `YYYY-MM-DD`: "19f81-12-30" sorts between
10950
+ // "1900-01-01" and "2024-01-01" and would pass them.
10951
+ if (!isCalendarDay(src)) {
10952
+ errors.push({
10953
+ message: "Value '".concat(src, "' is not a valid date (expected YYYY-MM-DD)"),
10954
+ value: src
10955
+ });
10956
+ return _defineProperty({}, path, errors);
10957
+ }
10958
+ var bounds = [["From", (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.from], ["To", (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.to]];
10959
+ for (var _i = 0, _bounds = bounds; _i < _bounds.length; _i++) {
10960
+ var _bounds$_i = _slicedToArray(_bounds[_i], 2),
10961
+ name = _bounds$_i[0],
10962
+ bound = _bounds$_i[1];
10963
+ if (bound !== undefined && !isCalendarDay(bound)) {
10964
+ errors.push({
10965
+ message: "".concat(name, " date '").concat(bound, "' is not a valid date (expected YYYY-MM-DD)"),
10966
+ value: src,
10967
+ typeError: true
10968
+ });
10969
+ return _defineProperty({}, path, errors);
10970
+ }
10971
+ }
10972
+ if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from && (_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10948
10973
  if (this.options.from > this.options.to) {
10949
10974
  errors.push({
10950
10975
  message: "From date ".concat(this.options.from, " is after to date ").concat(this.options.to),
@@ -10957,14 +10982,14 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
10957
10982
  value: src
10958
10983
  });
10959
10984
  }
10960
- } else if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.from) {
10985
+ } else if ((_this$options5 = this.options) !== null && _this$options5 !== void 0 && _this$options5.from) {
10961
10986
  if (src < this.options.from) {
10962
10987
  errors.push({
10963
10988
  message: "Date is before the minimum date ".concat(this.options.from),
10964
10989
  value: src
10965
10990
  });
10966
10991
  }
10967
- } else if ((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.to) {
10992
+ } else if ((_this$options6 = this.options) !== null && _this$options6 !== void 0 && _this$options6.to) {
10968
10993
  if (src > this.options.to) {
10969
10994
  errors.push({
10970
10995
  message: "Date is after the maximum date ".concat(this.options.to),
@@ -11134,6 +11159,27 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
11134
11159
  }
11135
11160
  }]);
11136
11161
  }(Schema);
11162
+ var CALENDAR_DAY = /^(\d{4})-(\d{2})-(\d{2})$/;
11163
+
11164
+ /**
11165
+ * Whether `value` is a `YYYY-MM-DD` day that exists on the calendar — so
11166
+ * "2023-02-29" and "2024-13-01" are not, even though they have the shape.
11167
+ */
11168
+ function isCalendarDay(value) {
11169
+ var match = CALENDAR_DAY.exec(value);
11170
+ if (!match) {
11171
+ return false;
11172
+ }
11173
+ var year = Number(match[1]);
11174
+ var month = Number(match[2]);
11175
+ var day = Number(match[3]);
11176
+ // Out-of-range fields roll over (Feb 30 -> Mar 2) instead of failing, so a
11177
+ // day is real only if it survives the round trip. setUTCFullYear, not
11178
+ // Date.UTC: the latter maps years 0-99 to 1900-1999.
11179
+ var date = new Date(0);
11180
+ date.setUTCFullYear(year, month - 1, day);
11181
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
11182
+ }
11137
11183
  var date = function date(options) {
11138
11184
  return new DateSchema(options);
11139
11185
  };
@@ -13313,6 +13359,63 @@ function createRemoteRef(remoteHost, _ref) {
13313
13359
  return "".concat(remoteHost, "/file/p/").concat(publicProjectId, "/b/").concat(bucket, "/v/").concat(coreVersion, "/h/").concat(validationHash, "/f/").concat(fileHash, "/p/").concat(filePath);
13314
13360
  }
13315
13361
 
13362
+ /**
13363
+ * How Val names a media file: a cleaned-up base name, the first five hex of the
13364
+ * content's SHA-256, and the extension — `hero-mountains_a1b2c.jpg`.
13365
+ *
13366
+ * Two producers need this and must agree: an upload (`createFilename`, which
13367
+ * has the bytes) and a rename (`createRenamedFilename`, which keeps the bytes
13368
+ * and only changes what is in front of the hash). If they disagreed, renaming a
13369
+ * file to the name it was uploaded with would give it a different name.
13370
+ */
13371
+
13372
+ /** The `_a1b2c` a Val filename ends in, before the extension. */
13373
+ var FILENAME_HASH_SUFFIX_LENGTH = 5;
13374
+
13375
+ /**
13376
+ * The part of a filename a person chose, made safe for a URL path.
13377
+ *
13378
+ * Lower case, with everything `encodeURIComponent` would escape dropped rather
13379
+ * than escaped — a path segment that needs decoding is a path segment that gets
13380
+ * decoded twice somewhere. Can return the empty string, for a name made only of
13381
+ * such characters; a caller that needs a name has to refuse that.
13382
+ */
13383
+ function sanitizeFilenameBase(base) {
13384
+ return encodeURIComponent(base).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
13385
+ }
13386
+
13387
+ /**
13388
+ * `base` with a trailing `_<hashPrefix>` removed, so a name that already carries
13389
+ * the hash does not get it twice (`photo_a1b2c` + `a1b2c` → `photo_a1b2c`, not
13390
+ * `photo_a1b2c_a1b2c`).
13391
+ */
13392
+ function stripHashSuffix(base, hashPrefix) {
13393
+ var pos = base.lastIndexOf("_");
13394
+ if (pos !== -1 && base.slice(pos + 1) === hashPrefix) {
13395
+ return base.slice(0, pos);
13396
+ }
13397
+ return base;
13398
+ }
13399
+
13400
+ /**
13401
+ * The name a file gets when it is renamed to `newBase`.
13402
+ *
13403
+ * The hash and the extension are not the editor's to change: the hash keeps two
13404
+ * different files from ever sharing a name, and the extension is part of a
13405
+ * remote file's validation hash and of how its bytes are served. So they are
13406
+ * passed in, and only the base comes from the person.
13407
+ *
13408
+ * Returns `null` when nothing usable is left of `newBase` after cleaning it.
13409
+ */
13410
+ function createRenamedFilename(newBase, sha256, ext) {
13411
+ var hashPrefix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
13412
+ var cleaned = sanitizeFilenameBase(stripHashSuffix(newBase.trim(), hashPrefix));
13413
+ if (cleaned === "") {
13414
+ return null;
13415
+ }
13416
+ return ext === "" ? "".concat(cleaned, "_").concat(hashPrefix) : "".concat(cleaned, "_").concat(hashPrefix, ".").concat(ext);
13417
+ }
13418
+
13316
13419
  /**
13317
13420
  * The validation basis is used in remote refs to determine if the remote content needs to be re-validated.
13318
13421
  *
@@ -14341,7 +14444,7 @@ function isPageRouter(routerId) {
14341
14444
 
14342
14445
  var corePackageJson = {
14343
14446
  name: "@valbuild/core",
14344
- version: "0.137.0",
14447
+ version: "0.138.2",
14345
14448
  "private": false,
14346
14449
  description: "Val - supercharged hard-coded content",
14347
14450
  repository: {
@@ -14528,21 +14631,17 @@ var Internal = {
14528
14631
  if (!data) {
14529
14632
  return filename;
14530
14633
  }
14531
- var shaSuffix = sha256.slice(0, 5);
14634
+ var shaSuffix = sha256.slice(0, FILENAME_HASH_SUFFIX_LENGTH);
14532
14635
  var mimeType = (_Internal$getMimeType = Internal.getMimeType(data)) !== null && _Internal$getMimeType !== void 0 ? _Internal$getMimeType : "unknown";
14533
14636
  var newExt = (_Internal$mimeTypeToF = Internal.mimeTypeToFileExt(mimeType)) !== null && _Internal$mimeTypeToF !== void 0 ? _Internal$mimeTypeToF : "unknown"; // Don't trust the file extension
14534
14637
  if (filename) {
14535
14638
  var cleanFilename = filename.split(".").slice(0, -1).join(".") || filename; // remove extension if it exists
14536
- var maybeShaSuffixPos = cleanFilename.lastIndexOf("_");
14537
- var currentShaSuffix = cleanFilename.slice(maybeShaSuffixPos + 1, cleanFilename.length);
14538
- if (currentShaSuffix === shaSuffix) {
14539
- cleanFilename = cleanFilename.slice(0, maybeShaSuffixPos);
14540
- }
14541
- var escapedFilename = encodeURIComponent(cleanFilename).replace(/%[0-9A-Fa-f]{2}/g, "").toLowerCase();
14639
+ var escapedFilename = sanitizeFilenameBase(stripHashSuffix(cleanFilename, shaSuffix));
14542
14640
  return "".concat(escapedFilename, "_").concat(shaSuffix, ".").concat(newExt);
14543
14641
  }
14544
14642
  return "".concat(sha256, ".").concat(newExt);
14545
- }
14643
+ },
14644
+ createRenamedFilename: createRenamedFilename
14546
14645
  };
14547
14646
  function tryJsonParse(str) {
14548
14647
  try {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('./index-fed897a2.cjs.dev.js');
5
+ var dist_valbuildCore = require('./index-8e33ef62.cjs.dev.js');
6
6
  require('./result-bb1f436e.cjs.dev.js');
7
7
 
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('./index-481a7dcd.cjs.prod.js');
5
+ var dist_valbuildCore = require('./index-87b5aa27.cjs.prod.js');
6
6
  require('./result-787e35f6.cjs.prod.js');
7
7
 
8
8
 
@@ -1,2 +1,2 @@
1
- export { v as ASSISTANT_SETTINGS_MAX_LENGTH, A as ArraySchema, B as BooleanSchema, Y as CODE_LANGUAGES, Z as COLOR_FORMATS, X as CodeSchema, W as ColorSchema, e as DEFAULT_APP_HOST, $ as DEFAULT_COLOR_FORMAT, D as DEFAULT_CONTENT_HOST, f as DEFAULT_STATIC_HOST, n as DEFAULT_VAL_REMOTE_HOST, t as DateSchema, a0 as DateTimeSchema, a6 as DiscriminatedUnionSchema, a7 as EnumSchema, F as FATAL_ERROR_TYPES, r as FileSchema, G as GenericSelector, q as ImageSchema, I as Internal, a1 as KeyOfSchema, a8 as LiteralSchema, L as LocaleSchema, M as ModuleFilePathSep, N as NumberSchema, O as ObjectSchema, R as RecordSchema, a5 as RichTextSchema, a4 as RouteSchema, z as SETTINGS_MODULE_CONVENTION, S as Schema, u as SettingsSchema, p as StringSchema, T as THEME_LOGO_DIRECTORY, x as THEME_RADIUS_LENGTHS, w as THEME_RADIUS_STEPS, am as UNSAFE_URL_SCHEMES, V as VAL_EXTENSION, a2 as ValViewSchema, y as assistantAvailability, j as computeSourcesSha, h as computeValModuleShas, K as declaredKeySetOf, o as derefPatch, ai as describeSchemeRejection, a9 as deserializeSchema, U as discriminatedUnionBranchOf, g as extractValModules, ag as getSourcePathFromRoute, l as hasMediaSchema, k as hasRemoteFileSchema, i as initVal, aj as isCheckableScheme, ab as isInlineRender, ah as isPageRouter, C as isRootModuleFilePath, a3 as isValViewSource, J as localeOfValue, H as localeTagError, Q as missingDeclaredKeys, m as modules, ac as parseNextJsRoutePattern, ad as parseTanStackRoutePattern, aa as previewScope, ak as rejectScheme, E as resolveSettingsModule, al as schemeOf, ae as tanStackSegmentsOfRoutePath, af as validateUrlAgainstPattern } from './index-42ab6700.esm.js';
1
+ export { v as ASSISTANT_SETTINGS_MAX_LENGTH, A as ArraySchema, B as BooleanSchema, Y as CODE_LANGUAGES, Z as COLOR_FORMATS, X as CodeSchema, W as ColorSchema, e as DEFAULT_APP_HOST, $ as DEFAULT_COLOR_FORMAT, D as DEFAULT_CONTENT_HOST, f as DEFAULT_STATIC_HOST, n as DEFAULT_VAL_REMOTE_HOST, t as DateSchema, a0 as DateTimeSchema, a6 as DiscriminatedUnionSchema, a7 as EnumSchema, F as FATAL_ERROR_TYPES, r as FileSchema, G as GenericSelector, q as ImageSchema, I as Internal, a1 as KeyOfSchema, a8 as LiteralSchema, L as LocaleSchema, M as ModuleFilePathSep, N as NumberSchema, O as ObjectSchema, R as RecordSchema, a5 as RichTextSchema, a4 as RouteSchema, z as SETTINGS_MODULE_CONVENTION, S as Schema, u as SettingsSchema, p as StringSchema, T as THEME_LOGO_DIRECTORY, x as THEME_RADIUS_LENGTHS, w as THEME_RADIUS_STEPS, am as UNSAFE_URL_SCHEMES, V as VAL_EXTENSION, a2 as ValViewSchema, y as assistantAvailability, j as computeSourcesSha, h as computeValModuleShas, K as declaredKeySetOf, o as derefPatch, ai as describeSchemeRejection, a9 as deserializeSchema, U as discriminatedUnionBranchOf, g as extractValModules, ag as getSourcePathFromRoute, l as hasMediaSchema, k as hasRemoteFileSchema, i as initVal, aj as isCheckableScheme, ab as isInlineRender, ah as isPageRouter, C as isRootModuleFilePath, a3 as isValViewSource, J as localeOfValue, H as localeTagError, Q as missingDeclaredKeys, m as modules, ac as parseNextJsRoutePattern, ad as parseTanStackRoutePattern, aa as previewScope, ak as rejectScheme, E as resolveSettingsModule, al as schemeOf, ae as tanStackSegmentsOfRoutePath, af as validateUrlAgainstPattern } from './index-36b5e0cb.esm.js';
2
2
  import './result-daff1cae.esm.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/core",
3
- "version": "0.137.0",
3
+ "version": "0.138.2",
4
4
  "private": false,
5
5
  "description": "Val - supercharged hard-coded content",
6
6
  "repository": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('../../dist/index-fed897a2.cjs.dev.js');
5
+ var dist_valbuildCore = require('../../dist/index-8e33ef62.cjs.dev.js');
6
6
  var result = require('../../dist/result-bb1f436e.cjs.dev.js');
7
7
  var util = require('../../dist/util-b213092b.cjs.dev.js');
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('../../dist/index-481a7dcd.cjs.prod.js');
5
+ var dist_valbuildCore = require('../../dist/index-87b5aa27.cjs.prod.js');
6
6
  var result = require('../../dist/result-787e35f6.cjs.prod.js');
7
7
  var util = require('../../dist/util-030d8a1f.cjs.prod.js');
8
8
 
@@ -1,5 +1,5 @@
1
- import { _ as _typeof, a as _slicedToArray, P as PatchError, s as splitModuleFilePathAndModulePath, b as _createClass, c as _classCallCheck, d as _toConsumableArray } from '../../dist/index-42ab6700.esm.js';
2
- export { P as PatchError } from '../../dist/index-42ab6700.esm.js';
1
+ import { _ as _typeof, a as _slicedToArray, P as PatchError, s as splitModuleFilePathAndModulePath, b as _createClass, c as _classCallCheck, d as _toConsumableArray } from '../../dist/index-36b5e0cb.esm.js';
2
+ export { P as PatchError } from '../../dist/index-36b5e0cb.esm.js';
3
3
  import { f as isNonEmpty, e as err, o as ok, m as map, g as flatMap, i as isErr, h as flatMapReduce, j as filterOrElse, k as mapErr, l as map$1, n as all, p as flatten, q as allT } from '../../dist/result-daff1cae.esm.js';
4
4
  import { p as pipe } from '../../dist/util-18613e99.esm.js';
5
5