@valbuild/core 0.126.0 → 0.127.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 +184 -0
- package/dist/declarations/src/index.d.ts +5 -1
- package/dist/declarations/src/initSchema.d.ts +16 -0
- 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/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 +51 -1
- 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-cd25c2dc.esm.js → index-5a6e6398.esm.js} +1035 -54
- package/dist/{index-b41b638f.cjs.dev.js → index-889ac441.cjs.dev.js} +1040 -53
- package/dist/{index-6db78f3c.cjs.prod.js → index-d44deccb.cjs.prod.js} +1040 -53
- 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
|
@@ -161,19 +161,217 @@ function _inherits(t, e) {
|
|
|
161
161
|
// import { SerializedI18nSchema } from "./future/i18n";
|
|
162
162
|
// import { SerializedOneOfSchema } from "./future/oneOf";
|
|
163
163
|
|
|
164
|
+
/**
|
|
165
|
+
* A locale scope's path, as something to read in a message.
|
|
166
|
+
*
|
|
167
|
+
* The walk names the item of an array or record `*`, which says nothing to
|
|
168
|
+
* whoever has to fix this. `[]` is the convention people already read as "each
|
|
169
|
+
* of these", and a path that is nothing BUT items has no field to name at all.
|
|
170
|
+
*/
|
|
171
|
+
function describeScopePath(path) {
|
|
172
|
+
if (path.every(function (segment) {
|
|
173
|
+
return segment === "*";
|
|
174
|
+
})) {
|
|
175
|
+
return "its entries";
|
|
176
|
+
}
|
|
177
|
+
var rendered = "";
|
|
178
|
+
var _iterator = _createForOfIteratorHelper(path),
|
|
179
|
+
_step;
|
|
180
|
+
try {
|
|
181
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
182
|
+
var segment = _step.value;
|
|
183
|
+
if (segment === "*") {
|
|
184
|
+
rendered += "[]";
|
|
185
|
+
} else {
|
|
186
|
+
rendered += rendered === "" ? segment : ".".concat(segment);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} catch (err) {
|
|
190
|
+
_iterator.e(err);
|
|
191
|
+
} finally {
|
|
192
|
+
_iterator.f();
|
|
193
|
+
}
|
|
194
|
+
return "'".concat(rendered, "'");
|
|
195
|
+
}
|
|
164
196
|
var Schema = /*#__PURE__*/function () {
|
|
165
197
|
function Schema() {
|
|
166
198
|
_classCallCheck(this, Schema);
|
|
199
|
+
/**
|
|
200
|
+
* The answer, computed once per schema.
|
|
201
|
+
*
|
|
202
|
+
* Memoised because the question is asked from `executeValidate`, which runs
|
|
203
|
+
* once per SOURCE instance: an array of five hundred blocks asks the item
|
|
204
|
+
* schema five hundred times, and each answer walks the schema below it
|
|
205
|
+
* looking for a nested scope. The answer cannot differ between two instances
|
|
206
|
+
* of the same schema — nothing here reads the source — so the walk is done
|
|
207
|
+
* once and the result handed back after that.
|
|
208
|
+
*
|
|
209
|
+
* The error is still reported at every instance's path. Val's validation
|
|
210
|
+
* errors are keyed by source path and that is where the Studio draws them, so
|
|
211
|
+
* a schema error on a row is a schema error on every row; reporting it on one
|
|
212
|
+
* arbitrary row would put it somewhere nobody was looking.
|
|
213
|
+
*/
|
|
214
|
+
_defineProperty(this, "localeScopeErrorsMemo", void 0);
|
|
167
215
|
}
|
|
168
216
|
return _createClass(Schema, [{
|
|
217
|
+
key: "isLocaleField",
|
|
218
|
+
value:
|
|
219
|
+
/**
|
|
220
|
+
* Whether this node is a locale — the field that MARKS a scope, `s.locale()`.
|
|
221
|
+
*
|
|
222
|
+
* Only `LocaleSchema` overrides this. A base implementation rather than an
|
|
223
|
+
* abstract one on purpose: every other schema class answers no, and a
|
|
224
|
+
* question every class had to answer would be twenty edits for one yes.
|
|
225
|
+
*
|
|
226
|
+
* Not the same question as {@link opensLocaleScope}: a locale field marks the
|
|
227
|
+
* scope, the object AROUND it is the scope. See `localeScope.ts`.
|
|
228
|
+
*/
|
|
229
|
+
function isLocaleField() {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Whether this node OPENS a locale scope, and what opens it.
|
|
235
|
+
*
|
|
236
|
+
* An object with a `s.locale()` field opens one; so does a record keyed by
|
|
237
|
+
* `s.locale()`. Everything below such a node is in that one language, which
|
|
238
|
+
* is why a scope may not contain another — see `localeScope.ts` for the rule
|
|
239
|
+
* and the reason it is validated rather than typed.
|
|
240
|
+
*/
|
|
241
|
+
}, {
|
|
242
|
+
key: "opensLocaleScope",
|
|
243
|
+
value: function opensLocaleScope() {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The child schemas a locale scope reaches, by the path segment that reaches
|
|
249
|
+
* them.
|
|
250
|
+
*
|
|
251
|
+
* A structural walk that deliberately does NOT go through `executeSerialize`:
|
|
252
|
+
* serializing a subtree at every node to ask a question about its shape is
|
|
253
|
+
* quadratic, and this is asked during validation. `*` stands for the item of
|
|
254
|
+
* an array or record, which has no name of its own.
|
|
255
|
+
*/
|
|
256
|
+
}, {
|
|
257
|
+
key: "localeScopeChildren",
|
|
258
|
+
value: function localeScopeChildren() {
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Every locale scope opened strictly BELOW this node, by path.
|
|
264
|
+
*
|
|
265
|
+
* Stops descending at each one it finds, so a scope three deep is reported
|
|
266
|
+
* once, by the scope immediately enclosing it, rather than by every ancestor.
|
|
267
|
+
*/
|
|
268
|
+
}, {
|
|
269
|
+
key: "localeScopesBelow",
|
|
270
|
+
value: function localeScopesBelow() {
|
|
271
|
+
var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
272
|
+
var found = [];
|
|
273
|
+
var _iterator2 = _createForOfIteratorHelper(this.localeScopeChildren()),
|
|
274
|
+
_step2;
|
|
275
|
+
try {
|
|
276
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
277
|
+
var _step2$value = _step2.value,
|
|
278
|
+
key = _step2$value.key,
|
|
279
|
+
schema = _step2$value.schema;
|
|
280
|
+
var _path = [].concat(_toConsumableArray(prefix), [key]);
|
|
281
|
+
var opened = schema.opensLocaleScope();
|
|
282
|
+
if (opened !== null) {
|
|
283
|
+
found.push({
|
|
284
|
+
path: _path,
|
|
285
|
+
kind: opened
|
|
286
|
+
});
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
found.push.apply(found, _toConsumableArray(schema.localeScopesBelow(_path)));
|
|
290
|
+
}
|
|
291
|
+
} catch (err) {
|
|
292
|
+
_iterator2.e(err);
|
|
293
|
+
} finally {
|
|
294
|
+
_iterator2.f();
|
|
295
|
+
}
|
|
296
|
+
return found;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* The scope rule, as errors at this node — or `false` if it is not broken.
|
|
301
|
+
*
|
|
302
|
+
* Two things are wrong and both are wrong in the SCHEMA rather than in the
|
|
303
|
+
* content, so both are `schemaError`s: an object with two locale fields (the
|
|
304
|
+
* subtree below it would be in two languages at once), and a locale scope
|
|
305
|
+
* inside another (the inner one would silently override the outer for part
|
|
306
|
+
* of a subtree that is supposed to be one language throughout).
|
|
307
|
+
*
|
|
308
|
+
* Validated rather than typed on purpose. Expressing "no scope below this
|
|
309
|
+
* one" as a constraint means threading it through every schema class's type
|
|
310
|
+
* parameter, and the errors that fall out of a recursive constraint like
|
|
311
|
+
* that name the whole tree — an unrelated typo in a `.val.ts` would print
|
|
312
|
+
* pages. See the design notes on the locales PR.
|
|
313
|
+
*/
|
|
314
|
+
}, {
|
|
315
|
+
key: "localeScopeErrors",
|
|
316
|
+
value: function localeScopeErrors() {
|
|
317
|
+
if (this.localeScopeErrorsMemo === undefined) {
|
|
318
|
+
this.localeScopeErrorsMemo = this.computeLocaleScopeErrors();
|
|
319
|
+
}
|
|
320
|
+
return this.localeScopeErrorsMemo;
|
|
321
|
+
}
|
|
322
|
+
}, {
|
|
323
|
+
key: "computeLocaleScopeErrors",
|
|
324
|
+
value: function computeLocaleScopeErrors() {
|
|
325
|
+
var errors = [];
|
|
326
|
+
var localeFields = this.localeFieldNames();
|
|
327
|
+
if (localeFields.length > 1) {
|
|
328
|
+
errors.push({
|
|
329
|
+
message: "An object can be in one language, so it can have one locale field. Found ".concat(localeFields.map(function (each) {
|
|
330
|
+
return "'".concat(each, "'");
|
|
331
|
+
}).join(", "), "."),
|
|
332
|
+
schemaError: true
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
var opened = this.opensLocaleScope();
|
|
336
|
+
if (opened !== null) {
|
|
337
|
+
var _iterator3 = _createForOfIteratorHelper(this.localeScopesBelow()),
|
|
338
|
+
_step3;
|
|
339
|
+
try {
|
|
340
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
341
|
+
var nested = _step3.value;
|
|
342
|
+
errors.push({
|
|
343
|
+
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."),
|
|
344
|
+
schemaError: true
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
} catch (err) {
|
|
348
|
+
_iterator3.e(err);
|
|
349
|
+
} finally {
|
|
350
|
+
_iterator3.f();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return errors;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* This node's own `s.locale()` fields, where it is an object that has any.
|
|
358
|
+
*
|
|
359
|
+
* Empty everywhere else, so `localeScopeErrors` can live on the base class.
|
|
360
|
+
*/
|
|
361
|
+
}, {
|
|
362
|
+
key: "localeFieldNames",
|
|
363
|
+
value: function localeFieldNames() {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
}, {
|
|
169
367
|
key: "executeCustomValidateFunctions",
|
|
170
368
|
value: function executeCustomValidateFunctions(src, customValidateFunctions, ctx) {
|
|
171
369
|
var errors = [];
|
|
172
|
-
var
|
|
173
|
-
|
|
370
|
+
var _iterator4 = _createForOfIteratorHelper(customValidateFunctions),
|
|
371
|
+
_step4;
|
|
174
372
|
try {
|
|
175
|
-
for (
|
|
176
|
-
var customValidateFunction =
|
|
373
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
374
|
+
var customValidateFunction = _step4.value;
|
|
177
375
|
try {
|
|
178
376
|
var result = customValidateFunction(src, ctx);
|
|
179
377
|
if (result) {
|
|
@@ -191,9 +389,9 @@ var Schema = /*#__PURE__*/function () {
|
|
|
191
389
|
}
|
|
192
390
|
}
|
|
193
391
|
} catch (err) {
|
|
194
|
-
|
|
392
|
+
_iterator4.e(err);
|
|
195
393
|
} finally {
|
|
196
|
-
|
|
394
|
+
_iterator4.f();
|
|
197
395
|
}
|
|
198
396
|
return errors;
|
|
199
397
|
}
|
|
@@ -292,11 +490,11 @@ var Schema = /*#__PURE__*/function () {
|
|
|
292
490
|
return incoming;
|
|
293
491
|
}
|
|
294
492
|
for (var pathS in incoming) {
|
|
295
|
-
var
|
|
296
|
-
if (current[
|
|
297
|
-
current[
|
|
493
|
+
var _path2 = pathS;
|
|
494
|
+
if (current[_path2]) {
|
|
495
|
+
current[_path2] = current[_path2].concat(incoming[_path2]);
|
|
298
496
|
} else {
|
|
299
|
-
current[
|
|
497
|
+
current[_path2] = incoming[_path2];
|
|
300
498
|
}
|
|
301
499
|
}
|
|
302
500
|
return current;
|
|
@@ -331,6 +529,10 @@ var GetSource = Symbol["for"]("@valbuild/core/GetSource");
|
|
|
331
529
|
var ValError = Symbol["for"]("@valbuild/core/ValError");
|
|
332
530
|
var GenericSelector = /*#__PURE__*/_createClass(function GenericSelector(valOrExpr, path, schema, error) {
|
|
333
531
|
_classCallCheck(this, GenericSelector);
|
|
532
|
+
_defineProperty(this, Path, void 0);
|
|
533
|
+
_defineProperty(this, GetSource, void 0);
|
|
534
|
+
_defineProperty(this, ValError, void 0);
|
|
535
|
+
_defineProperty(this, GetSchema, void 0);
|
|
334
536
|
this[Path] = path;
|
|
335
537
|
this[GetSource] = valOrExpr;
|
|
336
538
|
this[ValError] = error;
|
|
@@ -933,6 +1135,18 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
933
1135
|
} finally {
|
|
934
1136
|
_iterator.f();
|
|
935
1137
|
}
|
|
1138
|
+
var _iterator2 = _createForOfIteratorHelper(this.localeScopeErrors()),
|
|
1139
|
+
_step2;
|
|
1140
|
+
try {
|
|
1141
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1142
|
+
var scopeError = _step2.value;
|
|
1143
|
+
error = this.appendValidationError(error, path, scopeError.message, src, scopeError.schemaError);
|
|
1144
|
+
}
|
|
1145
|
+
} catch (err) {
|
|
1146
|
+
_iterator2.e(err);
|
|
1147
|
+
} finally {
|
|
1148
|
+
_iterator2.f();
|
|
1149
|
+
}
|
|
936
1150
|
for (var _i = 0, _Object$entries = Object.entries(this.items); _i < _Object$entries.length; _i++) {
|
|
937
1151
|
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
938
1152
|
_key = _Object$entries$_i[0],
|
|
@@ -1016,7 +1230,7 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1016
1230
|
key: "nullable",
|
|
1017
1231
|
value: function nullable() {
|
|
1018
1232
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
1019
|
-
return new ObjectSchema(this.items, true,
|
|
1233
|
+
return new ObjectSchema(this.items, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
1020
1234
|
}
|
|
1021
1235
|
}, {
|
|
1022
1236
|
key: "readonly",
|
|
@@ -1030,6 +1244,35 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1030
1244
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
1031
1245
|
return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
|
|
1032
1246
|
}
|
|
1247
|
+
|
|
1248
|
+
/** The names of this object's `s.locale()` fields, in declaration order. */
|
|
1249
|
+
}, {
|
|
1250
|
+
key: "localeFieldNames",
|
|
1251
|
+
value: function localeFieldNames() {
|
|
1252
|
+
var _this2 = this;
|
|
1253
|
+
return Object.keys(this.items).filter(function (key) {
|
|
1254
|
+
return _this2.items[key]["isLocaleField"]();
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
}, {
|
|
1258
|
+
key: "opensLocaleScope",
|
|
1259
|
+
value: function opensLocaleScope() {
|
|
1260
|
+
// More than one is itself the error, reported by `localeScopeErrors`. It
|
|
1261
|
+
// still opens a scope: reporting "two locale fields" AND "a scope inside a
|
|
1262
|
+
// scope" for the same object would be two errors about one mistake.
|
|
1263
|
+
return this.localeFieldNames().length > 0 ? "field" : null;
|
|
1264
|
+
}
|
|
1265
|
+
}, {
|
|
1266
|
+
key: "localeScopeChildren",
|
|
1267
|
+
value: function localeScopeChildren() {
|
|
1268
|
+
var _this3 = this;
|
|
1269
|
+
return Object.keys(this.items).map(function (key) {
|
|
1270
|
+
return {
|
|
1271
|
+
key: key,
|
|
1272
|
+
schema: _this3.items[key]
|
|
1273
|
+
};
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1033
1276
|
}, {
|
|
1034
1277
|
key: "executeCustomValidateAt",
|
|
1035
1278
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -1294,7 +1537,7 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1294
1537
|
key: "nullable",
|
|
1295
1538
|
value: function nullable() {
|
|
1296
1539
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
1297
|
-
return new ArraySchema(this.item, true,
|
|
1540
|
+
return new ArraySchema(this.item, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.previewInput, this.renderInput);
|
|
1298
1541
|
}
|
|
1299
1542
|
}, {
|
|
1300
1543
|
key: "readonly",
|
|
@@ -1308,6 +1551,14 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
|
|
|
1308
1551
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
1309
1552
|
return new ArraySchema(this.item, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.previewInput, this.renderInput);
|
|
1310
1553
|
}
|
|
1554
|
+
}, {
|
|
1555
|
+
key: "localeScopeChildren",
|
|
1556
|
+
value: function localeScopeChildren() {
|
|
1557
|
+
return [{
|
|
1558
|
+
key: "*",
|
|
1559
|
+
schema: this.item
|
|
1560
|
+
}];
|
|
1561
|
+
}
|
|
1311
1562
|
}, {
|
|
1312
1563
|
key: "executeCustomValidateAt",
|
|
1313
1564
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -1481,6 +1732,8 @@ var array = function array(schema) {
|
|
|
1481
1732
|
};
|
|
1482
1733
|
|
|
1483
1734
|
var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
1735
|
+
/** Type-only marker: as a record key, this declares the key set. See `LocaleSchema`. */
|
|
1736
|
+
|
|
1484
1737
|
function LiteralSchema(value) {
|
|
1485
1738
|
var _this;
|
|
1486
1739
|
var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -1612,7 +1865,7 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
|
|
|
1612
1865
|
}, {
|
|
1613
1866
|
key: "nullable",
|
|
1614
1867
|
value: function nullable() {
|
|
1615
|
-
return new LiteralSchema(this.value, true,
|
|
1868
|
+
return new LiteralSchema(this.value, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
1616
1869
|
}
|
|
1617
1870
|
}, {
|
|
1618
1871
|
key: "readonly",
|
|
@@ -2033,7 +2286,7 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2033
2286
|
key: "nullable",
|
|
2034
2287
|
value: function nullable() {
|
|
2035
2288
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
2036
|
-
return new DiscriminatedUnionSchema(this.key, this.items, true,
|
|
2289
|
+
return new DiscriminatedUnionSchema(this.key, this.items, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
2037
2290
|
}
|
|
2038
2291
|
}, {
|
|
2039
2292
|
key: "readonly",
|
|
@@ -2047,6 +2300,20 @@ var DiscriminatedUnionSchema = /*#__PURE__*/function (_Schema) {
|
|
|
2047
2300
|
var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2048
2301
|
return new DiscriminatedUnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
|
|
2049
2302
|
}
|
|
2303
|
+
}, {
|
|
2304
|
+
key: "localeScopeChildren",
|
|
2305
|
+
value: function localeScopeChildren() {
|
|
2306
|
+
// Every variant is walked under the SAME path: whichever one the value
|
|
2307
|
+
// takes, that is where it sits. `s.enum()` has no children at all — its
|
|
2308
|
+
// values are strings, not schemas — which is why only this half of the old
|
|
2309
|
+
// `s.union` has this.
|
|
2310
|
+
return this.items.map(function (item) {
|
|
2311
|
+
return {
|
|
2312
|
+
key: "*",
|
|
2313
|
+
schema: item
|
|
2314
|
+
};
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2050
2317
|
}, {
|
|
2051
2318
|
key: "executeCustomValidateAt",
|
|
2052
2319
|
value: function executeCustomValidateAt(path, src) {
|
|
@@ -4457,7 +4724,7 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
|
|
|
4457
4724
|
}, {
|
|
4458
4725
|
key: "nullable",
|
|
4459
4726
|
value: function nullable() {
|
|
4460
|
-
return new RichTextSchema(this.options, true,
|
|
4727
|
+
return new RichTextSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
4461
4728
|
}
|
|
4462
4729
|
}, {
|
|
4463
4730
|
key: "readonly",
|
|
@@ -4974,6 +5241,68 @@ function hasInlineExternalEntries(source) {
|
|
|
4974
5241
|
return _typeof(source) === "object" && source !== null && !Array.isArray(source) && !isExternal(source) && Object.keys(source).length > 0;
|
|
4975
5242
|
}
|
|
4976
5243
|
|
|
5244
|
+
/**
|
|
5245
|
+
* The keys a record is REQUIRED to hold, where its key schema says what they are.
|
|
5246
|
+
*
|
|
5247
|
+
* Most records have an open key set — `s.record(s.string(), item)` holds
|
|
5248
|
+
* whatever anyone adds — and this returns `null` for those. A record keyed by
|
|
5249
|
+
* something that enumerates its values is different in kind: the keys are part
|
|
5250
|
+
* of the schema, so a missing one is a hole in the content rather than content
|
|
5251
|
+
* nobody has written yet.
|
|
5252
|
+
*
|
|
5253
|
+
* Two key schemas enumerate. A union of literals does it locally, so its keys
|
|
5254
|
+
* are here. `s.locale()` does it in the settings module, which is another file
|
|
5255
|
+
* and so cannot be read from a serialized schema — that case says only which
|
|
5256
|
+
* kind it is, and is resolved against `locales.available` by
|
|
5257
|
+
* `resolveSchemaSourceFixes`, the same crossing `keyOf` and `route` make.
|
|
5258
|
+
*/
|
|
5259
|
+
|
|
5260
|
+
/**
|
|
5261
|
+
* What `key` requires a record to hold, or `null` where it requires nothing.
|
|
5262
|
+
*
|
|
5263
|
+
* Works from the SERIALIZED schema so that the Studio, the validation worker
|
|
5264
|
+
* and the server all answer this the same way — none of them has the schema
|
|
5265
|
+
* instance, and `SchemaStore` deliberately holds serialized schemas only.
|
|
5266
|
+
*/
|
|
5267
|
+
function declaredKeySetOf(key) {
|
|
5268
|
+
if (key === undefined) {
|
|
5269
|
+
return null;
|
|
5270
|
+
}
|
|
5271
|
+
if (key.type === "literal") {
|
|
5272
|
+
return {
|
|
5273
|
+
kind: "literals",
|
|
5274
|
+
keys: [key.value]
|
|
5275
|
+
};
|
|
5276
|
+
}
|
|
5277
|
+
if (key.type === "enum") {
|
|
5278
|
+
// An enum names every value it may take, so those values ARE the key set.
|
|
5279
|
+
// `discriminated-union` is deliberately absent: it discriminates objects
|
|
5280
|
+
// and cannot be a record key at all.
|
|
5281
|
+
return {
|
|
5282
|
+
kind: "literals",
|
|
5283
|
+
keys: _toConsumableArray(key.values)
|
|
5284
|
+
};
|
|
5285
|
+
}
|
|
5286
|
+
if (key.type === "locale") {
|
|
5287
|
+
return {
|
|
5288
|
+
kind: "locale"
|
|
5289
|
+
};
|
|
5290
|
+
}
|
|
5291
|
+
return null;
|
|
5292
|
+
}
|
|
5293
|
+
|
|
5294
|
+
/**
|
|
5295
|
+
* The declared keys a record is missing, in the order the schema declares them.
|
|
5296
|
+
*
|
|
5297
|
+
* Declaration order rather than the source's: this is read as "what is left to
|
|
5298
|
+
* write", and the answer should not reshuffle itself as entries are added.
|
|
5299
|
+
*/
|
|
5300
|
+
function missingDeclaredKeys(declared, present) {
|
|
5301
|
+
return declared.filter(function (key) {
|
|
5302
|
+
return !present.includes(key);
|
|
5303
|
+
});
|
|
5304
|
+
}
|
|
5305
|
+
|
|
4977
5306
|
/**
|
|
4978
5307
|
* The source type of a `.jsonValues()` record: every entry value is EITHER a
|
|
4979
5308
|
* lazily loaded {@link JsonSource} whose resolved content is the (loosened, see
|
|
@@ -5005,6 +5334,16 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5005
5334
|
var externalLabel = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : null;
|
|
5006
5335
|
_classCallCheck(this, RecordSchema);
|
|
5007
5336
|
_this = _callSuper(this, RecordSchema);
|
|
5337
|
+
/**
|
|
5338
|
+
* The key set this record's schema declares, computed once.
|
|
5339
|
+
*
|
|
5340
|
+
* `declaredKeySetOf` reads a SERIALIZED schema, and serializing the key
|
|
5341
|
+
* schema walks it — twice per validate, and once per record instance, for an
|
|
5342
|
+
* answer that is a property of the schema and cannot move between them. A
|
|
5343
|
+
* schema is built once and validated against many times, so the walk happens
|
|
5344
|
+
* on the first question and not on any after it.
|
|
5345
|
+
*/
|
|
5346
|
+
_defineProperty(_this, "declaredKeys", void 0);
|
|
5008
5347
|
_this.item = item;
|
|
5009
5348
|
_this.opt = opt;
|
|
5010
5349
|
_this.customValidateFunctions = customValidateFunctions;
|
|
@@ -5151,6 +5490,11 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5151
5490
|
error = _objectSpread2(_objectSpread2({}, error), {}, _defineProperty({}, path, [allFilesCheckError]));
|
|
5152
5491
|
}
|
|
5153
5492
|
}
|
|
5493
|
+
// A record whose keys are declared by its schema holds every one of them,
|
|
5494
|
+
// and an entry nobody has written yet is `null` rather than absent — so
|
|
5495
|
+
// `null` is a value here, not a value of the wrong type, and the item
|
|
5496
|
+
// schema is not asked about it.
|
|
5497
|
+
var hasDeclaredKeys = this.declaredKeySet() !== null;
|
|
5154
5498
|
Object.entries(src).forEach(function (_ref5) {
|
|
5155
5499
|
var _ref6 = _slicedToArray(_ref5, 2),
|
|
5156
5500
|
key = _ref6[0],
|
|
@@ -5190,7 +5534,7 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5190
5534
|
_this2.markKeyErrorsAtPath(entryErr, subPath);
|
|
5191
5535
|
}
|
|
5192
5536
|
error = _this2.mergeValidationErrors(error, entryErr);
|
|
5193
|
-
} else if (_this2.isJsonValues && isJson(elem)) ; else {
|
|
5537
|
+
} else if (hasDeclaredKeys && elem === null) ; else if (_this2.isJsonValues && isJson(elem)) ; else {
|
|
5194
5538
|
// Falls through for a jsonValues record whose entry content is inlined
|
|
5195
5539
|
// (loaded in the UI, or hand-authored): same as a plain record — validate
|
|
5196
5540
|
// the value against the item schema.
|
|
@@ -5198,8 +5542,79 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5198
5542
|
error = _this2.mergeValidationErrors(error, subError);
|
|
5199
5543
|
}
|
|
5200
5544
|
});
|
|
5545
|
+
var declaredKeys = this.getDeclaredKeysValidation(path, src);
|
|
5546
|
+
error = this.mergeValidationErrors(error, declaredKeys);
|
|
5547
|
+
var _iterator2 = _createForOfIteratorHelper(this.localeScopeErrors()),
|
|
5548
|
+
_step2;
|
|
5549
|
+
try {
|
|
5550
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
5551
|
+
var scopeError = _step2.value;
|
|
5552
|
+
error = this.appendValidationError(error, path, scopeError.message, src, scopeError.schemaError);
|
|
5553
|
+
}
|
|
5554
|
+
} catch (err) {
|
|
5555
|
+
_iterator2.e(err);
|
|
5556
|
+
} finally {
|
|
5557
|
+
_iterator2.f();
|
|
5558
|
+
}
|
|
5201
5559
|
return error;
|
|
5202
5560
|
}
|
|
5561
|
+
|
|
5562
|
+
/**
|
|
5563
|
+
* The check that a record with a DECLARED key set holds every one of them.
|
|
5564
|
+
*
|
|
5565
|
+
* `s.record(s.locale(), item)` has one entry per language and
|
|
5566
|
+
* `s.record(s.union(s.literal("a"), s.literal("b")), item)` has both — the
|
|
5567
|
+
* keys are part of the schema either way, so a missing one is a hole in the
|
|
5568
|
+
* content rather than content nobody has written yet. TypeScript already
|
|
5569
|
+
* demanded both keys of the second; this is the validator catching up, which
|
|
5570
|
+
* is why the two now behave the same.
|
|
5571
|
+
*
|
|
5572
|
+
* Deferred to `resolveSchemaSourceFixes` even for the literal case, where the
|
|
5573
|
+
* keys are known right here: a locale record's keys are in another file, and
|
|
5574
|
+
* one code path for both is one message, one fix and one thing to be wrong.
|
|
5575
|
+
*/
|
|
5576
|
+
}, {
|
|
5577
|
+
key: "getDeclaredKeysValidation",
|
|
5578
|
+
value: function getDeclaredKeysValidation(path, src) {
|
|
5579
|
+
if (this.keySchema === null) {
|
|
5580
|
+
return false;
|
|
5581
|
+
}
|
|
5582
|
+
var declared = this.declaredKeySet();
|
|
5583
|
+
if (declared === null) {
|
|
5584
|
+
return false;
|
|
5585
|
+
}
|
|
5586
|
+
return _defineProperty({}, path, [{
|
|
5587
|
+
fixes: ["record:fill-keys"],
|
|
5588
|
+
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.",
|
|
5589
|
+
value: {
|
|
5590
|
+
present: Object.keys(src),
|
|
5591
|
+
declared: declared.kind === "literals" ? declared.keys : null
|
|
5592
|
+
}
|
|
5593
|
+
}]);
|
|
5594
|
+
}
|
|
5595
|
+
}, {
|
|
5596
|
+
key: "declaredKeySet",
|
|
5597
|
+
value: function declaredKeySet() {
|
|
5598
|
+
if (this.declaredKeys === undefined) {
|
|
5599
|
+
this.declaredKeys = this.keySchema === null ? null : declaredKeySetOf(this.keySchema["executeSerialize"]());
|
|
5600
|
+
}
|
|
5601
|
+
return this.declaredKeys;
|
|
5602
|
+
}
|
|
5603
|
+
}, {
|
|
5604
|
+
key: "opensLocaleScope",
|
|
5605
|
+
value: function opensLocaleScope() {
|
|
5606
|
+
return this.keySchema !== null && this.keySchema["isLocaleField"]() ? "key" : null;
|
|
5607
|
+
}
|
|
5608
|
+
}, {
|
|
5609
|
+
key: "localeScopeChildren",
|
|
5610
|
+
value: function localeScopeChildren() {
|
|
5611
|
+
// The KEY schema is not a child here. A locale key is what opens this
|
|
5612
|
+
// record's scope; it is not something inside the scope.
|
|
5613
|
+
return [{
|
|
5614
|
+
key: "*",
|
|
5615
|
+
schema: this.item
|
|
5616
|
+
}];
|
|
5617
|
+
}
|
|
5203
5618
|
}, {
|
|
5204
5619
|
key: "isRemoteUrl",
|
|
5205
5620
|
value: function isRemoteUrl(url) {
|
|
@@ -5894,6 +6309,23 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
|
|
|
5894
6309
|
}]);
|
|
5895
6310
|
}(Schema);
|
|
5896
6311
|
|
|
6312
|
+
/**
|
|
6313
|
+
* The source of a record, given what its key schema says about its keys.
|
|
6314
|
+
*
|
|
6315
|
+
* A key schema that ENUMERATES its keys (a union of literals, or `s.locale()`)
|
|
6316
|
+
* makes every one of them an entry of the record, and an entry nobody has
|
|
6317
|
+
* written yet is `null` rather than absent — so the value type widens by
|
|
6318
|
+
* `null`. That is the whole of option F at the type level: a half-translated
|
|
6319
|
+
* record is a record with nulls in it, which is data you can count, filter and
|
|
6320
|
+
* see in a diff, rather than keys that are simply not there.
|
|
6321
|
+
*
|
|
6322
|
+
* For a union of literals TypeScript already required every key, since
|
|
6323
|
+
* `SelectorOfSchema<K>` is the literal union itself. `s.locale()` is a flavoured
|
|
6324
|
+
* string, so it requires nothing here and the requirement is the validator's —
|
|
6325
|
+
* deliberately: which languages exist is in the settings module, where the
|
|
6326
|
+
* project can change it without a deploy.
|
|
6327
|
+
*/
|
|
6328
|
+
|
|
5897
6329
|
// Overload: with key schema
|
|
5898
6330
|
|
|
5899
6331
|
// Overload: without key schema
|
|
@@ -5932,6 +6364,31 @@ function record(keyOrSchema, schema) {
|
|
|
5932
6364
|
* written without removing the key.
|
|
5933
6365
|
*/
|
|
5934
6366
|
|
|
6367
|
+
/**
|
|
6368
|
+
* The languages this project publishes.
|
|
6369
|
+
*
|
|
6370
|
+
* Content rather than configuration, and deliberately: which languages a site
|
|
6371
|
+
* has is a decision the people who write it make, and under a build-time
|
|
6372
|
+
* constant it took a developer and a deploy. It is the same move `assistant`
|
|
6373
|
+
* makes with `enabled`.
|
|
6374
|
+
*
|
|
6375
|
+
* Val ships no list of its own. A project with no `locales` section has not
|
|
6376
|
+
* said it is translated, and nothing about locales appears anywhere — no picker
|
|
6377
|
+
* in the Studio, no checks, nothing.
|
|
6378
|
+
*
|
|
6379
|
+
* **This list is a decision with a blast radius.** Every locale in content is
|
|
6380
|
+
* checked against it, so removing one invalidates the content that uses it, and
|
|
6381
|
+
* adding one leaves every locale-keyed record short of a language until it is
|
|
6382
|
+
* filled in. That is the intended behaviour — a language that is declared and
|
|
6383
|
+
* missing everywhere is worth being told about — but it is why the Studio warns
|
|
6384
|
+
* before saving a removal rather than treating this as an ordinary field.
|
|
6385
|
+
*
|
|
6386
|
+
* There is no default language, deliberately. Every locale-specific field asks
|
|
6387
|
+
* which language it is in, and a default is exactly the answer that lets that
|
|
6388
|
+
* question go unanswered — content ends up filed under a language nobody chose,
|
|
6389
|
+
* which is the state translation is meant to make visible.
|
|
6390
|
+
*/
|
|
6391
|
+
|
|
5935
6392
|
/**
|
|
5936
6393
|
* The assistant: whether editors have one, and what it is told about the
|
|
5937
6394
|
* project on every message.
|
|
@@ -5992,6 +6449,263 @@ settings) {
|
|
|
5992
6449
|
return "unconfigured";
|
|
5993
6450
|
}
|
|
5994
6451
|
|
|
6452
|
+
/**
|
|
6453
|
+
* One of the languages the project publishes.
|
|
6454
|
+
*
|
|
6455
|
+
* The set is NOT here. It is declared in the settings module — `locales.available`
|
|
6456
|
+
* — so that adding a language is something the people who write the content can
|
|
6457
|
+
* do, and so that one list drives validation, the Studio's picker and the
|
|
6458
|
+
* translation notes. This schema knows only that the value is one of them, which
|
|
6459
|
+
* is checked cross-module through the `locale:check-locale` fix, exactly as
|
|
6460
|
+
* `keyOf` and `route` check theirs.
|
|
6461
|
+
*
|
|
6462
|
+
* Never stega encoded (see `stegaEncode.ts`): a locale goes into `<html lang>`,
|
|
6463
|
+
* into `hreflang` and into `Intl` constructors, none of which survive invisible
|
|
6464
|
+
* characters.
|
|
6465
|
+
*/
|
|
6466
|
+
var LocaleSchema = /*#__PURE__*/function (_Schema) {
|
|
6467
|
+
/**
|
|
6468
|
+
* Type-only marker: as a record key, this schema DECLARES the key set.
|
|
6469
|
+
*
|
|
6470
|
+
* `declare` so it exists in the type and nowhere at runtime — reading it off
|
|
6471
|
+
* an instance gives `undefined`, and nothing should. It is how `record()`
|
|
6472
|
+
* knows to type entries as `Item | null`: a language nobody has translated
|
|
6473
|
+
* into is a null entry, not an absent key. See `DeclaredKeySet` and
|
|
6474
|
+
* `RecordSrcOf`.
|
|
6475
|
+
*/
|
|
6476
|
+
|
|
6477
|
+
function LocaleSchema() {
|
|
6478
|
+
var _this;
|
|
6479
|
+
var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
6480
|
+
var customValidateFunctions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
6481
|
+
var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6482
|
+
var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
6483
|
+
var description = arguments.length > 4 ? arguments[4] : undefined;
|
|
6484
|
+
var renderInput = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
|
|
6485
|
+
var previewInput = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
|
|
6486
|
+
_classCallCheck(this, LocaleSchema);
|
|
6487
|
+
_this = _callSuper(this, LocaleSchema);
|
|
6488
|
+
_this.opt = opt;
|
|
6489
|
+
_this.customValidateFunctions = customValidateFunctions;
|
|
6490
|
+
_this.isReadonly = isReadonly;
|
|
6491
|
+
_this.isHidden = isHidden;
|
|
6492
|
+
_this.description = description;
|
|
6493
|
+
_this.renderInput = renderInput;
|
|
6494
|
+
_this.previewInput = previewInput;
|
|
6495
|
+
return _this;
|
|
6496
|
+
}
|
|
6497
|
+
|
|
6498
|
+
/**
|
|
6499
|
+
* A note to whoever edits this field, shown under it in the Studio.
|
|
6500
|
+
*
|
|
6501
|
+
* Pass `null` to clear a description set earlier.
|
|
6502
|
+
*
|
|
6503
|
+
* @example
|
|
6504
|
+
* const schema = s.object({
|
|
6505
|
+
* locale: s.locale().describe("The language everything below is written in"),
|
|
6506
|
+
* title: s.string(),
|
|
6507
|
+
* });
|
|
6508
|
+
* export default c.define("/example.val.ts", schema, {
|
|
6509
|
+
* locale: "nb-NO",
|
|
6510
|
+
* title: "Vinterjakke",
|
|
6511
|
+
* });
|
|
6512
|
+
*/
|
|
6513
|
+
_inherits(LocaleSchema, _Schema);
|
|
6514
|
+
return _createClass(LocaleSchema, [{
|
|
6515
|
+
key: "describe",
|
|
6516
|
+
value: function describe(description) {
|
|
6517
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined, this.renderInput, this.previewInput);
|
|
6518
|
+
}
|
|
6519
|
+
|
|
6520
|
+
/**
|
|
6521
|
+
* A check of your own, on top of "is this one of the project's languages".
|
|
6522
|
+
*
|
|
6523
|
+
* Return a message when the value is WRONG and `false` when it is fine — the
|
|
6524
|
+
* two answers are a complaint and no complaint, so write the check as a
|
|
6525
|
+
* ternary rather than as `ok || "message"`, which returns `true` and `true`
|
|
6526
|
+
* is neither.
|
|
6527
|
+
*
|
|
6528
|
+
* @example
|
|
6529
|
+
* const schema = s.object({
|
|
6530
|
+
* locale: s.locale().validate((val) =>
|
|
6531
|
+
* val === "en-US" ? "This section is not translated into English yet" : false,
|
|
6532
|
+
* ),
|
|
6533
|
+
* title: s.string(),
|
|
6534
|
+
* });
|
|
6535
|
+
* export default c.define("/example.val.ts", schema, {
|
|
6536
|
+
* locale: "nb-NO",
|
|
6537
|
+
* title: "Vinterjakke",
|
|
6538
|
+
* });
|
|
6539
|
+
*/
|
|
6540
|
+
}, {
|
|
6541
|
+
key: "validate",
|
|
6542
|
+
value: function validate(validationFunction) {
|
|
6543
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions.concat(validationFunction), this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6544
|
+
}
|
|
6545
|
+
}, {
|
|
6546
|
+
key: "executeValidate",
|
|
6547
|
+
value: function executeValidate(path, src) {
|
|
6548
|
+
var customValidationErrors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
|
|
6549
|
+
path: path
|
|
6550
|
+
});
|
|
6551
|
+
if (this.opt && (src === null || src === undefined)) {
|
|
6552
|
+
return customValidationErrors.length > 0 ? _defineProperty({}, path, customValidationErrors) : false;
|
|
6553
|
+
}
|
|
6554
|
+
if (typeof src !== "string") {
|
|
6555
|
+
return _defineProperty({}, path, [{
|
|
6556
|
+
message: "Expected 'string', got '".concat(_typeof(src), "'"),
|
|
6557
|
+
value: src
|
|
6558
|
+
}]);
|
|
6559
|
+
}
|
|
6560
|
+
return _defineProperty({}, path, [].concat(_toConsumableArray(customValidationErrors), [{
|
|
6561
|
+
// Which languages exist is in another module, so this cannot be
|
|
6562
|
+
// answered here — the same shape `keyOf` and `route` use, resolved by
|
|
6563
|
+
// `resolveSchemaSourceFixes` against the settings module.
|
|
6564
|
+
fixes: ["locale:check-locale"],
|
|
6565
|
+
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.",
|
|
6566
|
+
value: {
|
|
6567
|
+
locale: src,
|
|
6568
|
+
sourcePath: path
|
|
6569
|
+
}
|
|
6570
|
+
}]));
|
|
6571
|
+
}
|
|
6572
|
+
}, {
|
|
6573
|
+
key: "executeAssert",
|
|
6574
|
+
value: function executeAssert(path, src) {
|
|
6575
|
+
if (this.opt && src === null) {
|
|
6576
|
+
return {
|
|
6577
|
+
success: true,
|
|
6578
|
+
data: src
|
|
6579
|
+
};
|
|
6580
|
+
}
|
|
6581
|
+
if (typeof src === "string") {
|
|
6582
|
+
return {
|
|
6583
|
+
success: true,
|
|
6584
|
+
data: src
|
|
6585
|
+
};
|
|
6586
|
+
}
|
|
6587
|
+
return {
|
|
6588
|
+
success: false,
|
|
6589
|
+
errors: _defineProperty({}, path, [{
|
|
6590
|
+
message: "Expected 'string', got '".concat(_typeof(src), "'"),
|
|
6591
|
+
typeError: true
|
|
6592
|
+
}])
|
|
6593
|
+
};
|
|
6594
|
+
}
|
|
6595
|
+
}, {
|
|
6596
|
+
key: "nullable",
|
|
6597
|
+
value: function nullable() {
|
|
6598
|
+
// Asserted whole, exactly as `RouteSchema.nullable` does: the source type
|
|
6599
|
+
// widens by `null` while the caller's validators and preview stay typed
|
|
6600
|
+
// against the value, and `executeValidate` returns before either sees one.
|
|
6601
|
+
return new LocaleSchema(true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6602
|
+
}
|
|
6603
|
+
}, {
|
|
6604
|
+
key: "readonly",
|
|
6605
|
+
value: function readonly() {
|
|
6606
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6607
|
+
}
|
|
6608
|
+
}, {
|
|
6609
|
+
key: "hidden",
|
|
6610
|
+
value: function hidden() {
|
|
6611
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
|
|
6612
|
+
}
|
|
6613
|
+
}, {
|
|
6614
|
+
key: "isLocaleField",
|
|
6615
|
+
value: function isLocaleField() {
|
|
6616
|
+
return true;
|
|
6617
|
+
}
|
|
6618
|
+
}, {
|
|
6619
|
+
key: "executeCustomValidateAt",
|
|
6620
|
+
value: function executeCustomValidateAt(path, src) {
|
|
6621
|
+
return this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
|
|
6622
|
+
path: path
|
|
6623
|
+
});
|
|
6624
|
+
}
|
|
6625
|
+
|
|
6626
|
+
/**
|
|
6627
|
+
* How this field is laid out where it is the item of an array or a record.
|
|
6628
|
+
* Static configuration, not a callback — see `render.ts`.
|
|
6629
|
+
*
|
|
6630
|
+
* @example
|
|
6631
|
+
* const schema = s.array(s.locale().render({ as: "inline" }));
|
|
6632
|
+
* export default c.define("/example.val.ts", schema, ["nb-NO", "en-US"]);
|
|
6633
|
+
*/
|
|
6634
|
+
}, {
|
|
6635
|
+
key: "render",
|
|
6636
|
+
value: function render(input) {
|
|
6637
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, input, this.previewInput);
|
|
6638
|
+
}
|
|
6639
|
+
|
|
6640
|
+
/**
|
|
6641
|
+
* How this VALUE is shown where a preview of it is needed. Never how the field
|
|
6642
|
+
* itself is edited (that is `render`). See `preview.ts`.
|
|
6643
|
+
*
|
|
6644
|
+
* @example
|
|
6645
|
+
* const schema = s.array(
|
|
6646
|
+
* s.locale().preview(({ val }) => ({ title: val })),
|
|
6647
|
+
* );
|
|
6648
|
+
* export default c.define("/example.val.ts", schema, ["nb-NO", "en-US"]);
|
|
6649
|
+
*/
|
|
6650
|
+
}, {
|
|
6651
|
+
key: "preview",
|
|
6652
|
+
value: function preview(select) {
|
|
6653
|
+
return new LocaleSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, select);
|
|
6654
|
+
}
|
|
6655
|
+
}, {
|
|
6656
|
+
key: "executePreviewItem",
|
|
6657
|
+
value: function executePreviewItem(src) {
|
|
6658
|
+
if (this.previewInput === null) {
|
|
6659
|
+
return null;
|
|
6660
|
+
}
|
|
6661
|
+
return this.previewInput({
|
|
6662
|
+
val: src
|
|
6663
|
+
});
|
|
6664
|
+
}
|
|
6665
|
+
}, {
|
|
6666
|
+
key: "declaresItemPreview",
|
|
6667
|
+
value: function declaresItemPreview() {
|
|
6668
|
+
return this.previewInput !== null;
|
|
6669
|
+
}
|
|
6670
|
+
}, {
|
|
6671
|
+
key: "executeSerialize",
|
|
6672
|
+
value: function executeSerialize() {
|
|
6673
|
+
var _this$renderInput, _this$customValidateF;
|
|
6674
|
+
return {
|
|
6675
|
+
type: "locale",
|
|
6676
|
+
render: (_this$renderInput = this.renderInput) !== null && _this$renderInput !== void 0 ? _this$renderInput : undefined,
|
|
6677
|
+
preview: this.previewInput ? true : undefined,
|
|
6678
|
+
opt: this.opt,
|
|
6679
|
+
customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0,
|
|
6680
|
+
readonly: this.isReadonly,
|
|
6681
|
+
hidden: this.isHidden,
|
|
6682
|
+
description: this.description
|
|
6683
|
+
};
|
|
6684
|
+
}
|
|
6685
|
+
}, {
|
|
6686
|
+
key: "executePreview",
|
|
6687
|
+
value: function executePreview() {
|
|
6688
|
+
return {};
|
|
6689
|
+
}
|
|
6690
|
+
}]);
|
|
6691
|
+
}(Schema);
|
|
6692
|
+
|
|
6693
|
+
/**
|
|
6694
|
+
* Define one of the project's languages.
|
|
6695
|
+
*
|
|
6696
|
+
* The languages themselves are declared in the settings module, under
|
|
6697
|
+
* `locales.available` — this says only that a value is one of them.
|
|
6698
|
+
*
|
|
6699
|
+
* @example // a field: everything under this object is in this language
|
|
6700
|
+
* const schema = s.object({ locale: s.locale(), title: s.string() });
|
|
6701
|
+
*
|
|
6702
|
+
* @example // a key: one entry per language
|
|
6703
|
+
* const schema = s.record(s.locale(), s.object({ title: s.string() }));
|
|
6704
|
+
*/
|
|
6705
|
+
var locale = function locale() {
|
|
6706
|
+
return new LocaleSchema();
|
|
6707
|
+
};
|
|
6708
|
+
|
|
5995
6709
|
var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
5996
6710
|
function BooleanSchema() {
|
|
5997
6711
|
var _this;
|
|
@@ -6109,7 +6823,7 @@ var BooleanSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6109
6823
|
}, {
|
|
6110
6824
|
key: "nullable",
|
|
6111
6825
|
value: function nullable() {
|
|
6112
|
-
return new BooleanSchema(true,
|
|
6826
|
+
return new BooleanSchema(true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
6113
6827
|
}
|
|
6114
6828
|
}, {
|
|
6115
6829
|
key: "readonly",
|
|
@@ -6205,6 +6919,99 @@ var _boolean = function _boolean() {
|
|
|
6205
6919
|
return new BooleanSchema();
|
|
6206
6920
|
};
|
|
6207
6921
|
|
|
6922
|
+
/**
|
|
6923
|
+
* Language tags, and what makes one wrong.
|
|
6924
|
+
*
|
|
6925
|
+
* Val does not ship a list of locales. Which languages a project publishes is a
|
|
6926
|
+
* property of that project, so it is declared in the settings module — see
|
|
6927
|
+
* `LocalesSettingsSource` — and everything downstream reads it from there.
|
|
6928
|
+
*
|
|
6929
|
+
* What Val does own is the SPELLING. A tag is checked against BCP 47
|
|
6930
|
+
* (RFC 5646) through `Intl.getCanonicalLocales`, which is the same
|
|
6931
|
+
* implementation the browser, `<html lang>` and every `Intl` constructor use.
|
|
6932
|
+
* Delegating rather than writing a matcher is the point: a tag this accepts is
|
|
6933
|
+
* a tag those accept.
|
|
6934
|
+
*/
|
|
6935
|
+
|
|
6936
|
+
/**
|
|
6937
|
+
* What is wrong with `tag` as a language tag, or `false` if nothing is.
|
|
6938
|
+
*
|
|
6939
|
+
* Canonical form, not merely parseable, and the difference is what makes this
|
|
6940
|
+
* worth checking at all. `nb-no` parses; `Intl.DisplayNames` and a
|
|
6941
|
+
* case-sensitive comparison against a stored key do not agree about it. Since a
|
|
6942
|
+
* locale is compared as a string everywhere — a record key, a URL segment, a
|
|
6943
|
+
* value in content — one spelling has to win, and the canonical one is the
|
|
6944
|
+
* spelling every other tool already produces.
|
|
6945
|
+
*
|
|
6946
|
+
* The message names the canonical form where there is one, because "not
|
|
6947
|
+
* canonical" is not an instruction and `nb-NO` is.
|
|
6948
|
+
*/
|
|
6949
|
+
function localeTagError(tag) {
|
|
6950
|
+
var canonical;
|
|
6951
|
+
try {
|
|
6952
|
+
canonical = Intl.getCanonicalLocales(tag);
|
|
6953
|
+
} catch (_unused) {
|
|
6954
|
+
// RangeError, for anything the grammar rejects: an underscore instead of a
|
|
6955
|
+
// hyphen (`nb_NO`, which is POSIX rather than BCP 47), an empty subtag, a
|
|
6956
|
+
// subtag of the wrong length.
|
|
6957
|
+
return "'".concat(tag, "' is not a language tag. Language then region, separated by a hyphen \u2014 'nb-NO', not 'nb_NO'");
|
|
6958
|
+
}
|
|
6959
|
+
if (canonical.length !== 1) {
|
|
6960
|
+
// A comma-separated list, or something that canonicalised to nothing.
|
|
6961
|
+
return "'".concat(tag, "' is not a single language tag");
|
|
6962
|
+
}
|
|
6963
|
+
if (canonical[0] !== tag) {
|
|
6964
|
+
return "'".concat(tag, "' is not canonical. Write it as '").concat(canonical[0], "'");
|
|
6965
|
+
}
|
|
6966
|
+
return false;
|
|
6967
|
+
}
|
|
6968
|
+
|
|
6969
|
+
/**
|
|
6970
|
+
* A language tag, as content holds it.
|
|
6971
|
+
*
|
|
6972
|
+
* A *flavoured* string rather than a union or a strict brand. Which languages a
|
|
6973
|
+
* project has is declared in its settings module, where the project can change
|
|
6974
|
+
* it, so there is no set for a type to enumerate — and a strict brand would make
|
|
6975
|
+
* `"nb-NO"` unassignable, which would mean writing every locale in a `.val.ts`
|
|
6976
|
+
* through a constructor. Content stays plain data.
|
|
6977
|
+
*
|
|
6978
|
+
* So this carries no compile-time guarantee, and is not meant to. It names the
|
|
6979
|
+
* concept where a bare `string` would say nothing, and the guarantee is the
|
|
6980
|
+
* `locale:check-locale` validation against `locales.available`.
|
|
6981
|
+
*/
|
|
6982
|
+
|
|
6983
|
+
/**
|
|
6984
|
+
* The locale a stored value means, or `null` if it means none of them.
|
|
6985
|
+
*
|
|
6986
|
+
* A lookup against the project's languages, and today that is all it is. It
|
|
6987
|
+
* stays a named function because it is the one place the question is asked —
|
|
6988
|
+
* the Studio, the validation worker and the server all come here rather than
|
|
6989
|
+
* comparing strings themselves, so they cannot disagree about what a stored
|
|
6990
|
+
* value is.
|
|
6991
|
+
*/
|
|
6992
|
+
function localeOfValue(value, available) {
|
|
6993
|
+
return available.includes(value) ? value : null;
|
|
6994
|
+
}
|
|
6995
|
+
|
|
6996
|
+
/**
|
|
6997
|
+
* A rule about a section that its individual fields cannot state.
|
|
6998
|
+
*
|
|
6999
|
+
* Paths are WITHIN the section, so an error lands on the value it is about —
|
|
7000
|
+
* including a row of a list, which is what makes this different from a
|
|
7001
|
+
* `.validate()` on the field.
|
|
7002
|
+
*/
|
|
7003
|
+
|
|
7004
|
+
/**
|
|
7005
|
+
* Every section's rules, by the name that travels in the serialized schema.
|
|
7006
|
+
*
|
|
7007
|
+
* Typed with `| undefined` on the value rather than as a `Partial`: the whole
|
|
7008
|
+
* point is that a lookup can miss, because the name comes off a serialized
|
|
7009
|
+
* schema that may have been written by a newer Val than the one reading it.
|
|
7010
|
+
*/
|
|
7011
|
+
var sectionValidators = {
|
|
7012
|
+
locales: localesSectionErrors
|
|
7013
|
+
};
|
|
7014
|
+
|
|
6208
7015
|
/**
|
|
6209
7016
|
* An object whose keys are all optional: absent means unset.
|
|
6210
7017
|
*
|
|
@@ -6223,6 +7030,23 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6223
7030
|
var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6224
7031
|
var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
6225
7032
|
var description = arguments.length > 4 ? arguments[4] : undefined;
|
|
7033
|
+
var
|
|
7034
|
+
/**
|
|
7035
|
+
* Which section this is, where Val has rules about it beyond its keys.
|
|
7036
|
+
*
|
|
7037
|
+
* Not the `validate` the class deliberately does not offer: that one is the
|
|
7038
|
+
* schema author's, and `s.settings()` takes no arguments to declare it
|
|
7039
|
+
* with. This names a rule Val states about a shape Val owns — no language
|
|
7040
|
+
* declared twice in `locales.available` is true of every project, and
|
|
7041
|
+
* there is nowhere else it can be said. A single value's rules stay on its
|
|
7042
|
+
* own schema; this is for the ones that need to see more than one value,
|
|
7043
|
+
* or to report on a row of a list.
|
|
7044
|
+
*
|
|
7045
|
+
* A NAME rather than the function, so it survives serialization: the schema
|
|
7046
|
+
* reaches the Studio's validation worker as JSON, and a closure would be
|
|
7047
|
+
* dropped on the way — which is how these rules once went missing there.
|
|
7048
|
+
*/
|
|
7049
|
+
section = arguments.length > 5 ? arguments[5] : undefined;
|
|
6226
7050
|
_classCallCheck(this, SettingsSchema);
|
|
6227
7051
|
_this = _callSuper(this, SettingsSchema);
|
|
6228
7052
|
_this.items = items;
|
|
@@ -6230,10 +7054,24 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6230
7054
|
_this.isReadonly = isReadonly;
|
|
6231
7055
|
_this.isHidden = isHidden;
|
|
6232
7056
|
_this.description = description;
|
|
7057
|
+
_this.section = section;
|
|
6233
7058
|
return _this;
|
|
6234
7059
|
}
|
|
7060
|
+
|
|
7061
|
+
/**
|
|
7062
|
+
* This section's rules, or `undefined` where there are none to run.
|
|
7063
|
+
*
|
|
7064
|
+
* A name this Val does not know means a schema written by a newer one. Its
|
|
7065
|
+
* per-field validation still runs; only the section's own rule is missed,
|
|
7066
|
+
* which is the mild half of the failure and better than refusing the schema.
|
|
7067
|
+
*/
|
|
6235
7068
|
_inherits(SettingsSchema, _Schema);
|
|
6236
7069
|
return _createClass(SettingsSchema, [{
|
|
7070
|
+
key: "sectionValidate",
|
|
7071
|
+
value: function sectionValidate() {
|
|
7072
|
+
return this.section === undefined ? undefined : sectionValidators[this.section];
|
|
7073
|
+
}
|
|
7074
|
+
}, {
|
|
6237
7075
|
key: "executeValidate",
|
|
6238
7076
|
value: function executeValidate(path, src) {
|
|
6239
7077
|
var error = false;
|
|
@@ -6286,6 +7124,39 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6286
7124
|
}).join(", ")), src, true);
|
|
6287
7125
|
}
|
|
6288
7126
|
}
|
|
7127
|
+
var sectionValidate = this.sectionValidate();
|
|
7128
|
+
if (sectionValidate) {
|
|
7129
|
+
var _iterator = _createForOfIteratorHelper(sectionValidate(src)),
|
|
7130
|
+
_step;
|
|
7131
|
+
try {
|
|
7132
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
7133
|
+
var _ref4;
|
|
7134
|
+
var _step$value = _step.value,
|
|
7135
|
+
keys = _step$value.path,
|
|
7136
|
+
message = _step$value.message;
|
|
7137
|
+
var _subPath = path;
|
|
7138
|
+
var _iterator2 = _createForOfIteratorHelper(keys),
|
|
7139
|
+
_step2;
|
|
7140
|
+
try {
|
|
7141
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
7142
|
+
var _key3 = _step2.value;
|
|
7143
|
+
_subPath = _subPath && createValPathOfItem(_subPath, _key3);
|
|
7144
|
+
}
|
|
7145
|
+
} catch (err) {
|
|
7146
|
+
_iterator2.e(err);
|
|
7147
|
+
} finally {
|
|
7148
|
+
_iterator2.f();
|
|
7149
|
+
}
|
|
7150
|
+
error = this.appendValidationError(error, // Falls back to the section itself, which is where an error belongs
|
|
7151
|
+
// when the value it is about is not addressable.
|
|
7152
|
+
(_ref4 = _subPath) !== null && _ref4 !== void 0 ? _ref4 : path, message, src);
|
|
7153
|
+
}
|
|
7154
|
+
} catch (err) {
|
|
7155
|
+
_iterator.e(err);
|
|
7156
|
+
} finally {
|
|
7157
|
+
_iterator.f();
|
|
7158
|
+
}
|
|
7159
|
+
}
|
|
6289
7160
|
return error;
|
|
6290
7161
|
}
|
|
6291
7162
|
}, {
|
|
@@ -6331,17 +7202,17 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6331
7202
|
}, {
|
|
6332
7203
|
key: "nullable",
|
|
6333
7204
|
value: function nullable() {
|
|
6334
|
-
return new SettingsSchema(this.items, true, this.isReadonly, this.isHidden, this.description);
|
|
7205
|
+
return new SettingsSchema(this.items, true, this.isReadonly, this.isHidden, this.description, this.section);
|
|
6335
7206
|
}
|
|
6336
7207
|
}, {
|
|
6337
7208
|
key: "readonly",
|
|
6338
7209
|
value: function readonly() {
|
|
6339
|
-
return new SettingsSchema(this.items, this.opt, true, this.isHidden, this.description);
|
|
7210
|
+
return new SettingsSchema(this.items, this.opt, true, this.isHidden, this.description, this.section);
|
|
6340
7211
|
}
|
|
6341
7212
|
}, {
|
|
6342
7213
|
key: "hidden",
|
|
6343
7214
|
value: function hidden() {
|
|
6344
|
-
return new SettingsSchema(this.items, this.opt, this.isReadonly, true, this.description);
|
|
7215
|
+
return new SettingsSchema(this.items, this.opt, this.isReadonly, true, this.description, this.section);
|
|
6345
7216
|
}
|
|
6346
7217
|
}, {
|
|
6347
7218
|
key: "executeCustomValidateAt",
|
|
@@ -6356,16 +7227,17 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6356
7227
|
value: function executeSerialize() {
|
|
6357
7228
|
return {
|
|
6358
7229
|
type: "settings",
|
|
6359
|
-
items: Object.fromEntries(Object.entries(this.items).map(function (
|
|
6360
|
-
var
|
|
6361
|
-
key =
|
|
6362
|
-
schema =
|
|
7230
|
+
items: Object.fromEntries(Object.entries(this.items).map(function (_ref5) {
|
|
7231
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
7232
|
+
key = _ref6[0],
|
|
7233
|
+
schema = _ref6[1];
|
|
6363
7234
|
return [key, schema["executeSerialize"]()];
|
|
6364
7235
|
})),
|
|
6365
7236
|
opt: this.opt,
|
|
6366
7237
|
readonly: this.isReadonly,
|
|
6367
7238
|
hidden: this.isHidden,
|
|
6368
|
-
description: this.description
|
|
7239
|
+
description: this.description,
|
|
7240
|
+
section: this.section
|
|
6369
7241
|
};
|
|
6370
7242
|
}
|
|
6371
7243
|
}, {
|
|
@@ -6375,19 +7247,19 @@ var SettingsSchema = /*#__PURE__*/function (_Schema) {
|
|
|
6375
7247
|
if (src === null) {
|
|
6376
7248
|
return res;
|
|
6377
7249
|
}
|
|
6378
|
-
for (var
|
|
6379
|
-
var itemSrc = src[
|
|
7250
|
+
for (var _key4 in this.items) {
|
|
7251
|
+
var itemSrc = src[_key4];
|
|
6380
7252
|
if (itemSrc === null || itemSrc === undefined) {
|
|
6381
7253
|
continue;
|
|
6382
7254
|
}
|
|
6383
|
-
var subPath = unsafeCreateSourcePath(sourcePath,
|
|
7255
|
+
var subPath = unsafeCreateSourcePath(sourcePath, _key4);
|
|
6384
7256
|
if (scope !== undefined && !scope.wantsUnder(subPath)) {
|
|
6385
7257
|
continue;
|
|
6386
7258
|
}
|
|
6387
|
-
var itemResult = this.items[
|
|
7259
|
+
var itemResult = this.items[_key4]["executePreview"](subPath, itemSrc, scope);
|
|
6388
7260
|
for (var keyS in itemResult) {
|
|
6389
|
-
var
|
|
6390
|
-
res[
|
|
7261
|
+
var _key5 = keyS;
|
|
7262
|
+
res[_key5] = itemResult[_key5];
|
|
6391
7263
|
}
|
|
6392
7264
|
}
|
|
6393
7265
|
return res;
|
|
@@ -6431,11 +7303,58 @@ function settings() {
|
|
|
6431
7303
|
assistant: new SettingsSchema({
|
|
6432
7304
|
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."),
|
|
6433
7305
|
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."),
|
|
6434
|
-
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.")
|
|
6435
|
-
|
|
7306
|
+
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."),
|
|
7307
|
+
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.")
|
|
7308
|
+
}),
|
|
7309
|
+
locales: new SettingsSchema({
|
|
7310
|
+
// Nullable because the source type is, and because the Studio writes
|
|
7311
|
+
// `null` for every sibling the first time a section is created.
|
|
7312
|
+
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.")
|
|
7313
|
+
}, false, false, false, undefined, "locales")
|
|
6436
7314
|
});
|
|
6437
7315
|
}
|
|
6438
7316
|
|
|
7317
|
+
/**
|
|
7318
|
+
* The rules about `locales` that need to see the whole list.
|
|
7319
|
+
*
|
|
7320
|
+
* Two of them, and both report on the ENTRY rather than the list: a tag has to
|
|
7321
|
+
* be spelled canonically, and a language cannot be declared twice. Neither can
|
|
7322
|
+
* live on the item schema — the item sees one string, and "twice" is a fact
|
|
7323
|
+
* about its siblings — and neither can be a `.validate()` on the array either,
|
|
7324
|
+
* since that reports one message on the array itself rather than on the row to
|
|
7325
|
+
* delete.
|
|
7326
|
+
*
|
|
7327
|
+
* Reads defensively rather than asserting the source's type. A settings module
|
|
7328
|
+
* is a file someone edits by hand, and validation runs against whatever is in
|
|
7329
|
+
* it — including the shapes the per-key pass is, in the same breath, reporting.
|
|
7330
|
+
*/
|
|
7331
|
+
function localesSectionErrors(src) {
|
|
7332
|
+
var errors = [];
|
|
7333
|
+
var raw = Array.isArray(src["available"]) ? src["available"] : [];
|
|
7334
|
+
var seen = new Set();
|
|
7335
|
+
for (var i = 0; i < raw.length; i++) {
|
|
7336
|
+
var tag = raw[i];
|
|
7337
|
+
if (typeof tag !== "string") {
|
|
7338
|
+
// The item's own schema has already said what is wrong with it.
|
|
7339
|
+
continue;
|
|
7340
|
+
}
|
|
7341
|
+
var spelling = localeTagError(tag);
|
|
7342
|
+
if (spelling !== false) {
|
|
7343
|
+
errors.push({
|
|
7344
|
+
path: ["available", i],
|
|
7345
|
+
message: spelling
|
|
7346
|
+
});
|
|
7347
|
+
} else if (seen.has(tag)) {
|
|
7348
|
+
errors.push({
|
|
7349
|
+
path: ["available", i],
|
|
7350
|
+
message: "'".concat(tag, "' is declared twice")
|
|
7351
|
+
});
|
|
7352
|
+
}
|
|
7353
|
+
seen.add(tag);
|
|
7354
|
+
}
|
|
7355
|
+
return errors;
|
|
7356
|
+
}
|
|
7357
|
+
|
|
6439
7358
|
/**
|
|
6440
7359
|
* What may be WRITTEN as an external record's source, on top of the marker.
|
|
6441
7360
|
*
|
|
@@ -7149,7 +8068,7 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7149
8068
|
}, {
|
|
7150
8069
|
key: "nullable",
|
|
7151
8070
|
value: function nullable() {
|
|
7152
|
-
return new NumberSchema(this.options, true,
|
|
8071
|
+
return new NumberSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7153
8072
|
}
|
|
7154
8073
|
}, {
|
|
7155
8074
|
key: "readonly",
|
|
@@ -7286,6 +8205,15 @@ var number = function number(options) {
|
|
|
7286
8205
|
* discriminated union's variants and must not try to recurse into these.
|
|
7287
8206
|
*/
|
|
7288
8207
|
var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
8208
|
+
/**
|
|
8209
|
+
* Type-only marker: as a record key, this declares the key set.
|
|
8210
|
+
*
|
|
8211
|
+
* An enum names every value it may take, so a record keyed by one holds
|
|
8212
|
+
* exactly those keys — the same claim `s.literal()` and `s.locale()` make.
|
|
8213
|
+
* `DiscriminatedUnionSchema` carries no marker: it discriminates objects and
|
|
8214
|
+
* cannot be a record key at all. See `LocaleSchema`.
|
|
8215
|
+
*/
|
|
8216
|
+
|
|
7289
8217
|
function EnumSchema(values) {
|
|
7290
8218
|
var _this;
|
|
7291
8219
|
var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -7439,7 +8367,7 @@ var EnumSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7439
8367
|
key: "nullable",
|
|
7440
8368
|
value: function nullable() {
|
|
7441
8369
|
// Explicit type args: `previewInput` would otherwise pin inference to `Src`.
|
|
7442
|
-
return new EnumSchema(this.values, true,
|
|
8370
|
+
return new EnumSchema(this.values, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7443
8371
|
}
|
|
7444
8372
|
}, {
|
|
7445
8373
|
key: "readonly",
|
|
@@ -7830,7 +8758,7 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
|
|
|
7830
8758
|
}, {
|
|
7831
8759
|
key: "nullable",
|
|
7832
8760
|
value: function nullable() {
|
|
7833
|
-
return new KeyOfSchema(this.schema, this.sourcePath, true,
|
|
8761
|
+
return new KeyOfSchema(this.schema, this.sourcePath, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
7834
8762
|
}
|
|
7835
8763
|
}, {
|
|
7836
8764
|
key: "readonly",
|
|
@@ -8604,7 +9532,7 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8604
9532
|
}, {
|
|
8605
9533
|
key: "nullable",
|
|
8606
9534
|
value: function nullable() {
|
|
8607
|
-
return new DateSchema(this.options, true,
|
|
9535
|
+
return new DateSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
8608
9536
|
}
|
|
8609
9537
|
}, {
|
|
8610
9538
|
key: "readonly",
|
|
@@ -8940,7 +9868,7 @@ var DateTimeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
8940
9868
|
}, {
|
|
8941
9869
|
key: "nullable",
|
|
8942
9870
|
value: function nullable() {
|
|
8943
|
-
return new DateTimeSchema(this.options, true,
|
|
9871
|
+
return new DateTimeSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
8944
9872
|
}
|
|
8945
9873
|
}, {
|
|
8946
9874
|
key: "readonly",
|
|
@@ -9188,7 +10116,7 @@ var CodeSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9188
10116
|
}, {
|
|
9189
10117
|
key: "nullable",
|
|
9190
10118
|
value: function nullable() {
|
|
9191
|
-
return new CodeSchema(this.options, true,
|
|
10119
|
+
return new CodeSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
9192
10120
|
}
|
|
9193
10121
|
}, {
|
|
9194
10122
|
key: "readonly",
|
|
@@ -9936,7 +10864,7 @@ var ColorSchema = /*#__PURE__*/function (_Schema) {
|
|
|
9936
10864
|
}, {
|
|
9937
10865
|
key: "nullable",
|
|
9938
10866
|
value: function nullable() {
|
|
9939
|
-
return new ColorSchema(this.options, true,
|
|
10867
|
+
return new ColorSchema(this.options, true, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
|
|
9940
10868
|
}
|
|
9941
10869
|
}, {
|
|
9942
10870
|
key: "readonly",
|
|
@@ -10125,6 +11053,7 @@ function initSchema() {
|
|
|
10125
11053
|
datetime: datetime,
|
|
10126
11054
|
color: color,
|
|
10127
11055
|
code: code,
|
|
11056
|
+
locale: locale,
|
|
10128
11057
|
route: route,
|
|
10129
11058
|
router: router,
|
|
10130
11059
|
images: images,
|
|
@@ -10263,6 +11192,8 @@ var Hash = /*#__PURE__*/function () {
|
|
|
10263
11192
|
_defineProperty(this, "F", 0x9b05688c | 0);
|
|
10264
11193
|
_defineProperty(this, "G", 0x1f83d9ab | 0);
|
|
10265
11194
|
_defineProperty(this, "H", 0x5be0cd19 | 0);
|
|
11195
|
+
_defineProperty(this, "_byte", void 0);
|
|
11196
|
+
_defineProperty(this, "_word", void 0);
|
|
10266
11197
|
_defineProperty(this, "_size", 0);
|
|
10267
11198
|
_defineProperty(this, "_sp", 0);
|
|
10268
11199
|
if (!sharedBuffer || sharedOffset >= N.allocTotal) {
|
|
@@ -11049,7 +11980,7 @@ function hasRemoteFileSchema(schema) {
|
|
|
11049
11980
|
return false;
|
|
11050
11981
|
} else if (schema.type === "boolean" ||
|
|
11051
11982
|
// An enum's values are strings, so there is nothing to look inside.
|
|
11052
|
-
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") {
|
|
11983
|
+
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") {
|
|
11053
11984
|
return false;
|
|
11054
11985
|
} else {
|
|
11055
11986
|
var exhaustiveCheck = schema;
|
|
@@ -11121,7 +12052,7 @@ function hasMediaSchema(schema) {
|
|
|
11121
12052
|
return false;
|
|
11122
12053
|
} else if (schema.type === "boolean" ||
|
|
11123
12054
|
// An enum's values are strings, so there is nothing to look inside.
|
|
11124
|
-
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" ||
|
|
12055
|
+
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" ||
|
|
11125
12056
|
// A settings module holds the assistant's configuration, not content, and
|
|
11126
12057
|
// nothing in it is media.
|
|
11127
12058
|
schema.type === "settings") {
|
|
@@ -11400,6 +12331,46 @@ function getFileHash(text) {
|
|
|
11400
12331
|
return hashToRemoteFileHash(getSHA256Hash(new Uint8Array(text)));
|
|
11401
12332
|
}
|
|
11402
12333
|
|
|
12334
|
+
/**
|
|
12335
|
+
* The variant of a discriminated union that a value takes, by its tag.
|
|
12336
|
+
*
|
|
12337
|
+
* A discriminated union is a fork rather than a level: the variant IS the node,
|
|
12338
|
+
* and everything a caller wants to know about that node — its fields, its
|
|
12339
|
+
* `locale` field, the schema to draw it with — is on the variant and not on the
|
|
12340
|
+
* union. Resolving it takes the source, so it cannot be done from the schema
|
|
12341
|
+
* alone, which is why every caller that has only the union ends up needing this.
|
|
12342
|
+
*
|
|
12343
|
+
* `undefined` where the tag matches nothing, rather than a fallback to the first
|
|
12344
|
+
* variant: a value whose tag names no variant is not a member of the union,
|
|
12345
|
+
* validation is already saying so, and reading fields out of the wrong shape
|
|
12346
|
+
* would answer confidently and wrongly.
|
|
12347
|
+
*
|
|
12348
|
+
* `s.enum()` never reaches here — it is a leaf whose values are strings, with no
|
|
12349
|
+
* variants to resolve — so anything that is not a discriminated union answers
|
|
12350
|
+
* `undefined` too.
|
|
12351
|
+
*/
|
|
12352
|
+
function discriminatedUnionBranchOf(schema, tag) {
|
|
12353
|
+
if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "discriminated-union") {
|
|
12354
|
+
return undefined;
|
|
12355
|
+
}
|
|
12356
|
+
var _iterator = _createForOfIteratorHelper(schema.items),
|
|
12357
|
+
_step;
|
|
12358
|
+
try {
|
|
12359
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
12360
|
+
var item = _step.value;
|
|
12361
|
+
var discriminator = item.items[schema.key];
|
|
12362
|
+
if ((discriminator === null || discriminator === void 0 ? void 0 : discriminator.type) === "literal" && discriminator.value === tag) {
|
|
12363
|
+
return item;
|
|
12364
|
+
}
|
|
12365
|
+
}
|
|
12366
|
+
} catch (err) {
|
|
12367
|
+
_iterator.e(err);
|
|
12368
|
+
} finally {
|
|
12369
|
+
_iterator.f();
|
|
12370
|
+
}
|
|
12371
|
+
return undefined;
|
|
12372
|
+
}
|
|
12373
|
+
|
|
11403
12374
|
function deserializeSchema(serialized) {
|
|
11404
12375
|
var schema = deserializeSchemaImpl(serialized);
|
|
11405
12376
|
if (serialized.readonly) {
|
|
@@ -11411,7 +12382,7 @@ function deserializeSchema(serialized) {
|
|
|
11411
12382
|
return schema;
|
|
11412
12383
|
}
|
|
11413
12384
|
function deserializeSchemaImpl(serialized) {
|
|
11414
|
-
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$directory, _serialized$remote, _serialized$jsonValue, _serialized$render0, _serialized$external, _serialized$render1, _serialized$
|
|
12385
|
+
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$directory, _serialized$remote, _serialized$jsonValue, _serialized$render0, _serialized$external, _serialized$render1, _serialized$render12, _serialized$render13, _serialized$render14, _serialized$render15, _serialized$render16, _serialized$render17;
|
|
11415
12386
|
switch (serialized.type) {
|
|
11416
12387
|
case "string":
|
|
11417
12388
|
return new StringSchema(_objectSpread2(_objectSpread2({}, serialized.options), {}, {
|
|
@@ -11440,7 +12411,12 @@ function deserializeSchemaImpl(serialized) {
|
|
|
11440
12411
|
key = _ref4[0],
|
|
11441
12412
|
item = _ref4[1];
|
|
11442
12413
|
return [key, deserializeSchema(item)];
|
|
11443
|
-
})), serialized.opt, false, false, serialized.description
|
|
12414
|
+
})), serialized.opt, false, false, serialized.description,
|
|
12415
|
+
// Carried through, or the Studio's validation worker — which only ever
|
|
12416
|
+
// sees the deserialized schema — would run every field's own rules and
|
|
12417
|
+
// none of the section's, so a language declared twice would be reported
|
|
12418
|
+
// by the CLI and silently accepted in the Studio.
|
|
12419
|
+
serialized.section);
|
|
11444
12420
|
case "array":
|
|
11445
12421
|
return new ArraySchema(deserializeSchema(serialized.item), serialized.opt, [], false, false, serialized.description,
|
|
11446
12422
|
// The preview closure cannot survive serialization; the render can.
|
|
@@ -11477,27 +12453,32 @@ function deserializeSchemaImpl(serialized) {
|
|
|
11477
12453
|
(_serialized$external = serialized.external) !== null && _serialized$external !== void 0 ? _serialized$external : null);
|
|
11478
12454
|
case "keyOf":
|
|
11479
12455
|
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);
|
|
11480
|
-
case "
|
|
12456
|
+
case "locale":
|
|
11481
12457
|
{
|
|
11482
12458
|
var _serialized$render10;
|
|
12459
|
+
return new LocaleSchema(serialized.opt, [], false, false, serialized.description, (_serialized$render10 = serialized.render) !== null && _serialized$render10 !== void 0 ? _serialized$render10 : null);
|
|
12460
|
+
}
|
|
12461
|
+
case "route":
|
|
12462
|
+
{
|
|
12463
|
+
var _serialized$render11;
|
|
11483
12464
|
var routeOptions = serialized.options ? {
|
|
11484
12465
|
include: serialized.options.include ? new RegExp(serialized.options.include.source, serialized.options.include.flags) : undefined,
|
|
11485
12466
|
exclude: serialized.options.exclude ? new RegExp(serialized.options.exclude.source, serialized.options.exclude.flags) : undefined
|
|
11486
12467
|
} : undefined;
|
|
11487
|
-
return new RouteSchema(routeOptions, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12468
|
+
return new RouteSchema(routeOptions, serialized.opt, [], false, false, serialized.description, (_serialized$render11 = serialized.render) !== null && _serialized$render11 !== void 0 ? _serialized$render11 : null);
|
|
11488
12469
|
}
|
|
11489
12470
|
case "file":
|
|
11490
|
-
return new FileSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$
|
|
12471
|
+
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);
|
|
11491
12472
|
case "image":
|
|
11492
|
-
return new ImageSchema(serialized.options, serialized.opt, serialized.remote, [], {}, false, false, serialized.description, (_serialized$
|
|
12473
|
+
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);
|
|
11493
12474
|
case "date":
|
|
11494
|
-
return new DateSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12475
|
+
return new DateSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render14 = serialized.render) !== null && _serialized$render14 !== void 0 ? _serialized$render14 : null);
|
|
11495
12476
|
case "dateTime":
|
|
11496
|
-
return new DateTimeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12477
|
+
return new DateTimeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render15 = serialized.render) !== null && _serialized$render15 !== void 0 ? _serialized$render15 : null);
|
|
11497
12478
|
case "color":
|
|
11498
|
-
return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12479
|
+
return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render16 = serialized.render) !== null && _serialized$render16 !== void 0 ? _serialized$render16 : null);
|
|
11499
12480
|
case "code":
|
|
11500
|
-
return new CodeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$
|
|
12481
|
+
return new CodeSchema(serialized.options, serialized.opt, [], false, false, serialized.description, (_serialized$render17 = serialized.render) !== null && _serialized$render17 !== void 0 ? _serialized$render17 : null);
|
|
11501
12482
|
default:
|
|
11502
12483
|
{
|
|
11503
12484
|
var exhaustiveCheck = serialized;
|
|
@@ -12164,7 +13145,7 @@ function isPageRouter(routerId) {
|
|
|
12164
13145
|
|
|
12165
13146
|
var corePackageJson = {
|
|
12166
13147
|
name: "@valbuild/core",
|
|
12167
|
-
version: "0.
|
|
13148
|
+
version: "0.127.0",
|
|
12168
13149
|
"private": false,
|
|
12169
13150
|
description: "Val - supercharged hard-coded content",
|
|
12170
13151
|
repository: {
|
|
@@ -12335,4 +13316,4 @@ function tryJsonParse(str) {
|
|
|
12335
13316
|
}
|
|
12336
13317
|
}
|
|
12337
13318
|
|
|
12338
|
-
export {
|
|
13319
|
+
export { DiscriminatedUnionSchema as $, ArraySchema as A, BooleanSchema as B, declaredKeySetOf as C, DEFAULT_CONTENT_HOST as D, missingDeclaredKeys as E, FATAL_ERROR_TYPES as F, GenericSelector as G, discriminatedUnionBranchOf as H, Internal as I, ColorSchema as J, CodeSchema as K, LocaleSchema as L, ModuleFilePathSep as M, NumberSchema as N, ObjectSchema as O, PatchError as P, CODE_LANGUAGES as Q, RecordSchema as R, Schema as S, COLOR_FORMATS as T, DEFAULT_COLOR_FORMAT as U, VAL_EXTENSION as V, DateTimeSchema as W, KeyOfSchema as X, RouteSchema as Y, RichTextSchema as Z, _typeof as _, _slicedToArray as a, EnumSchema as a0, LiteralSchema as a1, deserializeSchema as a2, previewScope as a3, isInlineRender as a4, parseNextJsRoutePattern as a5, parseTanStackRoutePattern as a6, tanStackSegmentsOfRoutePath as a7, validateUrlAgainstPattern as a8, getSourcePathFromRoute as a9, isPageRouter as aa, _createClass as b, _classCallCheck as c, _toConsumableArray as d, DEFAULT_APP_HOST as e, extractValModules as f, computeValModuleShas as g, hasRemoteFileSchema as h, initVal as i, hasMediaSchema as j, DEFAULT_VAL_REMOTE_HOST as k, derefPatch as l, modules as m, StringSchema as n, ImageSchema as o, FileSchema as p, DateSchema as q, SettingsSchema as r, splitModuleFilePathAndModulePath as s, ASSISTANT_SETTINGS_MAX_LENGTH as t, assistantAvailability as u, SETTINGS_MODULE_CONVENTION as v, isRootModuleFilePath as w, resolveSettingsModule as x, localeTagError as y, localeOfValue as z };
|