regor 1.4.6 → 1.4.7

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.
@@ -246,9 +246,184 @@ var Regor = (() => {
246
246
  (_b = context.unmounted) == null ? void 0 : _b.call(context);
247
247
  };
248
248
 
249
+ // src/log/warnings.ts
250
+ var warnings = {
251
+ [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
252
+ [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
253
+ [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
254
+ [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
255
+ [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
256
+ [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
257
+ [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
258
+ msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
259
+ args: [e]
260
+ }),
261
+ [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
262
+ [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
263
+ };
264
+ var warning = (type, ...args) => {
265
+ const msg = warnings[type];
266
+ const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
267
+ const handler = warningHandler.warning;
268
+ if (!handler) return;
269
+ if (isString(item)) handler(item);
270
+ else handler(item, ...item.args);
271
+ };
272
+ var warningHandler = {
273
+ warning: console.warn
274
+ };
275
+
276
+ // src/reactivity/refSymbols.ts
277
+ var refSymbol = Symbol("ref");
278
+ var srefSymbol = Symbol("sref");
279
+ var rawSymbol = Symbol("raw");
280
+
281
+ // src/reactivity/isRef.ts
282
+ var isRef = (value) => {
283
+ return value != null && value[srefSymbol] === 1;
284
+ };
285
+
286
+ // src/app/propValidators.ts
287
+ var PropValidationError = class extends Error {
288
+ constructor(propPath, detail) {
289
+ super(detail);
290
+ __publicField(this, "propPath");
291
+ __publicField(this, "detail");
292
+ this.name = "PropValidationError";
293
+ this.propPath = propPath;
294
+ this.detail = detail;
295
+ }
296
+ };
297
+ var fail = (name, message) => {
298
+ throw new PropValidationError(name, `${message}.`);
299
+ };
300
+ var describeValue = (value) => {
301
+ var _a;
302
+ if (value === null) return "null";
303
+ if (value === void 0) return "undefined";
304
+ if (typeof value === "string") return "string";
305
+ if (typeof value === "number") return "number";
306
+ if (typeof value === "boolean") return "boolean";
307
+ if (typeof value === "bigint") return "bigint";
308
+ if (typeof value === "symbol") return "symbol";
309
+ if (typeof value === "function") return "function";
310
+ if (isArray(value)) return "array";
311
+ if (value instanceof Date) return "Date";
312
+ if (value instanceof RegExp) return "RegExp";
313
+ if (value instanceof Map) return "Map";
314
+ if (value instanceof Set) return "Set";
315
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
316
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
317
+ };
318
+ var formatLiteral = (value) => {
319
+ if (typeof value === "string") return `"${value}"`;
320
+ if (typeof value === "number" || typeof value === "boolean") {
321
+ return String(value);
322
+ }
323
+ if (value === null) return "null";
324
+ if (value === void 0) return "undefined";
325
+ return describeValue(value);
326
+ };
327
+ var isString2 = (value, name) => {
328
+ if (typeof value !== "string") fail(name, "expected string");
329
+ };
330
+ var isNumber = (value, name) => {
331
+ if (typeof value !== "number") fail(name, "expected number");
332
+ };
333
+ var isBoolean = (value, name) => {
334
+ if (typeof value !== "boolean") fail(name, "expected boolean");
335
+ };
336
+ var isClass = (ctor) => {
337
+ return (value, name) => {
338
+ if (!(value instanceof ctor)) {
339
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
340
+ }
341
+ };
342
+ };
343
+ var optional = (validator) => {
344
+ return (value, name, head) => {
345
+ if (value === void 0) return;
346
+ validator(value, name, head);
347
+ };
348
+ };
349
+ var nullable = (validator) => {
350
+ return (value, name, head) => {
351
+ if (value === null) return;
352
+ validator(value, name, head);
353
+ };
354
+ };
355
+ var oneOf = (values) => {
356
+ return (value, name) => {
357
+ if (values.includes(value)) return;
358
+ fail(
359
+ name,
360
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
361
+ );
362
+ };
363
+ };
364
+ var arrayOf = (validator) => {
365
+ return (value, name, head) => {
366
+ if (!isArray(value)) fail(name, "expected array");
367
+ const items = value;
368
+ for (let i = 0; i < items.length; ++i) {
369
+ validator(items[i], `${name}[${i}]`, head);
370
+ }
371
+ };
372
+ };
373
+ var shape = (schema) => {
374
+ return (value, name, head) => {
375
+ if (!isObject(value)) fail(name, "expected object");
376
+ const record = value;
377
+ for (const key in schema) {
378
+ const validator = schema[key];
379
+ validator(record[key], `${name}.${key}`, head);
380
+ }
381
+ };
382
+ };
383
+ var refOf = (validator) => {
384
+ return (value, name, head) => {
385
+ if (!isRef(value)) fail(name, "expected ref");
386
+ const refValue = value;
387
+ validator(refValue(), `${name}.value`, head);
388
+ };
389
+ };
390
+ var pval = {
391
+ fail,
392
+ isString: isString2,
393
+ isNumber,
394
+ isBoolean,
395
+ isClass,
396
+ optional,
397
+ nullable,
398
+ oneOf,
399
+ arrayOf,
400
+ shape,
401
+ refOf
402
+ };
403
+
249
404
  // src/app/ComponentHead.ts
405
+ var formatComponentValidationError = (element, propName, error) => {
406
+ var _a, _b;
407
+ const tagName = ((_b = (_a = element.tagName) == null ? void 0 : _a.toLowerCase) == null ? void 0 : _b.call(_a)) || "unknown";
408
+ const finalPropName = error instanceof PropValidationError ? error.propPath : propName;
409
+ const detail = error instanceof PropValidationError ? error.detail : error instanceof Error ? error.message : String(error);
410
+ if (error instanceof Error) {
411
+ return new Error(
412
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
413
+ {
414
+ cause: error
415
+ }
416
+ );
417
+ }
418
+ return new Error(
419
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
420
+ {
421
+ cause: error
422
+ }
423
+ );
424
+ };
250
425
  var ComponentHead = class {
251
- constructor(props, element, ctx, start, end) {
426
+ constructor(props, element, ctx, start, end, propValidationMode) {
252
427
  /**
253
428
  * Values provided by parent for this component instance.
254
429
  *
@@ -335,6 +510,11 @@ var Regor = (() => {
335
510
  * @internal
336
511
  */
337
512
  __publicField(this, "__element");
513
+ /**
514
+ * Runtime behavior used when `validateProps(...)` encounters invalid input.
515
+ * Defaults to `'throw'`.
516
+ */
517
+ __publicField(this, "__propValidationMode");
338
518
  /**
339
519
  * Emits a custom DOM event from the component host element.
340
520
  *
@@ -358,6 +538,7 @@ var Regor = (() => {
358
538
  this.ctx = ctx;
359
539
  this.start = start;
360
540
  this.end = end;
541
+ this.__propValidationMode = propValidationMode;
361
542
  }
362
543
  /**
363
544
  * Finds a parent context instance by constructor type from the captured
@@ -429,7 +610,8 @@ var Regor = (() => {
429
610
  * known prop names while still allowing you to validate only a subset.
430
611
  *
431
612
  * Validators typically come from `pval`, but custom user validators are also
432
- * supported.
613
+ * supported. Custom validators may throw their own `Error`, though `pval.fail(...)`
614
+ * is recommended so nested validators can preserve the exact failing prop path.
433
615
  *
434
616
  * Example:
435
617
  * ```ts
@@ -439,15 +621,38 @@ var Regor = (() => {
439
621
  * })
440
622
  * ```
441
623
  *
624
+ * Example with a custom validator:
625
+ * ```ts
626
+ * const isNonEmptyString: PropValidator<string> = (value, name) => {
627
+ * if (typeof value !== 'string' || value.trim() === '') {
628
+ * pval.fail(name, 'expected non-empty string')
629
+ * }
630
+ * }
631
+ * ```
632
+ *
442
633
  * @param schema - Validators to apply to selected incoming props.
443
634
  */
444
635
  validateProps(schema) {
636
+ if (this.__propValidationMode === "off") return;
445
637
  const props = this.props;
446
638
  for (const name in schema) {
447
639
  const validator = schema[name];
448
640
  if (!validator) continue;
449
641
  const validateProp = validator;
450
- validateProp(props[name], name, this);
642
+ try {
643
+ validateProp(props[name], name, this);
644
+ } catch (error) {
645
+ const enrichedError = formatComponentValidationError(
646
+ this.__element,
647
+ name,
648
+ error
649
+ );
650
+ if (this.__propValidationMode === "warn") {
651
+ warningHandler.warning(enrichedError.message, enrichedError);
652
+ continue;
653
+ }
654
+ throw enrichedError;
655
+ }
451
656
  }
452
657
  }
453
658
  /**
@@ -483,33 +688,6 @@ var Regor = (() => {
483
688
  getBindData(node).unbinders.push(unbinder);
484
689
  };
485
690
 
486
- // src/log/warnings.ts
487
- var warnings = {
488
- [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
489
- [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
490
- [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
491
- [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
492
- [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
493
- [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
494
- [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
495
- msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
496
- args: [e]
497
- }),
498
- [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
499
- [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
500
- };
501
- var warning = (type, ...args) => {
502
- const msg = warnings[type];
503
- const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
504
- const handler = warningHandler.warning;
505
- if (!handler) return;
506
- if (isString(item)) handler(item);
507
- else handler(item, ...item.args);
508
- };
509
- var warningHandler = {
510
- warning: console.warn
511
- };
512
-
513
691
  // src/bind/switch.ts
514
692
  var switches = {};
515
693
  var switchCounter = {};
@@ -915,16 +1093,6 @@ var Regor = (() => {
915
1093
  return scopeSymbol2 in value;
916
1094
  };
917
1095
 
918
- // src/reactivity/refSymbols.ts
919
- var refSymbol = Symbol("ref");
920
- var srefSymbol = Symbol("sref");
921
- var rawSymbol = Symbol("raw");
922
-
923
- // src/reactivity/isRef.ts
924
- var isRef = (value) => {
925
- return value != null && value[srefSymbol] === 1;
926
- };
927
-
928
1096
  // src/directives/context.ts
929
1097
  var contextDirective = {
930
1098
  collectRefObj: true,
@@ -1497,7 +1665,8 @@ var Regor = (() => {
1497
1665
  component,
1498
1666
  capturedContext,
1499
1667
  startOfComponent,
1500
- endOfComponent
1668
+ endOfComponent,
1669
+ binder.__config.propValidationMode
1501
1670
  );
1502
1671
  const componentCtx2 = useScope(() => {
1503
1672
  var _a2;
@@ -3925,6 +4094,15 @@ var Regor = (() => {
3925
4094
  __publicField(this, "forGrowThreshold", 10);
3926
4095
  __publicField(this, "globalContext");
3927
4096
  __publicField(this, "useInterpolation", true);
4097
+ /**
4098
+ * Controls how `head.validateProps(...)` behaves when a validator fails.
4099
+ *
4100
+ * - `'throw'` (default): rethrows the validation error immediately.
4101
+ * - `'warn'`: forwards the validation error to `warningHandler.warning(...)`
4102
+ * and continues.
4103
+ * - `'off'`: skips runtime prop validation entirely.
4104
+ */
4105
+ __publicField(this, "propValidationMode", "throw");
3928
4106
  this.setDirectives("r-");
3929
4107
  if (globalContext) {
3930
4108
  this.globalContext = globalContext;
@@ -6206,113 +6384,6 @@ var Regor = (() => {
6206
6384
  };
6207
6385
  };
6208
6386
 
6209
- // src/app/propValidators.ts
6210
- var fail = (name, message) => {
6211
- throw new Error(`Invalid prop "${name}": ${message}.`);
6212
- };
6213
- var describeValue = (value) => {
6214
- var _a;
6215
- if (value === null) return "null";
6216
- if (value === void 0) return "undefined";
6217
- if (typeof value === "string") return "string";
6218
- if (typeof value === "number") return "number";
6219
- if (typeof value === "boolean") return "boolean";
6220
- if (typeof value === "bigint") return "bigint";
6221
- if (typeof value === "symbol") return "symbol";
6222
- if (typeof value === "function") return "function";
6223
- if (isArray(value)) return "array";
6224
- if (value instanceof Date) return "Date";
6225
- if (value instanceof RegExp) return "RegExp";
6226
- if (value instanceof Map) return "Map";
6227
- if (value instanceof Set) return "Set";
6228
- const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6229
- return ctorName && ctorName !== "Object" ? ctorName : "object";
6230
- };
6231
- var formatLiteral = (value) => {
6232
- if (typeof value === "string") return `"${value}"`;
6233
- if (typeof value === "number" || typeof value === "boolean") {
6234
- return String(value);
6235
- }
6236
- if (value === null) return "null";
6237
- if (value === void 0) return "undefined";
6238
- return describeValue(value);
6239
- };
6240
- var isString2 = (value, name) => {
6241
- if (typeof value !== "string") fail(name, "expected string");
6242
- };
6243
- var isNumber = (value, name) => {
6244
- if (typeof value !== "number") fail(name, "expected number");
6245
- };
6246
- var isBoolean = (value, name) => {
6247
- if (typeof value !== "boolean") fail(name, "expected boolean");
6248
- };
6249
- var isClass = (ctor) => {
6250
- return (value, name) => {
6251
- if (!(value instanceof ctor)) {
6252
- fail(name, `expected instance of ${ctor.name || "provided class"}`);
6253
- }
6254
- };
6255
- };
6256
- var optional = (validator) => {
6257
- return (value, name, head) => {
6258
- if (value === void 0) return;
6259
- validator(value, name, head);
6260
- };
6261
- };
6262
- var nullable = (validator) => {
6263
- return (value, name, head) => {
6264
- if (value === null) return;
6265
- validator(value, name, head);
6266
- };
6267
- };
6268
- var oneOf = (values) => {
6269
- return (value, name) => {
6270
- if (values.includes(value)) return;
6271
- fail(
6272
- name,
6273
- `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6274
- );
6275
- };
6276
- };
6277
- var arrayOf = (validator) => {
6278
- return (value, name, head) => {
6279
- if (!isArray(value)) fail(name, "expected array");
6280
- const items = value;
6281
- for (let i = 0; i < items.length; ++i) {
6282
- validator(items[i], `${name}[${i}]`, head);
6283
- }
6284
- };
6285
- };
6286
- var shape = (schema) => {
6287
- return (value, name, head) => {
6288
- if (!isObject(value)) fail(name, "expected object");
6289
- const record = value;
6290
- for (const key in schema) {
6291
- const validator = schema[key];
6292
- validator(record[key], `${name}.${key}`, head);
6293
- }
6294
- };
6295
- };
6296
- var refOf = (validator) => {
6297
- return (value, name, head) => {
6298
- if (!isRef(value)) fail(name, "expected ref");
6299
- const refValue = value;
6300
- validator(refValue(), `${name}.value`, head);
6301
- };
6302
- };
6303
- var pval = {
6304
- isString: isString2,
6305
- isNumber,
6306
- isBoolean,
6307
- isClass,
6308
- optional,
6309
- nullable,
6310
- oneOf,
6311
- arrayOf,
6312
- shape,
6313
- refOf
6314
- };
6315
-
6316
6387
  // src/composition/ContextRegistry.ts
6317
6388
  var ContextRegistry = class {
6318
6389
  constructor() {