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.
@@ -209,9 +209,184 @@ var Regor = (() => {
209
209
  (_b = context.unmounted) == null ? void 0 : _b.call(context);
210
210
  };
211
211
 
212
+ // src/log/warnings.ts
213
+ var warnings = {
214
+ [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
215
+ [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
216
+ [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
217
+ [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
218
+ [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
219
+ [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
220
+ [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
221
+ msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
222
+ args: [e]
223
+ }),
224
+ [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
225
+ [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
226
+ };
227
+ var warning = (type, ...args) => {
228
+ const msg = warnings[type];
229
+ const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
230
+ const handler = warningHandler.warning;
231
+ if (!handler) return;
232
+ if (isString(item)) handler(item);
233
+ else handler(item, ...item.args);
234
+ };
235
+ var warningHandler = {
236
+ warning: console.warn
237
+ };
238
+
239
+ // src/reactivity/refSymbols.ts
240
+ var refSymbol = Symbol("ref");
241
+ var srefSymbol = Symbol("sref");
242
+ var rawSymbol = Symbol("raw");
243
+
244
+ // src/reactivity/isRef.ts
245
+ var isRef = (value) => {
246
+ return value != null && value[srefSymbol] === 1;
247
+ };
248
+
249
+ // src/app/propValidators.ts
250
+ var PropValidationError = class extends Error {
251
+ constructor(propPath, detail) {
252
+ super(detail);
253
+ __publicField(this, "propPath");
254
+ __publicField(this, "detail");
255
+ this.name = "PropValidationError";
256
+ this.propPath = propPath;
257
+ this.detail = detail;
258
+ }
259
+ };
260
+ var fail = (name, message) => {
261
+ throw new PropValidationError(name, `${message}.`);
262
+ };
263
+ var describeValue = (value) => {
264
+ var _a;
265
+ if (value === null) return "null";
266
+ if (value === void 0) return "undefined";
267
+ if (typeof value === "string") return "string";
268
+ if (typeof value === "number") return "number";
269
+ if (typeof value === "boolean") return "boolean";
270
+ if (typeof value === "bigint") return "bigint";
271
+ if (typeof value === "symbol") return "symbol";
272
+ if (typeof value === "function") return "function";
273
+ if (isArray(value)) return "array";
274
+ if (value instanceof Date) return "Date";
275
+ if (value instanceof RegExp) return "RegExp";
276
+ if (value instanceof Map) return "Map";
277
+ if (value instanceof Set) return "Set";
278
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
279
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
280
+ };
281
+ var formatLiteral = (value) => {
282
+ if (typeof value === "string") return `"${value}"`;
283
+ if (typeof value === "number" || typeof value === "boolean") {
284
+ return String(value);
285
+ }
286
+ if (value === null) return "null";
287
+ if (value === void 0) return "undefined";
288
+ return describeValue(value);
289
+ };
290
+ var isString2 = (value, name) => {
291
+ if (typeof value !== "string") fail(name, "expected string");
292
+ };
293
+ var isNumber = (value, name) => {
294
+ if (typeof value !== "number") fail(name, "expected number");
295
+ };
296
+ var isBoolean = (value, name) => {
297
+ if (typeof value !== "boolean") fail(name, "expected boolean");
298
+ };
299
+ var isClass = (ctor) => {
300
+ return (value, name) => {
301
+ if (!(value instanceof ctor)) {
302
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
303
+ }
304
+ };
305
+ };
306
+ var optional = (validator) => {
307
+ return (value, name, head) => {
308
+ if (value === void 0) return;
309
+ validator(value, name, head);
310
+ };
311
+ };
312
+ var nullable = (validator) => {
313
+ return (value, name, head) => {
314
+ if (value === null) return;
315
+ validator(value, name, head);
316
+ };
317
+ };
318
+ var oneOf = (values) => {
319
+ return (value, name) => {
320
+ if (values.includes(value)) return;
321
+ fail(
322
+ name,
323
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
324
+ );
325
+ };
326
+ };
327
+ var arrayOf = (validator) => {
328
+ return (value, name, head) => {
329
+ if (!isArray(value)) fail(name, "expected array");
330
+ const items = value;
331
+ for (let i = 0; i < items.length; ++i) {
332
+ validator(items[i], `${name}[${i}]`, head);
333
+ }
334
+ };
335
+ };
336
+ var shape = (schema) => {
337
+ return (value, name, head) => {
338
+ if (!isObject(value)) fail(name, "expected object");
339
+ const record = value;
340
+ for (const key in schema) {
341
+ const validator = schema[key];
342
+ validator(record[key], `${name}.${key}`, head);
343
+ }
344
+ };
345
+ };
346
+ var refOf = (validator) => {
347
+ return (value, name, head) => {
348
+ if (!isRef(value)) fail(name, "expected ref");
349
+ const refValue = value;
350
+ validator(refValue(), `${name}.value`, head);
351
+ };
352
+ };
353
+ var pval = {
354
+ fail,
355
+ isString: isString2,
356
+ isNumber,
357
+ isBoolean,
358
+ isClass,
359
+ optional,
360
+ nullable,
361
+ oneOf,
362
+ arrayOf,
363
+ shape,
364
+ refOf
365
+ };
366
+
212
367
  // src/app/ComponentHead.ts
368
+ var formatComponentValidationError = (element, propName, error) => {
369
+ var _a, _b;
370
+ const tagName = ((_b = (_a = element.tagName) == null ? void 0 : _a.toLowerCase) == null ? void 0 : _b.call(_a)) || "unknown";
371
+ const finalPropName = error instanceof PropValidationError ? error.propPath : propName;
372
+ const detail = error instanceof PropValidationError ? error.detail : error instanceof Error ? error.message : String(error);
373
+ if (error instanceof Error) {
374
+ return new Error(
375
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
376
+ {
377
+ cause: error
378
+ }
379
+ );
380
+ }
381
+ return new Error(
382
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
383
+ {
384
+ cause: error
385
+ }
386
+ );
387
+ };
213
388
  var ComponentHead = class {
214
- constructor(props, element, ctx, start, end) {
389
+ constructor(props, element, ctx, start, end, propValidationMode) {
215
390
  /**
216
391
  * Values provided by parent for this component instance.
217
392
  *
@@ -298,6 +473,11 @@ var Regor = (() => {
298
473
  * @internal
299
474
  */
300
475
  __publicField(this, "__element");
476
+ /**
477
+ * Runtime behavior used when `validateProps(...)` encounters invalid input.
478
+ * Defaults to `'throw'`.
479
+ */
480
+ __publicField(this, "__propValidationMode");
301
481
  /**
302
482
  * Emits a custom DOM event from the component host element.
303
483
  *
@@ -321,6 +501,7 @@ var Regor = (() => {
321
501
  this.ctx = ctx;
322
502
  this.start = start;
323
503
  this.end = end;
504
+ this.__propValidationMode = propValidationMode;
324
505
  }
325
506
  /**
326
507
  * Finds a parent context instance by constructor type from the captured
@@ -383,7 +564,7 @@ var Regor = (() => {
383
564
  );
384
565
  }
385
566
  /**
386
- * Validates selected incoming props using assertion-style validators.
567
+ * Validates selected incoming props at runtime.
387
568
  *
388
569
  * Only keys listed in `schema` are checked. Validation throws immediately
389
570
  * on the first invalid prop and does not mutate `head.props`.
@@ -392,7 +573,8 @@ var Regor = (() => {
392
573
  * known prop names while still allowing you to validate only a subset.
393
574
  *
394
575
  * Validators typically come from `pval`, but custom user validators are also
395
- * supported.
576
+ * supported. Custom validators may throw their own `Error`, though `pval.fail(...)`
577
+ * is recommended so nested validators can preserve the exact failing prop path.
396
578
  *
397
579
  * Example:
398
580
  * ```ts
@@ -402,15 +584,38 @@ var Regor = (() => {
402
584
  * })
403
585
  * ```
404
586
  *
587
+ * Example with a custom validator:
588
+ * ```ts
589
+ * const isNonEmptyString: PropValidator<string> = (value, name) => {
590
+ * if (typeof value !== 'string' || value.trim() === '') {
591
+ * pval.fail(name, 'expected non-empty string')
592
+ * }
593
+ * }
594
+ * ```
595
+ *
405
596
  * @param schema - Validators to apply to selected incoming props.
406
597
  */
407
598
  validateProps(schema) {
599
+ if (this.__propValidationMode === "off") return;
408
600
  const props = this.props;
409
601
  for (const name in schema) {
410
602
  const validator = schema[name];
411
603
  if (!validator) continue;
412
604
  const validateProp = validator;
413
- validateProp(props[name], name, this);
605
+ try {
606
+ validateProp(props[name], name, this);
607
+ } catch (error) {
608
+ const enrichedError = formatComponentValidationError(
609
+ this.__element,
610
+ name,
611
+ error
612
+ );
613
+ if (this.__propValidationMode === "warn") {
614
+ warningHandler.warning(enrichedError.message, enrichedError);
615
+ continue;
616
+ }
617
+ throw enrichedError;
618
+ }
414
619
  }
415
620
  }
416
621
  /**
@@ -446,33 +651,6 @@ var Regor = (() => {
446
651
  getBindData(node).unbinders.push(unbinder);
447
652
  };
448
653
 
449
- // src/log/warnings.ts
450
- var warnings = {
451
- [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
452
- [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
453
- [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
454
- [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
455
- [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
456
- [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
457
- [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
458
- msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
459
- args: [e]
460
- }),
461
- [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
462
- [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
463
- };
464
- var warning = (type, ...args) => {
465
- const msg = warnings[type];
466
- const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
467
- const handler = warningHandler.warning;
468
- if (!handler) return;
469
- if (isString(item)) handler(item);
470
- else handler(item, ...item.args);
471
- };
472
- var warningHandler = {
473
- warning: console.warn
474
- };
475
-
476
654
  // src/bind/switch.ts
477
655
  var switches = {};
478
656
  var switchCounter = {};
@@ -878,16 +1056,6 @@ var Regor = (() => {
878
1056
  return scopeSymbol2 in value;
879
1057
  };
880
1058
 
881
- // src/reactivity/refSymbols.ts
882
- var refSymbol = Symbol("ref");
883
- var srefSymbol = Symbol("sref");
884
- var rawSymbol = Symbol("raw");
885
-
886
- // src/reactivity/isRef.ts
887
- var isRef = (value) => {
888
- return value != null && value[srefSymbol] === 1;
889
- };
890
-
891
1059
  // src/directives/context.ts
892
1060
  var contextDirective = {
893
1061
  collectRefObj: true,
@@ -1460,7 +1628,8 @@ var Regor = (() => {
1460
1628
  component,
1461
1629
  capturedContext,
1462
1630
  startOfComponent,
1463
- endOfComponent
1631
+ endOfComponent,
1632
+ binder.__config.propValidationMode
1464
1633
  );
1465
1634
  const componentCtx2 = useScope(() => {
1466
1635
  var _a2;
@@ -3888,6 +4057,15 @@ var Regor = (() => {
3888
4057
  __publicField(this, "forGrowThreshold", 10);
3889
4058
  __publicField(this, "globalContext");
3890
4059
  __publicField(this, "useInterpolation", true);
4060
+ /**
4061
+ * Controls how `head.validateProps(...)` behaves when a validator fails.
4062
+ *
4063
+ * - `'throw'` (default): rethrows the validation error immediately.
4064
+ * - `'warn'`: forwards the validation error to `warningHandler.warning(...)`
4065
+ * and continues.
4066
+ * - `'off'`: skips runtime prop validation entirely.
4067
+ */
4068
+ __publicField(this, "propValidationMode", "throw");
3891
4069
  this.setDirectives("r-");
3892
4070
  if (globalContext) {
3893
4071
  this.globalContext = globalContext;
@@ -6169,113 +6347,6 @@ var Regor = (() => {
6169
6347
  };
6170
6348
  };
6171
6349
 
6172
- // src/app/propValidators.ts
6173
- var fail = (name, message) => {
6174
- throw new Error(`Invalid prop "${name}": ${message}.`);
6175
- };
6176
- var describeValue = (value) => {
6177
- var _a;
6178
- if (value === null) return "null";
6179
- if (value === void 0) return "undefined";
6180
- if (typeof value === "string") return "string";
6181
- if (typeof value === "number") return "number";
6182
- if (typeof value === "boolean") return "boolean";
6183
- if (typeof value === "bigint") return "bigint";
6184
- if (typeof value === "symbol") return "symbol";
6185
- if (typeof value === "function") return "function";
6186
- if (isArray(value)) return "array";
6187
- if (value instanceof Date) return "Date";
6188
- if (value instanceof RegExp) return "RegExp";
6189
- if (value instanceof Map) return "Map";
6190
- if (value instanceof Set) return "Set";
6191
- const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6192
- return ctorName && ctorName !== "Object" ? ctorName : "object";
6193
- };
6194
- var formatLiteral = (value) => {
6195
- if (typeof value === "string") return `"${value}"`;
6196
- if (typeof value === "number" || typeof value === "boolean") {
6197
- return String(value);
6198
- }
6199
- if (value === null) return "null";
6200
- if (value === void 0) return "undefined";
6201
- return describeValue(value);
6202
- };
6203
- var isString2 = (value, name) => {
6204
- if (typeof value !== "string") fail(name, "expected string");
6205
- };
6206
- var isNumber = (value, name) => {
6207
- if (typeof value !== "number") fail(name, "expected number");
6208
- };
6209
- var isBoolean = (value, name) => {
6210
- if (typeof value !== "boolean") fail(name, "expected boolean");
6211
- };
6212
- var isClass = (ctor) => {
6213
- return (value, name) => {
6214
- if (!(value instanceof ctor)) {
6215
- fail(name, `expected instance of ${ctor.name || "provided class"}`);
6216
- }
6217
- };
6218
- };
6219
- var optional = (validator) => {
6220
- return (value, name, head) => {
6221
- if (value === void 0) return;
6222
- validator(value, name, head);
6223
- };
6224
- };
6225
- var nullable = (validator) => {
6226
- return (value, name, head) => {
6227
- if (value === null) return;
6228
- validator(value, name, head);
6229
- };
6230
- };
6231
- var oneOf = (values) => {
6232
- return (value, name) => {
6233
- if (values.includes(value)) return;
6234
- fail(
6235
- name,
6236
- `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6237
- );
6238
- };
6239
- };
6240
- var arrayOf = (validator) => {
6241
- return (value, name, head) => {
6242
- if (!isArray(value)) fail(name, "expected array");
6243
- const items = value;
6244
- for (let i = 0; i < items.length; ++i) {
6245
- validator(items[i], `${name}[${i}]`, head);
6246
- }
6247
- };
6248
- };
6249
- var shape = (schema) => {
6250
- return (value, name, head) => {
6251
- if (!isObject(value)) fail(name, "expected object");
6252
- const record = value;
6253
- for (const key in schema) {
6254
- const validator = schema[key];
6255
- validator(record[key], `${name}.${key}`, head);
6256
- }
6257
- };
6258
- };
6259
- var refOf = (validator) => {
6260
- return (value, name, head) => {
6261
- if (!isRef(value)) fail(name, "expected ref");
6262
- const refValue = value;
6263
- validator(refValue(), `${name}.value`, head);
6264
- };
6265
- };
6266
- var pval = {
6267
- isString: isString2,
6268
- isNumber,
6269
- isBoolean,
6270
- isClass,
6271
- optional,
6272
- nullable,
6273
- oneOf,
6274
- arrayOf,
6275
- shape,
6276
- refOf
6277
- };
6278
-
6279
6350
  // src/composition/ContextRegistry.ts
6280
6351
  var ContextRegistry = class {
6281
6352
  constructor() {