@valbuild/core 0.126.0 → 0.128.0
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 +296 -0
- package/dist/declarations/src/index.d.ts +5 -1
- package/dist/declarations/src/initSchema.d.ts +31 -15
- package/dist/declarations/src/locale.d.ts +55 -0
- package/dist/declarations/src/schema/array.d.ts +4 -0
- package/dist/declarations/src/schema/declaredKeys.d.ts +37 -0
- package/dist/declarations/src/schema/discriminatedUnion.d.ts +4 -0
- package/dist/declarations/src/schema/discriminatedUnionBranch.d.ts +20 -0
- package/dist/declarations/src/schema/enum.d.ts +9 -0
- package/dist/declarations/src/schema/file.d.ts +3 -3
- package/dist/declarations/src/schema/{files.d.ts → fileset.d.ts} +10 -10
- package/dist/declarations/src/schema/hasRemoteFileSchema.d.ts +3 -3
- package/dist/declarations/src/schema/image.d.ts +9 -5
- package/dist/declarations/src/schema/{images.d.ts → imageset.d.ts} +54 -21
- package/dist/declarations/src/schema/index.d.ts +116 -3
- package/dist/declarations/src/schema/literal.d.ts +2 -0
- package/dist/declarations/src/schema/locale.d.ts +132 -0
- package/dist/declarations/src/schema/object.d.ts +7 -0
- package/dist/declarations/src/schema/record.d.ts +57 -7
- package/dist/declarations/src/schema/settings.d.ts +54 -1
- package/dist/declarations/src/schema/validation/ValidationFix.d.ts +1 -1
- package/dist/declarations/src/source/settings.d.ts +51 -0
- package/dist/{index-6db78f3c.cjs.prod.js → index-053ccde2.cjs.prod.js} +1114 -91
- package/dist/{index-b41b638f.cjs.dev.js → index-c3ae637d.cjs.dev.js} +1114 -91
- package/dist/{index-cd25c2dc.esm.js → index-db41de3c.esm.js} +1109 -92
- package/dist/valbuild-core.cjs.dev.js +7 -1
- package/dist/valbuild-core.cjs.prod.js +7 -1
- package/dist/valbuild-core.esm.js +1 -1
- package/package.json +1 -1
- package/patch/dist/valbuild-core-patch.cjs.dev.js +1 -1
- package/patch/dist/valbuild-core-patch.cjs.prod.js +1 -1
- package/patch/dist/valbuild-core-patch.esm.js +2 -2
|
@@ -163,19 +163,217 @@ function _inherits(t, e) {
|
|
|
163
163
|
// import { SerializedI18nSchema } from "./future/i18n";
|
|
164
164
|
// import { SerializedOneOfSchema } from "./future/oneOf";
|
|
165
165
|
|
|
166
|
+
/**
|
|
167
|
+
* A locale scope's path, as something to read in a message.
|
|
168
|
+
*
|
|
169
|
+
* The walk names the item of an array or record `*`, which says nothing to
|
|
170
|
+
* whoever has to fix this. `[]` is the convention people already read as "each
|
|
171
|
+
* of these", and a path that is nothing BUT items has no field to name at all.
|
|
172
|
+
*/
|
|
173
|
+
function describeScopePath(path) {
|
|
174
|
+
if (path.every(function (segment) {
|
|
175
|
+
return segment === "*";
|
|
176
|
+
})) {
|
|
177
|
+
return "its entries";
|
|
178
|
+
}
|
|
179
|
+
var rendered = "";
|
|
180
|
+
var _iterator = result._createForOfIteratorHelper(path),
|
|
181
|
+
_step;
|
|
182
|
+
try {
|
|
183
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
184
|
+
var segment = _step.value;
|
|
185
|
+
if (segment === "*") {
|
|
186
|
+
rendered += "[]";
|
|
187
|
+
} else {
|
|
188
|
+
rendered += rendered === "" ? segment : ".".concat(segment);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch (err) {
|
|
192
|
+
_iterator.e(err);
|
|
193
|
+
} finally {
|
|
194
|
+
_iterator.f();
|
|
195
|
+
}
|
|
196
|
+
return "'".concat(rendered, "'");
|
|
197
|
+
}
|
|
166
198
|
var Schema = /*#__PURE__*/function () {
|
|
167
199
|
function Schema() {
|
|
168
200
|
_classCallCheck(this, Schema);
|
|
201
|
+
/**
|
|
202
|
+
* The answer, computed once per schema.
|
|
203
|
+
*
|
|
204
|
+
* Memoised because the question is asked from `executeValidate`, which runs
|
|
205
|
+
* once per SOURCE instance: an array of five hundred blocks asks the item
|
|
206
|
+
* schema five hundred times, and each answer walks the schema below it
|
|
207
|
+
* looking for a nested scope. The answer cannot differ between two instances
|
|
208
|
+
* of the same schema — nothing here reads the source — so the walk is done
|
|
209
|
+
* once and the result handed back after that.
|
|
210
|
+
*
|
|
211
|
+
* The error is still reported at every instance's path. Val's validation
|
|
212
|
+
* errors are keyed by source path and that is where the Studio draws them, so
|
|
213
|
+
* a schema error on a row is a schema error on every row; reporting it on one
|
|
214
|
+
* arbitrary row would put it somewhere nobody was looking.
|
|
215
|
+
*/
|
|
216
|
+
_defineProperty(this, "localeScopeErrorsMemo", void 0);
|
|
169
217
|
}
|
|
170
218
|
return _createClass(Schema, [{
|
|
219
|
+
key: "isLocaleField",
|
|
220
|
+
value:
|
|
221
|
+
/**
|
|
222
|
+
* Whether this node is a locale — the field that MARKS a scope, `s.locale()`.
|
|
223
|
+
*
|
|
224
|
+
* Only `LocaleSchema` overrides this. A base implementation rather than an
|
|
225
|
+
* abstract one on purpose: every other schema class answers no, and a
|
|
226
|
+
* question every class had to answer would be twenty edits for one yes.
|
|
227
|
+
*
|
|
228
|
+
* Not the same question as {@link opensLocaleScope}: a locale field marks the
|
|
229
|
+
* scope, the object AROUND it is the scope. See `localeScope.ts`.
|
|
230
|
+
*/
|
|
231
|
+
function isLocaleField() {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Whether this node OPENS a locale scope, and what opens it.
|
|
237
|
+
*
|
|
238
|
+
* An object with a `s.locale()` field opens one; so does a record keyed by
|
|
239
|
+
* `s.locale()`. Everything below such a node is in that one language, which
|
|
240
|
+
* is why a scope may not contain another — see `localeScope.ts` for the rule
|
|
241
|
+
* and the reason it is validated rather than typed.
|
|
242
|
+
*/
|
|
243
|
+
}, {
|
|
244
|
+
key: "opensLocaleScope",
|
|
245
|
+
value: function opensLocaleScope() {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* The child schemas a locale scope reaches, by the path segment that reaches
|
|
251
|
+
* them.
|
|
252
|
+
*
|
|
253
|
+
* A structural walk that deliberately does NOT go through `executeSerialize`:
|
|
254
|
+
* serializing a subtree at every node to ask a question about its shape is
|
|
255
|
+
* quadratic, and this is asked during validation. `*` stands for the item of
|
|
256
|
+
* an array or record, which has no name of its own.
|
|
257
|
+
*/
|
|
258
|
+
}, {
|
|
259
|
+
key: "localeScopeChildren",
|
|
260
|
+
value: function localeScopeChildren() {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Every locale scope opened strictly BELOW this node, by path.
|
|
266
|
+
*
|
|
267
|
+
* Stops descending at each one it finds, so a scope three deep is reported
|
|
268
|
+
* once, by the scope immediately enclosing it, rather than by every ancestor.
|
|
269
|
+
*/
|
|
270
|
+
}, {
|
|
271
|
+
key: "localeScopesBelow",
|
|
272
|
+
value: function localeScopesBelow() {
|
|
273
|
+
var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
274
|
+
var found = [];
|
|
275
|
+
var _iterator2 = result._createForOfIteratorHelper(this.localeScopeChildren()),
|
|
276
|
+
_step2;
|
|
277
|
+
try {
|
|
278
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
279
|
+
var _step2$value = _step2.value,
|
|
280
|
+
key = _step2$value.key,
|
|
281
|
+
schema = _step2$value.schema;
|
|
282
|
+
var _path = [].concat(_toConsumableArray(prefix), [key]);
|
|
283
|
+
var opened = schema.opensLocaleScope();
|
|
284
|
+
if (opened !== null) {
|
|
285
|
+
found.push({
|
|
286
|
+
path: _path,
|
|
287
|
+
kind: opened
|
|
288
|
+
});
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
found.push.apply(found, _toConsumableArray(schema.localeScopesBelow(_path)));
|
|
292
|
+
}
|
|
293
|
+
} catch (err) {
|
|
294
|
+
_iterator2.e(err);
|
|
295
|
+
} finally {
|
|
296
|
+
_iterator2.f();
|
|
297
|
+
}
|
|
298
|
+
return found;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* The scope rule, as errors at this node — or `false` if it is not broken.
|
|
303
|
+
*
|
|
304
|
+
* Two things are wrong and both are wrong in the SCHEMA rather than in the
|
|
305
|
+
* content, so both are `schemaError`s: an object with two locale fields (the
|
|
306
|
+
* subtree below it would be in two languages at once), and a locale scope
|
|
307
|
+
* inside another (the inner one would silently override the outer for part
|
|
308
|
+
* of a subtree that is supposed to be one language throughout).
|
|
309
|
+
*
|
|
310
|
+
* Validated rather than typed on purpose. Expressing "no scope below this
|
|
311
|
+
* one" as a constraint means threading it through every schema class's type
|
|
312
|
+
* parameter, and the errors that fall out of a recursive constraint like
|
|
313
|
+
* that name the whole tree — an unrelated typo in a `.val.ts` would print
|
|
314
|
+
* pages. See the design notes on the locales PR.
|
|
315
|
+
*/
|
|
316
|
+
}, {
|
|
317
|
+
key: "localeScopeErrors",
|
|
318
|
+
value: function localeScopeErrors() {
|
|
319
|
+
if (this.localeScopeErrorsMemo === undefined) {
|
|
320
|
+
this.localeScopeErrorsMemo = this.computeLocaleScopeErrors();
|
|
321
|
+
}
|
|
322
|
+
return this.localeScopeErrorsMemo;
|
|
323
|
+
}
|
|
324
|
+
}, {
|
|
325
|
+
key: "computeLocaleScopeErrors",
|
|
326
|
+
value: function computeLocaleScopeErrors() {
|
|
327
|
+
var errors = [];
|
|
328
|
+
var localeFields = this.localeFieldNames();
|
|
329
|
+
if (localeFields.length > 1) {
|
|
330
|
+
errors.push({
|
|
331
|
+
message: "An object can be in one language, so it can have one locale field. Found ".concat(localeFields.map(function (each) {
|
|
332
|
+
return "'".concat(each, "'");
|
|
333
|
+
}).join(", "), "."),
|
|
334
|
+
schemaError: true
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
var opened = this.opensLocaleScope();
|
|
338
|
+
if (opened !== null) {
|
|
339
|
+
var _iterator3 = result._createForOfIteratorHelper(this.localeScopesBelow()),
|
|
340
|
+
_step3;
|
|
341
|
+
try {
|
|
342
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
343
|
+
var nested = _step3.value;
|
|
344
|
+
errors.push({
|
|
345
|
+
message: "Everything here is already in one language, so ".concat(describeScopePath(nested.path), " cannot set another. Move the ").concat(nested.kind === "key" ? "locale-keyed record" : "locale field", " out of this ").concat(opened === "key" ? "locale-keyed record" : "object", ", or take the outer one away."),
|
|
346
|
+
schemaError: true
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
} catch (err) {
|
|
350
|
+
_iterator3.e(err);
|
|
351
|
+
} finally {
|
|
352
|
+
_iterator3.f();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return errors;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* This node's own `s.locale()` fields, where it is an object that has any.
|
|
360
|
+
*
|
|
361
|
+
* Empty everywhere else, so `localeScopeErrors` can live on the base class.
|
|
362
|
+
*/
|
|
363
|
+
}, {
|
|
364
|
+
key: "localeFieldNames",
|
|
365
|
+
value: function localeFieldNames() {
|
|
366
|
+
return [];
|
|
367
|
+
}
|
|
368
|
+
}, {
|
|
171
369
|
key: "executeCustomValidateFunctions",
|
|
172
370
|
value: function executeCustomValidateFunctions(src, customValidateFunctions, ctx) {
|
|
173
371
|
var errors = [];
|
|
174
|
-
var
|
|
175
|
-
|
|
372
|
+
var _iterator4 = result._createForOfIteratorHelper(customValidateFunctions),
|
|
373
|
+
_step4;
|
|
176
374
|
try {
|
|
177
|
-
for (
|
|
178
|
-
var customValidateFunction =
|
|
375
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
376
|
+
var customValidateFunction = _step4.value;
|
|
179
377
|
try {
|
|
180
378
|
var result$1 = customValidateFunction(src, ctx);
|
|
181
379
|
if (result$1) {
|
|
@@ -193,9 +391,9 @@ var Schema = /*#__PURE__*/function () {
|
|
|
193
391
|
}
|
|
194
392
|
}
|
|
195
393
|
} catch (err) {
|
|
196
|
-
|
|
394
|
+
_iterator4.e(err);
|
|
197
395
|
} finally {
|
|
198
|
-
|
|
396
|
+
_iterator4.f();
|
|
199
397
|
}
|
|
200
398
|
return errors;
|
|
201
399
|
}
|
|
@@ -294,11 +492,11 @@ var Schema = /*#__PURE__*/function () {
|
|
|
294
492
|
return incoming;
|
|
295
493
|
}
|
|
296
494
|
for (var pathS in incoming) {
|
|
297
|
-
var
|
|
298
|
-
if (current[
|
|
299
|
-
current[
|
|
495
|
+
var _path2 = pathS;
|
|
496
|
+
if (current[_path2]) {
|
|
497
|
+
current[_path2] = current[_path2].concat(incoming[_path2]);
|
|
300
498
|
} else {
|
|
301
|
-
current[
|
|
499
|
+
current[_path2] = incoming[_path2];
|
|
302
500
|
}
|
|
303
501
|
}
|
|
304
502
|
return current;
|
|
@@ -333,6 +531,10 @@ var GetSource = Symbol["for"]("@valbuild/core/GetSource");
|
|
|
333
531
|
var ValError = Symbol["for"]("@valbuild/core/ValError");
|
|
334
532
|
var GenericSelector = /*#__PURE__*/_createClass(function GenericSelector(valOrExpr, path, schema, error) {
|
|
335
533
|
_classCallCheck(this, GenericSelector);
|
|
534
|
+
_defineProperty(this, Path, void 0);
|
|
535
|
+
_defineProperty(this, GetSource, void 0);
|
|
536
|
+
_defineProperty(this, ValError, void 0);
|
|
537
|
+
_defineProperty(this, GetSchema, void 0);
|
|
336
538
|
this[Path] = path;
|
|
337
539
|
this[GetSource] = valOrExpr;
|
|
338
540
|
this[ValError] = error;
|
|
@@ -935,6 +1137,18 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
935
1137
|
} finally {
|
|
936
1138
|
_iterator.f();
|
|
937
1139
|
}
|
|
1140
|
+
var _iterator2 = result._createForOfIteratorHelper(this.localeScopeErrors()),
|
|
1141
|
+
_step2;
|
|
1142
|
+
try {
|
|
1143
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1144
|
+
var scopeError = _step2.value;
|
|
1145
|
+
error = this.appendValidationError(error, path, scopeError.message, src, scopeError.schemaError);
|
|
1146
|
+
}
|
|
1147
|
+
} catch (err) {
|
|
1148
|
+
_iterator2.e(err);
|
|
1149
|
+
} finally {
|
|
1150
|
+
_iterator2.f();
|
|
1151
|
+
}
|
|
938
1152
|
for (var _i = 0, _Object$entries = Object.entries(this.items); _i < _Object$entries.length; _i++) {
|
|
939
1153
|
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
940
1154
|
_key = _Object$entries$_i[0],
|
|
@@ -1018,7 +1232,7 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1018
1232
|
key: "nullable",
|
|
1019
1233
|
value: function nullable() {
|
|
1020
1234
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
1021
|
-
return new ObjectSchema(this.items, true,
|
|
1235
|
+
return new ObjectSchema(this.items, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
1022
1236
|
}
|
|
1023
1237
|
}, {
|
|
1024
1238
|
key: "readonly",
|
|
@@ -1032,6 +1246,35 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1032
1246
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
1033
1247
|
return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
|
|
1034
1248
|
}
|
|
1249
|
+
|
|
1250
|
+
/** The names of this object's `s.locale()` fields, in declaration order. */
|
|
1251
|
+
}, {
|
|
1252
|
+
key: "localeFieldNames",
|
|
1253
|
+
value: function localeFieldNames() {
|
|
1254
|
+
var _this2 = this;
|
|
1255
|
+
return Object.keys(this.items).filter(function (key) {
|
|
1256
|
+
return _this2.items[key]["isLocaleField"]();
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
}, {
|
|
1260
|
+
key: "opensLocaleScope",
|
|
1261
|
+
value: function opensLocaleScope() {
|
|
1262
|
+
// More than one is itself the error, reported by `localeScopeErrors`. It
|
|
1263
|
+
// still opens a scope: reporting "two locale fields" AND "a scope inside a
|
|
1264
|
+
// scope" for the same object would be two errors about one mistake.
|
|
1265
|
+
return this.localeFieldNames().length > 0 ? "field" : null;
|
|
1266
|
+
}
|
|
1267
|
+
}, {
|
|
1268
|
+
key: "localeScopeChildren",
|
|
1269
|
+
value: function localeScopeChildren() {
|
|
1270
|
+
var _this3 = this;
|
|
1271
|
+
return Object.keys(this.items).map(function (key) {
|
|
1272
|
+
return {
|
|
1273
|
+
key: key,
|
|
1274
|
+
schema: _this3.items[key]
|
|
1275
|
+
};
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1035
1278
|
}, {
|
|
1036
1279
|
key: "executeCustomValidateAt",
|
|
1037
1280
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -1296,7 +1539,7 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1296
1539
|
key: "nullable",
|
|
1297
1540
|
value: function nullable() {
|
|
1298
1541
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
1299
|
-
return new ArraySchema(this.item, true,
|
|
1542
|
+
return new ArraySchema(this.item, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.previewInput, this.renderInput);
|
|
1300
1543
|
}
|
|
1301
1544
|
}, {
|
|
1302
1545
|
key: "readonly",
|
|
@@ -1310,6 +1553,14 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1310
1553
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
1311
1554
|
return new ArraySchema(this.item, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.previewInput, this.renderInput);
|
|
1312
1555
|
}
|
|
1556
|
+
}, {
|
|
1557
|
+
key: "localeScopeChildren",
|
|
1558
|
+
value: function localeScopeChildren() {
|
|
1559
|
+
return [{
|
|
1560
|
+
key: "*",
|
|
1561
|
+
schema: this.item
|
|
1562
|
+
}];
|
|
1563
|
+
}
|
|
1313
1564
|
}, {
|
|
1314
1565
|
key: "executeCustomValidateAt",
|
|
1315
1566
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -1483,6 +1734,8 @@ var array = function array(schema) {
|
|
|
1483
1734
|
};
|
|
1484
1735
|
|
|
1485
1736
|
var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
1737
|
+
/** Type-only marker: as a record key, this declares the key set. See `LocaleSchema`. */
|
|
1738
|
+
|
|
1486
1739
|
function LiteralSchema(value) {
|
|
1487
1740
|
var _this;
|
|
1488
1741
|
var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -1614,7 +1867,7 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1614
1867
|
}, {
|
|
1615
1868
|
key: "nullable",
|
|
1616
1869
|
value: function nullable() {
|
|
1617
|
-
return new LiteralSchema(this.value, true,
|
|
1870
|
+
return new LiteralSchema(this.value, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
1618
1871
|
}
|
|
1619
1872
|
}, {
|
|
1620
1873
|
key: "readonly",
|
|
@@ -2035,7 +2288,7 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2035
2288
|
key: "nullable",
|
|
2036
2289
|
value: function nullable() {
|
|
2037
2290
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
2038
|
-
return new DiscriminatedUnionSchema(this.key, this.items, true,
|
|
2291
|
+
return new DiscriminatedUnionSchema(this.key, this.items, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
2039
2292
|
}
|
|
2040
2293
|
}, {
|
|
2041
2294
|
key: "readonly",
|
|
@@ -2049,6 +2302,20 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2049
2302
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2050
2303
|
return new DiscriminatedUnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
|
|
2051
2304
|
}
|
|
2305
|
+
}, {
|
|
2306
|
+
key: "localeScopeChildren",
|
|
2307
|
+
value: function localeScopeChildren() {
|
|
2308
|
+
// Every variant is walked under the SAME path: whichever one the value
|
|
2309
|
+
// takes, that is where it sits. `s.enum()` has no children at all — its
|
|
2310
|
+
// values are strings, not schemas — which is why only this half of the old
|
|
2311
|
+
// `s.union` has this.
|
|
2312
|
+
return this.items.map(function (item) {
|
|
2313
|
+
return {
|
|
2314
|
+
key: "*",
|
|
2315
|
+
schema: item
|
|
2316
|
+
};
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2052
2319
|
}, {
|
|
2053
2320
|
key: "executeCustomValidateAt",
|
|
2054
2321
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -3261,7 +3528,7 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
|
|
|
3261
3528
|
*
|
|
3262
3529
|
* @example
|
|
3263
3530
|
* const schema = s
|
|
3264
|
-
* .image({ accept: "image/webp",
|
|
3531
|
+
* .image({ accept: "image/webp", dir: "/public/val/images" })
|
|
3265
3532
|
* .remote();
|
|
3266
3533
|
* export default c.define("/example.val.ts", schema, {
|
|
3267
3534
|
* path: "https://remote.val.build/file/p/my-project/b/01/v/1.0.0/h/8f2a1c/f/3b9d70/p/public/val/images/example.webp",
|
|
@@ -3440,6 +3707,10 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
|
|
|
3440
3707
|
/**
|
|
3441
3708
|
* The entries of the gallery this field points at, or null when it is a
|
|
3442
3709
|
* standalone field.
|
|
3710
|
+
*
|
|
3711
|
+
* `AltSource` rather than a specific alt type: a field never reads an entry's
|
|
3712
|
+
* alt — it carries its own — so it only needs the entry keys and the
|
|
3713
|
+
* dimensions, and a gallery of any alt shape can back it.
|
|
3443
3714
|
*/
|
|
3444
3715
|
}, {
|
|
3445
3716
|
key: "galleryEntries",
|
|
@@ -4459,7 +4730,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
|
|
|
4459
4730
|
}, {
|
|
4460
4731
|
key: "nullable",
|
|
4461
4732
|
value: function nullable() {
|
|
4462
|
-
return new RichTextSchema(this.options, true,
|
|
4733
|
+
return new RichTextSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
4463
4734
|
}
|
|
4464
4735
|
}, {
|
|
4465
4736
|
key: "readonly",
|
|
@@ -4976,6 +5247,68 @@ function hasInlineExternalEntries(source) {
|
|
|
4976
5247
|
return _typeof(source) === "object" && source !== null && !Array.isArray(source) && !isExternal(source) && Object.keys(source).length > 0;
|
|
4977
5248
|
}
|
|
4978
5249
|
|
|
5250
|
+
/**
|
|
5251
|
+
* The keys a record is REQUIRED to hold, where its key schema says what they are.
|
|
5252
|
+
*
|
|
5253
|
+
* Most records have an open key set — `s.record(s.string(), item)` holds
|
|
5254
|
+
* whatever anyone adds — and this returns `null` for those. A record keyed by
|
|
5255
|
+
* something that enumerates its values is different in kind: the keys are part
|
|
5256
|
+
* of the schema, so a missing one is a hole in the content rather than content
|
|
5257
|
+
* nobody has written yet.
|
|
5258
|
+
*
|
|
5259
|
+
* Two key schemas enumerate. A union of literals does it locally, so its keys
|
|
5260
|
+
* are here. `s.locale()` does it in the settings module, which is another file
|
|
5261
|
+
* and so cannot be read from a serialized schema — that case says only which
|
|
5262
|
+
* kind it is, and is resolved against `locales.available` by
|
|
5263
|
+
* `resolveSchemaSourceFixes`, the same crossing `keyOf` and `route` make.
|
|
5264
|
+
*/
|
|
5265
|
+
|
|
5266
|
+
/**
|
|
5267
|
+
* What `key` requires a record to hold, or `null` where it requires nothing.
|
|
5268
|
+
*
|
|
5269
|
+
* Works from the SERIALIZED schema so that the Studio, the validation worker
|
|
5270
|
+
* and the server all answer this the same way — none of them has the schema
|
|
5271
|
+
* instance, and `SchemaStore` deliberately holds serialized schemas only.
|
|
5272
|
+
*/
|
|
5273
|
+
function declaredKeySetOf(key) {
|
|
5274
|
+
if (key === undefined) {
|
|
5275
|
+
return null;
|
|
5276
|
+
}
|
|
5277
|
+
if (key.type === "literal") {
|
|
5278
|
+
return {
|
|
5279
|
+
kind: "literals",
|
|
5280
|
+
keys: [key.value]
|
|
5281
|
+
};
|
|
5282
|
+
}
|
|
5283
|
+
if (key.type === "enum") {
|
|
5284
|
+
// An enum names every value it may take, so those values ARE the key set.
|
|
5285
|
+
// `discriminated-union` is deliberately absent: it discriminates objects
|
|
5286
|
+
// and cannot be a record key at all.
|
|
5287
|
+
return {
|
|
5288
|
+
kind: "literals",
|
|
5289
|
+
keys: _toConsumableArray(key.values)
|
|
5290
|
+
};
|
|
5291
|
+
}
|
|
5292
|
+
if (key.type === "locale") {
|
|
5293
|
+
return {
|
|
5294
|
+
kind: "locale"
|
|
5295
|
+
};
|
|
5296
|
+
}
|
|
5297
|
+
return null;
|
|
5298
|
+
}
|
|
5299
|
+
|
|
5300
|
+
/**
|
|
5301
|
+
* The declared keys a record is missing, in the order the schema declares them.
|
|
5302
|
+
*
|
|
5303
|
+
* Declaration order rather than the source's: this is read as "what is left to
|
|
5304
|
+
* write", and the answer should not reshuffle itself as entries are added.
|
|
5305
|
+
*/
|
|
5306
|
+
function missingDeclaredKeys(declared, present) {
|
|
5307
|
+
return declared.filter(function (key) {
|
|
5308
|
+
return !present.includes(key);
|
|
5309
|
+
});
|
|
5310
|
+
}
|
|
5311
|
+
|
|
4979
5312
|
/**
|
|
4980
5313
|
* The source type of a `.jsonValues()` record: every entry value is EITHER a
|
|
4981
5314
|
* lazily loaded {@link JsonSource} whose resolved content is the (loosened, see
|
|
@@ -5007,6 +5340,16 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5007
5340
|
var externalLabel = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : null;
|
|
5008
5341
|
_classCallCheck(this, RecordSchema);
|
|
5009
5342
|
_this = _callSuper(this, RecordSchema);
|
|
5343
|
+
/**
|
|
5344
|
+
* The key set this record's schema declares, computed once.
|
|
5345
|
+
*
|
|
5346
|
+
* `declaredKeySetOf` reads a SERIALIZED schema, and serializing the key
|
|
5347
|
+
* schema walks it — twice per validate, and once per record instance, for an
|
|
5348
|
+
* answer that is a property of the schema and cannot move between them. A
|
|
5349
|
+
* schema is built once and validated against many times, so the walk happens
|
|
5350
|
+
* on the first question and not on any after it.
|
|
5351
|
+
*/
|
|
5352
|
+
_defineProperty(_this, "declaredKeys", void 0);
|
|
5010
5353
|
_this.item = item;
|
|
5011
5354
|
_this.opt = opt;
|
|
5012
5355
|
_this.customValidateFunctions = customValidateFunctions;
|
|
@@ -5122,9 +5465,9 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5122
5465
|
if (this.mediaOptions) {
|
|
5123
5466
|
var checkFix = this.mediaOptions.type === "images" ? "images:check-unique-folder" : "files:check-unique-folder";
|
|
5124
5467
|
var uniqueCheckError = {
|
|
5125
|
-
message: "Gallery directory '".concat(this.mediaOptions.
|
|
5468
|
+
message: "Gallery directory '".concat(this.mediaOptions.dir, "' must be unique across all galleries"),
|
|
5126
5469
|
value: {
|
|
5127
|
-
|
|
5470
|
+
dir: this.mediaOptions.dir,
|
|
5128
5471
|
type: this.mediaOptions.type
|
|
5129
5472
|
},
|
|
5130
5473
|
fixes: [checkFix]
|
|
@@ -5140,9 +5483,9 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5140
5483
|
}
|
|
5141
5484
|
var allFilesCheckFix = this.mediaOptions.type === "images" ? "images:check-all-files" : "files:check-all-files";
|
|
5142
5485
|
var allFilesCheckError = {
|
|
5143
|
-
message: "Directory '".concat(this.mediaOptions.
|
|
5486
|
+
message: "Directory '".concat(this.mediaOptions.dir, "' may have files not tracked by this gallery"),
|
|
5144
5487
|
value: {
|
|
5145
|
-
|
|
5488
|
+
dir: this.mediaOptions.dir,
|
|
5146
5489
|
type: this.mediaOptions.type
|
|
5147
5490
|
},
|
|
5148
5491
|
fixes: [allFilesCheckFix]
|
|
@@ -5153,6 +5496,11 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5153
5496
|
error = _objectSpread2(_objectSpread2({}, error), {}, _defineProperty({}, path, [allFilesCheckError]));
|
|
5154
5497
|
}
|
|
5155
5498
|
}
|
|
5499
|
+
// A record whose keys are declared by its schema holds every one of them,
|
|
5500
|
+
// and an entry nobody has written yet is `null` rather than absent — so
|
|
5501
|
+
// `null` is a value here, not a value of the wrong type, and the item
|
|
5502
|
+
// schema is not asked about it.
|
|
5503
|
+
var hasDeclaredKeys = this.declaredKeySet() !== null;
|
|
5156
5504
|
Object.entries(src).forEach(function (_ref5) {
|
|
5157
5505
|
var _ref6 = _slicedToArray(_ref5, 2),
|
|
5158
5506
|
key = _ref6[0],
|
|
@@ -5192,7 +5540,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5192
5540
|
_this2.markKeyErrorsAtPath(entryErr, subPath);
|
|
5193
5541
|
}
|
|
5194
5542
|
error = _this2.mergeValidationErrors(error, entryErr);
|
|
5195
|
-
} else if (_this2.isJsonValues && isJson(elem)) ; else {
|
|
5543
|
+
} else if (hasDeclaredKeys && elem === null) ; else if (_this2.isJsonValues && isJson(elem)) ; else {
|
|
5196
5544
|
// Falls through for a jsonValues record whose entry content is inlined
|
|
5197
5545
|
// (loaded in the UI, or hand-authored): same as a plain record — validate
|
|
5198
5546
|
// the value against the item schema.
|
|
@@ -5200,8 +5548,79 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5200
5548
|
error = _this2.mergeValidationErrors(error, subError);
|
|
5201
5549
|
}
|
|
5202
5550
|
});
|
|
5551
|
+
var declaredKeys = this.getDeclaredKeysValidation(path, src);
|
|
5552
|
+
error = this.mergeValidationErrors(error, declaredKeys);
|
|
5553
|
+
var _iterator2 = result._createForOfIteratorHelper(this.localeScopeErrors()),
|
|
5554
|
+
_step2;
|
|
5555
|
+
try {
|
|
5556
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
5557
|
+
var scopeError = _step2.value;
|
|
5558
|
+
error = this.appendValidationError(error, path, scopeError.message, src, scopeError.schemaError);
|
|
5559
|
+
}
|
|
5560
|
+
} catch (err) {
|
|
5561
|
+
_iterator2.e(err);
|
|
5562
|
+
} finally {
|
|
5563
|
+
_iterator2.f();
|
|
5564
|
+
}
|
|
5203
5565
|
return error;
|
|
5204
5566
|
}
|
|
5567
|
+
|
|
5568
|
+
/**
|
|
5569
|
+
* The check that a record with a DECLARED key set holds every one of them.
|
|
5570
|
+
*
|
|
5571
|
+
* `s.record(s.locale(), item)` has one entry per language and
|
|
5572
|
+
* `s.record(s.union(s.literal("a"), s.literal("b")), item)` has both — the
|
|
5573
|
+
* keys are part of the schema either way, so a missing one is a hole in the
|
|
5574
|
+
* content rather than content nobody has written yet. TypeScript already
|
|
5575
|
+
* demanded both keys of the second; this is the validator catching up, which
|
|
5576
|
+
* is why the two now behave the same.
|
|
5577
|
+
*
|
|
5578
|
+
* Deferred to `resolveSchemaSourceFixes` even for the literal case, where the
|
|
5579
|
+
* keys are known right here: a locale record's keys are in another file, and
|
|
5580
|
+
* one code path for both is one message, one fix and one thing to be wrong.
|
|
5581
|
+
*/
|
|
5582
|
+
}, {
|
|
5583
|
+
key: "getDeclaredKeysValidation",
|
|
5584
|
+
value: function getDeclaredKeysValidation(path, src) {
|
|
5585
|
+
if (this.keySchema === null) {
|
|
5586
|
+
return false;
|
|
5587
|
+
}
|
|
5588
|
+
var declared = this.declaredKeySet();
|
|
5589
|
+
if (declared === null) {
|
|
5590
|
+
return false;
|
|
5591
|
+
}
|
|
5592
|
+
return _defineProperty({}, path, [{
|
|
5593
|
+
fixes: ["record:fill-keys"],
|
|
5594
|
+
message: "Did not validate record keys. This error (record:fill-keys) should typically be processed by Val internally. Seeing this error most likely means you have a Val version mismatch.",
|
|
5595
|
+
value: {
|
|
5596
|
+
present: Object.keys(src),
|
|
5597
|
+
declared: declared.kind === "literals" ? declared.keys : null
|
|
5598
|
+
}
|
|
5599
|
+
}]);
|
|
5600
|
+
}
|
|
5601
|
+
}, {
|
|
5602
|
+
key: "declaredKeySet",
|
|
5603
|
+
value: function declaredKeySet() {
|
|
5604
|
+
if (this.declaredKeys === undefined) {
|
|
5605
|
+
this.declaredKeys = this.keySchema === null ? null : declaredKeySetOf(this.keySchema["executeSerialize"]());
|
|
5606
|
+
}
|
|
5607
|
+
return this.declaredKeys;
|
|
5608
|
+
}
|
|
5609
|
+
}, {
|
|
5610
|
+
key: "opensLocaleScope",
|
|
5611
|
+
value: function opensLocaleScope() {
|
|
5612
|
+
return this.keySchema !== null && this.keySchema["isLocaleField"]() ? "key" : null;
|
|
5613
|
+
}
|
|
5614
|
+
}, {
|
|
5615
|
+
key: "localeScopeChildren",
|
|
5616
|
+
value: function localeScopeChildren() {
|
|
5617
|
+
// The KEY schema is not a child here. A locale key is what opens this
|
|
5618
|
+
// record's scope; it is not something inside the scope.
|
|
5619
|
+
return [{
|
|
5620
|
+
key: "*",
|
|
5621
|
+
schema: this.item
|
|
5622
|
+
}];
|
|
5623
|
+
}
|
|
5205
5624
|
}, {
|
|
5206
5625
|
key: "isRemoteUrl",
|
|
5207
5626
|
value: function isRemoteUrl(url) {
|
|
@@ -5227,13 +5646,13 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5227
5646
|
return false;
|
|
5228
5647
|
}
|
|
5229
5648
|
var _this$mediaOptions = this.mediaOptions,
|
|
5230
|
-
|
|
5649
|
+
dir = _this$mediaOptions.dir,
|
|
5231
5650
|
isRemote = _this$mediaOptions.remote,
|
|
5232
5651
|
type = _this$mediaOptions.type;
|
|
5233
5652
|
var mediaLabel = type === "images" ? "images" : "files";
|
|
5234
5653
|
var checkRemoteFix = type === "images" ? "images:check-remote" : "files:check-remote";
|
|
5235
5654
|
var isRemoteUrl = this.isRemoteUrl(key);
|
|
5236
|
-
var isLocalPath = key ===
|
|
5655
|
+
var isLocalPath = key === dir || key.startsWith(dir + "/");
|
|
5237
5656
|
if (isRemote) {
|
|
5238
5657
|
// When remote is enabled, accept either remote URLs or local paths
|
|
5239
5658
|
if (isRemoteUrl) {
|
|
@@ -5248,9 +5667,9 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5248
5667
|
}
|
|
5249
5668
|
// Check that the file path in the remote URL matches our directory constraint
|
|
5250
5669
|
var remotePath = "/" + remoteResult.filePath;
|
|
5251
|
-
if (remotePath !==
|
|
5670
|
+
if (remotePath !== dir && !remotePath.startsWith(dir + "/")) {
|
|
5252
5671
|
return _defineProperty({}, path, [{
|
|
5253
|
-
message: "Remote file path '".concat(remotePath, "' is not in expected directory '").concat(
|
|
5672
|
+
message: "Remote file path '".concat(remotePath, "' is not in expected directory '").concat(dir, "'. Use Val tooling to upload ").concat(mediaLabel, " to the correct directory."),
|
|
5254
5673
|
value: key,
|
|
5255
5674
|
fixes: [checkRemoteFix]
|
|
5256
5675
|
}]);
|
|
@@ -5259,7 +5678,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5259
5678
|
}
|
|
5260
5679
|
if (!isLocalPath) {
|
|
5261
5680
|
return _defineProperty({}, path, [{
|
|
5262
|
-
message: "Expected a remote URL (https://...) or a local path starting with ".concat(
|
|
5681
|
+
message: "Expected a remote URL (https://...) or a local path starting with ".concat(dir, "/. Got: ").concat(key),
|
|
5263
5682
|
value: key
|
|
5264
5683
|
}]);
|
|
5265
5684
|
}
|
|
@@ -5281,7 +5700,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5281
5700
|
}
|
|
5282
5701
|
if (!isLocalPath) {
|
|
5283
5702
|
return _defineProperty({}, path, [{
|
|
5284
|
-
message: "File path must be within the ".concat(
|
|
5703
|
+
message: "File path must be within the ".concat(dir, "/ directory. Got: ").concat(key),
|
|
5285
5704
|
value: key
|
|
5286
5705
|
}]);
|
|
5287
5706
|
}
|
|
@@ -5477,7 +5896,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5477
5896
|
* Allow the files in this gallery to be stored on Val's remote content host
|
|
5478
5897
|
* instead of in your repository.
|
|
5479
5898
|
*
|
|
5480
|
-
* For `s.
|
|
5899
|
+
* For `s.imageset()` and `s.fileset()`, which are records of media. Remote is off
|
|
5481
5900
|
* until this is called.
|
|
5482
5901
|
*
|
|
5483
5902
|
* Each entry is then keyed by its URL on the content host rather than by a
|
|
@@ -5486,7 +5905,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5486
5905
|
* upload it and rewrite the key.
|
|
5487
5906
|
*
|
|
5488
5907
|
* @example
|
|
5489
|
-
* const schema = s.
|
|
5908
|
+
* const schema = s.imageset({ dir: "/public/val/images" }).remote();
|
|
5490
5909
|
* export default c.define("/content/images.val.ts", schema, {
|
|
5491
5910
|
* "https://remote.val.build/file/p/my-project/b/01/v/1.0.0/h/8f2a1c/f/3b9d70/p/public/val/images/hero.webp":
|
|
5492
5911
|
* {
|
|
@@ -5512,7 +5931,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5512
5931
|
* which lets the runtime, the Studio and validation work one entry at a time
|
|
5513
5932
|
* so a record/router can scale to many thousands of entries.
|
|
5514
5933
|
*
|
|
5515
|
-
* Not supported on image/file galleries (`s.
|
|
5934
|
+
* Not supported on image/file galleries (`s.imageset()` / `s.fileset()`).
|
|
5516
5935
|
*
|
|
5517
5936
|
* Only supported on a module's ROOT record/router — a `.jsonValues()` record
|
|
5518
5937
|
* nested inside an object/array/record is rejected at startup with a module
|
|
@@ -5537,7 +5956,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5537
5956
|
key: "jsonValues",
|
|
5538
5957
|
value: function jsonValues() {
|
|
5539
5958
|
if (this.mediaOptions) {
|
|
5540
|
-
throw new Error(".jsonValues() cannot be used with image/file galleries (s.
|
|
5959
|
+
throw new Error(".jsonValues() cannot be used with image/file galleries (s.imageset()/s.fileset())");
|
|
5541
5960
|
}
|
|
5542
5961
|
if (this.customValidateFunctions.length > 0) {
|
|
5543
5962
|
// `.jsonValues()` changes the source shape to JsonSource entries, so a
|
|
@@ -5566,7 +5985,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5566
5985
|
* bucket — instead of in the module.
|
|
5567
5986
|
*
|
|
5568
5987
|
* Available on every record-derived schema, which is `s.record()`,
|
|
5569
|
-
* `s.router()`, `s.
|
|
5988
|
+
* `s.router()`, `s.imageset()` and `s.fileset()` alike: a router is a
|
|
5570
5989
|
* `RecordSchema` with a `ValRouter`, a gallery one with media options, so all
|
|
5571
5990
|
* four get external storage from this one method.
|
|
5572
5991
|
*
|
|
@@ -5721,7 +6140,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5721
6140
|
if (this.mediaOptions) {
|
|
5722
6141
|
result.mediaType = this.mediaOptions.type;
|
|
5723
6142
|
result.accept = this.mediaOptions.accept;
|
|
5724
|
-
result.
|
|
6143
|
+
result.dir = this.mediaOptions.dir;
|
|
5725
6144
|
result.remote = this.mediaOptions.remote;
|
|
5726
6145
|
if (this.mediaOptions.encode !== undefined) {
|
|
5727
6146
|
result.encode = this.mediaOptions.encode;
|
|
@@ -5896,6 +6315,23 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5896
6315
|
}]);
|
|
5897
6316
|
}(Schema);
|
|
5898
6317
|
|
|
6318
|
+
/**
|
|
6319
|
+
* The source of a record, given what its key schema says about its keys.
|
|
6320
|
+
*
|
|
6321
|
+
* A key schema that ENUMERATES its keys (a union of literals, or `s.locale()`)
|
|
6322
|
+
* makes every one of them an entry of the record, and an entry nobody has
|
|
6323
|
+
* written yet is `null` rather than absent — so the value type widens by
|
|
6324
|
+
* `null`. That is the whole of option F at the type level: a half-translated
|
|
6325
|
+
* record is a record with nulls in it, which is data you can count, filter and
|
|
6326
|
+
* see in a diff, rather than keys that are simply not there.
|
|
6327
|
+
*
|
|
6328
|
+
* For a union of literals TypeScript already required every key, since
|
|
6329
|
+
* `SelectorOfSchema<K>` is the literal union itself. `s.locale()` is a flavoured
|
|
6330
|
+
* string, so it requires nothing here and the requirement is the validator's —
|
|
6331
|
+
* deliberately: which languages exist is in the settings module, where the
|
|
6332
|
+
* project can change it without a deploy.
|
|
6333
|
+
*/
|
|
6334
|
+
|
|
5899
6335
|
// Overload: with key schema
|
|
5900
6336
|
|
|
5901
6337
|
// Overload: without key schema
|
|
@@ -5934,6 +6370,31 @@ function record(keyOrSchema, schema) {
|
|
|
5934
6370
|
* written without removing the key.
|
|
5935
6371
|
*/
|
|
5936
6372
|
|
|
6373
|
+
/**
|
|
6374
|
+
* The languages this project publishes.
|
|
6375
|
+
*
|
|
6376
|
+
* Content rather than configuration, and deliberately: which languages a site
|
|
6377
|
+
* has is a decision the people who write it make, and under a build-time
|
|
6378
|
+
* constant it took a developer and a deploy. It is the same move `assistant`
|
|
6379
|
+
* makes with `enabled`.
|
|
6380
|
+
*
|
|
6381
|
+
* Val ships no list of its own. A project with no `locales` section has not
|
|
6382
|
+
* said it is translated, and nothing about locales appears anywhere — no picker
|
|
6383
|
+
* in the Studio, no checks, nothing.
|
|
6384
|
+
*
|
|
6385
|
+
* **This list is a decision with a blast radius.** Every locale in content is
|
|
6386
|
+
* checked against it, so removing one invalidates the content that uses it, and
|
|
6387
|
+
* adding one leaves every locale-keyed record short of a language until it is
|
|
6388
|
+
* filled in. That is the intended behaviour — a language that is declared and
|
|
6389
|
+
* missing everywhere is worth being told about — but it is why the Studio warns
|
|
6390
|
+
* before saving a removal rather than treating this as an ordinary field.
|
|
6391
|
+
*
|
|
6392
|
+
* There is no default language, deliberately. Every locale-specific field asks
|
|
6393
|
+
* which language it is in, and a default is exactly the answer that lets that
|
|
6394
|
+
* question go unanswered — content ends up filed under a language nobody chose,
|
|
6395
|
+
* which is the state translation is meant to make visible.
|
|
6396
|
+
*/
|
|
6397
|
+
|
|
5937
6398
|
/**
|
|
5938
6399
|
* The assistant: whether editors have one, and what it is told about the
|
|
5939
6400
|
* project on every message.
|
|
@@ -5994,6 +6455,263 @@ settings) {
|
|
|
5994
6455
|
return "unconfigured";
|
|
5995
6456
|
}
|
|
5996
6457
|
|
|
6458
|
+
/**
|
|
6459
|
+
* One of the languages the project publishes.
|
|
6460
|
+
*
|
|
6461
|
+
* The set is NOT here. It is declared in the settings module — `locales.available`
|
|
6462
|
+
* — so that adding a language is something the people who write the content can
|
|
6463
|
+
* do, and so that one list drives validation, the Studio's picker and the
|
|
6464
|
+
* translation notes. This schema knows only that the value is one of them, which
|
|
6465
|
+
* is checked cross-module through the `locale:check-locale` fix, exactly as
|
|
6466
|
+
* `keyOf` and `route` check theirs.
|
|
6467
|
+
*
|
|
6468
|
+
* Never stega encoded (see `stegaEncode.ts`): a locale goes into `<html lang>`,
|
|
6469
|
+
* into `hreflang` and into `Intl` constructors, none of which survive invisible
|
|
6470
|
+
* characters.
|
|
6471
|
+
*/
|
|
6472
|
+
var LocaleSchema = /*#__PURE__*/function (_Schema) {
|
|
6473
|
+
/**
|
|
6474
|
+
* Type-only marker: as a record key, this schema DECLARES the key set.
|
|
6475
|
+
*
|
|
6476
|
+
* `declare` so it exists in the type and nowhere at runtime — reading it off
|
|
6477
|
+
* an instance gives `undefined`, and nothing should. It is how `record()`
|
|
6478
|
+
* knows to type entries as `Item | null`: a language nobody has translated
|
|
6479
|
+
* into is a null entry, not an absent key. See `DeclaredKeySet` and
|
|
6480
|
+
* `RecordSrcOf`.
|
|
6481
|
+
*/
|
|
6482
|
+
|
|
6483
|
+
function LocaleSchema() {
|
|
6484
|
+
var _this;
|
|
6485
|
+
var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
6486
|
+
var customValidateFunctions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
6487
|
+
var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6488
|
+
var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
6489
|
+
var description = arguments.length > 4 ? arguments[4] : undefined;
|
|
6490
|
+
var renderInput = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
|
|
6491
|
+
var previewInput = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
|
|
6492
|
+
_classCallCheck(this, LocaleSchema);
|
|
6493
|
+
_this = _callSuper(this, LocaleSchema);
|
|
6494
|
+
_this.opt = opt;
|
|
6495
|
+
_this.customValidateFunctions = customValidateFunctions;
|
|
6496
|
+
_this.isReadonly = isReadonly;
|
|
6497
|
+
_this.isHidden = isHidden;
|
|
6498
|
+
_this.description = description;
|
|
6499
|
+
_this.renderInput = renderInput;
|
|
6500
|
+
_this.previewInput = previewInput;
|
|
6501
|
+
return _this;
|
|
6502
|
+
}
|
|
6503
|
+
|
|
6504
|
+
/**
|
|
6505
|
+
* A note to whoever edits this field, shown under it in the Studio.
|
|
6506
|
+
*
|
|
6507
|
+
* Pass `null` to clear a description set earlier.
|
|
6508
|
+
*
|
|
6509
|
+
* @example
|
|
6510
|
+
* const schema = s.object({
|
|
6511
|
+
* locale: s.locale().describe("The language everything below is written in"),
|
|
6512
|
+
* title: s.string(),
|
|
6513
|
+
* });
|
|
6514
|
+
* export default c.define("/example.val.ts", schema, {
|
|
6515
|
+
* locale: "nb-NO",
|
|
6516
|
+
* title: "Vinterjakke",
|
|
6517
|
+
* });
|
|
6518
|
+
*/
|
|
6519
|
+
_inherits(LocaleSchema, _Schema);
|
|
6520
|
+
return _createClass(LocaleSchema, [{
|
|
6521
|
+
key: "describe",
|
|
6522
|
+
value: function describe(description) {
|
|
6523
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined, this.renderInput, this.previewInput);
|
|
6524
|
+
}
|
|
6525
|
+
|
|
6526
|
+
/**
|
|
6527
|
+
* A check of your own, on top of "is this one of the project's languages".
|
|
6528
|
+
*
|
|
6529
|
+
* Return a message when the value is WRONG and `false` when it is fine — the
|
|
6530
|
+
* two answers are a complaint and no complaint, so write the check as a
|
|
6531
|
+
* ternary rather than as `ok || "message"`, which returns `true` and `true`
|
|
6532
|
+
* is neither.
|
|
6533
|
+
*
|
|
6534
|
+
* @example
|
|
6535
|
+
* const schema = s.object({
|
|
6536
|
+
* locale: s.locale().validate((val) =>
|
|
6537
|
+
* val === "en-US" ? "This section is not translated into English yet" : false,
|
|
6538
|
+
* ),
|
|
6539
|
+
* title: s.string(),
|
|
6540
|
+
* });
|
|
6541
|
+
* export default c.define("/example.val.ts", schema, {
|
|
6542
|
+
* locale: "nb-NO",
|
|
6543
|
+
* title: "Vinterjakke",
|
|
6544
|
+
* });
|
|
6545
|
+
*/
|
|
6546
|
+
}, {
|
|
6547
|
+
key: "validate",
|
|
6548
|
+
value: function validate(validationFunction) {
|
|
6549
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions.concat(validationFunction), this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6550
|
+
}
|
|
6551
|
+
}, {
|
|
6552
|
+
key: "executeValidate",
|
|
6553
|
+
value: function executeValidate(path, src) {
|
|
6554
|
+
var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
|
|
6555
|
+
path: path
|
|
6556
|
+
});
|
|
6557
|
+
if (this.opt && (src === null || src === undefined)) {
|
|
6558
|
+
return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
|
|
6559
|
+
}
|
|
6560
|
+
if (typeof src !== "string") {
|
|
6561
|
+
return _defineProperty({}, path, [{
|
|
6562
|
+
message: "Expected 'string', got '".concat(_typeof(src), "'"),
|
|
6563
|
+
value: src
|
|
6564
|
+
}]);
|
|
6565
|
+
}
|
|
6566
|
+
return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
|
|
6567
|
+
// Which languages exist is in another module, so this cannot be
|
|
6568
|
+
// answered here — the same shape `keyOf` and `route` use, resolved by
|
|
6569
|
+
// `resolveSchemaSourceFixes` against the settings module.
|
|
6570
|
+
fixes: ["locale:check-locale"],
|
|
6571
|
+
message: "Did not validate locale. This error (locale:check-locale) should typically be processed by Val internally. Seeing this error most likely means you have a Val version mismatch.",
|
|
6572
|
+
value: {
|
|
6573
|
+
locale: src,
|
|
6574
|
+
sourcePath: path
|
|
6575
|
+
}
|
|
6576
|
+
}]));
|
|
6577
|
+
}
|
|
6578
|
+
}, {
|
|
6579
|
+
key: "executeAssert",
|
|
6580
|
+
value: function executeAssert(path, src) {
|
|
6581
|
+
if (this.opt && src === null) {
|
|
6582
|
+
return {
|
|
6583
|
+
success: true,
|
|
6584
|
+
data: src
|
|
6585
|
+
};
|
|
6586
|
+
}
|
|
6587
|
+
if (typeof src === "string") {
|
|
6588
|
+
return {
|
|
6589
|
+
success: true,
|
|
6590
|
+
data: src
|
|
6591
|
+
};
|
|
6592
|
+
}
|
|
6593
|
+
return {
|
|
6594
|
+
success: false,
|
|
6595
|
+
errors: _defineProperty({}, path, [{
|
|
6596
|
+
message: "Expected 'string', got '".concat(_typeof(src), "'"),
|
|
6597
|
+
typeError: true
|
|
6598
|
+
}])
|
|
6599
|
+
};
|
|
6600
|
+
}
|
|
6601
|
+
}, {
|
|
6602
|
+
key: "nullable",
|
|
6603
|
+
value: function nullable() {
|
|
6604
|
+
// Asserted whole, exactly as `RouteSchema.nullable` does: the source type
|
|
6605
|
+
// widens by `null` while the caller's validators and preview stay typed
|
|
6606
|
+
// against the value, and `executeValidate` returns before either sees one.
|
|
6607
|
+
return new LocaleSchema(true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6608
|
+
}
|
|
6609
|
+
}, {
|
|
6610
|
+
key: "readonly",
|
|
6611
|
+
value: function readonly() {
|
|
6612
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6613
|
+
}
|
|
6614
|
+
}, {
|
|
6615
|
+
key: "hidden",
|
|
6616
|
+
value: function hidden() {
|
|
6617
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
|
|
6618
|
+
}
|
|
6619
|
+
}, {
|
|
6620
|
+
key: "isLocaleField",
|
|
6621
|
+
value: function isLocaleField() {
|
|
6622
|
+
return true;
|
|
6623
|
+
}
|
|
6624
|
+
}, {
|
|
6625
|
+
key: "executeCustomValidateAt",
|
|
6626
|
+
value: function executeCustomValidateAt(path, src) {
|
|
6627
|
+
return this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
|
|
6628
|
+
path: path
|
|
6629
|
+
});
|
|
6630
|
+
}
|
|
6631
|
+
|
|
6632
|
+
/**
|
|
6633
|
+
* How this field is laid out where it is the item of an array or a record.
|
|
6634
|
+
* Static configuration, not a callback — see `render.ts`.
|
|
6635
|
+
*
|
|
6636
|
+
* @example
|
|
6637
|
+
* const schema = s.array(s.locale().render({ as: "inline" }));
|
|
6638
|
+
* export default c.define("/example.val.ts", schema, ["nb-NO", "en-US"]);
|
|
6639
|
+
*/
|
|
6640
|
+
}, {
|
|
6641
|
+
key: "render",
|
|
6642
|
+
value: function render(input) {
|
|
6643
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, input, this.previewInput);
|
|
6644
|
+
}
|
|
6645
|
+
|
|
6646
|
+
/**
|
|
6647
|
+
* How this VALUE is shown where a preview of it is needed. Never how the field
|
|
6648
|
+
* itself is edited (that is `render`). See `preview.ts`.
|
|
6649
|
+
*
|
|
6650
|
+
* @example
|
|
6651
|
+
* const schema = s.array(
|
|
6652
|
+
* s.locale().preview(({ val }) => ({ title: val })),
|
|
6653
|
+
* );
|
|
6654
|
+
* export default c.define("/example.val.ts", schema, ["nb-NO", "en-US"]);
|
|
6655
|
+
*/
|
|
6656
|
+
}, {
|
|
6657
|
+
key: "preview",
|
|
6658
|
+
value: function preview(select) {
|
|
6659
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, select);
|
|
6660
|
+
}
|
|
6661
|
+
}, {
|
|
6662
|
+
key: "executePreviewItem",
|
|
6663
|
+
value: function executePreviewItem(src) {
|
|
6664
|
+
if (this.previewInput === null) {
|
|
6665
|
+
return null;
|
|
6666
|
+
}
|
|
6667
|
+
return this.previewInput({
|
|
6668
|
+
val: src
|
|
6669
|
+
});
|
|
6670
|
+
}
|
|
6671
|
+
}, {
|
|
6672
|
+
key: "declaresItemPreview",
|
|
6673
|
+
value: function declaresItemPreview() {
|
|
6674
|
+
return this.previewInput !== null;
|
|
6675
|
+
}
|
|
6676
|
+
}, {
|
|
6677
|
+
key: "executeSerialize",
|
|
6678
|
+
value: function executeSerialize() {
|
|
6679
|
+
var _this$renderInput, _this$customValidateF;
|
|
6680
|
+
return {
|
|
6681
|
+
type: "locale",
|
|
6682
|
+
render: (_this$renderInput = this.renderInput) !== null && _this$renderInput !== void 0 ? _this$renderInput : undefined,
|
|
6683
|
+
preview: this.previewInput ? true : undefined,
|
|
6684
|
+
opt: this.opt,
|
|
6685
|
+
customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0,
|
|
6686
|
+
readonly: this.isReadonly,
|
|
6687
|
+
hidden: this.isHidden,
|
|
6688
|
+
description: this.description
|
|
6689
|
+
};
|
|
6690
|
+
}
|
|
6691
|
+
}, {
|
|
6692
|
+
key: "executePreview",
|
|
6693
|
+
value: function executePreview() {
|
|
6694
|
+
return {};
|
|
6695
|
+
}
|
|
6696
|
+
}]);
|
|
6697
|
+
}(Schema);
|
|
6698
|
+
|
|
6699
|
+
/**
|
|
6700
|
+
* Define one of the project's languages.
|
|
6701
|
+
*
|
|
6702
|
+
* The languages themselves are declared in the settings module, under
|
|
6703
|
+
* `locales.available` — this says only that a value is one of them.
|
|
6704
|
+
*
|
|
6705
|
+
* @example // a field: everything under this object is in this language
|
|
6706
|
+
* const schema = s.object({ locale: s.locale(), title: s.string() });
|
|
6707
|
+
*
|
|
6708
|
+
* @example // a key: one entry per language
|
|
6709
|
+
* const schema = s.record(s.locale(), s.object({ title: s.string() }));
|
|
6710
|
+
*/
|
|
6711
|
+
var locale = function locale() {
|
|
6712
|
+
return new LocaleSchema();
|
|
6713
|
+
};
|
|
6714
|
+
|
|
5997
6715
|
var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
5998
6716
|
function BooleanSchema() {
|
|
5999
6717
|
var _this;
|
|
@@ -6111,7 +6829,7 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6111
6829
|
}, {
|
|
6112
6830
|
key: "nullable",
|
|
6113
6831
|
value: function nullable() {
|
|
6114
|
-
return new BooleanSchema(true,
|
|
6832
|
+
return new BooleanSchema(true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6115
6833
|
}
|
|
6116
6834
|
}, {
|
|
6117
6835
|
key: "readonly",
|
|
@@ -6207,6 +6925,99 @@ var _boolean = function _boolean() {
|
|
|
6207
6925
|
return new BooleanSchema();
|
|
6208
6926
|
};
|
|
6209
6927
|
|
|
6928
|
+
/**
|
|
6929
|
+
* Language tags, and what makes one wrong.
|
|
6930
|
+
*
|
|
6931
|
+
* Val does not ship a list of locales. Which languages a project publishes is a
|
|
6932
|
+
* property of that project, so it is declared in the settings module — see
|
|
6933
|
+
* `LocalesSettingsSource` — and everything downstream reads it from there.
|
|
6934
|
+
*
|
|
6935
|
+
* What Val does own is the SPELLING. A tag is checked against BCP 47
|
|
6936
|
+
* (RFC 5646) through `Intl.getCanonicalLocales`, which is the same
|
|
6937
|
+
* implementation the browser, `<html lang>` and every `Intl` constructor use.
|
|
6938
|
+
* Delegating rather than writing a matcher is the point: a tag this accepts is
|
|
6939
|
+
* a tag those accept.
|
|
6940
|
+
*/
|
|
6941
|
+
|
|
6942
|
+
/**
|
|
6943
|
+
* What is wrong with `tag` as a language tag, or `false` if nothing is.
|
|
6944
|
+
*
|
|
6945
|
+
* Canonical form, not merely parseable, and the difference is what makes this
|
|
6946
|
+
* worth checking at all. `nb-no` parses; `Intl.DisplayNames` and a
|
|
6947
|
+
* case-sensitive comparison against a stored key do not agree about it. Since a
|
|
6948
|
+
* locale is compared as a string everywhere — a record key, a URL segment, a
|
|
6949
|
+
* value in content — one spelling has to win, and the canonical one is the
|
|
6950
|
+
* spelling every other tool already produces.
|
|
6951
|
+
*
|
|
6952
|
+
* The message names the canonical form where there is one, because "not
|
|
6953
|
+
* canonical" is not an instruction and `nb-NO` is.
|
|
6954
|
+
*/
|
|
6955
|
+
function localeTagError(tag) {
|
|
6956
|
+
var canonical;
|
|
6957
|
+
try {
|
|
6958
|
+
canonical = Intl.getCanonicalLocales(tag);
|
|
6959
|
+
} catch (_unused) {
|
|
6960
|
+
// RangeError, for anything the grammar rejects: an underscore instead of a
|
|
6961
|
+
// hyphen (`nb_NO`, which is POSIX rather than BCP 47), an empty subtag, a
|
|
6962
|
+
// subtag of the wrong length.
|
|
6963
|
+
return "'".concat(tag, "' is not a language tag. Language then region, separated by a hyphen \u2014 'nb-NO', not 'nb_NO'");
|
|
6964
|
+
}
|
|
6965
|
+
if (canonical.length !== 1) {
|
|
6966
|
+
// A comma-separated list, or something that canonicalised to nothing.
|
|
6967
|
+
return "'".concat(tag, "' is not a single language tag");
|
|
6968
|
+
}
|
|
6969
|
+
if (canonical[0] !== tag) {
|
|
6970
|
+
return "'".concat(tag, "' is not canonical. Write it as '").concat(canonical[0], "'");
|
|
6971
|
+
}
|
|
6972
|
+
return false;
|
|
6973
|
+
}
|
|
6974
|
+
|
|
6975
|
+
/**
|
|
6976
|
+
* A language tag, as content holds it.
|
|
6977
|
+
*
|
|
6978
|
+
* A *flavoured* string rather than a union or a strict brand. Which languages a
|
|
6979
|
+
* project has is declared in its settings module, where the project can change
|
|
6980
|
+
* it, so there is no set for a type to enumerate — and a strict brand would make
|
|
6981
|
+
* `"nb-NO"` unassignable, which would mean writing every locale in a `.val.ts`
|
|
6982
|
+
* through a constructor. Content stays plain data.
|
|
6983
|
+
*
|
|
6984
|
+
* So this carries no compile-time guarantee, and is not meant to. It names the
|
|
6985
|
+
* concept where a bare `string` would say nothing, and the guarantee is the
|
|
6986
|
+
* `locale:check-locale` validation against `locales.available`.
|
|
6987
|
+
*/
|
|
6988
|
+
|
|
6989
|
+
/**
|
|
6990
|
+
* The locale a stored value means, or `null` if it means none of them.
|
|
6991
|
+
*
|
|
6992
|
+
* A lookup against the project's languages, and today that is all it is. It
|
|
6993
|
+
* stays a named function because it is the one place the question is asked —
|
|
6994
|
+
* the Studio, the validation worker and the server all come here rather than
|
|
6995
|
+
* comparing strings themselves, so they cannot disagree about what a stored
|
|
6996
|
+
* value is.
|
|
6997
|
+
*/
|
|
6998
|
+
function localeOfValue(value, available) {
|
|
6999
|
+
return available.includes(value) ? value : null;
|
|
7000
|
+
}
|
|
7001
|
+
|
|
7002
|
+
/**
|
|
7003
|
+
* A rule about a section that its individual fields cannot state.
|
|
7004
|
+
*
|
|
7005
|
+
* Paths are WITHIN the section, so an error lands on the value it is about —
|
|
7006
|
+
* including a row of a list, which is what makes this different from a
|
|
7007
|
+
* `.validate()` on the field.
|
|
7008
|
+
*/
|
|
7009
|
+
|
|
7010
|
+
/**
|
|
7011
|
+
* Every section's rules, by the name that travels in the serialized schema.
|
|
7012
|
+
*
|
|
7013
|
+
* Typed with `| undefined` on the value rather than as a `Partial`: the whole
|
|
7014
|
+
* point is that a lookup can miss, because the name comes off a serialized
|
|
7015
|
+
* schema that may have been written by a newer Val than the one reading it.
|
|
7016
|
+
*/
|
|
7017
|
+
var sectionValidators = {
|
|
7018
|
+
locales: localesSectionErrors
|
|
7019
|
+
};
|
|
7020
|
+
|
|
6210
7021
|
/**
|
|
6211
7022
|
* An object whose keys are all optional: absent means unset.
|
|
6212
7023
|
*
|
|
@@ -6225,6 +7036,23 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6225
7036
|
var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6226
7037
|
var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
6227
7038
|
var description = arguments.length > 4 ? arguments[4] : undefined;
|
|
7039
|
+
var
|
|
7040
|
+
/**
|
|
7041
|
+
* Which section this is, where Val has rules about it beyond its keys.
|
|
7042
|
+
*
|
|
7043
|
+
* Not the `validate` the class deliberately does not offer: that one is the
|
|
7044
|
+
* schema author's, and `s.settings()` takes no arguments to declare it
|
|
7045
|
+
* with. This names a rule Val states about a shape Val owns — no language
|
|
7046
|
+
* declared twice in `locales.available` is true of every project, and
|
|
7047
|
+
* there is nowhere else it can be said. A single value's rules stay on its
|
|
7048
|
+
* own schema; this is for the ones that need to see more than one value,
|
|
7049
|
+
* or to report on a row of a list.
|
|
7050
|
+
*
|
|
7051
|
+
* A NAME rather than the function, so it survives serialization: the schema
|
|
7052
|
+
* reaches the Studio's validation worker as JSON, and a closure would be
|
|
7053
|
+
* dropped on the way — which is how these rules once went missing there.
|
|
7054
|
+
*/
|
|
7055
|
+
section = arguments.length > 5 ? arguments[5] : undefined;
|
|
6228
7056
|
_classCallCheck(this, SettingsSchema);
|
|
6229
7057
|
_this = _callSuper(this, SettingsSchema);
|
|
6230
7058
|
_this.items = items;
|
|
@@ -6232,10 +7060,24 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6232
7060
|
_this.isReadonly = isReadonly;
|
|
6233
7061
|
_this.isHidden = isHidden;
|
|
6234
7062
|
_this.description = description;
|
|
7063
|
+
_this.section = section;
|
|
6235
7064
|
return _this;
|
|
6236
7065
|
}
|
|
7066
|
+
|
|
7067
|
+
/**
|
|
7068
|
+
* This section's rules, or `undefined` where there are none to run.
|
|
7069
|
+
*
|
|
7070
|
+
* A name this Val does not know means a schema written by a newer one. Its
|
|
7071
|
+
* per-field validation still runs; only the section's own rule is missed,
|
|
7072
|
+
* which is the mild half of the failure and better than refusing the schema.
|
|
7073
|
+
*/
|
|
6237
7074
|
_inherits(SettingsSchema, _Schema);
|
|
6238
7075
|
return _createClass(SettingsSchema, [{
|
|
7076
|
+
key: "sectionValidate",
|
|
7077
|
+
value: function sectionValidate() {
|
|
7078
|
+
return this.section === undefined ? undefined : sectionValidators[this.section];
|
|
7079
|
+
}
|
|
7080
|
+
}, {
|
|
6239
7081
|
key: "executeValidate",
|
|
6240
7082
|
value: function executeValidate(path, src) {
|
|
6241
7083
|
var error = false;
|
|
@@ -6288,6 +7130,39 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6288
7130
|
}).join(", ")), src, true);
|
|
6289
7131
|
}
|
|
6290
7132
|
}
|
|
7133
|
+
var sectionValidate = this.sectionValidate();
|
|
7134
|
+
if (sectionValidate) {
|
|
7135
|
+
var _iterator = result._createForOfIteratorHelper(sectionValidate(src)),
|
|
7136
|
+
_step;
|
|
7137
|
+
try {
|
|
7138
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
7139
|
+
var _ref4;
|
|
7140
|
+
var _step$value = _step.value,
|
|
7141
|
+
keys = _step$value.path,
|
|
7142
|
+
message = _step$value.message;
|
|
7143
|
+
var _subPath = path;
|
|
7144
|
+
var _iterator2 = result._createForOfIteratorHelper(keys),
|
|
7145
|
+
_step2;
|
|
7146
|
+
try {
|
|
7147
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
7148
|
+
var _key3 = _step2.value;
|
|
7149
|
+
_subPath = _subPath && createValPathOfItem(_subPath, _key3);
|
|
7150
|
+
}
|
|
7151
|
+
} catch (err) {
|
|
7152
|
+
_iterator2.e(err);
|
|
7153
|
+
} finally {
|
|
7154
|
+
_iterator2.f();
|
|
7155
|
+
}
|
|
7156
|
+
error = this.appendValidationError(error, // Falls back to the section itself, which is where an error belongs
|
|
7157
|
+
// when the value it is about is not addressable.
|
|
7158
|
+
(_ref4 = _subPath) !== null && _ref4 !== void 0 ? _ref4 : path, message, src);
|
|
7159
|
+
}
|
|
7160
|
+
} catch (err) {
|
|
7161
|
+
_iterator.e(err);
|
|
7162
|
+
} finally {
|
|
7163
|
+
_iterator.f();
|
|
7164
|
+
}
|
|
7165
|
+
}
|
|
6291
7166
|
return error;
|
|
6292
7167
|
}
|
|
6293
7168
|
}, {
|
|
@@ -6333,17 +7208,17 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6333
7208
|
}, {
|
|
6334
7209
|
key: "nullable",
|
|
6335
7210
|
value: function nullable() {
|
|
6336
|
-
return new SettingsSchema(this.items, true, this.isReadonly, this.isHidden, this.description);
|
|
7211
|
+
return new SettingsSchema(this.items, true, this.isReadonly, this.isHidden, this.description, this.section);
|
|
6337
7212
|
}
|
|
6338
7213
|
}, {
|
|
6339
7214
|
key: "readonly",
|
|
6340
7215
|
value: function readonly() {
|
|
6341
|
-
return new SettingsSchema(this.items, this.opt, true, this.isHidden, this.description);
|
|
7216
|
+
return new SettingsSchema(this.items, this.opt, true, this.isHidden, this.description, this.section);
|
|
6342
7217
|
}
|
|
6343
7218
|
}, {
|
|
6344
7219
|
key: "hidden",
|
|
6345
7220
|
value: function hidden() {
|
|
6346
|
-
return new SettingsSchema(this.items, this.opt, this.isReadonly, true, this.description);
|
|
7221
|
+
return new SettingsSchema(this.items, this.opt, this.isReadonly, true, this.description, this.section);
|
|
6347
7222
|
}
|
|
6348
7223
|
}, {
|
|
6349
7224
|
key: "executeCustomValidateAt",
|
|
@@ -6358,16 +7233,17 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6358
7233
|
value: function executeSerialize() {
|
|
6359
7234
|
return {
|
|
6360
7235
|
type: "settings",
|
|
6361
|
-
items: Object.fromEntries(Object.entries(this.items).map(function (
|
|
6362
|
-
var
|
|
6363
|
-
key =
|
|
6364
|
-
schema =
|
|
7236
|
+
items: Object.fromEntries(Object.entries(this.items).map(function (_ref5) {
|
|
7237
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
7238
|
+
key = _ref6[0],
|
|
7239
|
+
schema = _ref6[1];
|
|
6365
7240
|
return [key, schema["executeSerialize"]()];
|
|
6366
7241
|
})),
|
|
6367
7242
|
opt: this.opt,
|
|
6368
7243
|
readonly: this.isReadonly,
|
|
6369
7244
|
hidden: this.isHidden,
|
|
6370
|
-
description: this.description
|
|
7245
|
+
description: this.description,
|
|
7246
|
+
section: this.section
|
|
6371
7247
|
};
|
|
6372
7248
|
}
|
|
6373
7249
|
}, {
|
|
@@ -6377,19 +7253,19 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6377
7253
|
if (src === null) {
|
|
6378
7254
|
return res;
|
|
6379
7255
|
}
|
|
6380
|
-
for (var
|
|
6381
|
-
var itemSrc = src[
|
|
7256
|
+
for (var _key4 in this.items) {
|
|
7257
|
+
var itemSrc = src[_key4];
|
|
6382
7258
|
if (itemSrc === null || itemSrc === undefined) {
|
|
6383
7259
|
continue;
|
|
6384
7260
|
}
|
|
6385
|
-
var subPath = unsafeCreateSourcePath(sourcePath,
|
|
7261
|
+
var subPath = unsafeCreateSourcePath(sourcePath, _key4);
|
|
6386
7262
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
6387
7263
|
continue;
|
|
6388
7264
|
}
|
|
6389
|
-
var itemResult = this.items[
|
|
7265
|
+
var itemResult = this.items[_key4]["executePreview"](subPath, itemSrc, scope);
|
|
6390
7266
|
for (var keyS in itemResult) {
|
|
6391
|
-
var
|
|
6392
|
-
res[
|
|
7267
|
+
var _key5 = keyS;
|
|
7268
|
+
res[_key5] = itemResult[_key5];
|
|
6393
7269
|
}
|
|
6394
7270
|
}
|
|
6395
7271
|
return res;
|
|
@@ -6433,11 +7309,58 @@ function settings() {
|
|
|
6433
7309
|
assistant: new SettingsSchema({
|
|
6434
7310
|
enabled: _boolean().nullable().describe("Whether editors have an assistant in this project. Unset means nobody has decided: it is offered, and turned on when someone accepts."),
|
|
6435
7311
|
context: string().multiline().maxLength(ASSISTANT_SETTINGS_MAX_LENGTH).nullable().describe("Background the assistant would otherwise have to guess: what this site is, who runs it, names and spellings that matter."),
|
|
6436
|
-
tone: string().multiline().maxLength(ASSISTANT_SETTINGS_MAX_LENGTH).nullable().describe("How the assistant should write when it writes content: formal or playful, British or American, how headings are cased.")
|
|
6437
|
-
|
|
7312
|
+
tone: string().multiline().maxLength(ASSISTANT_SETTINGS_MAX_LENGTH).nullable().describe("How the assistant should write when it writes content: formal or playful, British or American, how headings are cased."),
|
|
7313
|
+
translation: record(locale(), string().multiline().maxLength(ASSISTANT_SETTINGS_MAX_LENGTH).nullable()).nullable().describe("How to translate into each language: dialect, formality, and the words that stay untranslated.")
|
|
7314
|
+
}),
|
|
7315
|
+
locales: new SettingsSchema({
|
|
7316
|
+
// Nullable because the source type is, and because the Studio writes
|
|
7317
|
+
// `null` for every sibling the first time a section is created.
|
|
7318
|
+
available: array(string()).nullable().describe("The languages this project publishes, as BCP 47 tags: en-US, nb-NO. The order is kept: it is the order of the Studio's picker and of a locale-keyed record's rows.")
|
|
7319
|
+
}, false, false, false, undefined, "locales")
|
|
6438
7320
|
});
|
|
6439
7321
|
}
|
|
6440
7322
|
|
|
7323
|
+
/**
|
|
7324
|
+
* The rules about `locales` that need to see the whole list.
|
|
7325
|
+
*
|
|
7326
|
+
* Two of them, and both report on the ENTRY rather than the list: a tag has to
|
|
7327
|
+
* be spelled canonically, and a language cannot be declared twice. Neither can
|
|
7328
|
+
* live on the item schema — the item sees one string, and "twice" is a fact
|
|
7329
|
+
* about its siblings — and neither can be a `.validate()` on the array either,
|
|
7330
|
+
* since that reports one message on the array itself rather than on the row to
|
|
7331
|
+
* delete.
|
|
7332
|
+
*
|
|
7333
|
+
* Reads defensively rather than asserting the source's type. A settings module
|
|
7334
|
+
* is a file someone edits by hand, and validation runs against whatever is in
|
|
7335
|
+
* it — including the shapes the per-key pass is, in the same breath, reporting.
|
|
7336
|
+
*/
|
|
7337
|
+
function localesSectionErrors(src) {
|
|
7338
|
+
var errors = [];
|
|
7339
|
+
var raw = Array.isArray(src["available"]) ? src["available"] : [];
|
|
7340
|
+
var seen = new Set();
|
|
7341
|
+
for (var i = 0; i < raw.length; i++) {
|
|
7342
|
+
var tag = raw[i];
|
|
7343
|
+
if (typeof tag !== "string") {
|
|
7344
|
+
// The item's own schema has already said what is wrong with it.
|
|
7345
|
+
continue;
|
|
7346
|
+
}
|
|
7347
|
+
var spelling = localeTagError(tag);
|
|
7348
|
+
if (spelling !== false) {
|
|
7349
|
+
errors.push({
|
|
7350
|
+
path: ["available", i],
|
|
7351
|
+
message: spelling
|
|
7352
|
+
});
|
|
7353
|
+
} else if (seen.has(tag)) {
|
|
7354
|
+
errors.push({
|
|
7355
|
+
path: ["available", i],
|
|
7356
|
+
message: "'".concat(tag, "' is declared twice")
|
|
7357
|
+
});
|
|
7358
|
+
}
|
|
7359
|
+
seen.add(tag);
|
|
7360
|
+
}
|
|
7361
|
+
return errors;
|
|
7362
|
+
}
|
|
7363
|
+
|
|
6441
7364
|
/**
|
|
6442
7365
|
* What may be WRITTEN as an external record's source, on top of the marker.
|
|
6443
7366
|
*
|
|
@@ -7151,7 +8074,7 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7151
8074
|
}, {
|
|
7152
8075
|
key: "nullable",
|
|
7153
8076
|
value: function nullable() {
|
|
7154
|
-
return new NumberSchema(this.options, true,
|
|
8077
|
+
return new NumberSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7155
8078
|
}
|
|
7156
8079
|
}, {
|
|
7157
8080
|
key: "readonly",
|
|
@@ -7288,6 +8211,15 @@ var number = function number(options) {
|
|
|
7288
8211
|
* discriminated union's variants and must not try to recurse into these.
|
|
7289
8212
|
*/
|
|
7290
8213
|
var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
8214
|
+
/**
|
|
8215
|
+
* Type-only marker: as a record key, this declares the key set.
|
|
8216
|
+
*
|
|
8217
|
+
* An enum names every value it may take, so a record keyed by one holds
|
|
8218
|
+
* exactly those keys — the same claim `s.literal()` and `s.locale()` make.
|
|
8219
|
+
* `DiscriminatedUnionSchema` carries no marker: it discriminates objects and
|
|
8220
|
+
* cannot be a record key at all. See `LocaleSchema`.
|
|
8221
|
+
*/
|
|
8222
|
+
|
|
7291
8223
|
function EnumSchema(values) {
|
|
7292
8224
|
var _this;
|
|
7293
8225
|
var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -7441,7 +8373,7 @@ var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7441
8373
|
key: "nullable",
|
|
7442
8374
|
value: function nullable() {
|
|
7443
8375
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
7444
|
-
return new EnumSchema(this.values, true,
|
|
8376
|
+
return new EnumSchema(this.values, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7445
8377
|
}
|
|
7446
8378
|
}, {
|
|
7447
8379
|
key: "readonly",
|
|
@@ -7832,7 +8764,7 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7832
8764
|
}, {
|
|
7833
8765
|
key: "nullable",
|
|
7834
8766
|
value: function nullable() {
|
|
7835
|
-
return new KeyOfSchema(this.schema, this.sourcePath, true,
|
|
8767
|
+
return new KeyOfSchema(this.schema, this.sourcePath, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7836
8768
|
}
|
|
7837
8769
|
}, {
|
|
7838
8770
|
key: "readonly",
|
|
@@ -8380,7 +9312,7 @@ function file(options) {
|
|
|
8380
9312
|
}
|
|
8381
9313
|
|
|
8382
9314
|
/**
|
|
8383
|
-
* Options for s.
|
|
9315
|
+
* Options for s.fileset()
|
|
8384
9316
|
*/
|
|
8385
9317
|
|
|
8386
9318
|
/**
|
|
@@ -8394,9 +9326,9 @@ function file(options) {
|
|
|
8394
9326
|
*
|
|
8395
9327
|
* @example
|
|
8396
9328
|
* ```typescript
|
|
8397
|
-
* const schema = s.
|
|
9329
|
+
* const schema = s.fileset({
|
|
8398
9330
|
* accept: "application/pdf",
|
|
8399
|
-
*
|
|
9331
|
+
* dir: "/public/val/documents",
|
|
8400
9332
|
* });
|
|
8401
9333
|
* export default c.define("/content/documents.val.ts", schema, {
|
|
8402
9334
|
* "/public/val/documents/report.pdf": {
|
|
@@ -8405,15 +9337,15 @@ function file(options) {
|
|
|
8405
9337
|
* });
|
|
8406
9338
|
* ```
|
|
8407
9339
|
*/
|
|
8408
|
-
var
|
|
8409
|
-
var
|
|
9340
|
+
var fileset = function fileset(options) {
|
|
9341
|
+
var dir = options.dir;
|
|
8410
9342
|
var itemSchema = new ObjectSchema({
|
|
8411
9343
|
mimeType: new StringSchema({}, false)
|
|
8412
9344
|
}, false);
|
|
8413
9345
|
return new RecordSchema(itemSchema, false, [], null, null, {
|
|
8414
9346
|
type: "files",
|
|
8415
9347
|
accept: options.accept,
|
|
8416
|
-
|
|
9348
|
+
dir: dir,
|
|
8417
9349
|
remote: false
|
|
8418
9350
|
});
|
|
8419
9351
|
};
|
|
@@ -8606,7 +9538,7 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8606
9538
|
}, {
|
|
8607
9539
|
key: "nullable",
|
|
8608
9540
|
value: function nullable() {
|
|
8609
|
-
return new DateSchema(this.options, true,
|
|
9541
|
+
return new DateSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
8610
9542
|
}
|
|
8611
9543
|
}, {
|
|
8612
9544
|
key: "readonly",
|
|
@@ -8942,7 +9874,7 @@ var DateTimeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8942
9874
|
}, {
|
|
8943
9875
|
key: "nullable",
|
|
8944
9876
|
value: function nullable() {
|
|
8945
|
-
return new DateTimeSchema(this.options, true,
|
|
9877
|
+
return new DateTimeSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
8946
9878
|
}
|
|
8947
9879
|
}, {
|
|
8948
9880
|
key: "readonly",
|
|
@@ -9190,7 +10122,7 @@ var CodeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9190
10122
|
}, {
|
|
9191
10123
|
key: "nullable",
|
|
9192
10124
|
value: function nullable() {
|
|
9193
|
-
return new CodeSchema(this.options, true,
|
|
10125
|
+
return new CodeSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
9194
10126
|
}
|
|
9195
10127
|
}, {
|
|
9196
10128
|
key: "readonly",
|
|
@@ -9938,7 +10870,7 @@ var ColorSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9938
10870
|
}, {
|
|
9939
10871
|
key: "nullable",
|
|
9940
10872
|
value: function nullable() {
|
|
9941
|
-
return new ColorSchema(this.options, true,
|
|
10873
|
+
return new ColorSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
9942
10874
|
}
|
|
9943
10875
|
}, {
|
|
9944
10876
|
key: "readonly",
|
|
@@ -10044,14 +10976,37 @@ function router(router, keyOrItem, maybeItem) {
|
|
|
10044
10976
|
*/
|
|
10045
10977
|
|
|
10046
10978
|
/**
|
|
10047
|
-
*
|
|
10979
|
+
* What an entry's `alt` holds, for a given `alt` schema.
|
|
10980
|
+
*
|
|
10981
|
+
* This is the schema's own source type, not a second list that has to be kept
|
|
10982
|
+
* in step with `AltSchema`: `s.string()` gives `string`, `s.string().nullable()`
|
|
10983
|
+
* gives `string | null`, and `s.record(s.string())` gives
|
|
10984
|
+
* `Record<string, string>`.
|
|
10048
10985
|
*/
|
|
10049
10986
|
|
|
10987
|
+
/** Every `alt` value any `AltSchema` can produce. */
|
|
10988
|
+
|
|
10050
10989
|
/**
|
|
10051
|
-
*
|
|
10990
|
+
* Options for s.imageset()
|
|
10052
10991
|
*/
|
|
10053
10992
|
|
|
10054
|
-
|
|
10993
|
+
/**
|
|
10994
|
+
* `alt` is optional only when it is the default schema.
|
|
10995
|
+
*
|
|
10996
|
+
* Naming a different `Alt` and then leaving `alt` out would make the fallback
|
|
10997
|
+
* in `imageset()` a lie — `Alt` would say `s.string()` while the value was a
|
|
10998
|
+
* nullable one. Requiring it in that case is what makes the fallback sound:
|
|
10999
|
+
* the branch that uses it is reachable only when `Alt` IS the default.
|
|
11000
|
+
*/
|
|
11001
|
+
|
|
11002
|
+
/**
|
|
11003
|
+
* Metadata for an image entry in the images record.
|
|
11004
|
+
*
|
|
11005
|
+
* `alt` follows the schema's `alt` option, so it defaults to `string | null`
|
|
11006
|
+
* and becomes `string` under `s.string()` or `Record<string, string>` under
|
|
11007
|
+
* `s.record(s.string())`. Write `ImagesetEntryMetadata<AltSource>` where a
|
|
11008
|
+
* gallery of any alt shape is acceptable.
|
|
11009
|
+
*/
|
|
10055
11010
|
|
|
10056
11011
|
/**
|
|
10057
11012
|
* Define a collection of images.
|
|
@@ -10062,9 +11017,9 @@ function router(router, keyOrItem, maybeItem) {
|
|
|
10062
11017
|
*
|
|
10063
11018
|
* @example
|
|
10064
11019
|
* ```typescript
|
|
10065
|
-
* const schema = s.
|
|
11020
|
+
* const schema = s.imageset({
|
|
10066
11021
|
* accept: "image/webp",
|
|
10067
|
-
*
|
|
11022
|
+
* dir: "/public/val/images",
|
|
10068
11023
|
* alt: s.string().minLength(4),
|
|
10069
11024
|
* });
|
|
10070
11025
|
* export default c.define("/content/images.val.ts", schema, {
|
|
@@ -10077,9 +11032,18 @@ function router(router, keyOrItem, maybeItem) {
|
|
|
10077
11032
|
* });
|
|
10078
11033
|
* ```
|
|
10079
11034
|
*/
|
|
10080
|
-
var
|
|
11035
|
+
var imageset = function imageset(options) {
|
|
10081
11036
|
var _options$alt, _options$accept;
|
|
10082
|
-
var
|
|
11037
|
+
var dir = options.dir;
|
|
11038
|
+
// `options.alt` is `Alt | undefined`, and the fallback is exactly the schema
|
|
11039
|
+
// `Alt` defaults to when `alt` is omitted. TypeScript will not narrow a type
|
|
11040
|
+
// parameter from the absence of a value, so it cannot see that the two agree,
|
|
11041
|
+
// and the fallback is asserted here.
|
|
11042
|
+
//
|
|
11043
|
+
// Sound, not merely convenient: `ImagesetAltOption` makes `alt` REQUIRED
|
|
11044
|
+
// unless `Alt` is the default, so this branch is unreachable for any other
|
|
11045
|
+
// `Alt`. The one assertion in this file, and it replaces the wider one that
|
|
11046
|
+
// used to sit on the ObjectSchema below.
|
|
10083
11047
|
var altSchema = (_options$alt = options.alt) !== null && _options$alt !== void 0 ? _options$alt : string().nullable();
|
|
10084
11048
|
var itemSchema = new ObjectSchema({
|
|
10085
11049
|
width: new NumberSchema(undefined, false),
|
|
@@ -10090,7 +11054,7 @@ var images = function images(options) {
|
|
|
10090
11054
|
return new RecordSchema(itemSchema, false, [], null, null, {
|
|
10091
11055
|
type: "images",
|
|
10092
11056
|
accept: (_options$accept = options.accept) !== null && _options$accept !== void 0 ? _options$accept : "image/*",
|
|
10093
|
-
|
|
11057
|
+
dir: dir,
|
|
10094
11058
|
remote: false,
|
|
10095
11059
|
altSchema: altSchema,
|
|
10096
11060
|
encode: options.encode
|
|
@@ -10122,14 +11086,15 @@ function initSchema() {
|
|
|
10122
11086
|
keyOf: keyOf,
|
|
10123
11087
|
record: record,
|
|
10124
11088
|
file: file,
|
|
10125
|
-
|
|
11089
|
+
fileset: fileset,
|
|
10126
11090
|
date: date,
|
|
10127
11091
|
datetime: datetime,
|
|
10128
11092
|
color: color,
|
|
10129
11093
|
code: code,
|
|
11094
|
+
locale: locale,
|
|
10130
11095
|
route: route,
|
|
10131
11096
|
router: router,
|
|
10132
|
-
|
|
11097
|
+
imageset: imageset,
|
|
10133
11098
|
settings: settings
|
|
10134
11099
|
// i18n: i18n(locales),
|
|
10135
11100
|
};
|
|
@@ -10265,6 +11230,8 @@ var Hash = /*#__PURE__*/function () {
|
|
|
10265
11230
|
_defineProperty(this, "F", 0x9b05688c | 0);
|
|
10266
11231
|
_defineProperty(this, "G", 0x1f83d9ab | 0);
|
|
10267
11232
|
_defineProperty(this, "H", 0x5be0cd19 | 0);
|
|
11233
|
+
_defineProperty(this, "_byte", void 0);
|
|
11234
|
+
_defineProperty(this, "_word", void 0);
|
|
10268
11235
|
_defineProperty(this, "_size", 0);
|
|
10269
11236
|
_defineProperty(this, "_sp", 0);
|
|
10270
11237
|
if (!sharedBuffer || sharedOffset >= N.allocTotal) {
|
|
@@ -10969,7 +11936,7 @@ function _extractValModules() {
|
|
|
10969
11936
|
* The one answer to that question. There used to be two — `hasRemoteFileSchema`
|
|
10970
11937
|
* in the server, gating whether `/save` demands remote credentials, and
|
|
10971
11938
|
* `findRequiredRemoteFiles` in the Studio, gating the `/remote/settings` fetch —
|
|
10972
|
-
* and they disagreed about `s.
|
|
11939
|
+
* and they disagreed about `s.imageset({ ... }).remote()`: the Studio's version
|
|
10973
11940
|
* counted a remote media record, the server's did not, because a media
|
|
10974
11941
|
* collection serializes as a `record` of metadata rather than as an image
|
|
10975
11942
|
* schema.
|
|
@@ -11009,7 +11976,7 @@ function hasRemoteFileSchema(schema) {
|
|
|
11009
11976
|
return hasRemoteFileSchema(schema.item);
|
|
11010
11977
|
} else if (schema.type === "record") {
|
|
11011
11978
|
/**
|
|
11012
|
-
* A media collection — `s.
|
|
11979
|
+
* A media collection — `s.imageset()` / `s.fileset()` — is the case both of the
|
|
11013
11980
|
* old functions were written around, and the one they disagreed on.
|
|
11014
11981
|
*
|
|
11015
11982
|
* It has no file or image schema inside it to find: `item` is an object of
|
|
@@ -11051,7 +12018,7 @@ function hasRemoteFileSchema(schema) {
|
|
|
11051
12018
|
return false;
|
|
11052
12019
|
} else if (schema.type === "boolean" ||
|
|
11053
12020
|
// An enum's values are strings, so there is nothing to look inside.
|
|
11054
|
-
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route") {
|
|
12021
|
+
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" || schema.type === "locale") {
|
|
11055
12022
|
return false;
|
|
11056
12023
|
} else {
|
|
11057
12024
|
var exhaustiveCheck = schema;
|
|
@@ -11069,8 +12036,8 @@ function hasRemoteFileSchema(schema) {
|
|
|
11069
12036
|
*
|
|
11070
12037
|
* It is a walk over the SERIALIZED schema for the reasons given above, and for
|
|
11071
12038
|
* one more that is specific to this question: the two cases most likely to be
|
|
11072
|
-
* missed are invisible to a value type. A media collection (`s.
|
|
11073
|
-
* `s.
|
|
12039
|
+
* missed are invisible to a value type. A media collection (`s.imageset()` /
|
|
12040
|
+
* `s.fileset()`) serializes as a record of metadata with no image schema inside
|
|
11074
12041
|
* it, and a richtext inline image lives in a constructor argument. A check
|
|
11075
12042
|
* written against the item TYPE would silently pass both — and the gallery case
|
|
11076
12043
|
* already has a data-loss incident attached to it (see above).
|
|
@@ -11123,7 +12090,7 @@ function hasMediaSchema(schema) {
|
|
|
11123
12090
|
return false;
|
|
11124
12091
|
} else if (schema.type === "boolean" ||
|
|
11125
12092
|
// An enum's values are strings, so there is nothing to look inside.
|
|
11126
|
-
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" ||
|
|
12093
|
+
schema.type === "enum" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "dateTime" || schema.type === "color" || schema.type === "code" || schema.type === "keyOf" || schema.type === "route" || schema.type === "locale" ||
|
|
11127
12094
|
// A settings module holds the assistant's configuration, not content, and
|
|
11128
12095
|
// nothing in it is media.
|
|
11129
12096
|
schema.type === "settings") {
|
|
@@ -11402,6 +12369,46 @@ function getFileHash(text) {
|
|
|
11402
12369
|
return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(text)));
|
|
11403
12370
|
}
|
|
11404
12371
|
|
|
12372
|
+
/**
|
|
12373
|
+
* The variant of a discriminated union that a value takes, by its tag.
|
|
12374
|
+
*
|
|
12375
|
+
* A discriminated union is a fork rather than a level: the variant IS the node,
|
|
12376
|
+
* and everything a caller wants to know about that node — its fields, its
|
|
12377
|
+
* `locale` field, the schema to draw it with — is on the variant and not on the
|
|
12378
|
+
* union. Resolving it takes the source, so it cannot be done from the schema
|
|
12379
|
+
* alone, which is why every caller that has only the union ends up needing this.
|
|
12380
|
+
*
|
|
12381
|
+
* `undefined` where the tag matches nothing, rather than a fallback to the first
|
|
12382
|
+
* variant: a value whose tag names no variant is not a member of the union,
|
|
12383
|
+
* validation is already saying so, and reading fields out of the wrong shape
|
|
12384
|
+
* would answer confidently and wrongly.
|
|
12385
|
+
*
|
|
12386
|
+
* `s.enum()` never reaches here — it is a leaf whose values are strings, with no
|
|
12387
|
+
* variants to resolve — so anything that is not a discriminated union answers
|
|
12388
|
+
* `undefined` too.
|
|
12389
|
+
*/
|
|
12390
|
+
function discriminatedUnionBranchOf(schema, tag) {
|
|
12391
|
+
if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "discriminated-union") {
|
|
12392
|
+
return undefined;
|
|
12393
|
+
}
|
|
12394
|
+
var _iterator = result._createForOfIteratorHelper(schema.items),
|
|
12395
|
+
_step;
|
|
12396
|
+
try {
|
|
12397
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
12398
|
+
var item = _step.value;
|
|
12399
|
+
var discriminator = item.items[schema.key];
|
|
12400
|
+
if ((discriminator === null || discriminator === void 0 ? void 0 : discriminator.type) === "literal" && discriminator.value === tag) {
|
|
12401
|
+
return item;
|
|
12402
|
+
}
|
|
12403
|
+
}
|
|
12404
|
+
} catch (err) {
|
|
12405
|
+
_iterator.e(err);
|
|
12406
|
+
} finally {
|
|
12407
|
+
_iterator.f();
|
|
12408
|
+
}
|
|
12409
|
+
return undefined;
|
|
12410
|
+
}
|
|
12411
|
+
|
|
11405
12412
|
function deserializeSchema(serialized) {
|
|
11406
12413
|
var schema = deserializeSchemaImpl(serialized);
|
|
11407
12414
|
if (serialized.readonly) {
|
|
@@ -11413,7 +12420,7 @@ function deserializeSchema(serialized) {
|
|
|
11413
12420
|
return schema;
|
|
11414
12421
|
}
|
|
11415
12422
|
function deserializeSchemaImpl(serialized) {
|
|
11416
|
-
var _serialized$options, _serialized$options2, _serialized$render, _serialized$multiline, _serialized$render2, _serialized$render3, _serialized$render4, _serialized$render5, _serialized$render6, _serialized$render7, _serialized$render8, _serialized$accept, _serialized$
|
|
12423
|
+
var _serialized$options, _serialized$options2, _serialized$render, _serialized$multiline, _serialized$render2, _serialized$render3, _serialized$render4, _serialized$render5, _serialized$render6, _serialized$render7, _serialized$render8, _serialized$accept, _serialized$dir, _serialized$remote, _serialized$jsonValue, _serialized$render0, _serialized$external, _serialized$render1, _serialized$render12, _serialized$render13, _serialized$render14, _serialized$render15, _serialized$render16, _serialized$render17;
|
|
11417
12424
|
switch (serialized.type) {
|
|
11418
12425
|
case "string":
|
|
11419
12426
|
return new StringSchema(_objectSpread2(_objectSpread2({}, serialized.options), {}, {
|
|
@@ -11442,7 +12449,12 @@ function deserializeSchemaImpl(serialized) {
|
|
|
11442
12449
|
key = _ref4[0],
|
|
11443
12450
|
item = _ref4[1];
|
|
11444
12451
|
return [key, deserializeSchema(item)];
|
|
11445
|
-
})), serialized.opt, false, false, serialized.description
|
|
12452
|
+
})), serialized.opt, false, false, serialized.description,
|
|
12453
|
+
// Carried through, or the Studio's validation worker — which only ever
|
|
12454
|
+
// sees the deserialized schema — would run every field's own rules and
|
|
12455
|
+
// none of the section's, so a language declared twice would be reported
|
|
12456
|
+
// by the CLI and silently accepted in the Studio.
|
|
12457
|
+
serialized.section);
|
|
11446
12458
|
case "array":
|
|
11447
12459
|
return new ArraySchema(deserializeSchema(serialized.item), serialized.opt, [], false, false, serialized.description,
|
|
11448
12460
|
// The preview closure cannot survive serialization; the render can.
|
|
@@ -11468,7 +12480,7 @@ function deserializeSchemaImpl(serialized) {
|
|
|
11468
12480
|
return new RecordSchema(deserializeSchema(serialized.item), serialized.opt, [], null, serialized.key ? deserializeSchema(serialized.key) : null, serialized.mediaType ? {
|
|
11469
12481
|
type: serialized.mediaType,
|
|
11470
12482
|
accept: (_serialized$accept = serialized.accept) !== null && _serialized$accept !== void 0 ? _serialized$accept : "*/*",
|
|
11471
|
-
|
|
12483
|
+
dir: (_serialized$dir = serialized.dir) !== null && _serialized$dir !== void 0 ? _serialized$dir : "/public/val",
|
|
11472
12484
|
remote: (_serialized$remote = serialized.remote) !== null && _serialized$remote !== void 0 ? _serialized$remote : false,
|
|
11473
12485
|
altSchema: serialized.alt ? deserializeSchema(serialized.alt) : undefined
|
|
11474
12486
|
} : undefined, false, false, serialized.description, (_serialized$jsonValue = serialized.jsonValues) !== null && _serialized$jsonValue !== void 0 ? _serialized$jsonValue : false,
|
|
@@ -11479,27 +12491,32 @@ function deserializeSchemaImpl(serialized) {
|
|
|
11479
12491
|
(_serialized$external = serialized.external) !== null && _serialized$external !== void 0 ? _serialized$external : null);
|
|
11480
12492
|
case "keyOf":
|
|
11481
12493
|
return new KeyOfSchema(serialized.schema, serialized.path, serialized.opt, [], false, false, serialized.description, (_serialized$render1 = serialized.render) !== null && _serialized$render1 !== void 0 ? _serialized$render1 : null);
|
|
11482
|
-
case "
|
|
12494
|
+
case "locale":
|
|
11483
12495
|
{
|
|
11484
12496
|
var _serialized$render10;
|
|
12497
|
+
return new LocaleSchema(serialized.opt, [], false, false, serialized.description, (_serialized$render10 = serialized.render) !== null && _serialized$render10 !== void 0 ? _serialized$render10 : null);
|
|
12498
|
+
}
|
|
12499
|
+
case "route":
|
|
12500
|
+
{
|
|
12501
|
+
var _serialized$render11;
|
|
11485
12502
|
var routeOptions = serialized.options ? {
|
|
11486
12503
|
include: serialized.options.include ? new RegExp(serialized.options.include.source, serialized.options.include.flags) : undefined,
|
|
11487
12504
|
exclude: serialized.options.exclude ? new RegExp(serialized.options.exclude.source, serialized.options.exclude.flags) : undefined
|
|
11488
12505
|
} : undefined;
|
|
11489
|
-
return new RouteSchema(routeOptions, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12506
|
+
return new RouteSchema(routeOptions, serialized.opt, [], false, false, serialized.description, (_serialized$render11 = serialized.render) !== null && _serialized$render11 !== void 0 ? _serialized$render11 : null);
|
|
11490
12507
|
}
|
|
11491
12508
|
case "file":
|
|
11492
|
-
return new FileSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$
|
|
12509
|
+
return new FileSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$render12 = serialized.render) !== null && _serialized$render12 !== void 0 ? _serialized$render12 : null);
|
|
11493
12510
|
case "image":
|
|
11494
|
-
return new ImageSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$
|
|
12511
|
+
return new ImageSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$render13 = serialized.render) !== null && _serialized$render13 !== void 0 ? _serialized$render13 : null);
|
|
11495
12512
|
case "date":
|
|
11496
|
-
return new DateSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12513
|
+
return new DateSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render14 = serialized.render) !== null && _serialized$render14 !== void 0 ? _serialized$render14 : null);
|
|
11497
12514
|
case "dateTime":
|
|
11498
|
-
return new DateTimeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12515
|
+
return new DateTimeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render15 = serialized.render) !== null && _serialized$render15 !== void 0 ? _serialized$render15 : null);
|
|
11499
12516
|
case "color":
|
|
11500
|
-
return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12517
|
+
return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render16 = serialized.render) !== null && _serialized$render16 !== void 0 ? _serialized$render16 : null);
|
|
11501
12518
|
case "code":
|
|
11502
|
-
return new CodeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12519
|
+
return new CodeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render17 = serialized.render) !== null && _serialized$render17 !== void 0 ? _serialized$render17 : null);
|
|
11503
12520
|
default:
|
|
11504
12521
|
{
|
|
11505
12522
|
var exhaustiveCheck = serialized;
|
|
@@ -12166,7 +13183,7 @@ function isPageRouter(routerId) {
|
|
|
12166
13183
|
|
|
12167
13184
|
var corePackageJson = {
|
|
12168
13185
|
name: "@valbuild/core",
|
|
12169
|
-
version: "0.
|
|
13186
|
+
version: "0.128.0",
|
|
12170
13187
|
"private": false,
|
|
12171
13188
|
description: "Val - supercharged hard-coded content",
|
|
12172
13189
|
repository: {
|
|
@@ -12359,6 +13376,7 @@ exports.ImageSchema = ImageSchema;
|
|
|
12359
13376
|
exports.Internal = Internal;
|
|
12360
13377
|
exports.KeyOfSchema = KeyOfSchema;
|
|
12361
13378
|
exports.LiteralSchema = LiteralSchema;
|
|
13379
|
+
exports.LocaleSchema = LocaleSchema;
|
|
12362
13380
|
exports.ModuleFilePathSep = ModuleFilePathSep;
|
|
12363
13381
|
exports.NumberSchema = NumberSchema;
|
|
12364
13382
|
exports.ObjectSchema = ObjectSchema;
|
|
@@ -12378,8 +13396,10 @@ exports._toConsumableArray = _toConsumableArray;
|
|
|
12378
13396
|
exports._typeof = _typeof;
|
|
12379
13397
|
exports.assistantAvailability = assistantAvailability;
|
|
12380
13398
|
exports.computeValModuleShas = computeValModuleShas;
|
|
13399
|
+
exports.declaredKeySetOf = declaredKeySetOf;
|
|
12381
13400
|
exports.derefPatch = derefPatch;
|
|
12382
13401
|
exports.deserializeSchema = deserializeSchema;
|
|
13402
|
+
exports.discriminatedUnionBranchOf = discriminatedUnionBranchOf;
|
|
12383
13403
|
exports.extractValModules = extractValModules;
|
|
12384
13404
|
exports.getSourcePathFromRoute = getSourcePathFromRoute;
|
|
12385
13405
|
exports.hasMediaSchema = hasMediaSchema;
|
|
@@ -12388,6 +13408,9 @@ exports.initVal = initVal;
|
|
|
12388
13408
|
exports.isInlineRender = isInlineRender;
|
|
12389
13409
|
exports.isPageRouter = isPageRouter;
|
|
12390
13410
|
exports.isRootModuleFilePath = isRootModuleFilePath;
|
|
13411
|
+
exports.localeOfValue = localeOfValue;
|
|
13412
|
+
exports.localeTagError = localeTagError;
|
|
13413
|
+
exports.missingDeclaredKeys = missingDeclaredKeys;
|
|
12391
13414
|
exports.modules = modules;
|
|
12392
13415
|
exports.parseNextJsRoutePattern = parseNextJsRoutePattern;
|
|
12393
13416
|
exports.parseTanStackRoutePattern = parseTanStackRoutePattern;
|