@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.
@@ -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
- } else if (remoteOptions && noParamsUrl.startsWith(remoteOptions.remoteHost)) ; else if (!noParamsUrl.startsWith("/public")) {
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",
@@ -1054,6 +1054,10 @@ var PatchBlock = zod.z.object({
1054
1054
  parentRef: ParentRef$1
1055
1055
  });
1056
1056
 
1057
+ var SourcePath = zod.z.string().transform(function (path) {
1058
+ return path;
1059
+ });
1060
+
1057
1061
  function _objectWithoutPropertiesLoose(r, e) {
1058
1062
  if (null == r) return {};
1059
1063
  var t = {};
@@ -1076,10 +1080,6 @@ function _objectWithoutProperties(e, t) {
1076
1080
  return i;
1077
1081
  }
1078
1082
 
1079
- var SourcePath = zod.z.string().transform(function (path) {
1080
- return path;
1081
- });
1082
-
1083
1083
  var ModuleFilePath$1 = zod.z.string().transform(function (path) {
1084
1084
  return path;
1085
1085
  });
@@ -1621,7 +1621,7 @@ var ValConfig = zod.z.object({
1621
1621
  gitCommit: zod.z.string().optional(),
1622
1622
  gitBranch: zod.z.string().optional()
1623
1623
  });
1624
- var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("video:add-metadata"), zod.z.literal("video:upload-remote"), zod.z.literal("video:download-remote"), zod.z.literal("videos:add-metadata"), zod.z.literal("videos:check-remote"), zod.z.literal("videos:upload-remote"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("image:check-gallery"), zod.z.literal("file:check-gallery"), zod.z.literal("video:check-gallery"), zod.z.literal("router:check-route"), zod.z.literal("locale:check-locale"), zod.z.literal("router:check-locale-param"), zod.z.literal("record:fill-keys"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("videos:check-unique-folder"), zod.z.literal("videos:check-all-files"), zod.z.literal("jsonValues:extract-entry"), zod.z.literal("view:check-module")]);
1624
+ var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("video:add-metadata"), zod.z.literal("video:upload-remote"), zod.z.literal("video:download-remote"), zod.z.literal("videos:add-metadata"), zod.z.literal("videos:check-remote"), zod.z.literal("videos:upload-remote"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("image:check-gallery"), zod.z.literal("file:check-gallery"), zod.z.literal("video:check-gallery"), zod.z.literal("router:check-route"), zod.z.literal("locale:check-locale"), zod.z.literal("router:check-locale-param"), zod.z.literal("record:fill-keys"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("videos:check-unique-folder"), zod.z.literal("videos:check-all-files"), zod.z.literal("jsonValues:extract-entry"), zod.z.literal("view:check-module"), zod.z.literal("external:upload"), zod.z.literal("remote:rewrite-host")]);
1625
1625
  var ValidationError = zod.z.object({
1626
1626
  message: zod.z.string(),
1627
1627
  value: zod.z.unknown().optional(),
@@ -2023,7 +2023,13 @@ var Api = {
2023
2023
  coreVersion: zod.z.string(),
2024
2024
  remoteFileBuckets: zod.z.array(zod.z.object({
2025
2025
  bucket: zod.z.string()
2026
- }))
2026
+ })),
2027
+ /**
2028
+ * The host new refs name, from the project's settings: its own
2029
+ * address for a Hosted project whose files are in R2. Optional,
2030
+ * for a content service that predates it.
2031
+ */
2032
+ remoteHost: zod.z.string().optional()
2027
2033
  })
2028
2034
  }), zod.z.object({
2029
2035
  status: zod.z.literal(400),
@@ -2769,6 +2775,105 @@ var Api = {
2769
2775
  })])
2770
2776
  }
2771
2777
  },
2778
+ /**
2779
+ * The Studio's full check, one module per request: its sources against its
2780
+ * schema and its local files against their bytes, on the content the caller
2781
+ * is looking at. See `docs/plans/studio-validate.md`.
2782
+ */
2783
+ "/validate": {
2784
+ POST: {
2785
+ req: {
2786
+ body: zod.z.object({
2787
+ moduleFilePath: ModuleFilePath,
2788
+ /**
2789
+ * The patches the caller is showing, applied over base. Omitted
2790
+ * means every pending patch, as `/sources/~`; empty means base.
2791
+ */
2792
+ patchIds: zod.z.array(PatchId).optional()
2793
+ }),
2794
+ cookies: {
2795
+ val_session: zod.z.string().optional()
2796
+ }
2797
+ },
2798
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2799
+ status: zod.z.literal(500),
2800
+ json: zod.z.object({
2801
+ message: zod.z.string()
2802
+ })
2803
+ }), /** No full check on this server (one running in a browser tab). */
2804
+ zod.z.object({
2805
+ status: zod.z.literal(501),
2806
+ json: zod.z.object({
2807
+ message: zod.z.string()
2808
+ })
2809
+ }), zod.z.object({
2810
+ status: zod.z.literal(200),
2811
+ json: zod.z.object({
2812
+ moduleFilePath: ModuleFilePath,
2813
+ errors: zod.z.record(zod.z.string(), zod.z.array(ValidationError)),
2814
+ /** Set when the module's source could not be read at all. */
2815
+ invalidSource: zod.z.string().optional(),
2816
+ /**
2817
+ * Hosts that did not serve this module's remote files: one entry
2818
+ * per host, however many files it holds. Optional so a server
2819
+ * from before remote checks still parses.
2820
+ */
2821
+ remoteHosts: zod.z.array(zod.z.object({
2822
+ host: zod.z.string(),
2823
+ status: zod.z.union([zod.z.literal("missing"), zod.z.literal("unreachable")]),
2824
+ details: zod.z.string(),
2825
+ sourcePaths: zod.z.array(SourcePath)
2826
+ })).optional()
2827
+ })
2828
+ })])
2829
+ }
2830
+ },
2831
+ /**
2832
+ * The patch that fixes one error the full check reported. The server finds
2833
+ * the error again rather than trusting the caller's copy, and builds only the
2834
+ * fixes `STUDIO_FIXES` lists. The patch is returned, not applied: the Studio
2835
+ * adds it as a pending change like any edit.
2836
+ */
2837
+ "/validate/fix": {
2838
+ POST: {
2839
+ req: {
2840
+ body: zod.z.object({
2841
+ moduleFilePath: ModuleFilePath,
2842
+ sourcePath: SourcePath,
2843
+ fix: ValidationFixZ,
2844
+ patchIds: zod.z.array(PatchId).optional()
2845
+ }),
2846
+ cookies: {
2847
+ val_session: zod.z.string().optional()
2848
+ }
2849
+ },
2850
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2851
+ status: zod.z.literal(400),
2852
+ json: zod.z.object({
2853
+ message: zod.z.string()
2854
+ })
2855
+ }), zod.z.object({
2856
+ status: zod.z.literal(500),
2857
+ json: zod.z.object({
2858
+ message: zod.z.string()
2859
+ })
2860
+ }), /** No full check on this server (one running in a browser tab). */
2861
+ zod.z.object({
2862
+ status: zod.z.literal(501),
2863
+ json: zod.z.object({
2864
+ message: zod.z.string()
2865
+ })
2866
+ }), zod.z.object({
2867
+ status: zod.z.literal(200),
2868
+ json: zod.z.object({
2869
+ patch: Patch,
2870
+ remainingErrors: zod.z.array(ValidationError.extend({
2871
+ sourcePath: zod.z.string().optional()
2872
+ }))
2873
+ })
2874
+ })])
2875
+ }
2876
+ },
2772
2877
  "/publish-job-prepare": {
2773
2878
  POST: {
2774
2879
  req: {
@@ -3823,7 +3928,7 @@ var createValClient = function createValClient(host, config, options) {
3823
3928
  _context2.n = 2;
3824
3929
  break;
3825
3930
  }
3826
- console.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3931
+ core.Internal.log.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3827
3932
  path: path,
3828
3933
  method: method,
3829
3934
  body: anyReq.body,
@@ -3901,7 +4006,7 @@ var createValClient = function createValClient(host, config, options) {
3901
4006
  _context.n = 4;
3902
4007
  break;
3903
4008
  }
3904
- console.error("Server responded with an error", json);
4009
+ core.Internal.log.error("Server responded with an error", json);
3905
4010
  message = getErrorMessageFromUnknownJson(json, "Unknown error");
3906
4011
  return _context.a(2, {
3907
4012
  status: 500,
@@ -4526,14 +4631,14 @@ function filterRoutesByPatterns(routes, includePattern, excludePattern) {
4526
4631
  try {
4527
4632
  includeRegex = new RegExp(includePattern.source, includePattern.flags);
4528
4633
  } catch (e) {
4529
- 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.");
4634
+ 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.");
4530
4635
  }
4531
4636
  }
4532
4637
  if (excludePattern) {
4533
4638
  try {
4534
4639
  excludeRegex = new RegExp(excludePattern.source, excludePattern.flags);
4535
4640
  } catch (e) {
4536
- 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.");
4641
+ 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.");
4537
4642
  }
4538
4643
  }
4539
4644
  return routes.filter(function (route) {
@@ -6312,6 +6417,16 @@ function partitionValidationErrors(validationErrors) {
6312
6417
  skipped: skipped
6313
6418
  };
6314
6419
  }
6420
+
6421
+ /**
6422
+ * Whether the Studio leaves this error to the server, which repairs it on
6423
+ * save, rather than showing it and holding a publish back for it. One rule
6424
+ * for every gate: `val publish` asks the same question, so the CLI does not
6425
+ * refuse what the Studio would publish.
6426
+ */
6427
+ function isRepairedOnSave(error) {
6428
+ return isSkippedFix(error);
6429
+ }
6315
6430
  function isSkippedFix(error) {
6316
6431
  var _error$fixes;
6317
6432
  var fixes = (_error$fixes = error.fixes) !== null && _error$fixes !== void 0 ? _error$fixes : [];
@@ -6381,6 +6496,12 @@ function isSkippableFixCode(fix) {
6381
6496
  // under `val external upload` and never under a blanket `--fix`. Surfacing
6382
6497
  // it is the whole point: someone has to decide.
6383
6498
  return false;
6499
+ case "remote:rewrite-host":
6500
+ // Reported only by the server's full check (the Studio's Validate page,
6501
+ // `val validate`), which asks the ref's host -- never by a schema, so
6502
+ // the Studio's own validator never holds one. Were it to, a person has
6503
+ // to see it: the host is gone, and nothing on save repoints the ref.
6504
+ return false;
6384
6505
  default:
6385
6506
  {
6386
6507
  return false;
@@ -6420,6 +6541,33 @@ function filterBlockingValidationErrors(validationErrors, schemas, sources) {
6420
6541
  return partitionValidationErrors(resolved).surfaced;
6421
6542
  }
6422
6543
 
6544
+ /**
6545
+ * The fixes the Studio's full check offers a **Fix** button for.
6546
+ *
6547
+ * Each is one `createFixPatch` can build without a disk: it reads a file's
6548
+ * bytes through `FixFiles`, or needs no bytes at all. The server refuses any
6549
+ * other code on `/validate/fix`, and the Studio shows those errors with the
6550
+ * command to run instead of a button — so a code is added here when its fix
6551
+ * can run in http mode and on the platform, not before. See
6552
+ * `docs/plans/studio-validate.md`, "Order of work".
6553
+ */
6554
+ var STUDIO_FIXES = ["image:add-metadata", "image:check-metadata", "file:add-metadata", "file:check-metadata", "video:add-metadata", "videos:add-metadata", "view:check-module",
6555
+ // A stale remote ref: re-read through `FixFiles.readRemoteFile`, rewritten
6556
+ // on the host it was already on.
6557
+ "image:check-remote", "file:check-remote",
6558
+ // One entry of an `s.imagedir()` / `s.filedir()`: removed when its file is
6559
+ // gone, rewritten from its bytes when they disagree. Built for that entry
6560
+ // alone, never the whole directory (`fixForStudio`).
6561
+ "images:check-all-files", "files:check-all-files",
6562
+ // A platform ref on a host that no longer serves its project, pointed at
6563
+ // the project's own `valstart.dev` address. Derived from the ref alone.
6564
+ "remote:rewrite-host"];
6565
+ function isStudioFix(fix) {
6566
+ return STUDIO_FIXES.some(function (studioFix) {
6567
+ return studioFix === fix;
6568
+ });
6569
+ }
6570
+
6423
6571
  /**
6424
6572
  * Every decision `encode` makes, with none of the pixels.
6425
6573
  *
@@ -8212,7 +8360,7 @@ function schemaTypesOfPath(schema, patchPath) {
8212
8360
  } else {
8213
8361
  var _unreachable = current;
8214
8362
  var unknownType = _unreachable.type;
8215
- console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8363
+ core.Internal.log.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8216
8364
  return new Set([unknownType]);
8217
8365
  }
8218
8366
  }
@@ -8551,9 +8699,9 @@ var PatchSets = /*#__PURE__*/function () {
8551
8699
  } catch (e) {
8552
8700
  // We might be in this situation if the schema changes, etc etc:
8553
8701
  if (e instanceof Error) {
8554
- console.error("Could not resolve path while creating patch set", e.message);
8702
+ core.Internal.log.error("Could not resolve path while creating patch set", e.message);
8555
8703
  } else {
8556
- console.error("Could not resolve path while creating patch set", e);
8704
+ core.Internal.log.error("Could not resolve path while creating patch set", e);
8557
8705
  }
8558
8706
  // "terminate" the entire module file path (i.e. all patches are their own patch set)
8559
8707
  this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
@@ -8838,6 +8986,7 @@ exports.RemirrorTextMark = RemirrorTextMark;
8838
8986
  exports.RestoreVerdict = RestoreVerdict;
8839
8987
  exports.RichTextOptions = RichTextOptions;
8840
8988
  exports.SCHEMA_SOURCE_FIXES = SCHEMA_SOURCE_FIXES;
8989
+ exports.STUDIO_FIXES = STUDIO_FIXES;
8841
8990
  exports.SerializedArraySchema = SerializedArraySchema;
8842
8991
  exports.SerializedBooleanSchema = SerializedBooleanSchema;
8843
8992
  exports.SerializedCodeSchema = SerializedCodeSchema;
@@ -8913,8 +9062,10 @@ exports.isInsidePatchSetPath = isInsidePatchSetPath;
8913
9062
  exports.isLocaleSchema = isLocaleSchema;
8914
9063
  exports.isMimeTypeAccepted = isMimeTypeAccepted;
8915
9064
  exports.isRemoteSchema = isRemoteSchema;
9065
+ exports.isRepairedOnSave = isRepairedOnSave;
8916
9066
  exports.isSchemaSourceFixError = isSchemaSourceFixError;
8917
9067
  exports.isSkippedSource = isSkippedSource;
9068
+ exports.isStudioFix = isStudioFix;
8918
9069
  exports.joinSharedChanges = joinSharedChanges;
8919
9070
  exports.keyOfRecordPath = keyOfRecordPath;
8920
9071
  exports.levenshtein = levenshtein;
@@ -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
- } else if (remoteOptions && noParamsUrl.startsWith(remoteOptions.remoteHost)) ; else if (!noParamsUrl.startsWith("/public")) {
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",
@@ -1054,6 +1054,10 @@ var PatchBlock = zod.z.object({
1054
1054
  parentRef: ParentRef$1
1055
1055
  });
1056
1056
 
1057
+ var SourcePath = zod.z.string().transform(function (path) {
1058
+ return path;
1059
+ });
1060
+
1057
1061
  function _objectWithoutPropertiesLoose(r, e) {
1058
1062
  if (null == r) return {};
1059
1063
  var t = {};
@@ -1076,10 +1080,6 @@ function _objectWithoutProperties(e, t) {
1076
1080
  return i;
1077
1081
  }
1078
1082
 
1079
- var SourcePath = zod.z.string().transform(function (path) {
1080
- return path;
1081
- });
1082
-
1083
1083
  var ModuleFilePath$1 = zod.z.string().transform(function (path) {
1084
1084
  return path;
1085
1085
  });
@@ -1621,7 +1621,7 @@ var ValConfig = zod.z.object({
1621
1621
  gitCommit: zod.z.string().optional(),
1622
1622
  gitBranch: zod.z.string().optional()
1623
1623
  });
1624
- var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("video:add-metadata"), zod.z.literal("video:upload-remote"), zod.z.literal("video:download-remote"), zod.z.literal("videos:add-metadata"), zod.z.literal("videos:check-remote"), zod.z.literal("videos:upload-remote"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("image:check-gallery"), zod.z.literal("file:check-gallery"), zod.z.literal("video:check-gallery"), zod.z.literal("router:check-route"), zod.z.literal("locale:check-locale"), zod.z.literal("router:check-locale-param"), zod.z.literal("record:fill-keys"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("videos:check-unique-folder"), zod.z.literal("videos:check-all-files"), zod.z.literal("jsonValues:extract-entry"), zod.z.literal("view:check-module")]);
1624
+ var ValidationFixZ = zod.z.union([zod.z.literal("image:add-metadata"), zod.z.literal("image:check-metadata"), zod.z.literal("image:check-remote"), zod.z.literal("image:upload-remote"), zod.z.literal("image:download-remote"), zod.z.literal("images:check-remote"), zod.z.literal("images:upload-remote"), zod.z.literal("file:add-metadata"), zod.z.literal("video:add-metadata"), zod.z.literal("video:upload-remote"), zod.z.literal("video:download-remote"), zod.z.literal("videos:add-metadata"), zod.z.literal("videos:check-remote"), zod.z.literal("videos:upload-remote"), zod.z.literal("file:check-metadata"), zod.z.literal("file:check-remote"), zod.z.literal("file:upload-remote"), zod.z.literal("file:download-remote"), zod.z.literal("files:check-remote"), zod.z.literal("files:upload-remote"), zod.z.literal("keyof:check-keys"), zod.z.literal("image:check-gallery"), zod.z.literal("file:check-gallery"), zod.z.literal("video:check-gallery"), zod.z.literal("router:check-route"), zod.z.literal("locale:check-locale"), zod.z.literal("router:check-locale-param"), zod.z.literal("record:fill-keys"), zod.z.literal("images:check-unique-folder"), zod.z.literal("files:check-unique-folder"), zod.z.literal("images:check-all-files"), zod.z.literal("files:check-all-files"), zod.z.literal("videos:check-unique-folder"), zod.z.literal("videos:check-all-files"), zod.z.literal("jsonValues:extract-entry"), zod.z.literal("view:check-module"), zod.z.literal("external:upload"), zod.z.literal("remote:rewrite-host")]);
1625
1625
  var ValidationError = zod.z.object({
1626
1626
  message: zod.z.string(),
1627
1627
  value: zod.z.unknown().optional(),
@@ -2023,7 +2023,13 @@ var Api = {
2023
2023
  coreVersion: zod.z.string(),
2024
2024
  remoteFileBuckets: zod.z.array(zod.z.object({
2025
2025
  bucket: zod.z.string()
2026
- }))
2026
+ })),
2027
+ /**
2028
+ * The host new refs name, from the project's settings: its own
2029
+ * address for a Hosted project whose files are in R2. Optional,
2030
+ * for a content service that predates it.
2031
+ */
2032
+ remoteHost: zod.z.string().optional()
2027
2033
  })
2028
2034
  }), zod.z.object({
2029
2035
  status: zod.z.literal(400),
@@ -2769,6 +2775,105 @@ var Api = {
2769
2775
  })])
2770
2776
  }
2771
2777
  },
2778
+ /**
2779
+ * The Studio's full check, one module per request: its sources against its
2780
+ * schema and its local files against their bytes, on the content the caller
2781
+ * is looking at. See `docs/plans/studio-validate.md`.
2782
+ */
2783
+ "/validate": {
2784
+ POST: {
2785
+ req: {
2786
+ body: zod.z.object({
2787
+ moduleFilePath: ModuleFilePath,
2788
+ /**
2789
+ * The patches the caller is showing, applied over base. Omitted
2790
+ * means every pending patch, as `/sources/~`; empty means base.
2791
+ */
2792
+ patchIds: zod.z.array(PatchId).optional()
2793
+ }),
2794
+ cookies: {
2795
+ val_session: zod.z.string().optional()
2796
+ }
2797
+ },
2798
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2799
+ status: zod.z.literal(500),
2800
+ json: zod.z.object({
2801
+ message: zod.z.string()
2802
+ })
2803
+ }), /** No full check on this server (one running in a browser tab). */
2804
+ zod.z.object({
2805
+ status: zod.z.literal(501),
2806
+ json: zod.z.object({
2807
+ message: zod.z.string()
2808
+ })
2809
+ }), zod.z.object({
2810
+ status: zod.z.literal(200),
2811
+ json: zod.z.object({
2812
+ moduleFilePath: ModuleFilePath,
2813
+ errors: zod.z.record(zod.z.string(), zod.z.array(ValidationError)),
2814
+ /** Set when the module's source could not be read at all. */
2815
+ invalidSource: zod.z.string().optional(),
2816
+ /**
2817
+ * Hosts that did not serve this module's remote files: one entry
2818
+ * per host, however many files it holds. Optional so a server
2819
+ * from before remote checks still parses.
2820
+ */
2821
+ remoteHosts: zod.z.array(zod.z.object({
2822
+ host: zod.z.string(),
2823
+ status: zod.z.union([zod.z.literal("missing"), zod.z.literal("unreachable")]),
2824
+ details: zod.z.string(),
2825
+ sourcePaths: zod.z.array(SourcePath)
2826
+ })).optional()
2827
+ })
2828
+ })])
2829
+ }
2830
+ },
2831
+ /**
2832
+ * The patch that fixes one error the full check reported. The server finds
2833
+ * the error again rather than trusting the caller's copy, and builds only the
2834
+ * fixes `STUDIO_FIXES` lists. The patch is returned, not applied: the Studio
2835
+ * adds it as a pending change like any edit.
2836
+ */
2837
+ "/validate/fix": {
2838
+ POST: {
2839
+ req: {
2840
+ body: zod.z.object({
2841
+ moduleFilePath: ModuleFilePath,
2842
+ sourcePath: SourcePath,
2843
+ fix: ValidationFixZ,
2844
+ patchIds: zod.z.array(PatchId).optional()
2845
+ }),
2846
+ cookies: {
2847
+ val_session: zod.z.string().optional()
2848
+ }
2849
+ },
2850
+ res: zod.z.union([unauthorizedResponse, notFoundResponse, zod.z.object({
2851
+ status: zod.z.literal(400),
2852
+ json: zod.z.object({
2853
+ message: zod.z.string()
2854
+ })
2855
+ }), zod.z.object({
2856
+ status: zod.z.literal(500),
2857
+ json: zod.z.object({
2858
+ message: zod.z.string()
2859
+ })
2860
+ }), /** No full check on this server (one running in a browser tab). */
2861
+ zod.z.object({
2862
+ status: zod.z.literal(501),
2863
+ json: zod.z.object({
2864
+ message: zod.z.string()
2865
+ })
2866
+ }), zod.z.object({
2867
+ status: zod.z.literal(200),
2868
+ json: zod.z.object({
2869
+ patch: Patch,
2870
+ remainingErrors: zod.z.array(ValidationError.extend({
2871
+ sourcePath: zod.z.string().optional()
2872
+ }))
2873
+ })
2874
+ })])
2875
+ }
2876
+ },
2772
2877
  "/publish-job-prepare": {
2773
2878
  POST: {
2774
2879
  req: {
@@ -3823,7 +3928,7 @@ var createValClient = function createValClient(host, config, options) {
3823
3928
  _context2.n = 2;
3824
3929
  break;
3825
3930
  }
3826
- console.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3931
+ core.Internal.log.error("Got an invalid request body while validating client-side. This is most likely a Val bug.", {
3827
3932
  path: path,
3828
3933
  method: method,
3829
3934
  body: anyReq.body,
@@ -3901,7 +4006,7 @@ var createValClient = function createValClient(host, config, options) {
3901
4006
  _context.n = 4;
3902
4007
  break;
3903
4008
  }
3904
- console.error("Server responded with an error", json);
4009
+ core.Internal.log.error("Server responded with an error", json);
3905
4010
  message = getErrorMessageFromUnknownJson(json, "Unknown error");
3906
4011
  return _context.a(2, {
3907
4012
  status: 500,
@@ -4526,14 +4631,14 @@ function filterRoutesByPatterns(routes, includePattern, excludePattern) {
4526
4631
  try {
4527
4632
  includeRegex = new RegExp(includePattern.source, includePattern.flags);
4528
4633
  } catch (e) {
4529
- 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.");
4634
+ 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.");
4530
4635
  }
4531
4636
  }
4532
4637
  if (excludePattern) {
4533
4638
  try {
4534
4639
  excludeRegex = new RegExp(excludePattern.source, excludePattern.flags);
4535
4640
  } catch (e) {
4536
- 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.");
4641
+ 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.");
4537
4642
  }
4538
4643
  }
4539
4644
  return routes.filter(function (route) {
@@ -6312,6 +6417,16 @@ function partitionValidationErrors(validationErrors) {
6312
6417
  skipped: skipped
6313
6418
  };
6314
6419
  }
6420
+
6421
+ /**
6422
+ * Whether the Studio leaves this error to the server, which repairs it on
6423
+ * save, rather than showing it and holding a publish back for it. One rule
6424
+ * for every gate: `val publish` asks the same question, so the CLI does not
6425
+ * refuse what the Studio would publish.
6426
+ */
6427
+ function isRepairedOnSave(error) {
6428
+ return isSkippedFix(error);
6429
+ }
6315
6430
  function isSkippedFix(error) {
6316
6431
  var _error$fixes;
6317
6432
  var fixes = (_error$fixes = error.fixes) !== null && _error$fixes !== void 0 ? _error$fixes : [];
@@ -6381,6 +6496,12 @@ function isSkippableFixCode(fix) {
6381
6496
  // under `val external upload` and never under a blanket `--fix`. Surfacing
6382
6497
  // it is the whole point: someone has to decide.
6383
6498
  return false;
6499
+ case "remote:rewrite-host":
6500
+ // Reported only by the server's full check (the Studio's Validate page,
6501
+ // `val validate`), which asks the ref's host -- never by a schema, so
6502
+ // the Studio's own validator never holds one. Were it to, a person has
6503
+ // to see it: the host is gone, and nothing on save repoints the ref.
6504
+ return false;
6384
6505
  default:
6385
6506
  {
6386
6507
  return false;
@@ -6420,6 +6541,33 @@ function filterBlockingValidationErrors(validationErrors, schemas, sources) {
6420
6541
  return partitionValidationErrors(resolved).surfaced;
6421
6542
  }
6422
6543
 
6544
+ /**
6545
+ * The fixes the Studio's full check offers a **Fix** button for.
6546
+ *
6547
+ * Each is one `createFixPatch` can build without a disk: it reads a file's
6548
+ * bytes through `FixFiles`, or needs no bytes at all. The server refuses any
6549
+ * other code on `/validate/fix`, and the Studio shows those errors with the
6550
+ * command to run instead of a button — so a code is added here when its fix
6551
+ * can run in http mode and on the platform, not before. See
6552
+ * `docs/plans/studio-validate.md`, "Order of work".
6553
+ */
6554
+ var STUDIO_FIXES = ["image:add-metadata", "image:check-metadata", "file:add-metadata", "file:check-metadata", "video:add-metadata", "videos:add-metadata", "view:check-module",
6555
+ // A stale remote ref: re-read through `FixFiles.readRemoteFile`, rewritten
6556
+ // on the host it was already on.
6557
+ "image:check-remote", "file:check-remote",
6558
+ // One entry of an `s.imagedir()` / `s.filedir()`: removed when its file is
6559
+ // gone, rewritten from its bytes when they disagree. Built for that entry
6560
+ // alone, never the whole directory (`fixForStudio`).
6561
+ "images:check-all-files", "files:check-all-files",
6562
+ // A platform ref on a host that no longer serves its project, pointed at
6563
+ // the project's own `valstart.dev` address. Derived from the ref alone.
6564
+ "remote:rewrite-host"];
6565
+ function isStudioFix(fix) {
6566
+ return STUDIO_FIXES.some(function (studioFix) {
6567
+ return studioFix === fix;
6568
+ });
6569
+ }
6570
+
6423
6571
  /**
6424
6572
  * Every decision `encode` makes, with none of the pixels.
6425
6573
  *
@@ -8212,7 +8360,7 @@ function schemaTypesOfPath(schema, patchPath) {
8212
8360
  } else {
8213
8361
  var _unreachable = current;
8214
8362
  var unknownType = _unreachable.type;
8215
- console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8363
+ core.Internal.log.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
8216
8364
  return new Set([unknownType]);
8217
8365
  }
8218
8366
  }
@@ -8551,9 +8699,9 @@ var PatchSets = /*#__PURE__*/function () {
8551
8699
  } catch (e) {
8552
8700
  // We might be in this situation if the schema changes, etc etc:
8553
8701
  if (e instanceof Error) {
8554
- console.error("Could not resolve path while creating patch set", e.message);
8702
+ core.Internal.log.error("Could not resolve path while creating patch set", e.message);
8555
8703
  } else {
8556
- console.error("Could not resolve path while creating patch set", e);
8704
+ core.Internal.log.error("Could not resolve path while creating patch set", e);
8557
8705
  }
8558
8706
  // "terminate" the entire module file path (i.e. all patches are their own patch set)
8559
8707
  this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
@@ -8838,6 +8986,7 @@ exports.RemirrorTextMark = RemirrorTextMark;
8838
8986
  exports.RestoreVerdict = RestoreVerdict;
8839
8987
  exports.RichTextOptions = RichTextOptions;
8840
8988
  exports.SCHEMA_SOURCE_FIXES = SCHEMA_SOURCE_FIXES;
8989
+ exports.STUDIO_FIXES = STUDIO_FIXES;
8841
8990
  exports.SerializedArraySchema = SerializedArraySchema;
8842
8991
  exports.SerializedBooleanSchema = SerializedBooleanSchema;
8843
8992
  exports.SerializedCodeSchema = SerializedCodeSchema;
@@ -8913,8 +9062,10 @@ exports.isInsidePatchSetPath = isInsidePatchSetPath;
8913
9062
  exports.isLocaleSchema = isLocaleSchema;
8914
9063
  exports.isMimeTypeAccepted = isMimeTypeAccepted;
8915
9064
  exports.isRemoteSchema = isRemoteSchema;
9065
+ exports.isRepairedOnSave = isRepairedOnSave;
8916
9066
  exports.isSchemaSourceFixError = isSchemaSourceFixError;
8917
9067
  exports.isSkippedSource = isSkippedSource;
9068
+ exports.isStudioFix = isStudioFix;
8918
9069
  exports.joinSharedChanges = joinSharedChanges;
8919
9070
  exports.keyOfRecordPath = keyOfRecordPath;
8920
9071
  exports.levenshtein = levenshtein;