@stndrds/schema 1.0.0-alpha.233 → 1.0.0-alpha.235

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.
package/dist/index.mjs CHANGED
@@ -3,12 +3,12 @@ export { asTenantId, asUserId, deepEqual, generateId, indexBy } from './chunk-QY
3
3
  import './chunk-SP3PNHYF.mjs';
4
4
  import { parseComputedFormula } from './chunk-AAXJJNY6.mjs';
5
5
  export { ComputedFormulaParseError, parseAttributeConfig, parseComputedFormula } from './chunk-AAXJJNY6.mjs';
6
- import { createObjectValidator, SchemaError, SchemaErrorCode, createAttributeValidator, ValidationError } from './chunk-FRWPIJDK.mjs';
7
- export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, computeRecordStatus, createFormAttributeValidator, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-FRWPIJDK.mjs';
6
+ import { createObjectValidator, SchemaError, SchemaErrorCode, createAttributeValidator, ValidationError, NotFoundError, DuplicateError } from './chunk-NAS2HJ3Y.mjs';
7
+ export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, computeRecordStatus, createFormAttributeValidator, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-NAS2HJ3Y.mjs';
8
8
  import './chunk-OSSGN43B.mjs';
9
9
  import './chunk-Q44QKLN4.mjs';
10
10
  import './chunk-UANQJ2GH.mjs';
11
- import './chunk-NOMHDOVE.mjs';
11
+ import './chunk-U36ZIBEM.mjs';
12
12
  import './chunk-QVLQPW3O.mjs';
13
13
  import './chunk-ZDQ5AP26.mjs';
14
14
  import './chunk-LV3FEUKU.mjs';
@@ -4287,6 +4287,19 @@ function jsonFlag(name, defaultValue) {
4287
4287
  }
4288
4288
 
4289
4289
  // src/feature-flags/flag-registry.ts
4290
+ function duplicateFlagError(name) {
4291
+ return new DuplicateError(
4292
+ "feature flag",
4293
+ name,
4294
+ `Flag "${name}" is already registered. Each flag name must be unique.`
4295
+ );
4296
+ }
4297
+ function cloneFlagDefinition(flag) {
4298
+ return {
4299
+ ...flag,
4300
+ allowedLevels: [...flag.allowedLevels]
4301
+ };
4302
+ }
4290
4303
  var FlagRegistry = class {
4291
4304
  constructor() {
4292
4305
  this.flags = /* @__PURE__ */ new Map();
@@ -4295,7 +4308,7 @@ var FlagRegistry = class {
4295
4308
  * Register a feature flag definition.
4296
4309
  *
4297
4310
  * @param flag - The flag definition to register
4298
- * @throws {Error} If a flag with the same name is already registered
4311
+ * @throws DuplicateError If a flag with the same name is already registered
4299
4312
  *
4300
4313
  * @example
4301
4314
  * ```typescript
@@ -4307,33 +4320,25 @@ var FlagRegistry = class {
4307
4320
  */
4308
4321
  register(flag) {
4309
4322
  if (this.flags.has(flag.name)) {
4310
- throw new Error(`Flag "${flag.name}" is already registered. Each flag name must be unique.`);
4323
+ throw duplicateFlagError(flag.name);
4311
4324
  }
4312
- const cloned = {
4313
- ...flag,
4314
- allowedLevels: [...flag.allowedLevels]
4315
- };
4316
- this.flags.set(flag.name, cloned);
4325
+ this.flags.set(flag.name, cloneFlagDefinition(flag));
4317
4326
  }
4318
4327
  /**
4319
4328
  * Register multiple flags at once.
4320
4329
  * This operation is atomic - either all flags are registered or none are.
4321
4330
  *
4322
4331
  * @param flags - Array of flag definitions to register
4323
- * @throws {Error} If any flag name conflicts with existing or duplicate within batch
4332
+ * @throws DuplicateError If any flag name conflicts with existing or duplicate within batch
4324
4333
  */
4325
4334
  registerAll(flags) {
4326
4335
  const seenNames = /* @__PURE__ */ new Set();
4327
4336
  for (const flag of flags) {
4328
4337
  if (this.flags.has(flag.name)) {
4329
- throw new Error(
4330
- `Flag "${flag.name}" is already registered. Each flag name must be unique.`
4331
- );
4338
+ throw duplicateFlagError(flag.name);
4332
4339
  }
4333
4340
  if (seenNames.has(flag.name)) {
4334
- throw new Error(
4335
- `Flag "${flag.name}" is already registered. Each flag name must be unique.`
4336
- );
4341
+ throw duplicateFlagError(flag.name);
4337
4342
  }
4338
4343
  seenNames.add(flag.name);
4339
4344
  }
@@ -4348,19 +4353,23 @@ var FlagRegistry = class {
4348
4353
  * @returns The flag definition or undefined if not found
4349
4354
  */
4350
4355
  get(name) {
4351
- return this.flags.get(name);
4356
+ const flag = this.flags.get(name);
4357
+ return flag ? cloneFlagDefinition(flag) : void 0;
4352
4358
  }
4353
4359
  /**
4354
4360
  * Get a flag definition by name, throwing if not found.
4355
4361
  *
4356
4362
  * @param name - The flag name
4357
4363
  * @returns The flag definition
4358
- * @throws {Error} If the flag is not registered
4364
+ * @throws NotFoundError If the flag is not registered
4359
4365
  */
4360
4366
  getOrThrow(name) {
4361
4367
  const flag = this.get(name);
4362
4368
  if (!flag) {
4363
- throw new Error(
4369
+ throw new NotFoundError(
4370
+ "Feature flag",
4371
+ name,
4372
+ void 0,
4364
4373
  `Flag "${name}" is not registered. Available flags: ${this.listNames().join(", ")}`
4365
4374
  );
4366
4375
  }
@@ -4381,7 +4390,7 @@ var FlagRegistry = class {
4381
4390
  * @returns Array of all flag definitions
4382
4391
  */
4383
4392
  list() {
4384
- return Array.from(this.flags.values());
4393
+ return Array.from(this.flags.values(), cloneFlagDefinition);
4385
4394
  }
4386
4395
  /**
4387
4396
  * List all registered flag names.
@@ -4419,6 +4428,29 @@ function createFlagRegistry() {
4419
4428
  }
4420
4429
 
4421
4430
  // src/feature-flags/flag-service.ts
4431
+ function emptyOverrides() {
4432
+ return {
4433
+ global: /* @__PURE__ */ new Map(),
4434
+ tenant: /* @__PURE__ */ new Map(),
4435
+ user: /* @__PURE__ */ new Map()
4436
+ };
4437
+ }
4438
+ function isActiveOverride(override, now2) {
4439
+ return override.expiresAt === void 0 || override.expiresAt.getTime() > now2;
4440
+ }
4441
+ function indexOverrides(overrides, now2) {
4442
+ const byFlagName = /* @__PURE__ */ new Map();
4443
+ for (const override of overrides) {
4444
+ if (!isActiveOverride(override, now2)) {
4445
+ continue;
4446
+ }
4447
+ const flagName = override.flagName;
4448
+ if (!byFlagName.has(flagName)) {
4449
+ byFlagName.set(flagName, override);
4450
+ }
4451
+ }
4452
+ return byFlagName;
4453
+ }
4422
4454
  var FlagService = class {
4423
4455
  constructor(options) {
4424
4456
  this.repository = options.repository;
@@ -4441,7 +4473,7 @@ var FlagService = class {
4441
4473
  for (const name of this.staticDefaults.keys()) {
4442
4474
  flagNames.add(name);
4443
4475
  }
4444
- const overrides = this.repository && flagNames.size > 0 ? await this.getAllOverrides(context, [...flagNames]) : { global: [], tenant: [], user: [] };
4476
+ const overrides = this.repository && flagNames.size > 0 ? await this.getAllOverrides(context, [...flagNames]) : emptyOverrides();
4445
4477
  for (const name of flagNames) {
4446
4478
  const value = this.resolveValue(name, overrides, context);
4447
4479
  resolved.set(name, value);
@@ -4456,7 +4488,7 @@ var FlagService = class {
4456
4488
  * @returns Resolved flag with source information
4457
4489
  */
4458
4490
  async resolve(flagName, context = {}) {
4459
- const overrides = this.repository ? await this.getAllOverrides(context, [flagName]) : { global: [], tenant: [], user: [] };
4491
+ const overrides = this.repository ? await this.getAllOverrides(context, [flagName]) : emptyOverrides();
4460
4492
  return this.resolveWithSource(flagName, overrides, context);
4461
4493
  }
4462
4494
  /**
@@ -4491,18 +4523,19 @@ var FlagService = class {
4491
4523
  */
4492
4524
  async setOverride(flagName, level, value, options = {}) {
4493
4525
  if (!this.repository) {
4494
- throw new Error(
4495
- "Cannot set override: no FeatureFlagsRepository configured. Add featureFlags to your DatabaseAdapter to enable runtime overrides."
4526
+ throw new SchemaError(
4527
+ "Cannot set override: no FeatureFlagsRepository configured. Add featureFlags to your DatabaseAdapter to enable runtime overrides.",
4528
+ SchemaErrorCode.CONFIGURATION_REQUIRED
4496
4529
  );
4497
4530
  }
4498
4531
  const flag = this.registry.get(flagName);
4499
4532
  if (flag && !flag.allowedLevels.includes(level)) {
4500
- throw new Error(
4501
- `Flag "${flagName}" does not allow ${level}-level overrides. Allowed levels: ${flag.allowedLevels.join(", ")}`
4502
- );
4533
+ const message = `Flag "${flagName}" does not allow ${level}-level overrides. Allowed levels: ${flag.allowedLevels.join(", ")}`;
4534
+ throw new ValidationError(message, [{ path: ["level"], message }]);
4503
4535
  }
4504
4536
  if (flag?.system) {
4505
- throw new Error(`Flag "${flagName}" is a system flag and cannot be overridden via API.`);
4537
+ const message = `Flag "${flagName}" is a system flag and cannot be overridden via API.`;
4538
+ throw new ValidationError(message, [{ path: ["flagName"], message }]);
4506
4539
  }
4507
4540
  await this.repository.setOverride({
4508
4541
  flagName,
@@ -4522,7 +4555,10 @@ var FlagService = class {
4522
4555
  */
4523
4556
  async deleteOverride(flagName, level, targetId) {
4524
4557
  if (!this.repository) {
4525
- throw new Error("Cannot delete override: no FeatureFlagsRepository configured.");
4558
+ throw new SchemaError(
4559
+ "Cannot delete override: no FeatureFlagsRepository configured.",
4560
+ SchemaErrorCode.CONFIGURATION_REQUIRED
4561
+ );
4526
4562
  }
4527
4563
  await this.repository.deleteOverride(flagName, level, targetId);
4528
4564
  }
@@ -4534,17 +4570,18 @@ var FlagService = class {
4534
4570
  */
4535
4571
  async getAllOverrides(context, flagNames) {
4536
4572
  if (!this.repository) {
4537
- return { global: [], tenant: [], user: [] };
4573
+ return emptyOverrides();
4538
4574
  }
4539
4575
  const [globalOverrides, tenantOverrides, userOverrides] = await Promise.all([
4540
4576
  this.repository.getOverrides({ level: "global", flagNames }),
4541
4577
  context.tenantId ? this.repository.getOverrides({ level: "tenant", targetId: context.tenantId, flagNames }) : Promise.resolve([]),
4542
4578
  context.userId ? this.repository.getOverrides({ level: "user", targetId: context.userId, flagNames }) : Promise.resolve([])
4543
4579
  ]);
4580
+ const now2 = Date.now();
4544
4581
  return {
4545
- global: globalOverrides,
4546
- tenant: tenantOverrides,
4547
- user: userOverrides
4582
+ global: indexOverrides(globalOverrides, now2),
4583
+ tenant: indexOverrides(tenantOverrides, now2),
4584
+ user: indexOverrides(userOverrides, now2)
4548
4585
  };
4549
4586
  }
4550
4587
  /**
@@ -4561,7 +4598,7 @@ var FlagService = class {
4561
4598
  const flag = this.registry.get(flagName);
4562
4599
  const allowedLevels = flag?.allowedLevels ?? ["global", "tenant", "user"];
4563
4600
  if (context.userId && allowedLevels.includes("user")) {
4564
- const userOverride = overrides.user.find((o) => o.flagName === flagName);
4601
+ const userOverride = overrides.user.get(flagName);
4565
4602
  if (userOverride) {
4566
4603
  return {
4567
4604
  name: flagName,
@@ -4572,7 +4609,7 @@ var FlagService = class {
4572
4609
  }
4573
4610
  }
4574
4611
  if (context.tenantId && allowedLevels.includes("tenant")) {
4575
- const tenantOverride = overrides.tenant.find((o) => o.flagName === flagName);
4612
+ const tenantOverride = overrides.tenant.get(flagName);
4576
4613
  if (tenantOverride) {
4577
4614
  return {
4578
4615
  name: flagName,
@@ -4583,7 +4620,7 @@ var FlagService = class {
4583
4620
  }
4584
4621
  }
4585
4622
  if (allowedLevels.includes("global")) {
4586
- const globalOverride = overrides.global.find((o) => o.flagName === flagName);
4623
+ const globalOverride = overrides.global.get(flagName);
4587
4624
  if (globalOverride) {
4588
4625
  return {
4589
4626
  name: flagName,
@@ -4611,6 +4648,9 @@ function createFlagService(options) {
4611
4648
  }
4612
4649
 
4613
4650
  // src/native/registry.ts
4651
+ function cloneObjectDefinition(object2) {
4652
+ return structuredClone(object2);
4653
+ }
4614
4654
  var NativeObjectRegistryClass = class {
4615
4655
  constructor() {
4616
4656
  this.objects = /* @__PURE__ */ new Map();
@@ -4620,7 +4660,7 @@ var NativeObjectRegistryClass = class {
4620
4660
  * Auto-builds if ObjectBuilder is passed instead of ObjectDefinition
4621
4661
  * @param objects - Single object/builder or array of objects/builders to register
4622
4662
  * @returns this (for chaining)
4623
- * @throws Error if object is invalid or already registered
4663
+ * @throws SchemaError if object is invalid or already registered
4624
4664
  *
4625
4665
  * @example
4626
4666
  * ```typescript
@@ -4652,21 +4692,19 @@ var NativeObjectRegistryClass = class {
4652
4692
  */
4653
4693
  validateAndRegister(object2) {
4654
4694
  if (!object2.system) {
4655
- throw new Error(
4656
- `[NativeObjectRegistry] Cannot register object "${object2.name}" (id: ${object2.id}): missing system flag.
4657
- Native objects must have system=true. Did you call .runtime() on the builder? Remove that call \u2014 objects are system:true by default.`
4658
- );
4695
+ const message = `[NativeObjectRegistry] Cannot register object "${object2.name}" (id: ${object2.id}): missing system flag.
4696
+ Native objects must have system=true. Did you call .runtime() on the builder? Remove that call \u2014 objects are system:true by default.`;
4697
+ throw new ValidationError(message, []);
4659
4698
  }
4660
4699
  if (this.objects.has(object2.name)) {
4661
4700
  const existing = this.objects.get(object2.name);
4662
- throw new Error(
4663
- `[NativeObjectRegistry] Duplicate object name "${object2.name}":
4701
+ const message = `[NativeObjectRegistry] Duplicate object name "${object2.name}":
4664
4702
  - Existing: "${existing?.label}" (id: ${existing?.id})
4665
4703
  - New: "${object2.label}" (id: ${object2.id})
4666
- Please use unique names for each native object.`
4667
- );
4704
+ Please use unique names for each native object.`;
4705
+ throw new DuplicateError("object", object2.name, message);
4668
4706
  }
4669
- this.objects.set(object2.name, object2);
4707
+ this.objects.set(object2.name, cloneObjectDefinition(object2));
4670
4708
  }
4671
4709
  /**
4672
4710
  * Get a native object by its name
@@ -4682,21 +4720,21 @@ Please use unique names for each native object.`
4682
4720
  * ```
4683
4721
  */
4684
4722
  getByName(name) {
4685
- return this.objects.get(name);
4723
+ const object2 = this.objects.get(name);
4724
+ return object2 ? cloneObjectDefinition(object2) : void 0;
4686
4725
  }
4687
4726
  /**
4688
4727
  * Get a native object or throw if not found
4689
4728
  * @param name - The object name
4690
4729
  * @returns The object definition
4691
- * @throws Error if not found
4730
+ * @throws NotFoundError if not found
4692
4731
  */
4693
4732
  getByNameOrThrow(name) {
4694
- const object2 = this.objects.get(name);
4733
+ const object2 = this.getByName(name);
4695
4734
  if (!object2) {
4696
- throw new Error(
4697
- `[NativeObjectRegistry] Native object "${name}" not found.
4698
- Available objects: ${this.listNames().join(", ")}`
4699
- );
4735
+ const message = `[NativeObjectRegistry] Native object "${name}" not found.
4736
+ Available objects: ${this.listNames().join(", ")}`;
4737
+ throw new NotFoundError("Native object", name, SchemaErrorCode.OBJECT_NOT_FOUND, message);
4700
4738
  }
4701
4739
  return object2;
4702
4740
  }
@@ -4705,7 +4743,7 @@ Available objects: ${this.listNames().join(", ")}`
4705
4743
  * @returns Array of all registered object definitions
4706
4744
  */
4707
4745
  getAll() {
4708
- return Array.from(this.objects.values());
4746
+ return Array.from(this.objects.values(), cloneObjectDefinition);
4709
4747
  }
4710
4748
  /**
4711
4749
  * Get all registered native object names
@@ -4748,10 +4786,12 @@ Available objects: ${this.listNames().join(", ")}`
4748
4786
  ].join("\n");
4749
4787
  }
4750
4788
  /**
4751
- * Log registry summary to console
4789
+ * Return registry summary and optionally pass it to a debug writer.
4752
4790
  */
4753
- debug() {
4754
- console.info(this.summary());
4791
+ debug(write) {
4792
+ const summary = this.summary();
4793
+ write?.(summary);
4794
+ return summary;
4755
4795
  }
4756
4796
  };
4757
4797
  var registry = new NativeObjectRegistryClass();
@@ -4762,6 +4802,9 @@ var SKILL_VIEW = detailView("skill-detail", "Skill").for("skill").version(2).def
4762
4802
  var SKILL_LIST_VIEW = listView("skill-list", "Skills").for("skill").version(2).default().tab("all", "All").table().columns("name", "description").sort("name", "asc").build();
4763
4803
 
4764
4804
  // src/views/registry.ts
4805
+ function cloneViewDefinition(view) {
4806
+ return structuredClone(view);
4807
+ }
4765
4808
  var ViewRegistry = class {
4766
4809
  constructor() {
4767
4810
  this.views = /* @__PURE__ */ new Map();
@@ -4783,37 +4826,38 @@ var ViewRegistry = class {
4783
4826
  registerSingle(view) {
4784
4827
  const key = this.makeKey(view.object, view.name, view.type);
4785
4828
  if (this.views.has(key)) {
4786
- throw new Error(
4787
- `[ViewRegistry] Duplicate view: "${view.name}" (${view.type}) for object "${view.object}"`
4788
- );
4789
- }
4790
- this.views.set(key, view);
4791
- const objectViews = this.byObject.get(view.object) ?? [];
4792
- objectViews.push(view);
4793
- this.byObject.set(view.object, objectViews);
4794
- const typeKey = `${view.object}:${view.type}`;
4829
+ const message = `[ViewRegistry] Duplicate view: "${view.name}" (${view.type}) for object "${view.object}"`;
4830
+ throw new DuplicateError("view", key, message);
4831
+ }
4832
+ const storedView = cloneViewDefinition(view);
4833
+ this.views.set(key, storedView);
4834
+ const objectViews = this.byObject.get(storedView.object) ?? [];
4835
+ objectViews.push(storedView);
4836
+ this.byObject.set(storedView.object, objectViews);
4837
+ const typeKey = `${storedView.object}:${storedView.type}`;
4795
4838
  const typeViews = this.byObjectAndType.get(typeKey) ?? [];
4796
- typeViews.push(view);
4839
+ typeViews.push(storedView);
4797
4840
  this.byObjectAndType.set(typeKey, typeViews);
4798
4841
  }
4799
4842
  /**
4800
4843
  * Get all views for an object
4801
4844
  */
4802
4845
  getByObjectName(objectName) {
4803
- return this.byObject.get(objectName) ?? [];
4846
+ return Array.from(this.byObject.get(objectName) ?? [], cloneViewDefinition);
4804
4847
  }
4805
4848
  /**
4806
4849
  * Get views for an object filtered by type
4807
4850
  */
4808
4851
  getByObjectNameAndType(objectName, type) {
4809
- return this.byObjectAndType.get(`${objectName}:${type}`) ?? [];
4852
+ return Array.from(this.byObjectAndType.get(`${objectName}:${type}`) ?? [], cloneViewDefinition);
4810
4853
  }
4811
4854
  /**
4812
4855
  * Get a specific view by object, name, and type
4813
4856
  */
4814
4857
  get(objectName, viewName, type) {
4815
4858
  if (type) {
4816
- return this.views.get(this.makeKey(objectName, viewName, type));
4859
+ const view = this.views.get(this.makeKey(objectName, viewName, type));
4860
+ return view ? cloneViewDefinition(view) : void 0;
4817
4861
  }
4818
4862
  const objectViews = this.getByObjectName(objectName);
4819
4863
  return objectViews.find((v) => v.name === viewName);
@@ -4826,10 +4870,9 @@ var ViewRegistry = class {
4826
4870
  if (!view) {
4827
4871
  const available = this.getByObjectName(objectName);
4828
4872
  const availableNames = available.map((v) => `${v.name} (${v.type})`).join(", ") || "(none)";
4829
- throw new Error(
4830
- `[ViewRegistry] View "${viewName}" not found for object "${objectName}".
4831
- Available views: ${availableNames}`
4832
- );
4873
+ const message = `[ViewRegistry] View "${viewName}" not found for object "${objectName}".
4874
+ Available views: ${availableNames}`;
4875
+ throw new NotFoundError("View", `${objectName}:${viewName}`, void 0, message);
4833
4876
  }
4834
4877
  return view;
4835
4878
  }
@@ -4837,7 +4880,7 @@ Available views: ${availableNames}`
4837
4880
  * Get all registered views
4838
4881
  */
4839
4882
  getAll() {
4840
- return Array.from(this.views.values());
4883
+ return Array.from(this.views.values(), cloneViewDefinition);
4841
4884
  }
4842
4885
  /**
4843
4886
  * Check if a view exists
@@ -4901,10 +4944,12 @@ Available views: ${availableNames}`
4901
4944
  return lines.join("\n");
4902
4945
  }
4903
4946
  /**
4904
- * Log summary to console
4947
+ * Return summary and optionally pass it to a debug writer.
4905
4948
  */
4906
- debug() {
4907
- console.info(this.summary());
4949
+ debug(write) {
4950
+ const summary = this.summary();
4951
+ write?.(summary);
4952
+ return summary;
4908
4953
  }
4909
4954
  makeKey(objectName, viewName, type) {
4910
4955
  return `${objectName}:${viewName}:${type}`;
@@ -5126,6 +5171,9 @@ function getActiveTab(config, tabId) {
5126
5171
  }
5127
5172
 
5128
5173
  // src/forms/registry.ts
5174
+ function cloneFormDefinition(form2) {
5175
+ return structuredClone(form2);
5176
+ }
5129
5177
  var FormRegistry = class {
5130
5178
  constructor() {
5131
5179
  this.forms = /* @__PURE__ */ new Map();
@@ -5138,9 +5186,9 @@ var FormRegistry = class {
5138
5186
  const forms = Array.isArray(formOrForms) ? formOrForms : [formOrForms];
5139
5187
  for (const f of forms) {
5140
5188
  if (this.forms.has(f.name)) {
5141
- throw new Error(`[FormRegistry] Duplicate form: "${f.name}"`);
5189
+ throw new DuplicateError("form", f.name, `[FormRegistry] Duplicate form: "${f.name}"`);
5142
5190
  }
5143
- this.forms.set(f.name, f);
5191
+ this.forms.set(f.name, cloneFormDefinition(f));
5144
5192
  }
5145
5193
  return this;
5146
5194
  }
@@ -5148,13 +5196,14 @@ var FormRegistry = class {
5148
5196
  * Get a form definition by name.
5149
5197
  */
5150
5198
  get(name) {
5151
- return this.forms.get(name);
5199
+ const form2 = this.forms.get(name);
5200
+ return form2 ? cloneFormDefinition(form2) : void 0;
5152
5201
  }
5153
5202
  /**
5154
5203
  * Get all registered form definitions.
5155
5204
  */
5156
5205
  getAll() {
5157
- return Array.from(this.forms.values());
5206
+ return Array.from(this.forms.values(), cloneFormDefinition);
5158
5207
  }
5159
5208
  /**
5160
5209
  * List all registered form names.
@@ -2,11 +2,11 @@
2
2
 
3
3
  require('../chunk-PGERPYDR.js');
4
4
  var chunkNSM2JPC3_js = require('../chunk-NSM2JPC3.js');
5
- var chunk6SPNZSXS_js = require('../chunk-6SPNZSXS.js');
5
+ var chunkPZJN5IJW_js = require('../chunk-PZJN5IJW.js');
6
6
  require('../chunk-5WATIVCA.js');
7
7
  require('../chunk-SI34M4IC.js');
8
8
  require('../chunk-YIP5FJ5H.js');
9
- require('../chunk-SGSGREPG.js');
9
+ require('../chunk-QAF3HNKQ.js');
10
10
  require('../chunk-EW5XR2X3.js');
11
11
  require('../chunk-QWKLQRBX.js');
12
12
  require('../chunk-KNGWHQLR.js');
@@ -27,31 +27,31 @@ Object.defineProperty(exports, "parseAttributeConfig", {
27
27
  });
28
28
  Object.defineProperty(exports, "computeRecordStatus", {
29
29
  enumerable: true,
30
- get: function () { return chunk6SPNZSXS_js.computeRecordStatus; }
30
+ get: function () { return chunkPZJN5IJW_js.computeRecordStatus; }
31
31
  });
32
32
  Object.defineProperty(exports, "createFormAttributeValidator", {
33
33
  enumerable: true,
34
- get: function () { return chunk6SPNZSXS_js.createFormAttributeValidator; }
34
+ get: function () { return chunkPZJN5IJW_js.createFormAttributeValidator; }
35
35
  });
36
36
  Object.defineProperty(exports, "rejectUnknownAttributesOrThrow", {
37
37
  enumerable: true,
38
- get: function () { return chunk6SPNZSXS_js.rejectUnknownAttributesOrThrow; }
38
+ get: function () { return chunkPZJN5IJW_js.rejectUnknownAttributesOrThrow; }
39
39
  });
40
40
  Object.defineProperty(exports, "validateDraft", {
41
41
  enumerable: true,
42
- get: function () { return chunk6SPNZSXS_js.validateDraft; }
42
+ get: function () { return chunkPZJN5IJW_js.validateDraft; }
43
43
  });
44
44
  Object.defineProperty(exports, "validateDraftOrThrow", {
45
45
  enumerable: true,
46
- get: function () { return chunk6SPNZSXS_js.validateDraftOrThrow; }
46
+ get: function () { return chunkPZJN5IJW_js.validateDraftOrThrow; }
47
47
  });
48
48
  Object.defineProperty(exports, "validateObject", {
49
49
  enumerable: true,
50
- get: function () { return chunk6SPNZSXS_js.validateObject; }
50
+ get: function () { return chunkPZJN5IJW_js.validateObject; }
51
51
  });
52
52
  Object.defineProperty(exports, "validateObjectOrThrow", {
53
53
  enumerable: true,
54
- get: function () { return chunk6SPNZSXS_js.validateObjectOrThrow; }
54
+ get: function () { return chunkPZJN5IJW_js.validateObjectOrThrow; }
55
55
  });
56
56
  Object.defineProperty(exports, "DEFAULT_VALIDATION_MESSAGES", {
57
57
  enumerable: true,
@@ -1,10 +1,10 @@
1
1
  import '../chunk-SP3PNHYF.mjs';
2
2
  export { parseAttributeConfig } from '../chunk-AAXJJNY6.mjs';
3
- export { computeRecordStatus, createFormAttributeValidator, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from '../chunk-FRWPIJDK.mjs';
3
+ export { computeRecordStatus, createFormAttributeValidator, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from '../chunk-NAS2HJ3Y.mjs';
4
4
  import '../chunk-OSSGN43B.mjs';
5
5
  import '../chunk-Q44QKLN4.mjs';
6
6
  import '../chunk-UANQJ2GH.mjs';
7
- import '../chunk-NOMHDOVE.mjs';
7
+ import '../chunk-U36ZIBEM.mjs';
8
8
  import '../chunk-QVLQPW3O.mjs';
9
9
  import '../chunk-ZDQ5AP26.mjs';
10
10
  import '../chunk-LV3FEUKU.mjs';
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunk6SPNZSXS_js = require('../../chunk-6SPNZSXS.js');
3
+ var chunkPZJN5IJW_js = require('../../chunk-PZJN5IJW.js');
4
4
  require('../../chunk-5WATIVCA.js');
5
5
  require('../../chunk-SI34M4IC.js');
6
6
  require('../../chunk-YIP5FJ5H.js');
7
- require('../../chunk-SGSGREPG.js');
7
+ require('../../chunk-QAF3HNKQ.js');
8
8
  require('../../chunk-EW5XR2X3.js');
9
9
  require('../../chunk-QWKLQRBX.js');
10
10
  require('../../chunk-KNGWHQLR.js');
@@ -21,53 +21,53 @@ require('../../chunk-YKWSHBT5.js');
21
21
 
22
22
  Object.defineProperty(exports, "computeRecordStatus", {
23
23
  enumerable: true,
24
- get: function () { return chunk6SPNZSXS_js.computeRecordStatus; }
24
+ get: function () { return chunkPZJN5IJW_js.computeRecordStatus; }
25
25
  });
26
26
  Object.defineProperty(exports, "createAttributeValidator", {
27
27
  enumerable: true,
28
- get: function () { return chunk6SPNZSXS_js.createAttributeValidator; }
28
+ get: function () { return chunkPZJN5IJW_js.createAttributeValidator; }
29
29
  });
30
30
  Object.defineProperty(exports, "createDraftValidator", {
31
31
  enumerable: true,
32
- get: function () { return chunk6SPNZSXS_js.createDraftValidator; }
32
+ get: function () { return chunkPZJN5IJW_js.createDraftValidator; }
33
33
  });
34
34
  Object.defineProperty(exports, "createFormAttributeValidator", {
35
35
  enumerable: true,
36
- get: function () { return chunk6SPNZSXS_js.createFormAttributeValidator; }
36
+ get: function () { return chunkPZJN5IJW_js.createFormAttributeValidator; }
37
37
  });
38
38
  Object.defineProperty(exports, "createObjectValidator", {
39
39
  enumerable: true,
40
- get: function () { return chunk6SPNZSXS_js.createObjectValidator; }
40
+ get: function () { return chunkPZJN5IJW_js.createObjectValidator; }
41
41
  });
42
42
  Object.defineProperty(exports, "getMissingRequiredAttributes", {
43
43
  enumerable: true,
44
- get: function () { return chunk6SPNZSXS_js.getMissingRequiredAttributes; }
44
+ get: function () { return chunkPZJN5IJW_js.getMissingRequiredAttributes; }
45
45
  });
46
46
  Object.defineProperty(exports, "isRecordComplete", {
47
47
  enumerable: true,
48
- get: function () { return chunk6SPNZSXS_js.isRecordComplete; }
48
+ get: function () { return chunkPZJN5IJW_js.isRecordComplete; }
49
49
  });
50
50
  Object.defineProperty(exports, "rejectUnknownAttributesOrThrow", {
51
51
  enumerable: true,
52
- get: function () { return chunk6SPNZSXS_js.rejectUnknownAttributesOrThrow; }
52
+ get: function () { return chunkPZJN5IJW_js.rejectUnknownAttributesOrThrow; }
53
53
  });
54
54
  Object.defineProperty(exports, "validateAttribute", {
55
55
  enumerable: true,
56
- get: function () { return chunk6SPNZSXS_js.validateAttribute; }
56
+ get: function () { return chunkPZJN5IJW_js.validateAttribute; }
57
57
  });
58
58
  Object.defineProperty(exports, "validateDraft", {
59
59
  enumerable: true,
60
- get: function () { return chunk6SPNZSXS_js.validateDraft; }
60
+ get: function () { return chunkPZJN5IJW_js.validateDraft; }
61
61
  });
62
62
  Object.defineProperty(exports, "validateDraftOrThrow", {
63
63
  enumerable: true,
64
- get: function () { return chunk6SPNZSXS_js.validateDraftOrThrow; }
64
+ get: function () { return chunkPZJN5IJW_js.validateDraftOrThrow; }
65
65
  });
66
66
  Object.defineProperty(exports, "validateObject", {
67
67
  enumerable: true,
68
- get: function () { return chunk6SPNZSXS_js.validateObject; }
68
+ get: function () { return chunkPZJN5IJW_js.validateObject; }
69
69
  });
70
70
  Object.defineProperty(exports, "validateObjectOrThrow", {
71
71
  enumerable: true,
72
- get: function () { return chunk6SPNZSXS_js.validateObjectOrThrow; }
72
+ get: function () { return chunkPZJN5IJW_js.validateObjectOrThrow; }
73
73
  });
@@ -1,8 +1,8 @@
1
- export { computeRecordStatus, createAttributeValidator, createDraftValidator, createFormAttributeValidator, createObjectValidator, getMissingRequiredAttributes, isRecordComplete, rejectUnknownAttributesOrThrow, validateAttribute, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from '../../chunk-FRWPIJDK.mjs';
1
+ export { computeRecordStatus, createAttributeValidator, createDraftValidator, createFormAttributeValidator, createObjectValidator, getMissingRequiredAttributes, isRecordComplete, rejectUnknownAttributesOrThrow, validateAttribute, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from '../../chunk-NAS2HJ3Y.mjs';
2
2
  import '../../chunk-OSSGN43B.mjs';
3
3
  import '../../chunk-Q44QKLN4.mjs';
4
4
  import '../../chunk-UANQJ2GH.mjs';
5
- import '../../chunk-NOMHDOVE.mjs';
5
+ import '../../chunk-U36ZIBEM.mjs';
6
6
  import '../../chunk-QVLQPW3O.mjs';
7
7
  import '../../chunk-ZDQ5AP26.mjs';
8
8
  import '../../chunk-LV3FEUKU.mjs';
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkSGSGREPG_js = require('../../chunk-SGSGREPG.js');
3
+ var chunkQAF3HNKQ_js = require('../../chunk-QAF3HNKQ.js');
4
4
  require('../../chunk-YKWSHBT5.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "createTextValidator", {
9
9
  enumerable: true,
10
- get: function () { return chunkSGSGREPG_js.createTextValidator; }
10
+ get: function () { return chunkQAF3HNKQ_js.createTextValidator; }
11
11
  });