@valbuild/shared 0.148.0 → 0.148.3

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,69 @@
1
1
  # @valbuild/shared
2
2
 
3
+ ## 0.148.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#881](https://github.com/valbuild/val/pull/881) [`0139436`](https://github.com/valbuild/val/commit/0139436426142d91cbb29ec6c696dfb86f34ab9d) Thanks [@freekh](https://github.com/freekh)! - The content analytics script. With analytics on (it is off by default, and turned on in a hosted project's settings), a TanStack site counts which content each visitor's page **rendered** and which they actually **viewed** (at least half on screen for a second), and sends it to `/api/val/analytics`.
8
+
9
+ - No cookies, no storage, no visitor IDs. Each page view also says where it came from (the referring site's host and any `utm_source` / `utm_medium` / `utm_campaign`) and whether it was a phone, tablet or desktop.
10
+ - A page is sent as its route's pattern (`/posts/$postId`), never its address, so a path that holds something about one visitor (an order number, a token) is never stored. `startValAnalytics` takes this as `routeFor`; `ValProvider` passes TanStack's matched route.
11
+ - Editors are never counted: nothing is sent in draft mode, in the Studio, with Val enabled, or at a proposal's address, and nothing from automated browsers. A page the browser prerenders counts nothing until it is shown.
12
+ - The script is the new `@valbuild/react/analytics` entry, loaded only for visitors of a site with analytics on, after the page has hydrated. It imports nothing else from Val.
13
+ - Storing the counts and showing them is part of Val's hosting, which takes these beacons before they reach the site. Anywhere else, `/api/val/analytics` checks each beacon and stores nothing; in local development, with `VAL_DEBUG=1`, it logs a line per beacon, so you can see it working.
14
+ - `ValProvider`'s Studio check now matches `/val` and what is below it only, not every route starting with those letters (`/values`). The same fix is in `@valbuild/next`.
15
+
16
+ - [#896](https://github.com/valbuild/val/pull/896) [`5eff8a0`](https://github.com/valbuild/val/commit/5eff8a055a4ef50d476797c28f9c3e50deb73c89) Thanks [@freekh](https://github.com/freekh)! - A demo's tour can now be written by the site: `<ValApp demo={{ tour }}>`, with each step as data (`ValDemoTourStep`), so what it says changes with the site rather than with a Val release.
17
+
18
+ It is drawn as a ring around what a step is about, with nothing dimmed and the Studio usable underneath, and a step can move on by itself once the visitor has done what it asks:
19
+
20
+ ```ts
21
+ const tour: ValDemoTourStep[] = [
22
+ {
23
+ id: "click",
24
+ title: "This is Val",
25
+ body: "Click the heading on the page.",
26
+ target: "canvas",
27
+ page: HEADING, // outlined on the page
28
+ moveOn: { open: HEADING },
29
+ },
30
+ {
31
+ id: "type",
32
+ title: "Change a word",
33
+ body: "The page changes as you type.",
34
+ field: HEADING, // ringed wherever the field is shown
35
+ moveOn: {
36
+ edit: true,
37
+ path: HEADING,
38
+ value: "Coffee, roasted this weekend",
39
+ },
40
+ },
41
+ ];
42
+ ```
43
+
44
+ A step that moves on has **Do it for me**, which does it the way the Studio would, and **Skip**. On a phone the card is a sheet along the bottom. The Studio's own tour is unchanged.
45
+
46
+ ## 0.148.2
47
+
48
+ ### Patch Changes
49
+
50
+ - [#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
51
+ print, now prefixed with `[val]` so you can filter them. Val's own debug
52
+ output, which used to reach your terminal and browser console, is now off by
53
+ default. That includes the `Invalid JWT` line that printed on every request
54
+ with an expired session cookie, the "verifying draft mode" and polling notices,
55
+ and the Studio's sync and WebSocket chatter.
56
+
57
+ To turn the debug output back on, for example when reporting a bug:
58
+
59
+ - on the server, set `VAL_DEBUG=1`
60
+ - in the browser, run `localStorage.setItem("val:debug", "1")` in the console.
61
+ It takes effect immediately, with no reload. Remove the key to turn it off
62
+ again.
63
+
64
+ - Updated dependencies [[`dc7c8cc`](https://github.com/valbuild/val/commit/dc7c8ccd82f643e662d00225fabec411b5d39e3a)]:
65
+ - @valbuild/core@0.148.2
66
+
3
67
  ## 0.148.0
4
68
 
5
69
  ### Patch Changes
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-f6254b32.cjs.dev.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-a7f2cc6d.cjs.dev.js');
6
6
  require('@valbuild/core');
7
7
 
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-109be3b8.cjs.prod.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-40d76bf8.cjs.prod.js');
6
6
  require('@valbuild/core');
7
7
 
8
8
 
@@ -1,2 +1,2 @@
1
- export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as formatRoutePattern, j as getNextAppRouterSourceFolder, n as getPageRouterSitemapTree, l as getPageRouterSourceFolder, o as getPatternFromModuleFilePath, k as getTanStackRouterSourceFolder, m as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-c70ea145.esm.js';
1
+ export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as formatRoutePattern, j as getNextAppRouterSourceFolder, n as getPageRouterSitemapTree, l as getPageRouterSourceFolder, o as getPatternFromModuleFilePath, k as getTanStackRouterSourceFolder, m as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-cd006a36.esm.js';
2
2
  import '@valbuild/core';
@@ -45,6 +45,27 @@ type CookieValue = EnableCookieValue | {
45
45
  * this. Shared so client and server agree on the limit.
46
46
  */
47
47
  export declare const JSON_ENTRIES_BATCH_MAX = 100;
48
+ export declare const AnalyticsBeacon: z.ZodObject<{
49
+ v: z.ZodLiteral<1>;
50
+ route: z.ZodString;
51
+ cv: z.ZodOptional<z.ZodString>;
52
+ view: z.ZodOptional<z.ZodObject<{
53
+ ref: z.ZodOptional<z.ZodString>;
54
+ utm: z.ZodOptional<z.ZodObject<{
55
+ source: z.ZodOptional<z.ZodString>;
56
+ medium: z.ZodOptional<z.ZodString>;
57
+ campaign: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>>;
59
+ device: z.ZodEnum<{
60
+ phone: "phone";
61
+ tablet: "tablet";
62
+ desktop: "desktop";
63
+ }>;
64
+ }, z.core.$strip>>;
65
+ rendered: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
66
+ viewed: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
67
+ }, z.core.$strip>;
68
+ export type AnalyticsBeacon = z.infer<typeof AnalyticsBeacon>;
48
69
  export declare const Api: {
49
70
  "/draft/enable": {
50
71
  GET: {
@@ -98,6 +119,24 @@ export declare const Api: {
98
119
  }, z.core.$strip>]>;
99
120
  };
100
121
  };
122
+ "/analytics": {
123
+ POST: {
124
+ req: {
125
+ body: z.ZodUnknown;
126
+ };
127
+ res: z.ZodUnion<readonly [z.ZodObject<{
128
+ status: z.ZodLiteral<200>;
129
+ json: z.ZodObject<{
130
+ counted: z.ZodBoolean;
131
+ }, z.core.$strip>;
132
+ }, z.core.$strip>, z.ZodObject<{
133
+ status: z.ZodLiteral<400>;
134
+ json: z.ZodObject<{
135
+ message: z.ZodString;
136
+ }, z.core.$strip>;
137
+ }, z.core.$strip>]>;
138
+ };
139
+ };
101
140
  "/draft/stat": {
102
141
  GET: {
103
142
  req: {
@@ -23,6 +23,82 @@ export type ValDemoRuntime = {
23
23
  * refuses uploads before sending anything, and says why.
24
24
  */
25
25
  uploads: boolean;
26
+ /**
27
+ * The tour the site wrote, in place of the Studio's own demo tour. See
28
+ * `ValDemoTourStep`. Absent: the Studio's.
29
+ */
30
+ tour?: ValDemoTourStep[];
31
+ };
32
+ /**
33
+ * What the site starts the demo with: `<ValApp demo={{ tour }}>`.
34
+ *
35
+ * `demo` alone (`true`) is the same with nothing given.
36
+ */
37
+ export type ValDemoOptions = {
38
+ tour?: ValDemoTourStep[];
39
+ };
40
+ /**
41
+ * A control of the Studio's a step can point at.
42
+ *
43
+ * The `data-val-tour` markers the Studio puts on them. One that is not on
44
+ * screen (the rail on a phone) leaves the card on its own, so a step's words
45
+ * must work without the arrow: never "this button here".
46
+ */
47
+ export type ValDemoTourTarget = "canvas" | "pages" | "media" | "data" | "review" | "preview" | "publish" | "ai" | "locale" | "demo" | "utility";
48
+ /** A panel a step opens, so what it is about is on screen behind the card. */
49
+ export type ValDemoTourPanel = "pages" | "media" | "data" | "settings" | "ai";
50
+ /**
51
+ * What moves a step on by itself. A step without one has Next.
52
+ *
53
+ * Each is something the visitor does, because doing it is the lesson, and
54
+ * each has a "Do it for me" that does it the way the Studio would:
55
+ *
56
+ * - `open`: a field at or below this source path is opened -- by clicking it
57
+ * on the page, or anywhere else. Do it for me opens it.
58
+ * - `edit`: a change is made. Do it for me writes `value` at `path`; without
59
+ * them, it is offered nowhere and the step waits for the visitor.
60
+ * - `panel`: that panel is opened. Do it for me opens it.
61
+ * - `locale`: the language shown is changed. Do it for me picks the next one.
62
+ */
63
+ export type ValDemoTourMoveOn = {
64
+ open: string;
65
+ } | {
66
+ edit: true;
67
+ path?: string;
68
+ value?: string;
69
+ } | {
70
+ panel: ValDemoTourPanel;
71
+ } | {
72
+ locale: true;
73
+ };
74
+ /**
75
+ * One stop of the demo's tour, as the site writes it.
76
+ *
77
+ * Data rather than components, so the tour can be rewritten -- and tried on
78
+ * people -- without a Val release: the Studio draws it, the site says what it
79
+ * says. Written for someone who has never seen Val.
80
+ */
81
+ export type ValDemoTourStep = {
82
+ /** Stable, so a test can name a step without matching its words. */
83
+ id: string;
84
+ title: string;
85
+ body: string;
86
+ /** The control this step is about. */
87
+ target?: ValDemoTourTarget;
88
+ /**
89
+ * A field this step is about, as a source path: ringed wherever the Studio
90
+ * shows it -- the page's fields, or the module open in the editor. Takes
91
+ * precedence over `target`, which is what is ringed when the field is not
92
+ * on screen.
93
+ */
94
+ field?: string;
95
+ /**
96
+ * A place on the page this step is about, as a source path: the page
97
+ * outlines it and brings it into view.
98
+ */
99
+ page?: string;
100
+ panel?: ValDemoTourPanel;
101
+ moveOn?: ValDemoTourMoveOn;
26
102
  };
27
103
  declare global {
28
104
  var __VAL_DEMO__: ValDemoRuntime | undefined;
@@ -388,7 +388,7 @@ function getPageRouterSitemapTree(srcFolder, paths) {
388
388
  moduleFilePathS = path.moduleFilePath;
389
389
  var moduleFilePath = moduleFilePathS;
390
390
  if (!urlPath.startsWith("/")) {
391
- console.error("urlPath must start with /: ".concat(urlPath));
391
+ core.Internal.log.error("urlPath must start with /: ".concat(urlPath));
392
392
  return 0; // continue
393
393
  }
394
394
  var pattern = getPatternFromModuleFilePath(moduleFilePath, srcFolder);
@@ -388,7 +388,7 @@ function getPageRouterSitemapTree(srcFolder, paths) {
388
388
  moduleFilePathS = path.moduleFilePath;
389
389
  var moduleFilePath = moduleFilePathS;
390
390
  if (!urlPath.startsWith("/")) {
391
- console.error("urlPath must start with /: ".concat(urlPath));
391
+ core.Internal.log.error("urlPath must start with /: ".concat(urlPath));
392
392
  return 0; // continue
393
393
  }
394
394
  var pattern = getPatternFromModuleFilePath(moduleFilePath, srcFolder);
@@ -386,7 +386,7 @@ function getPageRouterSitemapTree(srcFolder, paths) {
386
386
  moduleFilePathS = path.moduleFilePath;
387
387
  var moduleFilePath = moduleFilePathS;
388
388
  if (!urlPath.startsWith("/")) {
389
- console.error("urlPath must start with /: ".concat(urlPath));
389
+ Internal.log.error("urlPath must start with /: ".concat(urlPath));
390
390
  return 0; // continue
391
391
  }
392
392
  var pattern = getPatternFromModuleFilePath(moduleFilePath, srcFolder);
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-f6254b32.cjs.dev.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-a7f2cc6d.cjs.dev.js');
6
6
  var core = require('@valbuild/core');
7
7
  var zod = require('zod');
8
8
  var zodValidationError = require('zod-validation-error');
@@ -266,17 +266,17 @@ function convertImageNode(path, node, files, configDirectory, remoteOptions) {
266
266
  if (remoteRef) {
267
267
  noParamsUrl = decodeURIComponent(remoteRef);
268
268
  } else {
269
- console.error("Remote image URL does not contain ref: " + url);
269
+ core.Internal.log.error("Remote image URL does not contain ref: " + url);
270
270
  }
271
271
  } else if (noParamsUrl.startsWith("/api/val/files/public")) {
272
272
  noParamsUrl = noParamsUrl.slice("/api/val/files".length);
273
273
  } else {
274
- console.error("Patched image URL does not start with /api/val/files: " + url);
274
+ core.Internal.log.error("Patched image URL does not start with /api/val/files: " + url);
275
275
  }
276
276
  } else if (core.Internal.remote.splitRemoteRef(noParamsUrl).status === "success") ; else if (!noParamsUrl.startsWith("/public")) {
277
277
  noParamsUrl = "/public".concat(noParamsUrl);
278
278
  } else {
279
- console.error("Unpatched image URL starts with /public: " + url);
279
+ core.Internal.log.error("Unpatched image URL starts with /public: " + url);
280
280
  }
281
281
  var tag = {
282
282
  tag: "img",
@@ -1782,6 +1782,48 @@ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1782
1782
  * this. Shared so client and server agree on the limit.
1783
1783
  */
1784
1784
  var JSON_ENTRIES_BATCH_MAX = 100;
1785
+
1786
+ /**
1787
+ * Content analytics, wire format version 1: the beacon the browser script
1788
+ * (`@valbuild/react/analytics`) sends to `POST /api/val/analytics`. Its
1789
+ * `AnalyticsBeacon` type is written by hand there, because that code is on
1790
+ * every visitor's page and must not load zod; `analytics/beacon.test.ts` in
1791
+ * `@valbuild/react` checks that what it builds parses here.
1792
+ */
1793
+ /*
1794
+ * The limits the browser script keeps to (`MAX_*` in
1795
+ * `@valbuild/react/analytics`'s `beacon.ts`, which cannot import this). The
1796
+ * endpoint takes anyone's POST, so it checks what it is sent rather than
1797
+ * trusting the sender; `beacon.test.ts` builds beacons at the limits and
1798
+ * parses them here.
1799
+ */
1800
+ var MAX_ANALYTICS_PATHS_PER_BEACON = 200;
1801
+ var AnalyticsPaths = zod.z.record(zod.z.string().max(512), zod.z.array(zod.z.string().max(1024)).max(MAX_ANALYTICS_PATHS_PER_BEACON));
1802
+ var countAnalyticsPaths = function countAnalyticsPaths(paths) {
1803
+ return Object.values(paths).reduce(function (n, list) {
1804
+ return n + list.length;
1805
+ }, 0);
1806
+ };
1807
+ var AnalyticsBeacon = zod.z.object({
1808
+ v: zod.z.literal(1),
1809
+ route: zod.z.string().max(512),
1810
+ cv: zod.z.string().max(128).optional(),
1811
+ view: zod.z.object({
1812
+ ref: zod.z.string().max(253).optional(),
1813
+ utm: zod.z.object({
1814
+ source: zod.z.string().max(100).optional(),
1815
+ medium: zod.z.string().max(100).optional(),
1816
+ campaign: zod.z.string().max(100).optional()
1817
+ }).optional(),
1818
+ device: zod.z["enum"](["phone", "tablet", "desktop"])
1819
+ }).optional(),
1820
+ rendered: AnalyticsPaths,
1821
+ viewed: AnalyticsPaths
1822
+ }).refine(function (beacon) {
1823
+ return countAnalyticsPaths(beacon.rendered) + countAnalyticsPaths(beacon.viewed) <= MAX_ANALYTICS_PATHS_PER_BEACON;
1824
+ }, {
1825
+ message: "At most ".concat(MAX_ANALYTICS_PATHS_PER_BEACON, " paths a beacon")
1826
+ });
1785
1827
  var Api = {
1786
1828
  "/draft/enable": {
1787
1829
  GET: {
@@ -1827,6 +1869,27 @@ var Api = {
1827
1869
  })])
1828
1870
  }
1829
1871
  },
1872
+ "/analytics": {
1873
+ POST: {
1874
+ // Parsed by the handler rather than here, so a beacon of a version this
1875
+ // server does not know is ignored instead of refused.
1876
+ req: {
1877
+ body: zod.z.unknown()
1878
+ },
1879
+ res: zod.z.union([
1880
+ // `counted` is false wherever nothing stores the counts -- every
1881
+ // server but the hosted platform's, for now.
1882
+ zod.z.object({
1883
+ status: zod.z.literal(200),
1884
+ json: zod.z.object({
1885
+ counted: zod.z["boolean"]()
1886
+ })
1887
+ }), zod.z.object({
1888
+ status: zod.z.literal(400),
1889
+ json: GenericError
1890
+ })])
1891
+ }
1892
+ },
1830
1893
  "/draft/stat": {
1831
1894
  GET: {
1832
1895
  req: {
@@ -3928,7 +3991,7 @@ var createValClient = function createValClient(host, config, options) {
3928
3991
  _context2.n = 2;
3929
3992
  break;
3930
3993
  }
3931
- console.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3994
+ core.Internal.log.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3932
3995
  path: path,
3933
3996
  method: method,
3934
3997
  body: anyReq.body,
@@ -4006,7 +4069,7 @@ var createValClient = function createValClient(host, config, options) {
4006
4069
  _context.n = 4;
4007
4070
  break;
4008
4071
  }
4009
- console.error("Server responded with an error", json);
4072
+ core.Internal.log.error("Server responded with an error", json);
4010
4073
  message = getErrorMessageFromUnknownJson(json, "Unknown error");
4011
4074
  return _context.a(2, {
4012
4075
  status: 500,
@@ -4093,6 +4156,44 @@ function isRetryable(error) {
4093
4156
  * modules. See `docs/plans/demo-mode.md`.
4094
4157
  */
4095
4158
 
4159
+ /**
4160
+ * What the site starts the demo with: `<ValApp demo={{ tour }}>`.
4161
+ *
4162
+ * `demo` alone (`true`) is the same with nothing given.
4163
+ */
4164
+
4165
+ /**
4166
+ * A control of the Studio's a step can point at.
4167
+ *
4168
+ * The `data-val-tour` markers the Studio puts on them. One that is not on
4169
+ * screen (the rail on a phone) leaves the card on its own, so a step's words
4170
+ * must work without the arrow: never "this button here".
4171
+ */
4172
+
4173
+ /** A panel a step opens, so what it is about is on screen behind the card. */
4174
+
4175
+ /**
4176
+ * What moves a step on by itself. A step without one has Next.
4177
+ *
4178
+ * Each is something the visitor does, because doing it is the lesson, and
4179
+ * each has a "Do it for me" that does it the way the Studio would:
4180
+ *
4181
+ * - `open`: a field at or below this source path is opened -- by clicking it
4182
+ * on the page, or anywhere else. Do it for me opens it.
4183
+ * - `edit`: a change is made. Do it for me writes `value` at `path`; without
4184
+ * them, it is offered nowhere and the step waits for the visitor.
4185
+ * - `panel`: that panel is opened. Do it for me opens it.
4186
+ * - `locale`: the language shown is changed. Do it for me picks the next one.
4187
+ */
4188
+
4189
+ /**
4190
+ * One stop of the demo's tour, as the site writes it.
4191
+ *
4192
+ * Data rather than components, so the tour can be rewritten -- and tried on
4193
+ * people -- without a Val release: the Studio draws it, the site says what it
4194
+ * says. Written for someone who has never seen Val.
4195
+ */
4196
+
4096
4197
  /*
4097
4198
  * A global `var` rather than a `Window` member: this package is compiled
4098
4199
  * without the DOM's types, and a `var` in global scope is also a property of
@@ -4631,14 +4732,14 @@ function filterRoutesByPatterns(routes, includePattern, excludePattern) {
4631
4732
  try {
4632
4733
  includeRegex = new RegExp(includePattern.source, includePattern.flags);
4633
4734
  } catch (e) {
4634
- console.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4735
+ core.Internal.log.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4635
4736
  }
4636
4737
  }
4637
4738
  if (excludePattern) {
4638
4739
  try {
4639
4740
  excludeRegex = new RegExp(excludePattern.source, excludePattern.flags);
4640
4741
  } catch (e) {
4641
- console.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4742
+ core.Internal.log.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4642
4743
  }
4643
4744
  }
4644
4745
  return routes.filter(function (route) {
@@ -8360,7 +8461,7 @@ function schemaTypesOfPath(schema, patchPath) {
8360
8461
  } else {
8361
8462
  var _unreachable = current;
8362
8463
  var unknownType = _unreachable.type;
8363
- console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8464
+ core.Internal.log.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8364
8465
  return new Set([unknownType]);
8365
8466
  }
8366
8467
  }
@@ -8699,9 +8800,9 @@ var PatchSets = /*#__PURE__*/function () {
8699
8800
  } catch (e) {
8700
8801
  // We might be in this situation if the schema changes, etc etc:
8701
8802
  if (e instanceof Error) {
8702
- console.error("Could not resolve path while creating patch set", e.message);
8803
+ core.Internal.log.error("Could not resolve path while creating patch set", e.message);
8703
8804
  } else {
8704
- console.error("Could not resolve path while creating patch set", e);
8805
+ core.Internal.log.error("Could not resolve path while creating patch set", e);
8705
8806
  }
8706
8807
  // "terminate" the entire module file path (i.e. all patches are their own patch set)
8707
8808
  this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
@@ -8943,6 +9044,7 @@ exports.parseRoutePattern = getSitemapTree.parseRoutePattern;
8943
9044
  exports.withValCanvasParam = getSitemapTree.withValCanvasParam;
8944
9045
  exports.AA_LARGE = AA_LARGE;
8945
9046
  exports.AA_TEXT = AA_TEXT;
9047
+ exports.AnalyticsBeacon = AnalyticsBeacon;
8946
9048
  exports.Api = Api;
8947
9049
  exports.BRAND_CONTRAST_PAIRS = BRAND_CONTRAST_PAIRS;
8948
9050
  exports.BinaryFileRef = BinaryFileRef;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-109be3b8.cjs.prod.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-40d76bf8.cjs.prod.js');
6
6
  var core = require('@valbuild/core');
7
7
  var zod = require('zod');
8
8
  var zodValidationError = require('zod-validation-error');
@@ -266,17 +266,17 @@ function convertImageNode(path, node, files, configDirectory, remoteOptions) {
266
266
  if (remoteRef) {
267
267
  noParamsUrl = decodeURIComponent(remoteRef);
268
268
  } else {
269
- console.error("Remote image URL does not contain ref: " + url);
269
+ core.Internal.log.error("Remote image URL does not contain ref: " + url);
270
270
  }
271
271
  } else if (noParamsUrl.startsWith("/api/val/files/public")) {
272
272
  noParamsUrl = noParamsUrl.slice("/api/val/files".length);
273
273
  } else {
274
- console.error("Patched image URL does not start with /api/val/files: " + url);
274
+ core.Internal.log.error("Patched image URL does not start with /api/val/files: " + url);
275
275
  }
276
276
  } else if (core.Internal.remote.splitRemoteRef(noParamsUrl).status === "success") ; else if (!noParamsUrl.startsWith("/public")) {
277
277
  noParamsUrl = "/public".concat(noParamsUrl);
278
278
  } else {
279
- console.error("Unpatched image URL starts with /public: " + url);
279
+ core.Internal.log.error("Unpatched image URL starts with /public: " + url);
280
280
  }
281
281
  var tag = {
282
282
  tag: "img",
@@ -1782,6 +1782,48 @@ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1782
1782
  * this. Shared so client and server agree on the limit.
1783
1783
  */
1784
1784
  var JSON_ENTRIES_BATCH_MAX = 100;
1785
+
1786
+ /**
1787
+ * Content analytics, wire format version 1: the beacon the browser script
1788
+ * (`@valbuild/react/analytics`) sends to `POST /api/val/analytics`. Its
1789
+ * `AnalyticsBeacon` type is written by hand there, because that code is on
1790
+ * every visitor's page and must not load zod; `analytics/beacon.test.ts` in
1791
+ * `@valbuild/react` checks that what it builds parses here.
1792
+ */
1793
+ /*
1794
+ * The limits the browser script keeps to (`MAX_*` in
1795
+ * `@valbuild/react/analytics`'s `beacon.ts`, which cannot import this). The
1796
+ * endpoint takes anyone's POST, so it checks what it is sent rather than
1797
+ * trusting the sender; `beacon.test.ts` builds beacons at the limits and
1798
+ * parses them here.
1799
+ */
1800
+ var MAX_ANALYTICS_PATHS_PER_BEACON = 200;
1801
+ var AnalyticsPaths = zod.z.record(zod.z.string().max(512), zod.z.array(zod.z.string().max(1024)).max(MAX_ANALYTICS_PATHS_PER_BEACON));
1802
+ var countAnalyticsPaths = function countAnalyticsPaths(paths) {
1803
+ return Object.values(paths).reduce(function (n, list) {
1804
+ return n + list.length;
1805
+ }, 0);
1806
+ };
1807
+ var AnalyticsBeacon = zod.z.object({
1808
+ v: zod.z.literal(1),
1809
+ route: zod.z.string().max(512),
1810
+ cv: zod.z.string().max(128).optional(),
1811
+ view: zod.z.object({
1812
+ ref: zod.z.string().max(253).optional(),
1813
+ utm: zod.z.object({
1814
+ source: zod.z.string().max(100).optional(),
1815
+ medium: zod.z.string().max(100).optional(),
1816
+ campaign: zod.z.string().max(100).optional()
1817
+ }).optional(),
1818
+ device: zod.z["enum"](["phone", "tablet", "desktop"])
1819
+ }).optional(),
1820
+ rendered: AnalyticsPaths,
1821
+ viewed: AnalyticsPaths
1822
+ }).refine(function (beacon) {
1823
+ return countAnalyticsPaths(beacon.rendered) + countAnalyticsPaths(beacon.viewed) <= MAX_ANALYTICS_PATHS_PER_BEACON;
1824
+ }, {
1825
+ message: "At most ".concat(MAX_ANALYTICS_PATHS_PER_BEACON, " paths a beacon")
1826
+ });
1785
1827
  var Api = {
1786
1828
  "/draft/enable": {
1787
1829
  GET: {
@@ -1827,6 +1869,27 @@ var Api = {
1827
1869
  })])
1828
1870
  }
1829
1871
  },
1872
+ "/analytics": {
1873
+ POST: {
1874
+ // Parsed by the handler rather than here, so a beacon of a version this
1875
+ // server does not know is ignored instead of refused.
1876
+ req: {
1877
+ body: zod.z.unknown()
1878
+ },
1879
+ res: zod.z.union([
1880
+ // `counted` is false wherever nothing stores the counts -- every
1881
+ // server but the hosted platform's, for now.
1882
+ zod.z.object({
1883
+ status: zod.z.literal(200),
1884
+ json: zod.z.object({
1885
+ counted: zod.z["boolean"]()
1886
+ })
1887
+ }), zod.z.object({
1888
+ status: zod.z.literal(400),
1889
+ json: GenericError
1890
+ })])
1891
+ }
1892
+ },
1830
1893
  "/draft/stat": {
1831
1894
  GET: {
1832
1895
  req: {
@@ -3928,7 +3991,7 @@ var createValClient = function createValClient(host, config, options) {
3928
3991
  _context2.n = 2;
3929
3992
  break;
3930
3993
  }
3931
- console.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3994
+ core.Internal.log.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3932
3995
  path: path,
3933
3996
  method: method,
3934
3997
  body: anyReq.body,
@@ -4006,7 +4069,7 @@ var createValClient = function createValClient(host, config, options) {
4006
4069
  _context.n = 4;
4007
4070
  break;
4008
4071
  }
4009
- console.error("Server responded with an error", json);
4072
+ core.Internal.log.error("Server responded with an error", json);
4010
4073
  message = getErrorMessageFromUnknownJson(json, "Unknown error");
4011
4074
  return _context.a(2, {
4012
4075
  status: 500,
@@ -4093,6 +4156,44 @@ function isRetryable(error) {
4093
4156
  * modules. See `docs/plans/demo-mode.md`.
4094
4157
  */
4095
4158
 
4159
+ /**
4160
+ * What the site starts the demo with: `<ValApp demo={{ tour }}>`.
4161
+ *
4162
+ * `demo` alone (`true`) is the same with nothing given.
4163
+ */
4164
+
4165
+ /**
4166
+ * A control of the Studio's a step can point at.
4167
+ *
4168
+ * The `data-val-tour` markers the Studio puts on them. One that is not on
4169
+ * screen (the rail on a phone) leaves the card on its own, so a step's words
4170
+ * must work without the arrow: never "this button here".
4171
+ */
4172
+
4173
+ /** A panel a step opens, so what it is about is on screen behind the card. */
4174
+
4175
+ /**
4176
+ * What moves a step on by itself. A step without one has Next.
4177
+ *
4178
+ * Each is something the visitor does, because doing it is the lesson, and
4179
+ * each has a "Do it for me" that does it the way the Studio would:
4180
+ *
4181
+ * - `open`: a field at or below this source path is opened -- by clicking it
4182
+ * on the page, or anywhere else. Do it for me opens it.
4183
+ * - `edit`: a change is made. Do it for me writes `value` at `path`; without
4184
+ * them, it is offered nowhere and the step waits for the visitor.
4185
+ * - `panel`: that panel is opened. Do it for me opens it.
4186
+ * - `locale`: the language shown is changed. Do it for me picks the next one.
4187
+ */
4188
+
4189
+ /**
4190
+ * One stop of the demo's tour, as the site writes it.
4191
+ *
4192
+ * Data rather than components, so the tour can be rewritten -- and tried on
4193
+ * people -- without a Val release: the Studio draws it, the site says what it
4194
+ * says. Written for someone who has never seen Val.
4195
+ */
4196
+
4096
4197
  /*
4097
4198
  * A global `var` rather than a `Window` member: this package is compiled
4098
4199
  * without the DOM's types, and a `var` in global scope is also a property of
@@ -4631,14 +4732,14 @@ function filterRoutesByPatterns(routes, includePattern, excludePattern) {
4631
4732
  try {
4632
4733
  includeRegex = new RegExp(includePattern.source, includePattern.flags);
4633
4734
  } catch (e) {
4634
- console.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4735
+ core.Internal.log.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4635
4736
  }
4636
4737
  }
4637
4738
  if (excludePattern) {
4638
4739
  try {
4639
4740
  excludeRegex = new RegExp(excludePattern.source, excludePattern.flags);
4640
4741
  } catch (e) {
4641
- console.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4742
+ core.Internal.log.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4642
4743
  }
4643
4744
  }
4644
4745
  return routes.filter(function (route) {
@@ -8360,7 +8461,7 @@ function schemaTypesOfPath(schema, patchPath) {
8360
8461
  } else {
8361
8462
  var _unreachable = current;
8362
8463
  var unknownType = _unreachable.type;
8363
- console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8464
+ core.Internal.log.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8364
8465
  return new Set([unknownType]);
8365
8466
  }
8366
8467
  }
@@ -8699,9 +8800,9 @@ var PatchSets = /*#__PURE__*/function () {
8699
8800
  } catch (e) {
8700
8801
  // We might be in this situation if the schema changes, etc etc:
8701
8802
  if (e instanceof Error) {
8702
- console.error("Could not resolve path while creating patch set", e.message);
8803
+ core.Internal.log.error("Could not resolve path while creating patch set", e.message);
8703
8804
  } else {
8704
- console.error("Could not resolve path while creating patch set", e);
8805
+ core.Internal.log.error("Could not resolve path while creating patch set", e);
8705
8806
  }
8706
8807
  // "terminate" the entire module file path (i.e. all patches are their own patch set)
8707
8808
  this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
@@ -8943,6 +9044,7 @@ exports.parseRoutePattern = getSitemapTree.parseRoutePattern;
8943
9044
  exports.withValCanvasParam = getSitemapTree.withValCanvasParam;
8944
9045
  exports.AA_LARGE = AA_LARGE;
8945
9046
  exports.AA_TEXT = AA_TEXT;
9047
+ exports.AnalyticsBeacon = AnalyticsBeacon;
8946
9048
  exports.Api = Api;
8947
9049
  exports.BRAND_CONTRAST_PAIRS = BRAND_CONTRAST_PAIRS;
8948
9050
  exports.BinaryFileRef = BinaryFileRef;
@@ -1,5 +1,5 @@
1
- import { _ as _createForOfIteratorHelper, q as _objectSpread2, r as _arrayLikeToArray, s as _unsupportedIterableToArray, t as _typeof, u as _defineProperty, v as _toPropertyKey } from '../../dist/getSitemapTree-c70ea145.esm.js';
2
- export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as formatRoutePattern, j as getNextAppRouterSourceFolder, n as getPageRouterSitemapTree, l as getPageRouterSourceFolder, o as getPatternFromModuleFilePath, k as getTanStackRouterSourceFolder, m as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-c70ea145.esm.js';
1
+ import { _ as _createForOfIteratorHelper, q as _objectSpread2, r as _arrayLikeToArray, s as _unsupportedIterableToArray, t as _typeof, u as _defineProperty, v as _toPropertyKey } from '../../dist/getSitemapTree-cd006a36.esm.js';
2
+ export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as formatRoutePattern, j as getNextAppRouterSourceFolder, n as getPageRouterSitemapTree, l as getPageRouterSourceFolder, o as getPatternFromModuleFilePath, k as getTanStackRouterSourceFolder, m as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-cd006a36.esm.js';
3
3
  import { Internal, CODE_LANGUAGES, resolveSettingsModule, missingDeclaredKeys, localeOfValue, discriminatedUnionBranchOf, routePatternOf, matchRoutePattern, DEFAULT_COLOR_FORMAT, declaredKeySetOf } from '@valbuild/core';
4
4
  import { z } from 'zod';
5
5
  import { fromError } from 'zod-validation-error';
@@ -259,17 +259,17 @@ function convertImageNode(path, node, files, configDirectory, remoteOptions) {
259
259
  if (remoteRef) {
260
260
  noParamsUrl = decodeURIComponent(remoteRef);
261
261
  } else {
262
- console.error("Remote image URL does not contain ref: " + url);
262
+ Internal.log.error("Remote image URL does not contain ref: " + url);
263
263
  }
264
264
  } else if (noParamsUrl.startsWith("/api/val/files/public")) {
265
265
  noParamsUrl = noParamsUrl.slice("/api/val/files".length);
266
266
  } else {
267
- console.error("Patched image URL does not start with /api/val/files: " + url);
267
+ Internal.log.error("Patched image URL does not start with /api/val/files: " + url);
268
268
  }
269
269
  } else if (Internal.remote.splitRemoteRef(noParamsUrl).status === "success") ; else if (!noParamsUrl.startsWith("/public")) {
270
270
  noParamsUrl = "/public".concat(noParamsUrl);
271
271
  } else {
272
- console.error("Unpatched image URL starts with /public: " + url);
272
+ Internal.log.error("Unpatched image URL starts with /public: " + url);
273
273
  }
274
274
  var tag = {
275
275
  tag: "img",
@@ -1775,6 +1775,48 @@ var onlyOneIntQueryParam = onlyOneStringQueryParam.refine(function (arg) {
1775
1775
  * this. Shared so client and server agree on the limit.
1776
1776
  */
1777
1777
  var JSON_ENTRIES_BATCH_MAX = 100;
1778
+
1779
+ /**
1780
+ * Content analytics, wire format version 1: the beacon the browser script
1781
+ * (`@valbuild/react/analytics`) sends to `POST /api/val/analytics`. Its
1782
+ * `AnalyticsBeacon` type is written by hand there, because that code is on
1783
+ * every visitor's page and must not load zod; `analytics/beacon.test.ts` in
1784
+ * `@valbuild/react` checks that what it builds parses here.
1785
+ */
1786
+ /*
1787
+ * The limits the browser script keeps to (`MAX_*` in
1788
+ * `@valbuild/react/analytics`'s `beacon.ts`, which cannot import this). The
1789
+ * endpoint takes anyone's POST, so it checks what it is sent rather than
1790
+ * trusting the sender; `beacon.test.ts` builds beacons at the limits and
1791
+ * parses them here.
1792
+ */
1793
+ var MAX_ANALYTICS_PATHS_PER_BEACON = 200;
1794
+ var AnalyticsPaths = z.record(z.string().max(512), z.array(z.string().max(1024)).max(MAX_ANALYTICS_PATHS_PER_BEACON));
1795
+ var countAnalyticsPaths = function countAnalyticsPaths(paths) {
1796
+ return Object.values(paths).reduce(function (n, list) {
1797
+ return n + list.length;
1798
+ }, 0);
1799
+ };
1800
+ var AnalyticsBeacon = z.object({
1801
+ v: z.literal(1),
1802
+ route: z.string().max(512),
1803
+ cv: z.string().max(128).optional(),
1804
+ view: z.object({
1805
+ ref: z.string().max(253).optional(),
1806
+ utm: z.object({
1807
+ source: z.string().max(100).optional(),
1808
+ medium: z.string().max(100).optional(),
1809
+ campaign: z.string().max(100).optional()
1810
+ }).optional(),
1811
+ device: z["enum"](["phone", "tablet", "desktop"])
1812
+ }).optional(),
1813
+ rendered: AnalyticsPaths,
1814
+ viewed: AnalyticsPaths
1815
+ }).refine(function (beacon) {
1816
+ return countAnalyticsPaths(beacon.rendered) + countAnalyticsPaths(beacon.viewed) <= MAX_ANALYTICS_PATHS_PER_BEACON;
1817
+ }, {
1818
+ message: "At most ".concat(MAX_ANALYTICS_PATHS_PER_BEACON, " paths a beacon")
1819
+ });
1778
1820
  var Api = {
1779
1821
  "/draft/enable": {
1780
1822
  GET: {
@@ -1820,6 +1862,27 @@ var Api = {
1820
1862
  })])
1821
1863
  }
1822
1864
  },
1865
+ "/analytics": {
1866
+ POST: {
1867
+ // Parsed by the handler rather than here, so a beacon of a version this
1868
+ // server does not know is ignored instead of refused.
1869
+ req: {
1870
+ body: z.unknown()
1871
+ },
1872
+ res: z.union([
1873
+ // `counted` is false wherever nothing stores the counts -- every
1874
+ // server but the hosted platform's, for now.
1875
+ z.object({
1876
+ status: z.literal(200),
1877
+ json: z.object({
1878
+ counted: z["boolean"]()
1879
+ })
1880
+ }), z.object({
1881
+ status: z.literal(400),
1882
+ json: GenericError
1883
+ })])
1884
+ }
1885
+ },
1823
1886
  "/draft/stat": {
1824
1887
  GET: {
1825
1888
  req: {
@@ -3921,7 +3984,7 @@ var createValClient = function createValClient(host, config, options) {
3921
3984
  _context2.n = 2;
3922
3985
  break;
3923
3986
  }
3924
- console.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3987
+ Internal.log.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3925
3988
  path: path,
3926
3989
  method: method,
3927
3990
  body: anyReq.body,
@@ -3999,7 +4062,7 @@ var createValClient = function createValClient(host, config, options) {
3999
4062
  _context.n = 4;
4000
4063
  break;
4001
4064
  }
4002
- console.error("Server responded with an error", json);
4065
+ Internal.log.error("Server responded with an error", json);
4003
4066
  message = getErrorMessageFromUnknownJson(json, "Unknown error");
4004
4067
  return _context.a(2, {
4005
4068
  status: 500,
@@ -4086,6 +4149,44 @@ function isRetryable(error) {
4086
4149
  * modules. See `docs/plans/demo-mode.md`.
4087
4150
  */
4088
4151
 
4152
+ /**
4153
+ * What the site starts the demo with: `<ValApp demo={{ tour }}>`.
4154
+ *
4155
+ * `demo` alone (`true`) is the same with nothing given.
4156
+ */
4157
+
4158
+ /**
4159
+ * A control of the Studio's a step can point at.
4160
+ *
4161
+ * The `data-val-tour` markers the Studio puts on them. One that is not on
4162
+ * screen (the rail on a phone) leaves the card on its own, so a step's words
4163
+ * must work without the arrow: never "this button here".
4164
+ */
4165
+
4166
+ /** A panel a step opens, so what it is about is on screen behind the card. */
4167
+
4168
+ /**
4169
+ * What moves a step on by itself. A step without one has Next.
4170
+ *
4171
+ * Each is something the visitor does, because doing it is the lesson, and
4172
+ * each has a "Do it for me" that does it the way the Studio would:
4173
+ *
4174
+ * - `open`: a field at or below this source path is opened -- by clicking it
4175
+ * on the page, or anywhere else. Do it for me opens it.
4176
+ * - `edit`: a change is made. Do it for me writes `value` at `path`; without
4177
+ * them, it is offered nowhere and the step waits for the visitor.
4178
+ * - `panel`: that panel is opened. Do it for me opens it.
4179
+ * - `locale`: the language shown is changed. Do it for me picks the next one.
4180
+ */
4181
+
4182
+ /**
4183
+ * One stop of the demo's tour, as the site writes it.
4184
+ *
4185
+ * Data rather than components, so the tour can be rewritten -- and tried on
4186
+ * people -- without a Val release: the Studio draws it, the site says what it
4187
+ * says. Written for someone who has never seen Val.
4188
+ */
4189
+
4089
4190
  /*
4090
4191
  * A global `var` rather than a `Window` member: this package is compiled
4091
4192
  * without the DOM's types, and a `var` in global scope is also a property of
@@ -4624,14 +4725,14 @@ function filterRoutesByPatterns(routes, includePattern, excludePattern) {
4624
4725
  try {
4625
4726
  includeRegex = new RegExp(includePattern.source, includePattern.flags);
4626
4727
  } catch (e) {
4627
- console.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4728
+ Internal.log.warn("[Val] Invalid include pattern: /".concat(includePattern.source, "/").concat(includePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed include pattern.");
4628
4729
  }
4629
4730
  }
4630
4731
  if (excludePattern) {
4631
4732
  try {
4632
4733
  excludeRegex = new RegExp(excludePattern.source, excludePattern.flags);
4633
4734
  } catch (e) {
4634
- console.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4735
+ Internal.log.warn("[Val] Invalid exclude pattern: /".concat(excludePattern.source, "/").concat(excludePattern.flags), "\nError: ".concat(e instanceof Error ? e.message : String(e)), "\nAll routes will be filtered out due to malformed exclude pattern.");
4635
4736
  }
4636
4737
  }
4637
4738
  return routes.filter(function (route) {
@@ -8353,7 +8454,7 @@ function schemaTypesOfPath(schema, patchPath) {
8353
8454
  } else {
8354
8455
  var _unreachable = current;
8355
8456
  var unknownType = _unreachable.type;
8356
- console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8457
+ Internal.log.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8357
8458
  return new Set([unknownType]);
8358
8459
  }
8359
8460
  }
@@ -8692,9 +8793,9 @@ var PatchSets = /*#__PURE__*/function () {
8692
8793
  } catch (e) {
8693
8794
  // We might be in this situation if the schema changes, etc etc:
8694
8795
  if (e instanceof Error) {
8695
- console.error("Could not resolve path while creating patch set", e.message);
8796
+ Internal.log.error("Could not resolve path while creating patch set", e.message);
8696
8797
  } else {
8697
- console.error("Could not resolve path while creating patch set", e);
8798
+ Internal.log.error("Could not resolve path while creating patch set", e);
8698
8799
  }
8699
8800
  // "terminate" the entire module file path (i.e. all patches are their own patch set)
8700
8801
  this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
@@ -8915,4 +9016,4 @@ function schemaErrorsOf(schema, moduleFilePath, source) {
8915
9016
  return errors;
8916
9017
  }
8917
9018
 
8918
- 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, PatchId, PatchJSON, PatchSets, PlanRefusalError, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, STUDIO_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, WASM_ENCODED_MIME_TYPES, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, enumLocaleTag, explainIncompatible, fallbackMimeType, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, getValDemo, indexModule, isInsidePatchSetPath, isLocaleSchema, isMimeTypeAccepted, isRemoteSchema, isRepairedOnSave, isSchemaSourceFixError, isSkippedSource, isStudioFix, joinSharedChanges, keyOfRecordPath, levenshtein, localeAt, localeMeantBy, 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, schemaErrorsOf, schemaTypesOfPath, selectionClosure, shouldEncodeWithWasm, sideFiles, sideSource, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
9019
+ export { AA_LARGE, AA_TEXT, AnalyticsBeacon, 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, PatchId, PatchJSON, PatchSets, PlanRefusalError, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, STUDIO_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, WASM_ENCODED_MIME_TYPES, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, enumLocaleTag, explainIncompatible, fallbackMimeType, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, getValDemo, indexModule, isInsidePatchSetPath, isLocaleSchema, isMimeTypeAccepted, isRemoteSchema, isRepairedOnSave, isSchemaSourceFixError, isSkippedSource, isStudioFix, joinSharedChanges, keyOfRecordPath, levenshtein, localeAt, localeMeantBy, 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, schemaErrorsOf, schemaTypesOfPath, selectionClosure, shouldEncodeWithWasm, sideFiles, sideSource, 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.148.0",
3
+ "version": "0.148.3",
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.148.0"
40
+ "@valbuild/core": "0.148.2"
41
41
  },
42
42
  "files": [
43
43
  "CHANGELOG.md",