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.
@@ -142,9 +142,184 @@ var callUnmounted = (context) => {
142
142
  (_b = context.unmounted) == null ? void 0 : _b.call(context);
143
143
  };
144
144
 
145
+ // src/log/warnings.ts
146
+ var warnings = {
147
+ [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
148
+ [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
149
+ [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
150
+ [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
151
+ [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
152
+ [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
153
+ [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
154
+ msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
155
+ args: [e]
156
+ }),
157
+ [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
158
+ [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
159
+ };
160
+ var warning = (type, ...args) => {
161
+ const msg = warnings[type];
162
+ const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
163
+ const handler = warningHandler.warning;
164
+ if (!handler) return;
165
+ if (isString(item)) handler(item);
166
+ else handler(item, ...item.args);
167
+ };
168
+ var warningHandler = {
169
+ warning: console.warn
170
+ };
171
+
172
+ // src/reactivity/refSymbols.ts
173
+ var refSymbol = Symbol("ref");
174
+ var srefSymbol = Symbol("sref");
175
+ var rawSymbol = Symbol("raw");
176
+
177
+ // src/reactivity/isRef.ts
178
+ var isRef = (value) => {
179
+ return value != null && value[srefSymbol] === 1;
180
+ };
181
+
182
+ // src/app/propValidators.ts
183
+ var PropValidationError = class extends Error {
184
+ constructor(propPath, detail) {
185
+ super(detail);
186
+ __publicField(this, "propPath");
187
+ __publicField(this, "detail");
188
+ this.name = "PropValidationError";
189
+ this.propPath = propPath;
190
+ this.detail = detail;
191
+ }
192
+ };
193
+ var fail = (name, message) => {
194
+ throw new PropValidationError(name, `${message}.`);
195
+ };
196
+ var describeValue = (value) => {
197
+ var _a;
198
+ if (value === null) return "null";
199
+ if (value === void 0) return "undefined";
200
+ if (typeof value === "string") return "string";
201
+ if (typeof value === "number") return "number";
202
+ if (typeof value === "boolean") return "boolean";
203
+ if (typeof value === "bigint") return "bigint";
204
+ if (typeof value === "symbol") return "symbol";
205
+ if (typeof value === "function") return "function";
206
+ if (isArray(value)) return "array";
207
+ if (value instanceof Date) return "Date";
208
+ if (value instanceof RegExp) return "RegExp";
209
+ if (value instanceof Map) return "Map";
210
+ if (value instanceof Set) return "Set";
211
+ const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
212
+ return ctorName && ctorName !== "Object" ? ctorName : "object";
213
+ };
214
+ var formatLiteral = (value) => {
215
+ if (typeof value === "string") return `"${value}"`;
216
+ if (typeof value === "number" || typeof value === "boolean") {
217
+ return String(value);
218
+ }
219
+ if (value === null) return "null";
220
+ if (value === void 0) return "undefined";
221
+ return describeValue(value);
222
+ };
223
+ var isString2 = (value, name) => {
224
+ if (typeof value !== "string") fail(name, "expected string");
225
+ };
226
+ var isNumber = (value, name) => {
227
+ if (typeof value !== "number") fail(name, "expected number");
228
+ };
229
+ var isBoolean = (value, name) => {
230
+ if (typeof value !== "boolean") fail(name, "expected boolean");
231
+ };
232
+ var isClass = (ctor) => {
233
+ return (value, name) => {
234
+ if (!(value instanceof ctor)) {
235
+ fail(name, `expected instance of ${ctor.name || "provided class"}`);
236
+ }
237
+ };
238
+ };
239
+ var optional = (validator) => {
240
+ return (value, name, head) => {
241
+ if (value === void 0) return;
242
+ validator(value, name, head);
243
+ };
244
+ };
245
+ var nullable = (validator) => {
246
+ return (value, name, head) => {
247
+ if (value === null) return;
248
+ validator(value, name, head);
249
+ };
250
+ };
251
+ var oneOf = (values) => {
252
+ return (value, name) => {
253
+ if (values.includes(value)) return;
254
+ fail(
255
+ name,
256
+ `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
257
+ );
258
+ };
259
+ };
260
+ var arrayOf = (validator) => {
261
+ return (value, name, head) => {
262
+ if (!isArray(value)) fail(name, "expected array");
263
+ const items = value;
264
+ for (let i = 0; i < items.length; ++i) {
265
+ validator(items[i], `${name}[${i}]`, head);
266
+ }
267
+ };
268
+ };
269
+ var shape = (schema) => {
270
+ return (value, name, head) => {
271
+ if (!isObject(value)) fail(name, "expected object");
272
+ const record = value;
273
+ for (const key in schema) {
274
+ const validator = schema[key];
275
+ validator(record[key], `${name}.${key}`, head);
276
+ }
277
+ };
278
+ };
279
+ var refOf = (validator) => {
280
+ return (value, name, head) => {
281
+ if (!isRef(value)) fail(name, "expected ref");
282
+ const refValue = value;
283
+ validator(refValue(), `${name}.value`, head);
284
+ };
285
+ };
286
+ var pval = {
287
+ fail,
288
+ isString: isString2,
289
+ isNumber,
290
+ isBoolean,
291
+ isClass,
292
+ optional,
293
+ nullable,
294
+ oneOf,
295
+ arrayOf,
296
+ shape,
297
+ refOf
298
+ };
299
+
145
300
  // src/app/ComponentHead.ts
301
+ var formatComponentValidationError = (element, propName, error) => {
302
+ var _a, _b;
303
+ const tagName = ((_b = (_a = element.tagName) == null ? void 0 : _a.toLowerCase) == null ? void 0 : _b.call(_a)) || "unknown";
304
+ const finalPropName = error instanceof PropValidationError ? error.propPath : propName;
305
+ const detail = error instanceof PropValidationError ? error.detail : error instanceof Error ? error.message : String(error);
306
+ if (error instanceof Error) {
307
+ return new Error(
308
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
309
+ {
310
+ cause: error
311
+ }
312
+ );
313
+ }
314
+ return new Error(
315
+ `Invalid prop "${finalPropName}" on <${tagName}>: ${detail}`,
316
+ {
317
+ cause: error
318
+ }
319
+ );
320
+ };
146
321
  var ComponentHead = class {
147
- constructor(props, element, ctx, start, end) {
322
+ constructor(props, element, ctx, start, end, propValidationMode) {
148
323
  /**
149
324
  * Values provided by parent for this component instance.
150
325
  *
@@ -231,6 +406,11 @@ var ComponentHead = class {
231
406
  * @internal
232
407
  */
233
408
  __publicField(this, "__element");
409
+ /**
410
+ * Runtime behavior used when `validateProps(...)` encounters invalid input.
411
+ * Defaults to `'throw'`.
412
+ */
413
+ __publicField(this, "__propValidationMode");
234
414
  /**
235
415
  * Emits a custom DOM event from the component host element.
236
416
  *
@@ -254,6 +434,7 @@ var ComponentHead = class {
254
434
  this.ctx = ctx;
255
435
  this.start = start;
256
436
  this.end = end;
437
+ this.__propValidationMode = propValidationMode;
257
438
  }
258
439
  /**
259
440
  * Finds a parent context instance by constructor type from the captured
@@ -316,7 +497,7 @@ var ComponentHead = class {
316
497
  );
317
498
  }
318
499
  /**
319
- * Validates selected incoming props using assertion-style validators.
500
+ * Validates selected incoming props at runtime.
320
501
  *
321
502
  * Only keys listed in `schema` are checked. Validation throws immediately
322
503
  * on the first invalid prop and does not mutate `head.props`.
@@ -325,7 +506,8 @@ var ComponentHead = class {
325
506
  * known prop names while still allowing you to validate only a subset.
326
507
  *
327
508
  * Validators typically come from `pval`, but custom user validators are also
328
- * supported.
509
+ * supported. Custom validators may throw their own `Error`, though `pval.fail(...)`
510
+ * is recommended so nested validators can preserve the exact failing prop path.
329
511
  *
330
512
  * Example:
331
513
  * ```ts
@@ -335,15 +517,38 @@ var ComponentHead = class {
335
517
  * })
336
518
  * ```
337
519
  *
520
+ * Example with a custom validator:
521
+ * ```ts
522
+ * const isNonEmptyString: PropValidator<string> = (value, name) => {
523
+ * if (typeof value !== 'string' || value.trim() === '') {
524
+ * pval.fail(name, 'expected non-empty string')
525
+ * }
526
+ * }
527
+ * ```
528
+ *
338
529
  * @param schema - Validators to apply to selected incoming props.
339
530
  */
340
531
  validateProps(schema) {
532
+ if (this.__propValidationMode === "off") return;
341
533
  const props = this.props;
342
534
  for (const name in schema) {
343
535
  const validator = schema[name];
344
536
  if (!validator) continue;
345
537
  const validateProp = validator;
346
- validateProp(props[name], name, this);
538
+ try {
539
+ validateProp(props[name], name, this);
540
+ } catch (error) {
541
+ const enrichedError = formatComponentValidationError(
542
+ this.__element,
543
+ name,
544
+ error
545
+ );
546
+ if (this.__propValidationMode === "warn") {
547
+ warningHandler.warning(enrichedError.message, enrichedError);
548
+ continue;
549
+ }
550
+ throw enrichedError;
551
+ }
347
552
  }
348
553
  }
349
554
  /**
@@ -379,33 +584,6 @@ var addUnbinder = (node, unbinder) => {
379
584
  getBindData(node).unbinders.push(unbinder);
380
585
  };
381
586
 
382
- // src/log/warnings.ts
383
- var warnings = {
384
- [8 /* ModelRequiresRef */]: (el) => `Model binding requires a ref at ${el.outerHTML}`,
385
- [7 /* ModelNotSupportOnElement */]: (el) => `Model binding is not supported on ${el.tagName} element at ${el.outerHTML}`,
386
- [0 /* MissingBindingExpression */]: (name, el) => `${name} binding expression is missing at ${el.outerHTML}`,
387
- [1 /* InvalidForExpression */]: (name, forPath, el) => `invalid ${name} expression: ${forPath} at ${el.outerHTML}`,
388
- [2 /* BindingRequiresObjectExpressions */]: (name, el) => `${name} requires object expression at ${el.outerHTML}`,
389
- [3 /* KeyIsEmpty */]: (name, el) => `${name} binder: key is empty on ${el.outerHTML}.`,
390
- [4 /* PropertyAssignmentFailed */]: (key, tag, value, e) => ({
391
- msg: `Failed setting prop "${key}" on <${tag.toLowerCase()}>: value ${value} is invalid.`,
392
- args: [e]
393
- }),
394
- [5 /* MissingEventType */]: (name, el) => `${name} binding missing event type at ${el.outerHTML}`,
395
- [6 /* ErrorLog */]: (msg, e) => ({ msg, args: [e] })
396
- };
397
- var warning = (type, ...args) => {
398
- const msg = warnings[type];
399
- const item = isFunction(msg) ? msg.call(warnings, ...args) : msg;
400
- const handler = warningHandler.warning;
401
- if (!handler) return;
402
- if (isString(item)) handler(item);
403
- else handler(item, ...item.args);
404
- };
405
- var warningHandler = {
406
- warning: console.warn
407
- };
408
-
409
587
  // src/bind/switch.ts
410
588
  var switches = {};
411
589
  var switchCounter = {};
@@ -811,16 +989,6 @@ var isScope = (value) => {
811
989
  return scopeSymbol2 in value;
812
990
  };
813
991
 
814
- // src/reactivity/refSymbols.ts
815
- var refSymbol = Symbol("ref");
816
- var srefSymbol = Symbol("sref");
817
- var rawSymbol = Symbol("raw");
818
-
819
- // src/reactivity/isRef.ts
820
- var isRef = (value) => {
821
- return value != null && value[srefSymbol] === 1;
822
- };
823
-
824
992
  // src/directives/context.ts
825
993
  var contextDirective = {
826
994
  collectRefObj: true,
@@ -1393,7 +1561,8 @@ var ComponentBinder = class {
1393
1561
  component,
1394
1562
  capturedContext,
1395
1563
  startOfComponent,
1396
- endOfComponent
1564
+ endOfComponent,
1565
+ binder.__config.propValidationMode
1397
1566
  );
1398
1567
  const componentCtx2 = useScope(() => {
1399
1568
  var _a2;
@@ -3821,6 +3990,15 @@ var _RegorConfig = class _RegorConfig {
3821
3990
  __publicField(this, "forGrowThreshold", 10);
3822
3991
  __publicField(this, "globalContext");
3823
3992
  __publicField(this, "useInterpolation", true);
3993
+ /**
3994
+ * Controls how `head.validateProps(...)` behaves when a validator fails.
3995
+ *
3996
+ * - `'throw'` (default): rethrows the validation error immediately.
3997
+ * - `'warn'`: forwards the validation error to `warningHandler.warning(...)`
3998
+ * and continues.
3999
+ * - `'off'`: skips runtime prop validation entirely.
4000
+ */
4001
+ __publicField(this, "propValidationMode", "throw");
3824
4002
  this.setDirectives("r-");
3825
4003
  if (globalContext) {
3826
4004
  this.globalContext = globalContext;
@@ -6102,113 +6280,6 @@ var defineComponent = (template, options = {}) => {
6102
6280
  };
6103
6281
  };
6104
6282
 
6105
- // src/app/propValidators.ts
6106
- var fail = (name, message) => {
6107
- throw new Error(`Invalid prop "${name}": ${message}.`);
6108
- };
6109
- var describeValue = (value) => {
6110
- var _a;
6111
- if (value === null) return "null";
6112
- if (value === void 0) return "undefined";
6113
- if (typeof value === "string") return "string";
6114
- if (typeof value === "number") return "number";
6115
- if (typeof value === "boolean") return "boolean";
6116
- if (typeof value === "bigint") return "bigint";
6117
- if (typeof value === "symbol") return "symbol";
6118
- if (typeof value === "function") return "function";
6119
- if (isArray(value)) return "array";
6120
- if (value instanceof Date) return "Date";
6121
- if (value instanceof RegExp) return "RegExp";
6122
- if (value instanceof Map) return "Map";
6123
- if (value instanceof Set) return "Set";
6124
- const ctorName = (_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name;
6125
- return ctorName && ctorName !== "Object" ? ctorName : "object";
6126
- };
6127
- var formatLiteral = (value) => {
6128
- if (typeof value === "string") return `"${value}"`;
6129
- if (typeof value === "number" || typeof value === "boolean") {
6130
- return String(value);
6131
- }
6132
- if (value === null) return "null";
6133
- if (value === void 0) return "undefined";
6134
- return describeValue(value);
6135
- };
6136
- var isString2 = (value, name) => {
6137
- if (typeof value !== "string") fail(name, "expected string");
6138
- };
6139
- var isNumber = (value, name) => {
6140
- if (typeof value !== "number") fail(name, "expected number");
6141
- };
6142
- var isBoolean = (value, name) => {
6143
- if (typeof value !== "boolean") fail(name, "expected boolean");
6144
- };
6145
- var isClass = (ctor) => {
6146
- return (value, name) => {
6147
- if (!(value instanceof ctor)) {
6148
- fail(name, `expected instance of ${ctor.name || "provided class"}`);
6149
- }
6150
- };
6151
- };
6152
- var optional = (validator) => {
6153
- return (value, name, head) => {
6154
- if (value === void 0) return;
6155
- validator(value, name, head);
6156
- };
6157
- };
6158
- var nullable = (validator) => {
6159
- return (value, name, head) => {
6160
- if (value === null) return;
6161
- validator(value, name, head);
6162
- };
6163
- };
6164
- var oneOf = (values) => {
6165
- return (value, name) => {
6166
- if (values.includes(value)) return;
6167
- fail(
6168
- name,
6169
- `expected one of ${values.map((x) => formatLiteral(x)).join(", ")}`
6170
- );
6171
- };
6172
- };
6173
- var arrayOf = (validator) => {
6174
- return (value, name, head) => {
6175
- if (!isArray(value)) fail(name, "expected array");
6176
- const items = value;
6177
- for (let i = 0; i < items.length; ++i) {
6178
- validator(items[i], `${name}[${i}]`, head);
6179
- }
6180
- };
6181
- };
6182
- var shape = (schema) => {
6183
- return (value, name, head) => {
6184
- if (!isObject(value)) fail(name, "expected object");
6185
- const record = value;
6186
- for (const key in schema) {
6187
- const validator = schema[key];
6188
- validator(record[key], `${name}.${key}`, head);
6189
- }
6190
- };
6191
- };
6192
- var refOf = (validator) => {
6193
- return (value, name, head) => {
6194
- if (!isRef(value)) fail(name, "expected ref");
6195
- const refValue = value;
6196
- validator(refValue(), `${name}.value`, head);
6197
- };
6198
- };
6199
- var pval = {
6200
- isString: isString2,
6201
- isNumber,
6202
- isBoolean,
6203
- isClass,
6204
- optional,
6205
- nullable,
6206
- oneOf,
6207
- arrayOf,
6208
- shape,
6209
- refOf
6210
- };
6211
-
6212
6283
  // src/composition/ContextRegistry.ts
6213
6284
  var ContextRegistry = class {
6214
6285
  constructor() {