@valbuild/shared 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,106 @@
1
1
  # @valbuild/shared
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
+ - Updated dependencies [[`dc7c8cc`](https://github.com/valbuild/val/commit/dc7c8ccd82f643e662d00225fabec411b5d39e3a)]:
22
+ - @valbuild/core@0.148.2
23
+
24
+ ## 0.148.0
25
+
26
+ ### Patch Changes
27
+
28
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - Remote files are now addressed on the host the project's settings name. For a
29
+ project hosted by Val, that is the project's own address, and its remote images
30
+ and files are served from there rather than from `remote.val.build`. Every other
31
+ project is unchanged.
32
+
33
+ - The Studio, `val validate --fix` and the MCP image tool all take the host from
34
+ the project's settings, falling back to `remote.val.build` as before.
35
+ - Re-reading a remote file whose recorded size or type is out of date keeps it
36
+ on the host it was on.
37
+ - When a remote file's host cannot be reached, tooling downloads it from the
38
+ project's permanent `<id>.valstart.dev` address instead, and keeps it only if
39
+ its bytes match the file the address names.
40
+
41
+ - [#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
42
+ `https://www.acme.no/_val/file/…`) are now checked for whether that address
43
+ still serves the project. When a custom domain has been removed or moved to
44
+ another project, the image or file is reported, and **Fix** on the Studio's
45
+ Validate page — or `val validate --fix` — points it at the project's permanent
46
+ `<id>.valstart.dev` address. Nothing is uploaded or downloaded: only the address
47
+ changes.
48
+
49
+ Remote file addresses with a `/_val` prefix after the host are now recognised.
50
+
51
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - Fix existing remote images in rich text being saved as `/publichttps://…`.
52
+
53
+ Editing a rich text field could rewrite every remote image already in it into a
54
+ broken path when the field was not set up to upload remote images itself — for
55
+ example before the project's remote file settings had loaded, or when the
56
+ field's image schema is not `.remote()`. A published remote image is now kept
57
+ as it is, whatever host it is on.
58
+
59
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - **Check everything** on the Studio's Validate page now checks media directories
60
+ (`s.imagedir()`, `s.filedir()`, `s.fontdir()` and `s.videodir()`) by the files
61
+ they list:
62
+
63
+ - An entry whose file is gone has a **Fix** that removes it from the directory.
64
+ - An image or file entry whose recorded size or type does not match its file has
65
+ a **Fix** that corrects it from the file, keeping its alt text.
66
+ - A video entry whose file is gone is reported, and is removed by hand: its
67
+ posters and captions may still be in use.
68
+ - A remote entry is checked with its host, like any remote file.
69
+
70
+ `val validate --fix` fixes media directories exactly as before.
71
+
72
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - **Check everything** on the Studio's Validate page now checks remote images and
73
+ files too.
74
+
75
+ - A remote image or file whose address no longer matches what is recorded about
76
+ it (its size, type or the schema's options changed since it was uploaded) has
77
+ a **Fix**, which re-reads the file and corrects it, as `val validate --fix`
78
+ does.
79
+ - A remote host that does not answer is shown once, at the top of the page, with
80
+ how many files it holds and a **Try again**, rather than as an error on every
81
+ image.
82
+ - A file its host no longer has is shown at the image or file that uses it.
83
+
84
+ Images and files in your unpublished changes are not asked about until they are
85
+ published; the check makes sure the change still has them.
86
+
87
+ - [#818](https://github.com/valbuild/val/pull/818) [`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1) Thanks [@freekh](https://github.com/freekh)! - Two new Studio API routes for the full content check, not yet used by the
88
+ Studio's UI:
89
+
90
+ - `POST /api/val/validate` checks one module — its content against its schema,
91
+ and its local images and files against their bytes — on the content the
92
+ Studio is showing.
93
+ - `POST /api/val/validate/fix` returns the patch that fixes one of those errors,
94
+ for the Studio to add as a pending change. It builds only the fixes that need
95
+ no disk or remote host: image, file and video metadata, and a view pointing at
96
+ the wrong module.
97
+
98
+ Also fixed: an API route whose name started with another route's name could be
99
+ answered by the other route.
100
+
101
+ - Updated dependencies [[`562d032`](https://github.com/valbuild/val/commit/562d03280c3fcf97a80562e8b017dd2125ac4ad1)]:
102
+ - @valbuild/core@0.148.0
103
+
3
104
  ## 0.147.0
4
105
 
5
106
  ### Minor 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';
@@ -328,6 +328,7 @@ export declare const Api: {
328
328
  remoteFileBuckets: z.ZodArray<z.ZodObject<{
329
329
  bucket: z.ZodString;
330
330
  }, z.core.$strip>>;
331
+ remoteHost: z.ZodOptional<z.ZodString>;
331
332
  }, z.core.$strip>;
332
333
  }, z.core.$strip>, z.ZodObject<{
333
334
  status: z.ZodLiteral<400>;
@@ -1024,6 +1025,153 @@ export declare const Api: {
1024
1025
  }, z.core.$strip>]>;
1025
1026
  };
1026
1027
  };
1028
+ /**
1029
+ * The Studio's full check, one module per request: its sources against its
1030
+ * schema and its local files against their bytes, on the content the caller
1031
+ * is looking at. See `docs/plans/studio-validate.md`.
1032
+ */
1033
+ "/validate": {
1034
+ POST: {
1035
+ req: {
1036
+ body: z.ZodObject<{
1037
+ moduleFilePath: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1038
+ patchIds: z.ZodOptional<z.ZodArray<z.ZodString & z.ZodType<PatchIdT, string, z.core.$ZodTypeInternals<PatchIdT, string>>>>;
1039
+ }, z.core.$strip>;
1040
+ cookies: {
1041
+ val_session: z.ZodOptional<z.ZodString>;
1042
+ };
1043
+ };
1044
+ res: z.ZodUnion<readonly [z.ZodObject<{
1045
+ status: z.ZodLiteral<401>;
1046
+ json: z.ZodObject<{
1047
+ message: z.ZodString;
1048
+ }, z.core.$strip>;
1049
+ }, z.core.$strip>, z.ZodObject<{
1050
+ status: z.ZodLiteral<404>;
1051
+ json: z.ZodObject<{
1052
+ message: z.ZodString;
1053
+ }, z.core.$strip>;
1054
+ }, z.core.$strip>, z.ZodObject<{
1055
+ status: z.ZodLiteral<500>;
1056
+ json: z.ZodObject<{
1057
+ message: z.ZodString;
1058
+ }, z.core.$strip>;
1059
+ }, z.core.$strip>, z.ZodObject<{
1060
+ status: z.ZodLiteral<501>;
1061
+ json: z.ZodObject<{
1062
+ message: z.ZodString;
1063
+ }, z.core.$strip>;
1064
+ }, z.core.$strip>, z.ZodObject<{
1065
+ status: z.ZodLiteral<200>;
1066
+ json: z.ZodObject<{
1067
+ moduleFilePath: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1068
+ errors: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
1069
+ message: z.ZodString;
1070
+ value: z.ZodOptional<z.ZodUnknown>;
1071
+ fatal: z.ZodOptional<z.ZodBoolean>;
1072
+ fixes: z.ZodOptional<z.ZodArray<z.ZodType<ValidationFix, unknown, z.core.$ZodTypeInternals<ValidationFix, unknown>>>>;
1073
+ }, z.core.$strip>>>;
1074
+ invalidSource: z.ZodOptional<z.ZodString>;
1075
+ remoteHosts: z.ZodOptional<z.ZodArray<z.ZodObject<{
1076
+ host: z.ZodString;
1077
+ status: z.ZodUnion<readonly [z.ZodLiteral<"missing">, z.ZodLiteral<"unreachable">]>;
1078
+ details: z.ZodString;
1079
+ sourcePaths: z.ZodArray<z.ZodType<SourcePathT, unknown, z.core.$ZodTypeInternals<SourcePathT, unknown>>>;
1080
+ }, z.core.$strip>>>;
1081
+ }, z.core.$strip>;
1082
+ }, z.core.$strip>]>;
1083
+ };
1084
+ };
1085
+ /**
1086
+ * The patch that fixes one error the full check reported. The server finds
1087
+ * the error again rather than trusting the caller's copy, and builds only the
1088
+ * fixes `STUDIO_FIXES` lists. The patch is returned, not applied: the Studio
1089
+ * adds it as a pending change like any edit.
1090
+ */
1091
+ "/validate/fix": {
1092
+ POST: {
1093
+ req: {
1094
+ body: z.ZodObject<{
1095
+ moduleFilePath: z.ZodString & z.ZodType<ModuleFilePath, string, z.core.$ZodTypeInternals<ModuleFilePath, string>>;
1096
+ sourcePath: z.ZodType<SourcePathT, unknown, z.core.$ZodTypeInternals<SourcePathT, unknown>>;
1097
+ fix: z.ZodType<ValidationFix, unknown, z.core.$ZodTypeInternals<ValidationFix, unknown>>;
1098
+ patchIds: z.ZodOptional<z.ZodArray<z.ZodString & z.ZodType<PatchIdT, string, z.core.$ZodTypeInternals<PatchIdT, string>>>>;
1099
+ }, z.core.$strip>;
1100
+ cookies: {
1101
+ val_session: z.ZodOptional<z.ZodString>;
1102
+ };
1103
+ };
1104
+ res: z.ZodUnion<readonly [z.ZodObject<{
1105
+ status: z.ZodLiteral<401>;
1106
+ json: z.ZodObject<{
1107
+ message: z.ZodString;
1108
+ }, z.core.$strip>;
1109
+ }, z.core.$strip>, z.ZodObject<{
1110
+ status: z.ZodLiteral<404>;
1111
+ json: z.ZodObject<{
1112
+ message: z.ZodString;
1113
+ }, z.core.$strip>;
1114
+ }, z.core.$strip>, z.ZodObject<{
1115
+ status: z.ZodLiteral<400>;
1116
+ json: z.ZodObject<{
1117
+ message: z.ZodString;
1118
+ }, z.core.$strip>;
1119
+ }, z.core.$strip>, z.ZodObject<{
1120
+ status: z.ZodLiteral<500>;
1121
+ json: z.ZodObject<{
1122
+ message: z.ZodString;
1123
+ }, z.core.$strip>;
1124
+ }, z.core.$strip>, z.ZodObject<{
1125
+ status: z.ZodLiteral<501>;
1126
+ json: z.ZodObject<{
1127
+ message: z.ZodString;
1128
+ }, z.core.$strip>;
1129
+ }, z.core.$strip>, z.ZodObject<{
1130
+ status: z.ZodLiteral<200>;
1131
+ json: z.ZodObject<{
1132
+ patch: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1133
+ op: z.ZodLiteral<"add">;
1134
+ path: z.ZodArray<z.ZodString>;
1135
+ value: z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>;
1136
+ }, z.core.$strict>, z.ZodObject<{
1137
+ op: z.ZodLiteral<"remove">;
1138
+ path: z.ZodTuple<[z.ZodString], z.ZodString>;
1139
+ }, z.core.$strict>, z.ZodObject<{
1140
+ op: z.ZodLiteral<"replace">;
1141
+ path: z.ZodArray<z.ZodString>;
1142
+ value: z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>;
1143
+ }, z.core.$strict>, z.ZodObject<{
1144
+ op: z.ZodLiteral<"move">;
1145
+ from: z.ZodTuple<[z.ZodString], z.ZodString>;
1146
+ path: z.ZodArray<z.ZodString>;
1147
+ }, z.core.$strict>, z.ZodObject<{
1148
+ op: z.ZodLiteral<"copy">;
1149
+ from: z.ZodArray<z.ZodString>;
1150
+ path: z.ZodArray<z.ZodString>;
1151
+ }, z.core.$strict>, z.ZodObject<{
1152
+ op: z.ZodLiteral<"test">;
1153
+ path: z.ZodArray<z.ZodString>;
1154
+ value: z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>;
1155
+ }, z.core.$strict>, z.ZodObject<{
1156
+ op: z.ZodLiteral<"file">;
1157
+ path: z.ZodArray<z.ZodString>;
1158
+ filePath: z.ZodString;
1159
+ value: z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>;
1160
+ remote: z.ZodBoolean;
1161
+ nestedFilePath: z.ZodOptional<z.ZodArray<z.ZodString>>;
1162
+ metadata: z.ZodOptional<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
1163
+ }, z.core.$strict>], "op">>;
1164
+ remainingErrors: z.ZodArray<z.ZodObject<{
1165
+ message: z.ZodString;
1166
+ value: z.ZodOptional<z.ZodUnknown>;
1167
+ fatal: z.ZodOptional<z.ZodBoolean>;
1168
+ fixes: z.ZodOptional<z.ZodArray<z.ZodType<ValidationFix, unknown, z.core.$ZodTypeInternals<ValidationFix, unknown>>>>;
1169
+ sourcePath: z.ZodOptional<z.ZodString>;
1170
+ }, z.core.$strip>>;
1171
+ }, z.core.$strip>;
1172
+ }, z.core.$strip>]>;
1173
+ };
1174
+ };
1027
1175
  "/publish-job-prepare": {
1028
1176
  POST: {
1029
1177
  req: {
@@ -30,6 +30,7 @@ export * from "./aiTools/aiImageToolPatches.js";
30
30
  export * from "./aiTools/aiSourceToolPatches.js";
31
31
  export * from "./validation/partitionValidationErrors.js";
32
32
  export * from "./validation/blockingValidationErrors.js";
33
+ export * from "./validation/studioFixes.js";
33
34
  export * from "./media/encodeImageDecisions.js";
34
35
  export * from "./search/searchIndex.js";
35
36
  export * from "./search/traverseSchemaSource.js";
@@ -26,3 +26,10 @@ export declare function partitionValidationErrors(validationErrors: Record<Sourc
26
26
  surfaced: Record<SourcePath, ValidationError[]>;
27
27
  skipped: Record<SourcePath, ValidationError[]>;
28
28
  };
29
+ /**
30
+ * Whether the Studio leaves this error to the server, which repairs it on
31
+ * save, rather than showing it and holding a publish back for it. One rule
32
+ * for every gate: `val publish` asks the same question, so the CLI does not
33
+ * refuse what the Studio would publish.
34
+ */
35
+ export declare function isRepairedOnSave(error: ValidationError): boolean;
@@ -0,0 +1,14 @@
1
+ import type { ValidationFix } from "@valbuild/core";
2
+ /**
3
+ * The fixes the Studio's full check offers a **Fix** button for.
4
+ *
5
+ * Each is one `createFixPatch` can build without a disk: it reads a file's
6
+ * bytes through `FixFiles`, or needs no bytes at all. The server refuses any
7
+ * other code on `/validate/fix`, and the Studio shows those errors with the
8
+ * command to run instead of a button — so a code is added here when its fix
9
+ * can run in http mode and on the platform, not before. See
10
+ * `docs/plans/studio-validate.md`, "Order of work".
11
+ */
12
+ export declare const STUDIO_FIXES: readonly ["image:add-metadata", "image:check-metadata", "file:add-metadata", "file:check-metadata", "video:add-metadata", "videos:add-metadata", "view:check-module", "image:check-remote", "file:check-remote", "images:check-all-files", "files:check-all-files", "remote:rewrite-host"];
13
+ export type StudioFix = (typeof STUDIO_FIXES)[number];
14
+ export declare function isStudioFix(fix: ValidationFix): fix is StudioFix;
@@ -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);