@valbuild/core 0.120.0 → 0.121.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/declarations/src/index.d.ts +3 -0
  3. package/dist/declarations/src/initSchema.d.ts +27 -0
  4. package/dist/declarations/src/initVal.d.ts +11 -8
  5. package/dist/declarations/src/schema/array.d.ts +2 -2
  6. package/dist/declarations/src/schema/boolean.d.ts +2 -2
  7. package/dist/declarations/src/schema/code.d.ts +2 -2
  8. package/dist/declarations/src/schema/color.d.ts +2 -2
  9. package/dist/declarations/src/schema/date.d.ts +2 -2
  10. package/dist/declarations/src/schema/datetime.d.ts +2 -2
  11. package/dist/declarations/src/schema/file.d.ts +2 -2
  12. package/dist/declarations/src/schema/image.d.ts +2 -2
  13. package/dist/declarations/src/schema/index.d.ts +12 -3
  14. package/dist/declarations/src/schema/keyOf.d.ts +2 -2
  15. package/dist/declarations/src/schema/literal.d.ts +2 -2
  16. package/dist/declarations/src/schema/number.d.ts +2 -2
  17. package/dist/declarations/src/schema/object.d.ts +2 -2
  18. package/dist/declarations/src/schema/record.d.ts +2 -2
  19. package/dist/declarations/src/schema/richtext.d.ts +2 -2
  20. package/dist/declarations/src/schema/route.d.ts +2 -2
  21. package/dist/declarations/src/schema/settings.d.ts +102 -0
  22. package/dist/declarations/src/schema/string.d.ts +2 -2
  23. package/dist/declarations/src/schema/union.d.ts +2 -2
  24. package/dist/declarations/src/selector/index.d.ts +3 -2
  25. package/dist/declarations/src/settingsModule.d.ts +60 -0
  26. package/dist/declarations/src/source/index.d.ts +2 -1
  27. package/dist/declarations/src/source/settings.d.ts +94 -0
  28. package/dist/{index-2f65e194.esm.js → index-5fe6fb98.esm.js} +707 -201
  29. package/dist/{index-861944d8.cjs.prod.js → index-61237991.cjs.prod.js} +712 -200
  30. package/dist/{index-01f673d2.cjs.dev.js → index-9860179f.cjs.dev.js} +712 -200
  31. package/dist/valbuild-core.cjs.dev.js +7 -1
  32. package/dist/valbuild-core.cjs.prod.js +7 -1
  33. package/dist/valbuild-core.esm.js +1 -1
  34. package/package.json +1 -1
  35. package/patch/dist/valbuild-core-patch.cjs.dev.js +1 -1
  36. package/patch/dist/valbuild-core-patch.cjs.prod.js +1 -1
  37. package/patch/dist/valbuild-core-patch.esm.js +2 -2
@@ -591,12 +591,14 @@ var StringSchema = /*#__PURE__*/function (_Schema) {
591
591
  }, {
592
592
  key: "readonly",
593
593
  value: function readonly() {
594
- return new StringSchema(this.options, this.opt, this.isRaw, this.customValidateFunctions, this.renderInput, true, this.isHidden, this.description, this.previewInput, this.isMultiline);
594
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
595
+ return new StringSchema(this.options, this.opt, this.isRaw, this.customValidateFunctions, this.renderInput, isReadonly, this.isHidden, this.description, this.previewInput, this.isMultiline);
595
596
  }
596
597
  }, {
597
598
  key: "hidden",
598
599
  value: function hidden() {
599
- return new StringSchema(this.options, this.opt, this.isRaw, this.customValidateFunctions, this.renderInput, this.isReadonly, true, this.description, this.previewInput, this.isMultiline);
600
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
601
+ return new StringSchema(this.options, this.opt, this.isRaw, this.customValidateFunctions, this.renderInput, this.isReadonly, isHidden, this.description, this.previewInput, this.isMultiline);
600
602
  }
601
603
  }, {
602
604
  key: "raw",
@@ -869,12 +871,14 @@ var ObjectSchema = /*#__PURE__*/function (_Schema) {
869
871
  }, {
870
872
  key: "readonly",
871
873
  value: function readonly() {
872
- return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
874
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
875
+ return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
873
876
  }
874
877
  }, {
875
878
  key: "hidden",
876
879
  value: function hidden() {
877
- return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
880
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
881
+ return new ObjectSchema(this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
878
882
  }
879
883
  }, {
880
884
  key: "executeCustomValidateAt",
@@ -1085,12 +1089,14 @@ var ArraySchema = /*#__PURE__*/function (_Schema) {
1085
1089
  }, {
1086
1090
  key: "readonly",
1087
1091
  value: function readonly() {
1088
- return new ArraySchema(this.item, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.previewInput, this.renderInput);
1092
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1093
+ return new ArraySchema(this.item, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.previewInput, this.renderInput);
1089
1094
  }
1090
1095
  }, {
1091
1096
  key: "hidden",
1092
1097
  value: function hidden() {
1093
- return new ArraySchema(this.item, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.previewInput, this.renderInput);
1098
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1099
+ return new ArraySchema(this.item, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.previewInput, this.renderInput);
1094
1100
  }
1095
1101
  }, {
1096
1102
  key: "executeCustomValidateAt",
@@ -1338,12 +1344,14 @@ var LiteralSchema = /*#__PURE__*/function (_Schema) {
1338
1344
  }, {
1339
1345
  key: "readonly",
1340
1346
  value: function readonly() {
1341
- return new LiteralSchema(this.value, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
1347
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1348
+ return new LiteralSchema(this.value, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
1342
1349
  }
1343
1350
  }, {
1344
1351
  key: "hidden",
1345
1352
  value: function hidden() {
1346
- return new LiteralSchema(this.value, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
1353
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1354
+ return new LiteralSchema(this.value, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
1347
1355
  }
1348
1356
  }, {
1349
1357
  key: "executeCustomValidateAt",
@@ -1749,12 +1757,14 @@ var UnionSchema = /*#__PURE__*/function (_Schema) {
1749
1757
  }, {
1750
1758
  key: "readonly",
1751
1759
  value: function readonly() {
1752
- return new UnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
1760
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1761
+ return new UnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
1753
1762
  }
1754
1763
  }, {
1755
1764
  key: "hidden",
1756
1765
  value: function hidden() {
1757
- return new UnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
1766
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1767
+ return new UnionSchema(this.key, this.items, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
1758
1768
  }
1759
1769
  }, {
1760
1770
  key: "executeCustomValidateAt",
@@ -3127,12 +3137,14 @@ var ImageSchema = /*#__PURE__*/function (_Schema) {
3127
3137
  }, {
3128
3138
  key: "readonly",
3129
3139
  value: function readonly() {
3130
- return new ImageSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, true, this.isHidden, this.description, this.renderInput, this.previewInput);
3140
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3141
+ return new ImageSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
3131
3142
  }
3132
3143
  }, {
3133
3144
  key: "hidden",
3134
3145
  value: function hidden() {
3135
- return new ImageSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
3146
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3147
+ return new ImageSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
3136
3148
  }
3137
3149
  }, {
3138
3150
  key: "executeCustomValidateAt",
@@ -3364,12 +3376,14 @@ var RouteSchema = /*#__PURE__*/function (_Schema) {
3364
3376
  }, {
3365
3377
  key: "readonly",
3366
3378
  value: function readonly() {
3367
- return new RouteSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
3379
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3380
+ return new RouteSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
3368
3381
  }
3369
3382
  }, {
3370
3383
  key: "hidden",
3371
3384
  value: function hidden() {
3372
- return new RouteSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
3385
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3386
+ return new RouteSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
3373
3387
  }
3374
3388
  }, {
3375
3389
  key: "executeCustomValidateAt",
@@ -3948,12 +3962,14 @@ var RichTextSchema = /*#__PURE__*/function (_Schema) {
3948
3962
  }, {
3949
3963
  key: "readonly",
3950
3964
  value: function readonly() {
3951
- return new RichTextSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
3965
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3966
+ return new RichTextSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
3952
3967
  }
3953
3968
  }, {
3954
3969
  key: "hidden",
3955
3970
  value: function hidden() {
3956
- return new RichTextSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
3971
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
3972
+ return new RichTextSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
3957
3973
  }
3958
3974
  }, {
3959
3975
  key: "executeCustomValidateAt",
@@ -4755,12 +4771,14 @@ var RecordSchema = /*#__PURE__*/function (_Schema) {
4755
4771
  }, {
4756
4772
  key: "readonly",
4757
4773
  value: function readonly() {
4758
- return new RecordSchema(this.item, this.opt, this.customValidateFunctions, this.currentRouter, this.keySchema, this.mediaOptions, true, this.isHidden, this.description, this.isJsonValues, this.previewInput, this.renderInput);
4774
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
4775
+ return new RecordSchema(this.item, this.opt, this.customValidateFunctions, this.currentRouter, this.keySchema, this.mediaOptions, isReadonly, this.isHidden, this.description, this.isJsonValues, this.previewInput, this.renderInput);
4759
4776
  }
4760
4777
  }, {
4761
4778
  key: "hidden",
4762
4779
  value: function hidden() {
4763
- return new RecordSchema(this.item, this.opt, this.customValidateFunctions, this.currentRouter, this.keySchema, this.mediaOptions, this.isReadonly, true, this.description, this.isJsonValues, this.previewInput, this.renderInput);
4780
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
4781
+ return new RecordSchema(this.item, this.opt, this.customValidateFunctions, this.currentRouter, this.keySchema, this.mediaOptions, this.isReadonly, isHidden, this.description, this.isJsonValues, this.previewInput, this.renderInput);
4764
4782
  }
4765
4783
  }, {
4766
4784
  key: "router",
@@ -5049,6 +5067,487 @@ function record(keyOrSchema, schema) {
5049
5067
  }
5050
5068
  }
5051
5069
 
5070
+ /**
5071
+ * The source of the project's settings module — `s.settings()`.
5072
+ *
5073
+ * **Every key is optional, at every level, and that is the whole point.** A
5074
+ * settings module is written as
5075
+ *
5076
+ * ```typescript
5077
+ * export default c.define("/settings.val.ts", s.settings(), {});
5078
+ * ```
5079
+ *
5080
+ * and `{}` has to keep validating as sections are added to it. A project that
5081
+ * never touched the assistant's settings should not have to edit its settings
5082
+ * file the day `locales` or `permissions` land.
5083
+ *
5084
+ * That is why settings is not sugar over `s.object()`: an object schema errors
5085
+ * with `Expected key 'assistant' not found in object` for any absent key (see
5086
+ * `ObjectSchema.executeAssert`), and `.nullable()` permits `null`, not absence.
5087
+ * `SettingsSchema` gives absent keys the meaning "unset" instead.
5088
+ *
5089
+ * `null` means unset too, so the editor can clear a field it has already
5090
+ * written without removing the key.
5091
+ */
5092
+
5093
+ /**
5094
+ * The assistant: whether editors have one, and what it is told about the
5095
+ * project on every message.
5096
+ *
5097
+ * `context` and `tone` are prose the model reads, not instructions Val
5098
+ * interprets, and both are capped (see {@link ASSISTANT_SETTINGS_MAX_LENGTH}):
5099
+ * they are prepended to every request the chat makes, so an unbounded field
5100
+ * here is an unbounded cost on every turn.
5101
+ */
5102
+
5103
+ /**
5104
+ * The cap on each of the assistant's prose fields, in characters.
5105
+ *
5106
+ * Roughly a thousand tokens each. Generous enough for a paragraph of
5107
+ * background and a house style, small enough that the two of them together do
5108
+ * not dominate the system prompt they are appended to.
5109
+ */
5110
+ var ASSISTANT_SETTINGS_MAX_LENGTH = 4000;
5111
+
5112
+ /**
5113
+ * Whether a project has an assistant — and the answer is not a boolean.
5114
+ *
5115
+ * - `"on"`: use it.
5116
+ * - `"off"`: every trace of it goes. No button in the top bar, no row in the
5117
+ * quick actions, no panel, nothing sent. A project that says `false` has
5118
+ * decided, and the Studio does not keep offering.
5119
+ * - `"unconfigured"`: nobody has said. The affordances are SHOWN, and asking to
5120
+ * use the assistant asks to turn it on first. That is the difference between
5121
+ * this and `"off"`, and the reason `enabled` is a tri-state: hiding an
5122
+ * unconfigured assistant means nobody discovers it, and quietly enabling one
5123
+ * means a project starts sending its content to a model because it did not
5124
+ * know to say no.
5125
+ *
5126
+ * A project with NO settings module is `"on"`. There is nowhere to record a
5127
+ * decision, so there is nothing to prompt for and nothing to prompt INTO — the
5128
+ * prompt writes to a settings module, and that project has none.
5129
+ *
5130
+ * This is the only answer to "does this project have an assistant":
5131
+ * `config.ai.chat` is gone, and with it the chat's title, description and
5132
+ * suggestions, which nothing replaces. The AI commit-message summariser is
5133
+ * deliberately not part of this — `config.ai.commitMessages` stays where it is,
5134
+ * and gets settings of its own later.
5135
+ */
5136
+
5137
+ function assistantAvailability(/** The settings module's source, or `undefined` where the project has none. */
5138
+ settings) {
5139
+ var _settings$assistant;
5140
+ if (settings === undefined) {
5141
+ return "on";
5142
+ }
5143
+ var enabled = (_settings$assistant = settings.assistant) === null || _settings$assistant === void 0 ? void 0 : _settings$assistant.enabled;
5144
+ if (enabled === true) {
5145
+ return "on";
5146
+ }
5147
+ if (enabled === false) {
5148
+ return "off";
5149
+ }
5150
+ return "unconfigured";
5151
+ }
5152
+
5153
+ var BooleanSchema = /*#__PURE__*/function (_Schema) {
5154
+ function BooleanSchema() {
5155
+ var _this;
5156
+ var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
5157
+ var customValidateFunctions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
5158
+ var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
5159
+ var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
5160
+ var description = arguments.length > 4 ? arguments[4] : undefined;
5161
+ var renderInput = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
5162
+ var previewInput = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
5163
+ _classCallCheck(this, BooleanSchema);
5164
+ _this = _callSuper(this, BooleanSchema);
5165
+ _this.opt = opt;
5166
+ _this.customValidateFunctions = customValidateFunctions;
5167
+ _this.isReadonly = isReadonly;
5168
+ _this.isHidden = isHidden;
5169
+ _this.description = description;
5170
+ _this.renderInput = renderInput;
5171
+ _this.previewInput = previewInput;
5172
+ return _this;
5173
+ }
5174
+ _inherits(BooleanSchema, _Schema);
5175
+ return _createClass(BooleanSchema, [{
5176
+ key: "describe",
5177
+ value: function describe(description) {
5178
+ return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined, this.renderInput, this.previewInput);
5179
+ }
5180
+ }, {
5181
+ key: "validate",
5182
+ value: function validate(validationFunction) {
5183
+ return new BooleanSchema(this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]), this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5184
+ }
5185
+ }, {
5186
+ key: "executeValidate",
5187
+ value: function executeValidate(path, src) {
5188
+ if (this.opt && (src === null || src === undefined)) {
5189
+ return false;
5190
+ }
5191
+ if (typeof src !== "boolean") {
5192
+ return _defineProperty({}, path, [{
5193
+ message: "Expected 'boolean', got '".concat(_typeof(src), "'"),
5194
+ value: src
5195
+ }]);
5196
+ }
5197
+ return false;
5198
+ }
5199
+ }, {
5200
+ key: "executeAssert",
5201
+ value: function executeAssert(path, src) {
5202
+ if (this.opt && src === null) {
5203
+ return {
5204
+ success: true,
5205
+ data: src
5206
+ };
5207
+ }
5208
+ if (src === null) {
5209
+ return {
5210
+ success: false,
5211
+ errors: _defineProperty({}, path, [{
5212
+ message: "Expected 'boolean', got 'null'",
5213
+ typeError: true
5214
+ }])
5215
+ };
5216
+ }
5217
+ if (typeof src !== "boolean") {
5218
+ return {
5219
+ success: false,
5220
+ errors: _defineProperty({}, path, [{
5221
+ message: "Expected 'boolean', got '".concat(_typeof(src), "'"),
5222
+ typeError: true
5223
+ }])
5224
+ };
5225
+ }
5226
+ return {
5227
+ success: true,
5228
+ data: src
5229
+ };
5230
+ }
5231
+ }, {
5232
+ key: "nullable",
5233
+ value: function nullable() {
5234
+ return new BooleanSchema(true, [], this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5235
+ }
5236
+ }, {
5237
+ key: "readonly",
5238
+ value: function readonly() {
5239
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
5240
+ return new BooleanSchema(this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5241
+ }
5242
+ }, {
5243
+ key: "hidden",
5244
+ value: function hidden() {
5245
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
5246
+ return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
5247
+ }
5248
+ }, {
5249
+ key: "executeCustomValidateAt",
5250
+ value: function executeCustomValidateAt(path, src) {
5251
+ return this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
5252
+ path: path
5253
+ });
5254
+ }
5255
+
5256
+ /**
5257
+ * How this field is laid out in the editor when it is the item of an array
5258
+ * or record: `{ as: "inline" }` renders the field itself inside each row,
5259
+ * instead of a preview row that navigates to it.
5260
+ *
5261
+ * Static configuration, not a callback — see `render.ts`.
5262
+ */
5263
+ }, {
5264
+ key: "render",
5265
+ value: function render(input) {
5266
+ return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, input, this.previewInput);
5267
+ }
5268
+
5269
+ /**
5270
+ * How this VALUE is shown where a preview of it is needed — a row in a
5271
+ * sortable list, a reference dropdown, a search hit. Never how the field
5272
+ * itself is edited (that is `render`). See `preview.ts`.
5273
+ */
5274
+ }, {
5275
+ key: "preview",
5276
+ value: function preview(select) {
5277
+ return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, select);
5278
+ }
5279
+ }, {
5280
+ key: "executePreviewItem",
5281
+ value: function executePreviewItem(src) {
5282
+ if (this.previewInput === null) {
5283
+ return null;
5284
+ }
5285
+ return this.previewInput({
5286
+ val: src
5287
+ });
5288
+ }
5289
+ }, {
5290
+ key: "declaresItemPreview",
5291
+ value: function declaresItemPreview() {
5292
+ return this.previewInput !== null;
5293
+ }
5294
+ }, {
5295
+ key: "executeSerialize",
5296
+ value: function executeSerialize() {
5297
+ var _this$renderInput, _this$customValidateF;
5298
+ return {
5299
+ type: "boolean",
5300
+ render: (_this$renderInput = this.renderInput) !== null && _this$renderInput !== void 0 ? _this$renderInput : undefined,
5301
+ preview: this.previewInput ? true : undefined,
5302
+ opt: this.opt,
5303
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0,
5304
+ readonly: this.isReadonly,
5305
+ hidden: this.isHidden,
5306
+ description: this.description
5307
+ };
5308
+ }
5309
+ }, {
5310
+ key: "executePreview",
5311
+ value: function executePreview() {
5312
+ return {};
5313
+ }
5314
+ }]);
5315
+ }(Schema);
5316
+ var _boolean = function _boolean() {
5317
+ return new BooleanSchema();
5318
+ };
5319
+
5320
+ /**
5321
+ * An object whose keys are all optional: absent means unset.
5322
+ *
5323
+ * Both the settings module itself and each of its sections are this. See
5324
+ * {@link SettingsSource} for why settings cannot be an object schema, and
5325
+ * {@link settings} for what a settings module holds.
5326
+ *
5327
+ * There is no `describe`, `validate`, `render` or `preview` on purpose: the
5328
+ * shape is Val's, not the schema author's — `s.settings()` takes no arguments —
5329
+ * and the Studio renders each section with a UI built for it.
5330
+ */
5331
+ var SettingsSchema = /*#__PURE__*/function (_Schema) {
5332
+ function SettingsSchema(items) {
5333
+ var _this;
5334
+ var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
5335
+ var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
5336
+ var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
5337
+ var description = arguments.length > 4 ? arguments[4] : undefined;
5338
+ _classCallCheck(this, SettingsSchema);
5339
+ _this = _callSuper(this, SettingsSchema);
5340
+ _this.items = items;
5341
+ _this.opt = opt;
5342
+ _this.isReadonly = isReadonly;
5343
+ _this.isHidden = isHidden;
5344
+ _this.description = description;
5345
+ return _this;
5346
+ }
5347
+ _inherits(SettingsSchema, _Schema);
5348
+ return _createClass(SettingsSchema, [{
5349
+ key: "executeValidate",
5350
+ value: function executeValidate(path, src) {
5351
+ var error = false;
5352
+ if (src === null || src === undefined) {
5353
+ if (this.opt) {
5354
+ return false;
5355
+ }
5356
+ return _defineProperty({}, path, [{
5357
+ message: "Expected 'object', got '".concat(src, "'")
5358
+ }]);
5359
+ }
5360
+ if (_typeof(src) !== "object") {
5361
+ return _defineProperty({}, path, [{
5362
+ message: "Expected 'object', got '".concat(_typeof(src), "'")
5363
+ }]);
5364
+ }
5365
+ if (Array.isArray(src)) {
5366
+ return _defineProperty({}, path, [{
5367
+ message: "Expected 'object', got 'array'"
5368
+ }]);
5369
+ }
5370
+ for (var _i = 0, _Object$entries = Object.entries(this.items); _i < _Object$entries.length; _i++) {
5371
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
5372
+ _key = _Object$entries$_i[0],
5373
+ schema = _Object$entries$_i[1];
5374
+ // Absent is the unset value, so there is nothing to validate. A key that
5375
+ // is present as `undefined` is the same statement written differently.
5376
+ if (src[_key] === undefined) {
5377
+ continue;
5378
+ }
5379
+ var subPath = createValPathOfItem(path, _key);
5380
+ if (!subPath) {
5381
+ error = this.appendValidationError(error, path, "Internal error: could not create path at ".concat(!path && typeof path === "string" ? "<empty string>" : path, " at key ").concat(_key),
5382
+ // Should! never happen
5383
+ src);
5384
+ } else {
5385
+ var subError = schema["executeValidate"](subPath, src[_key]);
5386
+ error = this.mergeValidationErrors(error, subError);
5387
+ }
5388
+ }
5389
+ // An unknown key is reported rather than ignored (which is what an object
5390
+ // schema does with extra keys): the shape is closed and Val-defined, so the
5391
+ // realistic cause is a typo — `toneOfVoice` for `tone` — and silence there
5392
+ // means a setting that never takes effect and never says why.
5393
+ for (var _i2 = 0, _Object$keys = Object.keys(src); _i2 < _Object$keys.length; _i2++) {
5394
+ var _key2 = _Object$keys[_i2];
5395
+ if (!(_key2 in this.items)) {
5396
+ error = this.appendValidationError(error, path, "Unknown settings key: '".concat(_key2, "'. Expected one of: ").concat(Object.keys(this.items).map(function (key) {
5397
+ return "'".concat(key, "'");
5398
+ }).join(", ")), src, true);
5399
+ }
5400
+ }
5401
+ return error;
5402
+ }
5403
+ }, {
5404
+ key: "executeAssert",
5405
+ value: function executeAssert(path, src) {
5406
+ if (this.opt && src === null) {
5407
+ return {
5408
+ success: true,
5409
+ data: src
5410
+ };
5411
+ }
5412
+ var typeError = function typeError(got) {
5413
+ return {
5414
+ message: "Expected 'object', got '".concat(got, "'"),
5415
+ typeError: true
5416
+ };
5417
+ };
5418
+ if (src === null) {
5419
+ return {
5420
+ success: false,
5421
+ errors: _defineProperty({}, path, [typeError("null")])
5422
+ };
5423
+ }
5424
+ if (_typeof(src) !== "object") {
5425
+ return {
5426
+ success: false,
5427
+ errors: _defineProperty({}, path, [typeError(_typeof(src))])
5428
+ };
5429
+ }
5430
+ if (Array.isArray(src)) {
5431
+ return {
5432
+ success: false,
5433
+ errors: _defineProperty({}, path, [typeError("array")])
5434
+ };
5435
+ }
5436
+ // No per-key check, unlike an object schema: every key is optional, so an
5437
+ // object is all this can assert.
5438
+ return {
5439
+ success: true,
5440
+ data: src
5441
+ };
5442
+ }
5443
+ }, {
5444
+ key: "nullable",
5445
+ value: function nullable() {
5446
+ return new SettingsSchema(this.items, true, this.isReadonly, this.isHidden, this.description);
5447
+ }
5448
+ }, {
5449
+ key: "readonly",
5450
+ value: function readonly() {
5451
+ return new SettingsSchema(this.items, this.opt, true, this.isHidden, this.description);
5452
+ }
5453
+ }, {
5454
+ key: "hidden",
5455
+ value: function hidden() {
5456
+ return new SettingsSchema(this.items, this.opt, this.isReadonly, true, this.description);
5457
+ }
5458
+ }, {
5459
+ key: "executeCustomValidateAt",
5460
+ value: function executeCustomValidateAt() {
5461
+ // Settings declares no `validate`, so there are no custom validators to
5462
+ // run. Implemented rather than inherited because the base class makes this
5463
+ // abstract on purpose — see `Schema.executeCustomValidateAt`.
5464
+ return [];
5465
+ }
5466
+ }, {
5467
+ key: "executeSerialize",
5468
+ value: function executeSerialize() {
5469
+ return {
5470
+ type: "settings",
5471
+ items: Object.fromEntries(Object.entries(this.items).map(function (_ref4) {
5472
+ var _ref5 = _slicedToArray(_ref4, 2),
5473
+ key = _ref5[0],
5474
+ schema = _ref5[1];
5475
+ return [key, schema["executeSerialize"]()];
5476
+ })),
5477
+ opt: this.opt,
5478
+ readonly: this.isReadonly,
5479
+ hidden: this.isHidden,
5480
+ description: this.description
5481
+ };
5482
+ }
5483
+ }, {
5484
+ key: "executePreview",
5485
+ value: function executePreview(sourcePath, src, scope) {
5486
+ var res = {};
5487
+ if (src === null) {
5488
+ return res;
5489
+ }
5490
+ for (var _key3 in this.items) {
5491
+ var itemSrc = src[_key3];
5492
+ if (itemSrc === null || itemSrc === undefined) {
5493
+ continue;
5494
+ }
5495
+ var subPath = unsafeCreateSourcePath(sourcePath, _key3);
5496
+ if (scope !== undefined && !scope.wantsUnder(subPath)) {
5497
+ continue;
5498
+ }
5499
+ var itemResult = this.items[_key3]["executePreview"](subPath, itemSrc, scope);
5500
+ for (var keyS in itemResult) {
5501
+ var _key4 = keyS;
5502
+ res[_key4] = itemResult[_key4];
5503
+ }
5504
+ }
5505
+ return res;
5506
+ }
5507
+ }]);
5508
+ }(Schema);
5509
+
5510
+ /**
5511
+ * Define the project's settings.
5512
+ *
5513
+ * One settings module per project, at the root of the content tree — a module
5514
+ * file path with no directory segment, `/settings.val.ts` by convention:
5515
+ *
5516
+ * ```typescript
5517
+ * export default c.define("/settings.val.ts", s.settings(), {});
5518
+ * ```
5519
+ *
5520
+ * Every section is optional, so `{}` is a complete settings module and stays
5521
+ * one as sections are added. Fill in what the project needs:
5522
+ *
5523
+ * ```typescript
5524
+ * export default c.define("/settings.val.ts", s.settings(), {
5525
+ * assistant: {
5526
+ * enabled: true,
5527
+ * context: "Val is a CMS for developers. British English, and 'Val' is never 'VAL'.",
5528
+ * tone: "Plain and direct. No exclamation marks, sentence case in headings.",
5529
+ * },
5530
+ * });
5531
+ * ```
5532
+ *
5533
+ * The Studio edits it under the cog at the foot of the left rail, and the
5534
+ * assistant is told `assistant.context` and `assistant.tone` on every message.
5535
+ *
5536
+ * `s.settings()` takes no arguments: the shape is Val's, which is what lets the
5537
+ * Studio render a UI built for each field rather than a generic form. A
5538
+ * project's own global content — a site name, social links — belongs in a
5539
+ * module of its own.
5540
+ */
5541
+ function settings() {
5542
+ return new SettingsSchema({
5543
+ assistant: new SettingsSchema({
5544
+ 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."),
5545
+ 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."),
5546
+ 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.")
5547
+ })
5548
+ });
5549
+ }
5550
+
5052
5551
  function define(id,
5053
5552
  // TODO: `/${string}`
5054
5553
  schema, source) {
@@ -5086,6 +5585,17 @@ function joinModuleFilePathAndModulePath(moduleFilePath, modulePath) {
5086
5585
  function isObjectSchema(schema) {
5087
5586
  return schema instanceof ObjectSchema || _typeof(schema) === "object" && "type" in schema && schema.type === "object";
5088
5587
  }
5588
+
5589
+ /**
5590
+ * Settings, which walks like an object but whose keys are all OPTIONAL.
5591
+ *
5592
+ * That difference is the whole reason it is not an object schema: descending
5593
+ * into an unset section must resolve to `undefined`, not fail — see
5594
+ * `SettingsSource`.
5595
+ */
5596
+ function isSettingsSchema(schema) {
5597
+ return schema instanceof SettingsSchema || _typeof(schema) === "object" && "type" in schema && schema.type === "settings";
5598
+ }
5089
5599
  function isRecordSchema(schema) {
5090
5600
  return schema instanceof RecordSchema || _typeof(schema) === "object" && "type" in schema && schema.type === "record";
5091
5601
  }
@@ -5164,6 +5674,16 @@ function resolvePath(path, valModule, schema) {
5164
5674
  if (isJson(resolvedSource) && parts.length > 0) {
5165
5675
  throw Error("Cannot resolve path into a jsonValues entry until its content is loaded. Path: ".concat(path));
5166
5676
  }
5677
+ } else if (isSettingsSchema(resolvedSchema)) {
5678
+ if (resolvedSource !== null && resolvedSource !== undefined && _typeof(resolvedSource) !== "object") {
5679
+ throw Error("Schema type error: expected source to be type of object, but got ".concat(_typeof(resolvedSource)));
5680
+ }
5681
+ // An absent key is NOT an error here, unlike an object's: every settings
5682
+ // key is optional, so a path into a section the project has not set
5683
+ // resolves to `undefined` — and keeps resolving, one level per part, so a
5684
+ // path two deep into an unset section still lands on the right schema.
5685
+ resolvedSource = resolvedSource === null || resolvedSource === undefined ? resolvedSource : resolvedSource[part];
5686
+ resolvedSchema = resolvedSchema instanceof SettingsSchema ? resolvedSchema["items"][part] : resolvedSchema.items[part];
5167
5687
  } else if (isObjectSchema(resolvedSchema)) {
5168
5688
  if (_typeof(resolvedSource) !== "object") {
5169
5689
  throw Error("Schema type error: expected source to be type of object, but got ".concat(_typeof(resolvedSource)));
@@ -5378,6 +5898,21 @@ function safeResolvePath(path, valModule, schema) {
5378
5898
  }
5379
5899
  };
5380
5900
  }
5901
+ } else if (isSettingsSchema(resolvedSchema)) {
5902
+ if (resolvedSource !== null && resolvedSource !== undefined && _typeof(resolvedSource) !== "object") {
5903
+ return {
5904
+ v: {
5905
+ status: "error",
5906
+ message: "Schema type error: expected source to be type of object, but got ".concat(_typeof(resolvedSource))
5907
+ }
5908
+ };
5909
+ }
5910
+ // Absent is a value here — see the note in `resolvePath`. `undefined` has
5911
+ // to be let through as well as `null`: descending into a section the
5912
+ // project has not set produces one, and the NEXT part then arrives with
5913
+ // an undefined source that is not an error either.
5914
+ resolvedSource = resolvedSource === null || resolvedSource === undefined ? resolvedSource : resolvedSource[part];
5915
+ resolvedSchema = resolvedSchema instanceof SettingsSchema ? resolvedSchema["items"][part] : resolvedSchema.items[part];
5381
5916
  } else if (isObjectSchema(resolvedSchema)) {
5382
5917
  if (resolvedSource === undefined) {
5383
5918
  return {
@@ -5696,12 +6231,14 @@ var NumberSchema = /*#__PURE__*/function (_Schema) {
5696
6231
  }, {
5697
6232
  key: "readonly",
5698
6233
  value: function readonly() {
5699
- return new NumberSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
6234
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6235
+ return new NumberSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5700
6236
  }
5701
6237
  }, {
5702
6238
  key: "hidden",
5703
6239
  value: function hidden() {
5704
- return new NumberSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
6240
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6241
+ return new NumberSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
5705
6242
  }
5706
6243
  }, {
5707
6244
  key: "max",
@@ -5790,171 +6327,6 @@ var number = function number(options) {
5790
6327
  return new NumberSchema(options);
5791
6328
  };
5792
6329
 
5793
- var BooleanSchema = /*#__PURE__*/function (_Schema) {
5794
- function BooleanSchema() {
5795
- var _this;
5796
- var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
5797
- var customValidateFunctions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
5798
- var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
5799
- var isHidden = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
5800
- var description = arguments.length > 4 ? arguments[4] : undefined;
5801
- var renderInput = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
5802
- var previewInput = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
5803
- _classCallCheck(this, BooleanSchema);
5804
- _this = _callSuper(this, BooleanSchema);
5805
- _this.opt = opt;
5806
- _this.customValidateFunctions = customValidateFunctions;
5807
- _this.isReadonly = isReadonly;
5808
- _this.isHidden = isHidden;
5809
- _this.description = description;
5810
- _this.renderInput = renderInput;
5811
- _this.previewInput = previewInput;
5812
- return _this;
5813
- }
5814
- _inherits(BooleanSchema, _Schema);
5815
- return _createClass(BooleanSchema, [{
5816
- key: "describe",
5817
- value: function describe(description) {
5818
- return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined, this.renderInput, this.previewInput);
5819
- }
5820
- }, {
5821
- key: "validate",
5822
- value: function validate(validationFunction) {
5823
- return new BooleanSchema(this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]), this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5824
- }
5825
- }, {
5826
- key: "executeValidate",
5827
- value: function executeValidate(path, src) {
5828
- if (this.opt && (src === null || src === undefined)) {
5829
- return false;
5830
- }
5831
- if (typeof src !== "boolean") {
5832
- return _defineProperty({}, path, [{
5833
- message: "Expected 'boolean', got '".concat(_typeof(src), "'"),
5834
- value: src
5835
- }]);
5836
- }
5837
- return false;
5838
- }
5839
- }, {
5840
- key: "executeAssert",
5841
- value: function executeAssert(path, src) {
5842
- if (this.opt && src === null) {
5843
- return {
5844
- success: true,
5845
- data: src
5846
- };
5847
- }
5848
- if (src === null) {
5849
- return {
5850
- success: false,
5851
- errors: _defineProperty({}, path, [{
5852
- message: "Expected 'boolean', got 'null'",
5853
- typeError: true
5854
- }])
5855
- };
5856
- }
5857
- if (typeof src !== "boolean") {
5858
- return {
5859
- success: false,
5860
- errors: _defineProperty({}, path, [{
5861
- message: "Expected 'boolean', got '".concat(_typeof(src), "'"),
5862
- typeError: true
5863
- }])
5864
- };
5865
- }
5866
- return {
5867
- success: true,
5868
- data: src
5869
- };
5870
- }
5871
- }, {
5872
- key: "nullable",
5873
- value: function nullable() {
5874
- return new BooleanSchema(true, [], this.isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
5875
- }
5876
- }, {
5877
- key: "readonly",
5878
- value: function readonly() {
5879
- return new BooleanSchema(this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
5880
- }
5881
- }, {
5882
- key: "hidden",
5883
- value: function hidden() {
5884
- return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
5885
- }
5886
- }, {
5887
- key: "executeCustomValidateAt",
5888
- value: function executeCustomValidateAt(path, src) {
5889
- return this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
5890
- path: path
5891
- });
5892
- }
5893
-
5894
- /**
5895
- * How this field is laid out in the editor when it is the item of an array
5896
- * or record: `{ as: "inline" }` renders the field itself inside each row,
5897
- * instead of a preview row that navigates to it.
5898
- *
5899
- * Static configuration, not a callback — see `render.ts`.
5900
- */
5901
- }, {
5902
- key: "render",
5903
- value: function render(input) {
5904
- return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, input, this.previewInput);
5905
- }
5906
-
5907
- /**
5908
- * How this VALUE is shown where a preview of it is needed — a row in a
5909
- * sortable list, a reference dropdown, a search hit. Never how the field
5910
- * itself is edited (that is `render`). See `preview.ts`.
5911
- */
5912
- }, {
5913
- key: "preview",
5914
- value: function preview(select) {
5915
- return new BooleanSchema(this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, this.description, this.renderInput, select);
5916
- }
5917
- }, {
5918
- key: "executePreviewItem",
5919
- value: function executePreviewItem(src) {
5920
- if (this.previewInput === null) {
5921
- return null;
5922
- }
5923
- return this.previewInput({
5924
- val: src
5925
- });
5926
- }
5927
- }, {
5928
- key: "declaresItemPreview",
5929
- value: function declaresItemPreview() {
5930
- return this.previewInput !== null;
5931
- }
5932
- }, {
5933
- key: "executeSerialize",
5934
- value: function executeSerialize() {
5935
- var _this$renderInput, _this$customValidateF;
5936
- return {
5937
- type: "boolean",
5938
- render: (_this$renderInput = this.renderInput) !== null && _this$renderInput !== void 0 ? _this$renderInput : undefined,
5939
- preview: this.previewInput ? true : undefined,
5940
- opt: this.opt,
5941
- customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0,
5942
- readonly: this.isReadonly,
5943
- hidden: this.isHidden,
5944
- description: this.description
5945
- };
5946
- }
5947
- }, {
5948
- key: "executePreview",
5949
- value: function executePreview() {
5950
- return {};
5951
- }
5952
- }]);
5953
- }(Schema);
5954
- var _boolean = function _boolean() {
5955
- return new BooleanSchema();
5956
- };
5957
-
5958
6330
  var KeyOfSchema = /*#__PURE__*/function (_Schema) {
5959
6331
  function KeyOfSchema(schema, sourcePath) {
5960
6332
  var _this;
@@ -6122,12 +6494,14 @@ var KeyOfSchema = /*#__PURE__*/function (_Schema) {
6122
6494
  }, {
6123
6495
  key: "readonly",
6124
6496
  value: function readonly() {
6125
- return new KeyOfSchema(this.schema, this.sourcePath, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
6497
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6498
+ return new KeyOfSchema(this.schema, this.sourcePath, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
6126
6499
  }
6127
6500
  }, {
6128
6501
  key: "hidden",
6129
6502
  value: function hidden() {
6130
- return new KeyOfSchema(this.schema, this.sourcePath, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
6503
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6504
+ return new KeyOfSchema(this.schema, this.sourcePath, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
6131
6505
  }
6132
6506
  }, {
6133
6507
  key: "executeCustomValidateAt",
@@ -6464,12 +6838,14 @@ var FileSchema = /*#__PURE__*/function (_Schema) {
6464
6838
  }, {
6465
6839
  key: "readonly",
6466
6840
  value: function readonly() {
6467
- return new FileSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, true, this.isHidden, this.description, this.renderInput, this.previewInput);
6841
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6842
+ return new FileSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
6468
6843
  }
6469
6844
  }, {
6470
6845
  key: "hidden",
6471
6846
  value: function hidden() {
6472
- return new FileSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
6847
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
6848
+ return new FileSchema(this.options, this.opt, this.isRemote, this.customValidateFunctions, this.moduleMetadata, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
6473
6849
  }
6474
6850
  }, {
6475
6851
  key: "executeCustomValidateAt",
@@ -6743,12 +7119,14 @@ var DateSchema = /*#__PURE__*/function (_Schema) {
6743
7119
  }, {
6744
7120
  key: "readonly",
6745
7121
  value: function readonly() {
6746
- return new DateSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
7122
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7123
+ return new DateSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
6747
7124
  }
6748
7125
  }, {
6749
7126
  key: "hidden",
6750
7127
  value: function hidden() {
6751
- return new DateSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
7128
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7129
+ return new DateSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
6752
7130
  }
6753
7131
  }, {
6754
7132
  key: "executeCustomValidateAt",
@@ -6992,12 +7370,14 @@ var DateTimeSchema = /*#__PURE__*/function (_Schema) {
6992
7370
  }, {
6993
7371
  key: "readonly",
6994
7372
  value: function readonly() {
6995
- return new DateTimeSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
7373
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7374
+ return new DateTimeSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
6996
7375
  }
6997
7376
  }, {
6998
7377
  key: "hidden",
6999
7378
  value: function hidden() {
7000
- return new DateTimeSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
7379
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7380
+ return new DateTimeSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
7001
7381
  }
7002
7382
  }, {
7003
7383
  key: "executeCustomValidateAt",
@@ -7177,12 +7557,14 @@ var CodeSchema = /*#__PURE__*/function (_Schema) {
7177
7557
  }, {
7178
7558
  key: "readonly",
7179
7559
  value: function readonly() {
7180
- return new CodeSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
7560
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7561
+ return new CodeSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
7181
7562
  }
7182
7563
  }, {
7183
7564
  key: "hidden",
7184
7565
  value: function hidden() {
7185
- return new CodeSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
7566
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7567
+ return new CodeSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
7186
7568
  }
7187
7569
 
7188
7570
  /**
@@ -7863,12 +8245,14 @@ var ColorSchema = /*#__PURE__*/function (_Schema) {
7863
8245
  }, {
7864
8246
  key: "readonly",
7865
8247
  value: function readonly() {
7866
- return new ColorSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description, this.renderInput, this.previewInput);
8248
+ var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
8249
+ return new ColorSchema(this.options, this.opt, this.customValidateFunctions, isReadonly, this.isHidden, this.description, this.renderInput, this.previewInput);
7867
8250
  }
7868
8251
  }, {
7869
8252
  key: "hidden",
7870
8253
  value: function hidden() {
7871
- return new ColorSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description, this.renderInput, this.previewInput);
8254
+ var isHidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
8255
+ return new ColorSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, isHidden, this.description, this.renderInput, this.previewInput);
7872
8256
  }
7873
8257
 
7874
8258
  /**
@@ -8031,7 +8415,8 @@ function initSchema() {
8031
8415
  code: code,
8032
8416
  route: route,
8033
8417
  router: router,
8034
- images: images
8418
+ images: images,
8419
+ settings: settings
8035
8420
  // i18n: i18n(locales),
8036
8421
  };
8037
8422
  }
@@ -8432,6 +8817,98 @@ var getSHA256Hash = function getSHA256Hash(bits) {
8432
8817
  return createHash().update(bits).digest("hex");
8433
8818
  };
8434
8819
 
8820
+ /**
8821
+ * Where a settings module goes unless a project has a reason not to.
8822
+ *
8823
+ * A convention, not a rule: any module file path at the root of the content
8824
+ * tree may hold `s.settings()` — see {@link resolveSettingsModule}.
8825
+ */
8826
+ var SETTINGS_MODULE_CONVENTION = "/settings.val.ts";
8827
+
8828
+ /**
8829
+ * Whether a module file path is at the root of the content tree.
8830
+ *
8831
+ * `/settings.val.ts` is; `/content/settings.val.ts` is not. The settings module
8832
+ * is the project's, not a folder's, and a project-wide setting found three
8833
+ * directories down reads as one section's — so the position is part of what it
8834
+ * means.
8835
+ */
8836
+ function isRootModuleFilePath(moduleFilePath) {
8837
+ return moduleFilePath.startsWith("/") && !moduleFilePath.slice(1).includes("/");
8838
+ }
8839
+
8840
+ /**
8841
+ * Structurally an `ExtractedModuleError`, declared here rather than imported to
8842
+ * keep `extractValModules` -> `settingsModule` a one-way dependency.
8843
+ */
8844
+
8845
+ /**
8846
+ * Find the project's settings module among all its schemas.
8847
+ *
8848
+ * One per project, at the root: a settings module in a subdirectory is an
8849
+ * error, and so is a second one. Both are reported rather than resolved by
8850
+ * picking a winner — a project with two settings modules has a question to
8851
+ * answer, and answering it by sort order means the answer changes when a file
8852
+ * is renamed.
8853
+ */
8854
+ function resolveSettingsModule(schemas) {
8855
+ var rootModules = [];
8856
+ var nestedModules = [];
8857
+ var _iterator = result._createForOfIteratorHelper(Object.keys(schemas).sort()),
8858
+ _step;
8859
+ try {
8860
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
8861
+ var _schemas$_moduleFileP;
8862
+ var moduleFilePathS = _step.value;
8863
+ var _moduleFilePath2 = moduleFilePathS;
8864
+ if (((_schemas$_moduleFileP = schemas[_moduleFilePath2]) === null || _schemas$_moduleFileP === void 0 ? void 0 : _schemas$_moduleFileP.type) !== "settings") {
8865
+ continue;
8866
+ }
8867
+ if (isRootModuleFilePath(_moduleFilePath2)) {
8868
+ rootModules.push(_moduleFilePath2);
8869
+ } else {
8870
+ nestedModules.push(_moduleFilePath2);
8871
+ }
8872
+ }
8873
+ } catch (err) {
8874
+ _iterator.e(err);
8875
+ } finally {
8876
+ _iterator.f();
8877
+ }
8878
+ var errors = [];
8879
+ for (var _i = 0, _nestedModules = nestedModules; _i < _nestedModules.length; _i++) {
8880
+ var moduleFilePath = _nestedModules[_i];
8881
+ errors.push({
8882
+ path: moduleFilePath,
8883
+ message: "Settings must be defined at the root of the content tree, but s.settings() was found in '".concat(moduleFilePath, "'. Move it to a module file path with no directory in it, e.g. '").concat(SETTINGS_MODULE_CONVENTION, "'.")
8884
+ });
8885
+ }
8886
+ if (rootModules.length > 1) {
8887
+ var listed = rootModules.map(function (moduleFilePath) {
8888
+ return "'".concat(moduleFilePath, "'");
8889
+ }).join(" and ");
8890
+ var _iterator2 = result._createForOfIteratorHelper(rootModules),
8891
+ _step2;
8892
+ try {
8893
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
8894
+ var _moduleFilePath = _step2.value;
8895
+ errors.push({
8896
+ path: _moduleFilePath,
8897
+ message: "A project can only define settings once, but s.settings() was found in ".concat(listed, ". Keep one of them.")
8898
+ });
8899
+ }
8900
+ } catch (err) {
8901
+ _iterator2.e(err);
8902
+ } finally {
8903
+ _iterator2.f();
8904
+ }
8905
+ }
8906
+ return {
8907
+ moduleFilePath: errors.length === 0 && rootModules.length === 1 ? rootModules[0] : null,
8908
+ errors: errors
8909
+ };
8910
+ }
8911
+
8435
8912
  // Lazily constructed: this module is also evaluated inside the `vm` sandbox
8436
8913
  // used by loadValModules (when user val modules import @valbuild/core), and
8437
8914
  // that sandbox has no `TextEncoder` global. `hash()` is never called from
@@ -8599,7 +9076,7 @@ function extractValModules(_x) {
8599
9076
  }
8600
9077
  function _extractValModules() {
8601
9078
  _extractValModules = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(valModules) {
8602
- var moduleErrors, addModuleError, sources, schemas, serializedSchemas, shaEntries, moduleIdx, module, at, value, path, schema, source, serializedSchema, pathM, _t, _t2;
9079
+ var moduleErrors, addModuleError, sources, schemas, serializedSchemas, shaEntries, moduleIdx, module, at, value, path, schema, source, serializedSchema, pathM, _iterator2, _step2, error, _t, _t2;
8603
9080
  return _regenerator().w(function (_context) {
8604
9081
  while (1) switch (_context.p = _context.n) {
8605
9082
  case 0:
@@ -8738,6 +9215,25 @@ function _extractValModules() {
8738
9215
  _context.n = 1;
8739
9216
  break;
8740
9217
  case 18:
9218
+ // Settings is the one rule that cannot be checked while looking at a single
9219
+ // module: "one per project, at the root" is a statement about the whole set.
9220
+ // Reported here so that every consumer of extraction gets it — the dev
9221
+ // server, `val validate` and the Studio all read `moduleErrors`.
9222
+ //
9223
+ // Appended AFTER the loop on purpose: each entry's `moduleErrorsAt` is the
9224
+ // error count at the time it was folded in, so the SHAs stay a function of
9225
+ // the modules themselves.
9226
+ _iterator2 = result._createForOfIteratorHelper(resolveSettingsModule(serializedSchemas).errors);
9227
+ try {
9228
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
9229
+ error = _step2.value;
9230
+ moduleErrors.push(error);
9231
+ }
9232
+ } catch (err) {
9233
+ _iterator2.e(err);
9234
+ } finally {
9235
+ _iterator2.f();
9236
+ }
8741
9237
  return _context.a(2, _objectSpread2(_objectSpread2({
8742
9238
  sources: sources,
8743
9239
  schemas: schemas,
@@ -8809,7 +9305,10 @@ function hasRemoteFileSchema(schema) {
8809
9305
  return true;
8810
9306
  }
8811
9307
  return hasRemoteFileSchema(schema.item);
8812
- } else if (schema.type === "object") {
9308
+ } else if (schema.type === "object" || schema.type === "settings") {
9309
+ // Settings holds its sections the way an object holds its keys, so looking
9310
+ // inside is the same walk. Nothing in settings takes a file today, but the
9311
+ // answer should stay right when something does.
8813
9312
  for (var key in schema.items) {
8814
9313
  var hasRemoteFile = hasRemoteFileSchema(schema.items[key]);
8815
9314
  if (hasRemoteFile) {
@@ -9077,6 +9576,13 @@ function deserializeSchemaImpl(serialized) {
9077
9576
  item = _ref2[1];
9078
9577
  return [key, deserializeSchema(item)];
9079
9578
  })), serialized.opt, [], false, false, serialized.description, (_serialized$render5 = serialized.render) !== null && _serialized$render5 !== void 0 ? _serialized$render5 : null);
9579
+ case "settings":
9580
+ return new SettingsSchema(Object.fromEntries(Object.entries(serialized.items).map(function (_ref3) {
9581
+ var _ref4 = _slicedToArray(_ref3, 2),
9582
+ key = _ref4[0],
9583
+ item = _ref4[1];
9584
+ return [key, deserializeSchema(item)];
9585
+ })), serialized.opt, false, false, serialized.description);
9080
9586
  case "array":
9081
9587
  return new ArraySchema(deserializeSchema(serialized.item), serialized.opt, [], false, false, serialized.description,
9082
9588
  // The preview closure cannot survive serialization; the render can.
@@ -9734,6 +10240,7 @@ function tryJsonParse(str) {
9734
10240
  }
9735
10241
  }
9736
10242
 
10243
+ exports.ASSISTANT_SETTINGS_MAX_LENGTH = ASSISTANT_SETTINGS_MAX_LENGTH;
9737
10244
  exports.ArraySchema = ArraySchema;
9738
10245
  exports.BooleanSchema = BooleanSchema;
9739
10246
  exports.CODE_LANGUAGES = CODE_LANGUAGES;
@@ -9760,7 +10267,9 @@ exports.PatchError = PatchError;
9760
10267
  exports.RecordSchema = RecordSchema;
9761
10268
  exports.RichTextSchema = RichTextSchema;
9762
10269
  exports.RouteSchema = RouteSchema;
10270
+ exports.SETTINGS_MODULE_CONVENTION = SETTINGS_MODULE_CONVENTION;
9763
10271
  exports.Schema = Schema;
10272
+ exports.SettingsSchema = SettingsSchema;
9764
10273
  exports.StringSchema = StringSchema;
9765
10274
  exports.UnionSchema = UnionSchema;
9766
10275
  exports.VAL_EXTENSION = VAL_EXTENSION;
@@ -9769,6 +10278,7 @@ exports._createClass = _createClass;
9769
10278
  exports._slicedToArray = _slicedToArray;
9770
10279
  exports._toConsumableArray = _toConsumableArray;
9771
10280
  exports._typeof = _typeof;
10281
+ exports.assistantAvailability = assistantAvailability;
9772
10282
  exports.computeValModuleShas = computeValModuleShas;
9773
10283
  exports.derefPatch = derefPatch;
9774
10284
  exports.deserializeSchema = deserializeSchema;
@@ -9777,6 +10287,8 @@ exports.getSourcePathFromRoute = getSourcePathFromRoute;
9777
10287
  exports.hasRemoteFileSchema = hasRemoteFileSchema;
9778
10288
  exports.initVal = initVal;
9779
10289
  exports.isInlineRender = isInlineRender;
10290
+ exports.isRootModuleFilePath = isRootModuleFilePath;
9780
10291
  exports.modules = modules;
9781
10292
  exports.previewScope = previewScope;
10293
+ exports.resolveSettingsModule = resolveSettingsModule;
9782
10294
  exports.splitModuleFilePathAndModulePath = splitModuleFilePathAndModulePath;