regor 1.4.6 → 1.4.8

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.
@@ -206,7 +206,180 @@ var callUnmounted = (context) => {
206
206
  context.unmounted?.();
207
207
  };
208
208
 
209
+ // src/log/warnings.ts
210
+ var warnings = {
211
+ [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
212
+ [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
213
+ [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
214
+ [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
215
+ [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
216
+ [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
217
+ [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
218
+ msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
219
+ args: [e]
220
+ }),
221
+ [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
222
+ [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
223
+ };
224
+ var warning = (type, ...args) => {
225
+ const msg = warnings[type];
226
+ const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
227
+ const handler = warningHandler.warning;
228
+ if (!handler) return;
229
+ if (isString(item)) handler(item);
230
+ else handler(item, ...item.args);
231
+ };
232
+ var warningHandler = {
233
+ warning: console.warn
234
+ };
235
+
236
+ // src/reactivity/refSymbols.ts
237
+ var refSymbol = Symbol("ref");
238
+ var srefSymbol = Symbol("sref");
239
+ var rawSymbol = Symbol("raw");
240
+
241
+ // src/reactivity/isRef.ts
242
+ var isRef = (value) => {
243
+ return value != null && value[srefSymbol] === 1;
244
+ };
245
+
246
+ // src/app/propValidators.ts
247
+ var PropValidationError = class extends Error {
248
+ propPath;
249
+ detail;
250
+ constructor(propPath, detail) {
251
+ super(detail);
252
+ this.name = "PropValidationError";
253
+ this.propPath = propPath;
254
+ this.detail = detail;
255
+ }
256
+ };
257
+ var fail = (name, message) => {
258
+ throw new PropValidationError(name, `${message}.`);
259
+ };
260
+ var describeValue = (value) => {
261
+ if (value === null) return "null";
262
+ if (value === void 0) return "undefined";
263
+ if (typeof value === "string") return "string";
264
+ if (typeof value === "number") return "number";
265
+ if (typeof value === "boolean") return "boolean";
266
+ if (typeof value === "bigint") return "bigint";
267
+ if (typeof value === "symbol") return "symbol";
268
+ if (typeof value === "function") return "function";
269
+ if (isArray(value)) return "array";
270
+ if (value instanceof Date) return "Date";
271
+ if (value instanceof RegExp) return "RegExp";
272
+ if (value instanceof Map) return "Map";
273
+ if (value instanceof Set) return "Set";
274
+ const ctorName = value?.constructor?.name;
275
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
276
+ };
277
+ var formatLiteral = (value) => {
278
+ if (typeof value === "string") return `"${value}"`;
279
+ if (typeof value === "number" || typeof value === "boolean") {
280
+ return String(value);
281
+ }
282
+ if (value === null) return "null";
283
+ if (value === void 0) return "undefined";
284
+ return describeValue(value);
285
+ };
286
+ var isString2 = (value, name) => {
287
+ if (typeof value !== "string") fail(name, "expected string");
288
+ };
289
+ var isNumber = (value, name) => {
290
+ if (typeof value !== "number") fail(name, "expected number");
291
+ };
292
+ var isBoolean = (value, name) => {
293
+ if (typeof value !== "boolean") fail(name, "expected boolean");
294
+ };
295
+ var isClass = (ctor) => {
296
+ return (value, name) => {
297
+ if (!(value instanceof ctor)) {
298
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
299
+ }
300
+ };
301
+ };
302
+ var optional = (validator) => {
303
+ return (value, name, head) => {
304
+ if (value === void 0) return;
305
+ validator(value, name, head);
306
+ };
307
+ };
308
+ var nullable = (validator) => {
309
+ return (value, name, head) => {
310
+ if (value === null) return;
311
+ validator(value, name, head);
312
+ };
313
+ };
314
+ var oneOf = (values) => {
315
+ return (value, name) => {
316
+ if (values.includes(value)) return;
317
+ fail(
318
+ name,
319
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
320
+ );
321
+ };
322
+ };
323
+ var arrayOf = (validator) => {
324
+ return (value, name, head) => {
325
+ if (!isArray(value)) fail(name, "expected array");
326
+ const items = value;
327
+ for (let i = 0; i < items.length; ++i) {
328
+ validator(items[i], `${name}[${i}]`, head);
329
+ }
330
+ };
331
+ };
332
+ var shape = (schema) => {
333
+ return (value, name, head) => {
334
+ if (!isObject(value)) fail(name, "expected object");
335
+ const record = value;
336
+ for (const key in schema) {
337
+ const validator = schema[key];
338
+ validator(record[key], `${name}.${key}`, head);
339
+ }
340
+ };
341
+ };
342
+ var refOf = (validator) => {
343
+ return (value, name, head) => {
344
+ if (!isRef(value)) fail(name, "expected ref");
345
+ const refValue = value;
346
+ validator(refValue(), `${name}.value`, head);
347
+ };
348
+ };
349
+ var pval = {
350
+ fail,
351
+ isString: isString2,
352
+ isNumber,
353
+ isBoolean,
354
+ isClass,
355
+ optional,
356
+ nullable,
357
+ oneOf,
358
+ arrayOf,
359
+ shape,
360
+ refOf
361
+ };
362
+
209
363
  // src/app/ComponentHead.ts
364
+ var formatComponentValidationError = (element, propName, error) => {
365
+ const tagName = element.tagName?.toLowerCase?.() || "unknown";
366
+ const finalPropName = error instanceof PropValidationError ? error.propPath : propName;
367
+ const detail = error instanceof PropValidationError ? error.detail : error instanceof Error ? error.message : String(error);
368
+ if (error instanceof Error) {
369
+ return new Error(
370
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
371
+ {
372
+ cause: error
373
+ }
374
+ );
375
+ }
376
+ return new Error(
377
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
378
+ {
379
+ cause: error
380
+ }
381
+ );
382
+ };
210
383
  var ComponentHead = class {
211
384
  /**
212
385
  * Values provided by parent for this component instance.
@@ -294,12 +467,18 @@ var ComponentHead = class {
294
467
  * @internal
295
468
  */
296
469
  __element;
297
- constructor(props, element, ctx, start, end) {
470
+ /**
471
+ * Runtime behavior used when `validateProps(...)` encounters invalid input.
472
+ * Defaults to `'throw'`.
473
+ */
474
+ __propValidationMode;
475
+ constructor(props, element, ctx, start, end, propValidationMode) {
298
476
  this.props = props;
299
477
  this.__element = element;
300
478
  this.ctx = ctx;
301
479
  this.start = start;
302
480
  this.end = end;
481
+ this.__propValidationMode = propValidationMode;
303
482
  }
304
483
  /**
305
484
  * Emits a custom DOM event from the component host element.
@@ -379,7 +558,7 @@ var ComponentHead = class {
379
558
  );
380
559
  }
381
560
  /**
382
- * Validates selected incoming props using assertion-style validators.
561
+ * Validates selected incoming props at runtime.
383
562
  *
384
563
  * Only keys listed in `schema` are checked. Validation throws immediately
385
564
  * on the first invalid prop and does not mutate `head.props`.
@@ -388,7 +567,8 @@ var ComponentHead = class {
388
567
  * known prop names while still allowing you to validate only a subset.
389
568
  *
390
569
  * Validators typically come from `pval`, but custom user validators are also
391
- * supported.
570
+ * supported. Custom validators may throw their own `Error`, though `pval.fail(...)`
571
+ * is recommended so nested validators can preserve the exact failing prop path.
392
572
  *
393
573
  * Example:
394
574
  * ```ts
@@ -398,15 +578,38 @@ var ComponentHead = class {
398
578
  * })
399
579
  * ```
400
580
  *
581
+ * Example with a custom validator:
582
+ * ```ts
583
+ * const isNonEmptyString: PropValidator<string> = (value, name) => {
584
+ * if (typeof value !== 'string' || value.trim() === '') {
585
+ * pval.fail(name, 'expected non-empty string')
586
+ * }
587
+ * }
588
+ * ```
589
+ *
401
590
  * @param schema - Validators to apply to selected incoming props.
402
591
  */
403
592
  validateProps(schema) {
593
+ if (this.__propValidationMode === "off") return;
404
594
  const props = this.props;
405
595
  for (const name in schema) {
406
596
  const validator = schema[name];
407
597
  if (!validator) continue;
408
598
  const validateProp = validator;
409
- validateProp(props[name], name, this);
599
+ try {
600
+ validateProp(props[name], name, this);
601
+ } catch (error) {
602
+ const enrichedError = formatComponentValidationError(
603
+ this.__element,
604
+ name,
605
+ error
606
+ );
607
+ if (this.__propValidationMode === "warn") {
608
+ warningHandler.warning(enrichedError.message, enrichedError);
609
+ continue;
610
+ }
611
+ throw enrichedError;
612
+ }
410
613
  }
411
614
  }
412
615
  /**
@@ -442,33 +645,6 @@ var addUnbinder = (node, unbinder) => {
442
645
  getBindData(node).unbinders.push(unbinder);
443
646
  };
444
647
 
445
- // src/log/warnings.ts
446
- var warnings = {
447
- [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
448
- [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
449
- [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
450
- [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
451
- [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
452
- [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
453
- [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
454
- msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
455
- args: [e]
456
- }),
457
- [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
458
- [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
459
- };
460
- var warning = (type, ...args) => {
461
- const msg = warnings[type];
462
- const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
463
- const handler = warningHandler.warning;
464
- if (!handler) return;
465
- if (isString(item)) handler(item);
466
- else handler(item, ...item.args);
467
- };
468
- var warningHandler = {
469
- warning: console.warn
470
- };
471
-
472
648
  // src/bind/switch.ts
473
649
  var switches = {};
474
650
  var switchCounter = {};
@@ -872,16 +1048,6 @@ var isScope = (value) => {
872
1048
  return scopeSymbol2 in value;
873
1049
  };
874
1050
 
875
- // src/reactivity/refSymbols.ts
876
- var refSymbol = Symbol("ref");
877
- var srefSymbol = Symbol("sref");
878
- var rawSymbol = Symbol("raw");
879
-
880
- // src/reactivity/isRef.ts
881
- var isRef = (value) => {
882
- return value != null && value[srefSymbol] === 1;
883
- };
884
-
885
1051
  // src/directives/context.ts
886
1052
  var contextDirective = {
887
1053
  collectRefObj: true,
@@ -1449,7 +1615,8 @@ var ComponentBinder = class {
1449
1615
  component,
1450
1616
  capturedContext,
1451
1617
  startOfComponent,
1452
- endOfComponent
1618
+ endOfComponent,
1619
+ binder.__config.propValidationMode
1453
1620
  );
1454
1621
  const componentCtx2 = useScope(() => {
1455
1622
  return registeredComponent.context(head2) ?? {};
@@ -3863,6 +4030,15 @@ var RegorConfig = class _RegorConfig {
3863
4030
  forGrowThreshold = 10;
3864
4031
  globalContext;
3865
4032
  useInterpolation = true;
4033
+ /**
4034
+ * Controls how `head.validateProps(...)` behaves when a validator fails.
4035
+ *
4036
+ * - `'throw'` (default): rethrows the validation error immediately.
4037
+ * - `'warn'`: forwards the validation error to `warningHandler.warning(...)`
4038
+ * and continues.
4039
+ * - `'off'`: skips runtime prop validation entirely.
4040
+ */
4041
+ propValidationMode = "throw";
3866
4042
  constructor(globalContext) {
3867
4043
  this.setDirectives("r-");
3868
4044
  if (globalContext) {
@@ -6114,112 +6290,6 @@ var defineComponent = (template, options = {}) => {
6114
6290
  };
6115
6291
  };
6116
6292
 
6117
- // src/app/propValidators.ts
6118
- var fail = (name, message) => {
6119
- throw new Error(`Invalid prop "${name}": ${message}.`);
6120
- };
6121
- var describeValue = (value) => {
6122
- if (value === null) return "null";
6123
- if (value === void 0) return "undefined";
6124
- if (typeof value === "string") return "string";
6125
- if (typeof value === "number") return "number";
6126
- if (typeof value === "boolean") return "boolean";
6127
- if (typeof value === "bigint") return "bigint";
6128
- if (typeof value === "symbol") return "symbol";
6129
- if (typeof value === "function") return "function";
6130
- if (isArray(value)) return "array";
6131
- if (value instanceof Date) return "Date";
6132
- if (value instanceof RegExp) return "RegExp";
6133
- if (value instanceof Map) return "Map";
6134
- if (value instanceof Set) return "Set";
6135
- const ctorName = value?.constructor?.name;
6136
- return ctorName && ctorName !== "Object" ? ctorName : "object";
6137
- };
6138
- var formatLiteral = (value) => {
6139
- if (typeof value === "string") return `"${value}"`;
6140
- if (typeof value === "number" || typeof value === "boolean") {
6141
- return String(value);
6142
- }
6143
- if (value === null) return "null";
6144
- if (value === void 0) return "undefined";
6145
- return describeValue(value);
6146
- };
6147
- var isString2 = (value, name) => {
6148
- if (typeof value !== "string") fail(name, "expected string");
6149
- };
6150
- var isNumber = (value, name) => {
6151
- if (typeof value !== "number") fail(name, "expected number");
6152
- };
6153
- var isBoolean = (value, name) => {
6154
- if (typeof value !== "boolean") fail(name, "expected boolean");
6155
- };
6156
- var isClass = (ctor) => {
6157
- return (value, name) => {
6158
- if (!(value instanceof ctor)) {
6159
- fail(name, `expected instance of ${ctor.name || "provided class"}`);
6160
- }
6161
- };
6162
- };
6163
- var optional = (validator) => {
6164
- return (value, name, head) => {
6165
- if (value === void 0) return;
6166
- validator(value, name, head);
6167
- };
6168
- };
6169
- var nullable = (validator) => {
6170
- return (value, name, head) => {
6171
- if (value === null) return;
6172
- validator(value, name, head);
6173
- };
6174
- };
6175
- var oneOf = (values) => {
6176
- return (value, name) => {
6177
- if (values.includes(value)) return;
6178
- fail(
6179
- name,
6180
- `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6181
- );
6182
- };
6183
- };
6184
- var arrayOf = (validator) => {
6185
- return (value, name, head) => {
6186
- if (!isArray(value)) fail(name, "expected array");
6187
- const items = value;
6188
- for (let i = 0; i < items.length; ++i) {
6189
- validator(items[i], `${name}[${i}]`, head);
6190
- }
6191
- };
6192
- };
6193
- var shape = (schema) => {
6194
- return (value, name, head) => {
6195
- if (!isObject(value)) fail(name, "expected object");
6196
- const record = value;
6197
- for (const key in schema) {
6198
- const validator = schema[key];
6199
- validator(record[key], `${name}.${key}`, head);
6200
- }
6201
- };
6202
- };
6203
- var refOf = (validator) => {
6204
- return (value, name, head) => {
6205
- if (!isRef(value)) fail(name, "expected ref");
6206
- const refValue = value;
6207
- validator(refValue(), `${name}.value`, head);
6208
- };
6209
- };
6210
- var pval = {
6211
- isString: isString2,
6212
- isNumber,
6213
- isBoolean,
6214
- isClass,
6215
- optional,
6216
- nullable,
6217
- oneOf,
6218
- arrayOf,
6219
- shape,
6220
- refOf
6221
- };
6222
-
6223
6293
  // src/composition/ContextRegistry.ts
6224
6294
  var ContextRegistry = class {
6225
6295
  byConstructor = /* @__PURE__ */ new Map();