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