@valbuild/core 0.147.0 → 0.148.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,37 @@
1
1
  # @valbuild/core
2
2
 
3
+ ## 0.148.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#889](https://github.com/valbuild/val/pull/889) [`dc7c8cc`](https://github.com/valbuild/val/commit/dc7c8ccd82f643e662d00225fabec411b5d39e3a) Thanks [@freekh](https://github.com/freekh)! - Val is quieter in your app's console. Errors and warnings you can act on still
8
+ print, now prefixed with `[val]` so you can filter them. Val's own debug
9
+ output, which used to reach your terminal and browser console, is now off by
10
+ default. That includes the `Invalid JWT` line that printed on every request
11
+ with an expired session cookie, the "verifying draft mode" and polling notices,
12
+ and the Studio's sync and WebSocket chatter.
13
+
14
+ To turn the debug output back on, for example when reporting a bug:
15
+
16
+ - on the server, set `VAL_DEBUG=1`
17
+ - in the browser, run `localStorage.setItem("val:debug", "1")` in the console.
18
+ It takes effect immediately, with no reload. Remove the key to turn it off
19
+ again.
20
+
21
+ ## 0.148.0
22
+
23
+ ### Patch Changes
24
+
25
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - Remote files served from a project's own site (addresses like
26
+ `https://www.acme.no/_val/file/…`) are now checked for whether that address
27
+ still serves the project. When a custom domain has been removed or moved to
28
+ another project, the image or file is reported, and **Fix** on the Studio's
29
+ Validate page — or `val validate --fix` — points it at the project's permanent
30
+ `<id>.valstart.dev` address. Nothing is uploaded or downloaded: only the address
31
+ changes.
32
+
33
+ Remote file addresses with a `/_val` prefix after the host are now recognised.
34
+
3
35
  ## 0.147.0
4
36
 
5
37
  ### Minor Changes
@@ -105,6 +105,7 @@ export { getSourcePathFromRoute, isPageRouter, routePatternOf, } from "./getSour
105
105
  export { describeSchemeRejection, isCheckableScheme, rejectScheme, schemeOf, UNSAFE_URL_SCHEMES, } from "./externalUrlSchemes.js";
106
106
  export type { ExternalUrlSchemePolicy, SchemeRejection, } from "./externalUrlSchemes.js";
107
107
  import { describeSchemeRejection, isCheckableScheme, rejectScheme, schemeOf } from "./externalUrlSchemes.js";
108
+ import { isDebugEnabled } from "./log.js";
108
109
  export declare const FATAL_ERROR_TYPES: readonly ["no-schema", "no-source", "invalid-id", "no-module", "invalid-patch"];
109
110
  export type FatalErrorType = (typeof FATAL_ERROR_TYPES)[number];
110
111
  export declare const DEFAULT_CONTENT_HOST = "https://content.val.build";
@@ -138,6 +139,15 @@ export declare const DEFAULT_APP_HOST = "https://admin.val.build";
138
139
  */
139
140
  export declare const DEFAULT_STATIC_HOST = "https://content.val.build/v1/static";
140
141
  declare const Internal: {
142
+ /** Val's console output. See `log.ts` for which levels print, and when. */
143
+ log: {
144
+ error(...args: unknown[]): void;
145
+ warn(...args: unknown[]): void;
146
+ info(...args: unknown[]): void;
147
+ debug(...args: unknown[]): void;
148
+ };
149
+ isDebugEnabled: typeof isDebugEnabled;
150
+ VAL_DEBUG_STORAGE_KEY: string;
141
151
  VERSION: {
142
152
  core: string;
143
153
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Val's console output, and the one place that decides what reaches it.
3
+ *
4
+ * Val runs inside someone else's app: the server in their dev server and their
5
+ * production logs, the Studio in their browser tab. Everything Val prints lands
6
+ * in a console that belongs to a developer who did not write the code printing
7
+ * it, so the levels are split by who the line is FOR:
8
+ *
9
+ * - `error` and `warn` are for that developer -- something broke, or something
10
+ * they can fix -- and always print.
11
+ * - `info` and `debug` are for whoever is debugging Val, and print only when
12
+ * asked for: `VAL_DEBUG=1` in the environment of a server, or
13
+ * `localStorage.setItem("val:debug", "1")` in a browser. Both are read on
14
+ * every call, so turning it on in a live tab needs no reload.
15
+ *
16
+ * In Node `console.debug` IS `console.log`, so a bare `console.debug` is not
17
+ * quiet on a server: it went to the developer's terminal on every request.
18
+ * That is why `no-console` is on for the packages that run in a host app, and
19
+ * this file is the exemption.
20
+ *
21
+ * Every line gets a `[val]` prefix, so a developer can filter Val out (or in).
22
+ * Arguments are otherwise passed through as they are, so an `Error` still
23
+ * prints with its stack.
24
+ */
25
+ /** The localStorage key that turns `debug` and `info` on in a browser. */
26
+ export declare const VAL_DEBUG_STORAGE_KEY = "val:debug";
27
+ export declare function isDebugEnabled(): boolean;
28
+ export declare const log: {
29
+ error(...args: unknown[]): void;
30
+ warn(...args: unknown[]): void;
31
+ info(...args: unknown[]): void;
32
+ debug(...args: unknown[]): void;
33
+ };
@@ -1,3 +1,2 @@
1
- import { Buffer } from "buffer";
2
1
  export declare function hashToRemoteFileHash(hash: string): string;
3
- export declare function getFileHash(text: Buffer): string;
2
+ export declare function getFileHash(bytes: Uint8Array): string;
@@ -1,2 +1,2 @@
1
- export declare const ValidationFix: readonly ["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", "video:add-metadata", "video:upload-remote", "video:download-remote", "videos:add-metadata", "videos:check-remote", "videos:upload-remote", "keyof:check-keys", "image:check-gallery", "file:check-gallery", "video:check-gallery", "router:check-route", "locale:check-locale", "router:check-locale-param", "images:check-unique-folder", "files:check-unique-folder", "images:check-all-files", "files:check-all-files", "videos:check-unique-folder", "videos:check-all-files", "jsonValues:extract-entry", "record:fill-keys", "external:upload", "view:check-module"];
1
+ export declare const ValidationFix: readonly ["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", "video:add-metadata", "video:upload-remote", "video:download-remote", "videos:add-metadata", "videos:check-remote", "videos:upload-remote", "keyof:check-keys", "image:check-gallery", "file:check-gallery", "video:check-gallery", "router:check-route", "locale:check-locale", "router:check-locale-param", "images:check-unique-folder", "files:check-unique-folder", "images:check-all-files", "files:check-all-files", "videos:check-unique-folder", "videos:check-all-files", "jsonValues:extract-entry", "record:fill-keys", "external:upload", "view:check-module", "remote:rewrite-host"];
2
2
  export type ValidationFix = (typeof ValidationFix)[number];
@@ -2764,6 +2764,122 @@ var discriminatedUnion = function discriminatedUnion(key) {
2764
2764
  return new DiscriminatedUnionSchema(key, objects);
2765
2765
  };
2766
2766
 
2767
+ function _toArray(r) {
2768
+ return _arrayWithHoles(r) || _iterableToArray(r) || result._unsupportedIterableToArray(r) || _nonIterableRest();
2769
+ }
2770
+
2771
+ /**
2772
+ * Val's console output, and the one place that decides what reaches it.
2773
+ *
2774
+ * Val runs inside someone else's app: the server in their dev server and their
2775
+ * production logs, the Studio in their browser tab. Everything Val prints lands
2776
+ * in a console that belongs to a developer who did not write the code printing
2777
+ * it, so the levels are split by who the line is FOR:
2778
+ *
2779
+ * - `error` and `warn` are for that developer -- something broke, or something
2780
+ * they can fix -- and always print.
2781
+ * - `info` and `debug` are for whoever is debugging Val, and print only when
2782
+ * asked for: `VAL_DEBUG=1` in the environment of a server, or
2783
+ * `localStorage.setItem("val:debug", "1")` in a browser. Both are read on
2784
+ * every call, so turning it on in a live tab needs no reload.
2785
+ *
2786
+ * In Node `console.debug` IS `console.log`, so a bare `console.debug` is not
2787
+ * quiet on a server: it went to the developer's terminal on every request.
2788
+ * That is why `no-console` is on for the packages that run in a host app, and
2789
+ * this file is the exemption.
2790
+ *
2791
+ * Every line gets a `[val]` prefix, so a developer can filter Val out (or in).
2792
+ * Arguments are otherwise passed through as they are, so an `Error` still
2793
+ * prints with its stack.
2794
+ */
2795
+
2796
+ var PREFIX = "[val]";
2797
+
2798
+ /** The localStorage key that turns `debug` and `info` on in a browser. */
2799
+ var VAL_DEBUG_STORAGE_KEY = "val:debug";
2800
+ function isOn(value) {
2801
+ return value !== undefined && value !== null && value !== "" && value !== "0" && value !== "false";
2802
+ }
2803
+ function fromEnv() {
2804
+ var _process$env;
2805
+ // `typeof` first: a browser bundle may have no `process` at all.
2806
+ if (typeof process === "undefined") {
2807
+ return undefined;
2808
+ }
2809
+ return (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.VAL_DEBUG;
2810
+ }
2811
+ function fromLocalStorage() {
2812
+ // Not in Node, even where it has a `localStorage`: from Node 25 merely
2813
+ // touching it without `--localstorage-file` prints a warning of its own.
2814
+ if (!("window" in globalThis)) {
2815
+ return undefined;
2816
+ }
2817
+ try {
2818
+ var storage = Reflect.get(globalThis, "localStorage");
2819
+ if (_typeof(storage) === "object" && storage !== null && "getItem" in storage && typeof storage.getItem === "function") {
2820
+ var value = storage.getItem(VAL_DEBUG_STORAGE_KEY);
2821
+ return typeof value === "string" ? value : null;
2822
+ }
2823
+ } catch (_unused) {
2824
+ // A sandboxed frame or blocked site data throws on access.
2825
+ }
2826
+ return undefined;
2827
+ }
2828
+ function isDebugEnabled() {
2829
+ return isOn(fromEnv()) || isOn(fromLocalStorage());
2830
+ }
2831
+ function withPrefix(args) {
2832
+ var _args = _toArray(args),
2833
+ first = _args[0],
2834
+ rest = result._arrayLikeToArray(_args).slice(1);
2835
+ if (typeof first === "string") {
2836
+ if (/^\[val\]/i.test(first)) {
2837
+ return args;
2838
+ }
2839
+ return ["".concat(PREFIX, " ").concat(first)].concat(_toConsumableArray(rest));
2840
+ }
2841
+ return [PREFIX].concat(_toConsumableArray(args));
2842
+ }
2843
+
2844
+ /*
2845
+ * `console` is looked up on every call rather than captured, so a test that
2846
+ * spies on `console.warn` after this module loaded still sees the call.
2847
+ */
2848
+ var log = {
2849
+ error: function error() {
2850
+ var _console;
2851
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2852
+ args[_key] = arguments[_key];
2853
+ }
2854
+ (_console = console).error.apply(_console, _toConsumableArray(withPrefix(args)));
2855
+ },
2856
+ warn: function warn() {
2857
+ var _console2;
2858
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2859
+ args[_key2] = arguments[_key2];
2860
+ }
2861
+ (_console2 = console).warn.apply(_console2, _toConsumableArray(withPrefix(args)));
2862
+ },
2863
+ info: function info() {
2864
+ if (isDebugEnabled()) {
2865
+ var _console3;
2866
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
2867
+ args[_key3] = arguments[_key3];
2868
+ }
2869
+ (_console3 = console).info.apply(_console3, _toConsumableArray(withPrefix(args)));
2870
+ }
2871
+ },
2872
+ debug: function debug() {
2873
+ if (isDebugEnabled()) {
2874
+ var _console4;
2875
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
2876
+ args[_key4] = arguments[_key4];
2877
+ }
2878
+ (_console4 = console).debug.apply(_console4, _toConsumableArray(withPrefix(args)));
2879
+ }
2880
+ }
2881
+ };
2882
+
2767
2883
  function _objectWithoutPropertiesLoose(r, e) {
2768
2884
  if (null == r) return {};
2769
2885
  var t = {};
@@ -2786,7 +2902,14 @@ function _objectWithoutProperties(e, t) {
2786
2902
  return i;
2787
2903
  }
2788
2904
 
2789
- var RegEx$1 = /^(https?:\/\/[^/]+)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2905
+ /**
2906
+ * The host part may carry a `/_val` prefix: a ref served by the platform
2907
+ * loader names `https://www.acme.no/_val/file/…`, because a customer's site
2908
+ * can have a `/file/…` route of its own. The prefix is part of `remoteHost`,
2909
+ * so `createRemoteRef(remoteHost, …)` writes it back unchanged. See valbuild/home
2910
+ * `docs/remote-files-on-platform.md`, "The ref".
2911
+ */
2912
+ var RegEx$1 = /^(https?:\/\/[^/]+(?:\/_val)?)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2790
2913
  function splitRemoteRef(ref) {
2791
2914
  if (ref[0] === "/") {
2792
2915
  return {
@@ -5035,7 +5158,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
5035
5158
  return hrefSchema["executeValidate"](hrefPath, node.href);
5036
5159
  } else {
5037
5160
  var exhaustiveCheck = hrefSchema;
5038
- console.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5161
+ log.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5039
5162
  return false;
5040
5163
  }
5041
5164
  };
@@ -15286,7 +15409,7 @@ function collectObjectRecursive(item, collector) {
15286
15409
  }
15287
15410
  return;
15288
15411
  } else {
15289
- console.warn("Unknown type encountered when hashing object", _typeof(item), item);
15412
+ log.warn("Unknown type encountered when hashing object", _typeof(item), item);
15290
15413
  }
15291
15414
  }
15292
15415
 
@@ -16121,8 +16244,8 @@ function hashToRemoteFileHash(hash) {
16121
16244
  return hash.slice(0, 12 // 12 hex characters = 6 bytes = 48 bits = 2^48 = 281474976710656 possibilities or 1 in 281474976710656 or using birthday problem estimate with 10K files: p = (k, n) => (k*k)/(2x2**n) and p(10_000,12*4) = 1.7763568394002505e-7 chance of collision which should be good enough
16122
16245
  );
16123
16246
  }
16124
- function getFileHash(text) {
16125
- return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(text)));
16247
+ function getFileHash(bytes) {
16248
+ return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(bytes)));
16126
16249
  }
16127
16250
 
16128
16251
  var cache$1 = new WeakMap();
@@ -16798,7 +16921,7 @@ function isInlineRender(container) {
16798
16921
 
16799
16922
  var corePackageJson = {
16800
16923
  name: "@valbuild/core",
16801
- version: "0.147.0",
16924
+ version: "0.148.2",
16802
16925
  "private": false,
16803
16926
  description: "Val - supercharged hard-coded content",
16804
16927
  repository: {
@@ -16885,6 +17008,10 @@ var DEFAULT_APP_HOST = "https://admin.val.build";
16885
17008
  */
16886
17009
  var DEFAULT_STATIC_HOST = "https://content.val.build/v1/static";
16887
17010
  var Internal = {
17011
+ /** Val's console output. See `log.ts` for which levels print, and when. */
17012
+ log: log,
17013
+ isDebugEnabled: isDebugEnabled,
17014
+ VAL_DEBUG_STORAGE_KEY: VAL_DEBUG_STORAGE_KEY,
16888
17015
  VERSION: {
16889
17016
  core: corePackageJson.version
16890
17017
  },
@@ -2762,6 +2762,122 @@ var discriminatedUnion = function discriminatedUnion(key) {
2762
2762
  return new DiscriminatedUnionSchema(key, objects);
2763
2763
  };
2764
2764
 
2765
+ function _toArray(r) {
2766
+ return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest();
2767
+ }
2768
+
2769
+ /**
2770
+ * Val's console output, and the one place that decides what reaches it.
2771
+ *
2772
+ * Val runs inside someone else's app: the server in their dev server and their
2773
+ * production logs, the Studio in their browser tab. Everything Val prints lands
2774
+ * in a console that belongs to a developer who did not write the code printing
2775
+ * it, so the levels are split by who the line is FOR:
2776
+ *
2777
+ * - `error` and `warn` are for that developer -- something broke, or something
2778
+ * they can fix -- and always print.
2779
+ * - `info` and `debug` are for whoever is debugging Val, and print only when
2780
+ * asked for: `VAL_DEBUG=1` in the environment of a server, or
2781
+ * `localStorage.setItem("val:debug", "1")` in a browser. Both are read on
2782
+ * every call, so turning it on in a live tab needs no reload.
2783
+ *
2784
+ * In Node `console.debug` IS `console.log`, so a bare `console.debug` is not
2785
+ * quiet on a server: it went to the developer's terminal on every request.
2786
+ * That is why `no-console` is on for the packages that run in a host app, and
2787
+ * this file is the exemption.
2788
+ *
2789
+ * Every line gets a `[val]` prefix, so a developer can filter Val out (or in).
2790
+ * Arguments are otherwise passed through as they are, so an `Error` still
2791
+ * prints with its stack.
2792
+ */
2793
+
2794
+ var PREFIX = "[val]";
2795
+
2796
+ /** The localStorage key that turns `debug` and `info` on in a browser. */
2797
+ var VAL_DEBUG_STORAGE_KEY = "val:debug";
2798
+ function isOn(value) {
2799
+ return value !== undefined && value !== null && value !== "" && value !== "0" && value !== "false";
2800
+ }
2801
+ function fromEnv() {
2802
+ var _process$env;
2803
+ // `typeof` first: a browser bundle may have no `process` at all.
2804
+ if (typeof process === "undefined") {
2805
+ return undefined;
2806
+ }
2807
+ return (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.VAL_DEBUG;
2808
+ }
2809
+ function fromLocalStorage() {
2810
+ // Not in Node, even where it has a `localStorage`: from Node 25 merely
2811
+ // touching it without `--localstorage-file` prints a warning of its own.
2812
+ if (!("window" in globalThis)) {
2813
+ return undefined;
2814
+ }
2815
+ try {
2816
+ var storage = Reflect.get(globalThis, "localStorage");
2817
+ if (_typeof(storage) === "object" && storage !== null && "getItem" in storage && typeof storage.getItem === "function") {
2818
+ var value = storage.getItem(VAL_DEBUG_STORAGE_KEY);
2819
+ return typeof value === "string" ? value : null;
2820
+ }
2821
+ } catch (_unused) {
2822
+ // A sandboxed frame or blocked site data throws on access.
2823
+ }
2824
+ return undefined;
2825
+ }
2826
+ function isDebugEnabled() {
2827
+ return isOn(fromEnv()) || isOn(fromLocalStorage());
2828
+ }
2829
+ function withPrefix(args) {
2830
+ var _args = _toArray(args),
2831
+ first = _args[0],
2832
+ rest = _arrayLikeToArray(_args).slice(1);
2833
+ if (typeof first === "string") {
2834
+ if (/^\[val\]/i.test(first)) {
2835
+ return args;
2836
+ }
2837
+ return ["".concat(PREFIX, " ").concat(first)].concat(_toConsumableArray(rest));
2838
+ }
2839
+ return [PREFIX].concat(_toConsumableArray(args));
2840
+ }
2841
+
2842
+ /*
2843
+ * `console` is looked up on every call rather than captured, so a test that
2844
+ * spies on `console.warn` after this module loaded still sees the call.
2845
+ */
2846
+ var log = {
2847
+ error: function error() {
2848
+ var _console;
2849
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2850
+ args[_key] = arguments[_key];
2851
+ }
2852
+ (_console = console).error.apply(_console, _toConsumableArray(withPrefix(args)));
2853
+ },
2854
+ warn: function warn() {
2855
+ var _console2;
2856
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2857
+ args[_key2] = arguments[_key2];
2858
+ }
2859
+ (_console2 = console).warn.apply(_console2, _toConsumableArray(withPrefix(args)));
2860
+ },
2861
+ info: function info() {
2862
+ if (isDebugEnabled()) {
2863
+ var _console3;
2864
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
2865
+ args[_key3] = arguments[_key3];
2866
+ }
2867
+ (_console3 = console).info.apply(_console3, _toConsumableArray(withPrefix(args)));
2868
+ }
2869
+ },
2870
+ debug: function debug() {
2871
+ if (isDebugEnabled()) {
2872
+ var _console4;
2873
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
2874
+ args[_key4] = arguments[_key4];
2875
+ }
2876
+ (_console4 = console).debug.apply(_console4, _toConsumableArray(withPrefix(args)));
2877
+ }
2878
+ }
2879
+ };
2880
+
2765
2881
  function _objectWithoutPropertiesLoose(r, e) {
2766
2882
  if (null == r) return {};
2767
2883
  var t = {};
@@ -2784,7 +2900,14 @@ function _objectWithoutProperties(e, t) {
2784
2900
  return i;
2785
2901
  }
2786
2902
 
2787
- var RegEx$1 = /^(https?:\/\/[^/]+)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2903
+ /**
2904
+ * The host part may carry a `/_val` prefix: a ref served by the platform
2905
+ * loader names `https://www.acme.no/_val/file/…`, because a customer's site
2906
+ * can have a `/file/…` route of its own. The prefix is part of `remoteHost`,
2907
+ * so `createRemoteRef(remoteHost, …)` writes it back unchanged. See valbuild/home
2908
+ * `docs/remote-files-on-platform.md`, "The ref".
2909
+ */
2910
+ var RegEx$1 = /^(https?:\/\/[^/]+(?:\/_val)?)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2788
2911
  function splitRemoteRef(ref) {
2789
2912
  if (ref[0] === "/") {
2790
2913
  return {
@@ -5033,7 +5156,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
5033
5156
  return hrefSchema["executeValidate"](hrefPath, node.href);
5034
5157
  } else {
5035
5158
  var exhaustiveCheck = hrefSchema;
5036
- console.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5159
+ log.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5037
5160
  return false;
5038
5161
  }
5039
5162
  };
@@ -15284,7 +15407,7 @@ function collectObjectRecursive(item, collector) {
15284
15407
  }
15285
15408
  return;
15286
15409
  } else {
15287
- console.warn("Unknown type encountered when hashing object", _typeof(item), item);
15410
+ log.warn("Unknown type encountered when hashing object", _typeof(item), item);
15288
15411
  }
15289
15412
  }
15290
15413
 
@@ -16119,8 +16242,8 @@ function hashToRemoteFileHash(hash) {
16119
16242
  return hash.slice(0, 12 // 12 hex characters = 6 bytes = 48 bits = 2^48 = 281474976710656 possibilities or 1 in 281474976710656 or using birthday problem estimate with 10K files: p = (k, n) => (k*k)/(2x2**n) and p(10_000,12*4) = 1.7763568394002505e-7 chance of collision which should be good enough
16120
16243
  );
16121
16244
  }
16122
- function getFileHash(text) {
16123
- return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(text)));
16245
+ function getFileHash(bytes) {
16246
+ return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(bytes)));
16124
16247
  }
16125
16248
 
16126
16249
  var cache$1 = new WeakMap();
@@ -16796,7 +16919,7 @@ function isInlineRender(container) {
16796
16919
 
16797
16920
  var corePackageJson = {
16798
16921
  name: "@valbuild/core",
16799
- version: "0.147.0",
16922
+ version: "0.148.2",
16800
16923
  "private": false,
16801
16924
  description: "Val - supercharged hard-coded content",
16802
16925
  repository: {
@@ -16883,6 +17006,10 @@ var DEFAULT_APP_HOST = "https://admin.val.build";
16883
17006
  */
16884
17007
  var DEFAULT_STATIC_HOST = "https://content.val.build/v1/static";
16885
17008
  var Internal = {
17009
+ /** Val's console output. See `log.ts` for which levels print, and when. */
17010
+ log: log,
17011
+ isDebugEnabled: isDebugEnabled,
17012
+ VAL_DEBUG_STORAGE_KEY: VAL_DEBUG_STORAGE_KEY,
16886
17013
  VERSION: {
16887
17014
  core: corePackageJson.version
16888
17015
  },
@@ -2764,6 +2764,122 @@ var discriminatedUnion = function discriminatedUnion(key) {
2764
2764
  return new DiscriminatedUnionSchema(key, objects);
2765
2765
  };
2766
2766
 
2767
+ function _toArray(r) {
2768
+ return _arrayWithHoles(r) || _iterableToArray(r) || result._unsupportedIterableToArray(r) || _nonIterableRest();
2769
+ }
2770
+
2771
+ /**
2772
+ * Val's console output, and the one place that decides what reaches it.
2773
+ *
2774
+ * Val runs inside someone else's app: the server in their dev server and their
2775
+ * production logs, the Studio in their browser tab. Everything Val prints lands
2776
+ * in a console that belongs to a developer who did not write the code printing
2777
+ * it, so the levels are split by who the line is FOR:
2778
+ *
2779
+ * - `error` and `warn` are for that developer -- something broke, or something
2780
+ * they can fix -- and always print.
2781
+ * - `info` and `debug` are for whoever is debugging Val, and print only when
2782
+ * asked for: `VAL_DEBUG=1` in the environment of a server, or
2783
+ * `localStorage.setItem("val:debug", "1")` in a browser. Both are read on
2784
+ * every call, so turning it on in a live tab needs no reload.
2785
+ *
2786
+ * In Node `console.debug` IS `console.log`, so a bare `console.debug` is not
2787
+ * quiet on a server: it went to the developer's terminal on every request.
2788
+ * That is why `no-console` is on for the packages that run in a host app, and
2789
+ * this file is the exemption.
2790
+ *
2791
+ * Every line gets a `[val]` prefix, so a developer can filter Val out (or in).
2792
+ * Arguments are otherwise passed through as they are, so an `Error` still
2793
+ * prints with its stack.
2794
+ */
2795
+
2796
+ var PREFIX = "[val]";
2797
+
2798
+ /** The localStorage key that turns `debug` and `info` on in a browser. */
2799
+ var VAL_DEBUG_STORAGE_KEY = "val:debug";
2800
+ function isOn(value) {
2801
+ return value !== undefined && value !== null && value !== "" && value !== "0" && value !== "false";
2802
+ }
2803
+ function fromEnv() {
2804
+ var _process$env;
2805
+ // `typeof` first: a browser bundle may have no `process` at all.
2806
+ if (typeof process === "undefined") {
2807
+ return undefined;
2808
+ }
2809
+ return (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.VAL_DEBUG;
2810
+ }
2811
+ function fromLocalStorage() {
2812
+ // Not in Node, even where it has a `localStorage`: from Node 25 merely
2813
+ // touching it without `--localstorage-file` prints a warning of its own.
2814
+ if (!("window" in globalThis)) {
2815
+ return undefined;
2816
+ }
2817
+ try {
2818
+ var storage = Reflect.get(globalThis, "localStorage");
2819
+ if (_typeof(storage) === "object" && storage !== null && "getItem" in storage && typeof storage.getItem === "function") {
2820
+ var value = storage.getItem(VAL_DEBUG_STORAGE_KEY);
2821
+ return typeof value === "string" ? value : null;
2822
+ }
2823
+ } catch (_unused) {
2824
+ // A sandboxed frame or blocked site data throws on access.
2825
+ }
2826
+ return undefined;
2827
+ }
2828
+ function isDebugEnabled() {
2829
+ return isOn(fromEnv()) || isOn(fromLocalStorage());
2830
+ }
2831
+ function withPrefix(args) {
2832
+ var _args = _toArray(args),
2833
+ first = _args[0],
2834
+ rest = result._arrayLikeToArray(_args).slice(1);
2835
+ if (typeof first === "string") {
2836
+ if (/^\[val\]/i.test(first)) {
2837
+ return args;
2838
+ }
2839
+ return ["".concat(PREFIX, " ").concat(first)].concat(_toConsumableArray(rest));
2840
+ }
2841
+ return [PREFIX].concat(_toConsumableArray(args));
2842
+ }
2843
+
2844
+ /*
2845
+ * `console` is looked up on every call rather than captured, so a test that
2846
+ * spies on `console.warn` after this module loaded still sees the call.
2847
+ */
2848
+ var log = {
2849
+ error: function error() {
2850
+ var _console;
2851
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2852
+ args[_key] = arguments[_key];
2853
+ }
2854
+ (_console = console).error.apply(_console, _toConsumableArray(withPrefix(args)));
2855
+ },
2856
+ warn: function warn() {
2857
+ var _console2;
2858
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2859
+ args[_key2] = arguments[_key2];
2860
+ }
2861
+ (_console2 = console).warn.apply(_console2, _toConsumableArray(withPrefix(args)));
2862
+ },
2863
+ info: function info() {
2864
+ if (isDebugEnabled()) {
2865
+ var _console3;
2866
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
2867
+ args[_key3] = arguments[_key3];
2868
+ }
2869
+ (_console3 = console).info.apply(_console3, _toConsumableArray(withPrefix(args)));
2870
+ }
2871
+ },
2872
+ debug: function debug() {
2873
+ if (isDebugEnabled()) {
2874
+ var _console4;
2875
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
2876
+ args[_key4] = arguments[_key4];
2877
+ }
2878
+ (_console4 = console).debug.apply(_console4, _toConsumableArray(withPrefix(args)));
2879
+ }
2880
+ }
2881
+ };
2882
+
2767
2883
  function _objectWithoutPropertiesLoose(r, e) {
2768
2884
  if (null == r) return {};
2769
2885
  var t = {};
@@ -2786,7 +2902,14 @@ function _objectWithoutProperties(e, t) {
2786
2902
  return i;
2787
2903
  }
2788
2904
 
2789
- var RegEx$1 = /^(https?:\/\/[^/]+)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2905
+ /**
2906
+ * The host part may carry a `/_val` prefix: a ref served by the platform
2907
+ * loader names `https://www.acme.no/_val/file/…`, because a customer's site
2908
+ * can have a `/file/…` route of its own. The prefix is part of `remoteHost`,
2909
+ * so `createRemoteRef(remoteHost, …)` writes it back unchanged. See valbuild/home
2910
+ * `docs/remote-files-on-platform.md`, "The ref".
2911
+ */
2912
+ var RegEx$1 = /^(https?:\/\/[^/]+(?:\/_val)?)\/file\/p\/([^/]+)\/b\/([^/]+)\/v\/([^/]+)\/h\/([^/]+)\/f\/([^/]+)\/p\/(.+)$/;
2790
2913
  function splitRemoteRef(ref) {
2791
2914
  if (ref[0] === "/") {
2792
2915
  return {
@@ -5035,7 +5158,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
5035
5158
  return hrefSchema["executeValidate"](hrefPath, node.href);
5036
5159
  } else {
5037
5160
  var exhaustiveCheck = hrefSchema;
5038
- console.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5161
+ log.error("Exhaustive check failed in RichText (anchor href validation)", exhaustiveCheck);
5039
5162
  return false;
5040
5163
  }
5041
5164
  };
@@ -15286,7 +15409,7 @@ function collectObjectRecursive(item, collector) {
15286
15409
  }
15287
15410
  return;
15288
15411
  } else {
15289
- console.warn("Unknown type encountered when hashing object", _typeof(item), item);
15412
+ log.warn("Unknown type encountered when hashing object", _typeof(item), item);
15290
15413
  }
15291
15414
  }
15292
15415
 
@@ -16121,8 +16244,8 @@ function hashToRemoteFileHash(hash) {
16121
16244
  return hash.slice(0, 12 // 12 hex characters = 6 bytes = 48 bits = 2^48 = 281474976710656 possibilities or 1 in 281474976710656 or using birthday problem estimate with 10K files: p = (k, n) => (k*k)/(2x2**n) and p(10_000,12*4) = 1.7763568394002505e-7 chance of collision which should be good enough
16122
16245
  );
16123
16246
  }
16124
- function getFileHash(text) {
16125
- return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(text)));
16247
+ function getFileHash(bytes) {
16248
+ return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(bytes)));
16126
16249
  }
16127
16250
 
16128
16251
  var cache$1 = new WeakMap();
@@ -16798,7 +16921,7 @@ function isInlineRender(container) {
16798
16921
 
16799
16922
  var corePackageJson = {
16800
16923
  name: "@valbuild/core",
16801
- version: "0.147.0",
16924
+ version: "0.148.2",
16802
16925
  "private": false,
16803
16926
  description: "Val - supercharged hard-coded content",
16804
16927
  repository: {
@@ -16885,6 +17008,10 @@ var DEFAULT_APP_HOST = "https://admin.val.build";
16885
17008
  */
16886
17009
  var DEFAULT_STATIC_HOST = "https://content.val.build/v1/static";
16887
17010
  var Internal = {
17011
+ /** Val's console output. See `log.ts` for which levels print, and when. */
17012
+ log: log,
17013
+ isDebugEnabled: isDebugEnabled,
17014
+ VAL_DEBUG_STORAGE_KEY: VAL_DEBUG_STORAGE_KEY,
16888
17015
  VERSION: {
16889
17016
  core: corePackageJson.version
16890
17017
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('./index-63547301.cjs.dev.js');
5
+ var dist_valbuildCore = require('./index-858ec9e8.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-989ebd80.cjs.prod.js');
5
+ var dist_valbuildCore = require('./index-c21fa511.cjs.prod.js');
6
6
  require('./result-787e35f6.cjs.prod.js');
7
7
 
8
8
 
@@ -1,2 +1,2 @@
1
- export { H as ASSISTANT_SETTINGS_MAX_LENGTH, A as ArraySchema, B as BooleanSchema, a4 as CODE_LANGUAGES, a5 as COLOR_FORMATS, a3 as CodeSchema, a2 as ColorSchema, e as DEFAULT_APP_HOST, a6 as DEFAULT_COLOR_FORMAT, D as DEFAULT_CONTENT_HOST, u as DEFAULT_FONT_ACCEPT, f as DEFAULT_STATIC_HOST, o as DEFAULT_VAL_REMOTE_HOST, x as DEFAULT_VIDEO_ACCEPT, y as DEFAULT_VIDEO_RENDITIONS, z as DEFAULT_VIDEO_SEGMENT_DURATION, C as DateSchema, a7 as DateTimeSchema, ad as DiscriminatedUnionSchema, ae as EnumSchema, F as FATAL_ERROR_TYPES, v as FONT_MIME_TYPES, t as FileSchema, G as GenericSelector, r as ImageSchema, I as Internal, a8 as KeyOfSchema, af as LiteralSchema, Z as LocaleSchema, M as ModuleFilePathSep, N as NumberSchema, O as ObjectSchema, R as RecordSchema, ac as RichTextSchema, ab as RouteSchema, Q as SETTINGS_MODULE_CONVENTION, S as Schema, E as SettingsSchema, q as StringSchema, T as THEME_LOGO_DIRECTORY, K as THEME_RADIUS_LENGTHS, J as THEME_RADIUS_STEPS, av as UNSAFE_URL_SCHEMES, V as VAL_EXTENSION, a9 as ValViewSchema, w as VideoSchema, L as assistantAvailability, k as computeSchemaSha, j as computeSourcesSha, h as computeValModuleShas, $ as declaredKeySetOf, p as derefPatch, ar as describeSchemeRejection, ag as deserializeSchema, a1 as discriminatedUnionBranchOf, g as extractValModules, ao as getSourcePathFromRoute, n as hasMediaSchema, l as hasRemoteFileSchema, i as initVal, as as isCheckableScheme, ai as isInlineRender, ap as isPageRouter, U as isRootModuleFilePath, aa as isValViewSource, Y as localeOfValue, X as localeTagError, an as matchRoutePattern, a0 as missingDeclaredKeys, m as modules, aj as parseNextJsRoutePattern, ak as parseTanStackRoutePattern, ah as previewScope, at as rejectScheme, W as resolveSettingsModule, aq as routePatternOf, au as schemeOf, al as tanStackSegmentsOfRoutePath, am as validateUrlAgainstPattern } from './index-cb122769.esm.js';
1
+ export { H as ASSISTANT_SETTINGS_MAX_LENGTH, A as ArraySchema, B as BooleanSchema, a4 as CODE_LANGUAGES, a5 as COLOR_FORMATS, a3 as CodeSchema, a2 as ColorSchema, e as DEFAULT_APP_HOST, a6 as DEFAULT_COLOR_FORMAT, D as DEFAULT_CONTENT_HOST, u as DEFAULT_FONT_ACCEPT, f as DEFAULT_STATIC_HOST, o as DEFAULT_VAL_REMOTE_HOST, x as DEFAULT_VIDEO_ACCEPT, y as DEFAULT_VIDEO_RENDITIONS, z as DEFAULT_VIDEO_SEGMENT_DURATION, C as DateSchema, a7 as DateTimeSchema, ad as DiscriminatedUnionSchema, ae as EnumSchema, F as FATAL_ERROR_TYPES, v as FONT_MIME_TYPES, t as FileSchema, G as GenericSelector, r as ImageSchema, I as Internal, a8 as KeyOfSchema, af as LiteralSchema, Z as LocaleSchema, M as ModuleFilePathSep, N as NumberSchema, O as ObjectSchema, R as RecordSchema, ac as RichTextSchema, ab as RouteSchema, Q as SETTINGS_MODULE_CONVENTION, S as Schema, E as SettingsSchema, q as StringSchema, T as THEME_LOGO_DIRECTORY, K as THEME_RADIUS_LENGTHS, J as THEME_RADIUS_STEPS, av as UNSAFE_URL_SCHEMES, V as VAL_EXTENSION, a9 as ValViewSchema, w as VideoSchema, L as assistantAvailability, k as computeSchemaSha, j as computeSourcesSha, h as computeValModuleShas, $ as declaredKeySetOf, p as derefPatch, ar as describeSchemeRejection, ag as deserializeSchema, a1 as discriminatedUnionBranchOf, g as extractValModules, ao as getSourcePathFromRoute, n as hasMediaSchema, l as hasRemoteFileSchema, i as initVal, as as isCheckableScheme, ai as isInlineRender, ap as isPageRouter, U as isRootModuleFilePath, aa as isValViewSource, Y as localeOfValue, X as localeTagError, an as matchRoutePattern, a0 as missingDeclaredKeys, m as modules, aj as parseNextJsRoutePattern, ak as parseTanStackRoutePattern, ah as previewScope, at as rejectScheme, W as resolveSettingsModule, aq as routePatternOf, au as schemeOf, al as tanStackSegmentsOfRoutePath, am as validateUrlAgainstPattern } from './index-a91ac6a3.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.147.0",
3
+ "version": "0.148.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-63547301.cjs.dev.js');
5
+ var dist_valbuildCore = require('../../dist/index-858ec9e8.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-989ebd80.cjs.prod.js');
5
+ var dist_valbuildCore = require('../../dist/index-c21fa511.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-cb122769.esm.js';
2
- export { P as PatchError } from '../../dist/index-cb122769.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-a91ac6a3.esm.js';
2
+ export { P as PatchError } from '../../dist/index-a91ac6a3.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