@stndrds/schema 1.0.0-alpha.188 → 1.0.0-alpha.190

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.
@@ -0,0 +1,639 @@
1
+ import { createCheckboxValidator } from './chunk-TMYBEXBT.mjs';
2
+ import { createDateValidator } from './chunk-4KRLCWJM.mjs';
3
+ import { createNumberValidator } from './chunk-KNYZH2WD.mjs';
4
+ import { createRatingValidator } from './chunk-RUYUFXNW.mjs';
5
+ import { createTextAreaValidator, createTextValidator } from './chunk-KWVCGQ7N.mjs';
6
+ import { createRichtextValidator } from './chunk-BLXQGQLK.mjs';
7
+ import { createMultiselectValidator, createSelectValidator, createStatusValidator } from './chunk-SMOHDR6M.mjs';
8
+ import { createUserValidator } from './chunk-ITTQ4FGR.mjs';
9
+ import { createFormulaValidator } from './chunk-IRTRJH37.mjs';
10
+ import { createRollupValidator } from './chunk-OLJLCVNY.mjs';
11
+ import { createCurrencyValidator } from './chunk-TEQNVO7W.mjs';
12
+ import { createFileValidator } from './chunk-4TC27SMF.mjs';
13
+ import { createLocationValidator } from './chunk-TBYXYSGA.mjs';
14
+ import { createPhoneValidator } from './chunk-Z75P63VF.mjs';
15
+ import { createRelationValidator } from './chunk-R4CJHCC4.mjs';
16
+ import { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './chunk-UQVW4KPP.mjs';
17
+ import { z } from 'zod';
18
+
19
+ function isEmptyValue(value) {
20
+ if (value === null || value === void 0) return true;
21
+ if (typeof value === "string" && value.trim() === "") return true;
22
+ if (value instanceof Date) return false;
23
+ if (typeof value === "object" && !Array.isArray(value)) {
24
+ return Object.values(value).every(
25
+ (v) => v === null || v === void 0 || typeof v === "string" && v.trim() === ""
26
+ );
27
+ }
28
+ return false;
29
+ }
30
+ function withEmptyToNull(validator) {
31
+ return z.preprocess((val) => isEmptyValue(val) ? null : val, validator.nullish());
32
+ }
33
+
34
+ // src/validation/object/attribute-factory.ts
35
+ function createAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
36
+ switch (attr.type) {
37
+ case "text":
38
+ return createTextValidator(attr, messages);
39
+ case "textarea":
40
+ return createTextAreaValidator(attr, messages);
41
+ case "richtext":
42
+ return createRichtextValidator(attr, messages);
43
+ case "number":
44
+ return createNumberValidator(attr, messages);
45
+ case "checkbox":
46
+ return createCheckboxValidator(attr, messages);
47
+ case "date":
48
+ return createDateValidator(attr, messages);
49
+ case "phone":
50
+ return createPhoneValidator(attr, messages);
51
+ case "currency":
52
+ return createCurrencyValidator(attr, messages);
53
+ case "status":
54
+ return createStatusValidator(attr, messages);
55
+ case "location":
56
+ return createLocationValidator(attr, messages);
57
+ case "select":
58
+ return createSelectValidator(attr, messages);
59
+ case "multiselect":
60
+ return createMultiselectValidator(attr, messages);
61
+ case "file":
62
+ return createFileValidator(attr, messages);
63
+ case "user":
64
+ return createUserValidator(attr, messages);
65
+ case "relation":
66
+ return createRelationValidator(attr, messages);
67
+ case "rating":
68
+ return createRatingValidator(attr, messages);
69
+ case "formula":
70
+ return createFormulaValidator(attr, messages);
71
+ case "rollup":
72
+ return createRollupValidator(attr, messages);
73
+ default:
74
+ return z.unknown();
75
+ }
76
+ }
77
+ function createFormAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
78
+ const validator = createAttributeValidator(attr, messages);
79
+ if (!attr.required) {
80
+ return withEmptyToNull(validator);
81
+ }
82
+ return validator;
83
+ }
84
+ var objectValidatorCache = /* @__PURE__ */ new WeakMap();
85
+ var draftValidatorCache = /* @__PURE__ */ new WeakMap();
86
+ function createObjectValidator(objectDef) {
87
+ const cached = objectValidatorCache.get(objectDef);
88
+ if (cached) return cached;
89
+ const shape = {};
90
+ for (const attr of objectDef.attributes) {
91
+ const validator = createAttributeValidator(attr);
92
+ shape[attr.name] = attr.required ? validator : withEmptyToNull(validator);
93
+ }
94
+ const schema = z.object(shape).passthrough();
95
+ objectValidatorCache.set(objectDef, schema);
96
+ return schema;
97
+ }
98
+ function createDraftValidator(objectDef) {
99
+ const cached = draftValidatorCache.get(objectDef);
100
+ if (cached) return cached;
101
+ const shape = {};
102
+ for (const attr of objectDef.attributes) {
103
+ const validator = createAttributeValidator(attr);
104
+ shape[attr.name] = withEmptyToNull(validator);
105
+ }
106
+ const schema = z.object(shape).passthrough();
107
+ draftValidatorCache.set(objectDef, schema);
108
+ return schema;
109
+ }
110
+
111
+ // src/exceptions.ts
112
+ var SchemaErrorCode = {
113
+ // Generic
114
+ UNKNOWN: "SCHEMA_UNKNOWN_ERROR",
115
+ // Not Found
116
+ OBJECT_NOT_FOUND: "SCHEMA_OBJECT_NOT_FOUND",
117
+ ATTRIBUTE_NOT_FOUND: "SCHEMA_ATTRIBUTE_NOT_FOUND",
118
+ RECORD_NOT_FOUND: "SCHEMA_RECORD_NOT_FOUND",
119
+ ROLE_NOT_FOUND: "SCHEMA_ROLE_NOT_FOUND",
120
+ MEMORY_NOT_FOUND: "SCHEMA_MEMORY_NOT_FOUND",
121
+ // Validation
122
+ VALIDATION_FAILED: "SCHEMA_VALIDATION_FAILED",
123
+ INVALID_ATTRIBUTE_NAME: "SCHEMA_INVALID_ATTRIBUTE_NAME",
124
+ INVALID_OBJECT_NAME: "SCHEMA_INVALID_OBJECT_NAME",
125
+ // Protected Resources
126
+ PROTECTED_OBJECT: "SCHEMA_PROTECTED_OBJECT",
127
+ PROTECTED_ATTRIBUTE: "SCHEMA_PROTECTED_ATTRIBUTE",
128
+ PROTECTED_VIEW: "SCHEMA_PROTECTED_VIEW",
129
+ PROTECTED_ROLE: "SCHEMA_PROTECTED_ROLE",
130
+ // Permissions
131
+ FORBIDDEN: "SCHEMA_FORBIDDEN",
132
+ ACCESS_DENIED: "SCHEMA_ACCESS_DENIED",
133
+ // Sync
134
+ SYNC_FAILED: "SCHEMA_SYNC_FAILED",
135
+ SYNC_CONFLICT: "SCHEMA_SYNC_CONFLICT",
136
+ SYNC_CASCADE: "SCHEMA_SYNC_CASCADE",
137
+ ORPHAN_SYSTEM_ATTRIBUTE: "SCHEMA_ORPHAN_SYSTEM_ATTRIBUTE",
138
+ // System Entity Immutability
139
+ SYSTEM_ENTITY_IMMUTABLE: "SCHEMA_SYSTEM_ENTITY_IMMUTABLE",
140
+ // L2 — migration system simplification (2026-05-17)
141
+ DESTRUCTIVE_NOT_ALLOWED: "SCHEMA_DESTRUCTIVE_NOT_ALLOWED",
142
+ MIGRATION_TIMEOUT: "SCHEMA_MIGRATION_TIMEOUT",
143
+ CHANGE_TYPE_NOT_SUPPORTED: "SCHEMA_CHANGE_TYPE_NOT_SUPPORTED",
144
+ // Duplicates
145
+ DUPLICATE_OBJECT: "SCHEMA_DUPLICATE_OBJECT",
146
+ DUPLICATE_ATTRIBUTE: "SCHEMA_DUPLICATE_ATTRIBUTE",
147
+ // Concurrency
148
+ CONFLICT: "SCHEMA_CONFLICT",
149
+ // Storage
150
+ STORAGE_UPLOAD_FAILED: "SCHEMA_STORAGE_UPLOAD_FAILED",
151
+ STORAGE_DOWNLOAD_FAILED: "SCHEMA_STORAGE_DOWNLOAD_FAILED",
152
+ STORAGE_DELETE_FAILED: "SCHEMA_STORAGE_DELETE_FAILED",
153
+ STORAGE_URL_FAILED: "SCHEMA_STORAGE_URL_FAILED",
154
+ // Repository Operations
155
+ REPOSITORY_CREATE_FAILED: "SCHEMA_REPOSITORY_CREATE_FAILED",
156
+ REPOSITORY_UPDATE_FAILED: "SCHEMA_REPOSITORY_UPDATE_FAILED",
157
+ REPOSITORY_DELETE_FAILED: "SCHEMA_REPOSITORY_DELETE_FAILED",
158
+ REPOSITORY_QUERY_FAILED: "SCHEMA_REPOSITORY_QUERY_FAILED",
159
+ // Not Implemented
160
+ NOT_IMPLEMENTED: "SCHEMA_NOT_IMPLEMENTED",
161
+ // Timeout
162
+ TIMEOUT: "SCHEMA_TIMEOUT",
163
+ // Schema Integrity
164
+ RECORD_REFERENCED: "SCHEMA_RECORD_REFERENCED",
165
+ ATTRIBUTE_IN_USE: "SCHEMA_ATTRIBUTE_IN_USE",
166
+ OBJECT_REFERENCED: "SCHEMA_OBJECT_REFERENCED"
167
+ };
168
+ var SchemaError = class extends Error {
169
+ constructor(message, code = SchemaErrorCode.UNKNOWN, details) {
170
+ super(message);
171
+ this.name = "SchemaError";
172
+ this.code = code;
173
+ this.details = details;
174
+ Object.setPrototypeOf(this, new.target.prototype);
175
+ }
176
+ toJSON() {
177
+ return {
178
+ name: this.name,
179
+ code: this.code,
180
+ message: this.message,
181
+ details: this.details
182
+ };
183
+ }
184
+ };
185
+ var NotFoundError = class extends SchemaError {
186
+ constructor(resourceType, resourceId, code = SchemaErrorCode.RECORD_NOT_FOUND) {
187
+ super(`${resourceType} with id "${resourceId}" not found`, code, {
188
+ resourceType,
189
+ resourceId
190
+ });
191
+ this.name = "NotFoundError";
192
+ this.resourceType = resourceType;
193
+ this.resourceId = resourceId;
194
+ }
195
+ };
196
+ var ObjectNotFoundError = class extends NotFoundError {
197
+ constructor(objectId) {
198
+ super("Object", objectId, SchemaErrorCode.OBJECT_NOT_FOUND);
199
+ this.name = "ObjectNotFoundError";
200
+ }
201
+ };
202
+ var AttributeNotFoundError = class extends NotFoundError {
203
+ constructor(attributeId) {
204
+ super("Attribute", attributeId, SchemaErrorCode.ATTRIBUTE_NOT_FOUND);
205
+ this.name = "AttributeNotFoundError";
206
+ }
207
+ };
208
+ var RecordNotFoundError = class extends NotFoundError {
209
+ constructor(recordId) {
210
+ super("Record", recordId, SchemaErrorCode.RECORD_NOT_FOUND);
211
+ this.name = "RecordNotFoundError";
212
+ }
213
+ };
214
+ var ValidationError = class _ValidationError extends SchemaError {
215
+ constructor(message, errors) {
216
+ super(message, SchemaErrorCode.VALIDATION_FAILED, { errors });
217
+ this.name = "ValidationError";
218
+ this.errors = errors;
219
+ }
220
+ /**
221
+ * Create a validation error from Zod-style errors
222
+ */
223
+ static fromZodErrors(errors) {
224
+ const details = errors.map((err) => ({
225
+ path: err.path.map(String),
226
+ message: err.message
227
+ }));
228
+ const message = `Validation failed: ${details.map((d) => `${d.path.join(".")}: ${d.message}`).join(", ")}`;
229
+ return new _ValidationError(message, details);
230
+ }
231
+ };
232
+ var ProtectedResourceError = class extends SchemaError {
233
+ constructor(resourceType, resourceName, operation) {
234
+ const code = resourceType === "object" ? SchemaErrorCode.PROTECTED_OBJECT : resourceType === "view" ? SchemaErrorCode.PROTECTED_VIEW : SchemaErrorCode.PROTECTED_ATTRIBUTE;
235
+ super(`Cannot ${operation} system ${resourceType} "${resourceName}"`, code, {
236
+ resourceType,
237
+ resourceName,
238
+ operation
239
+ });
240
+ this.name = "ProtectedResourceError";
241
+ this.resourceType = resourceType;
242
+ this.resourceName = resourceName;
243
+ this.operation = operation;
244
+ }
245
+ };
246
+ var SyncError = class extends SchemaError {
247
+ constructor(objectName, message, cause) {
248
+ super(`Failed to sync object "${objectName}": ${message}`, SchemaErrorCode.SYNC_FAILED, {
249
+ objectName,
250
+ cause: cause?.message
251
+ });
252
+ this.name = "SyncError";
253
+ this.objectName = objectName;
254
+ this.cause = cause;
255
+ }
256
+ };
257
+ var SystemEntityImmutableError = class extends SchemaError {
258
+ constructor(entityType, entityName) {
259
+ super(
260
+ `Cannot mutate system ${entityType} "${entityName}". System entities are declared in code and immutable at runtime.`,
261
+ SchemaErrorCode.SYSTEM_ENTITY_IMMUTABLE,
262
+ { entityType, entityName }
263
+ );
264
+ this.name = "SystemEntityImmutableError";
265
+ this.entityType = entityType;
266
+ this.entityName = entityName;
267
+ }
268
+ };
269
+ var SyncConflictError = class extends SchemaError {
270
+ constructor(params) {
271
+ const target = params.attributeName ? `"${params.objectName}.${params.attributeName}"` : `"${params.objectName}"`;
272
+ super(
273
+ `Cannot promote runtime entity ${target}: ${params.reason}. Resolve via: (1) relax the code constraint, (2) migrate runtime values manually, or (3) rename the code declaration.`,
274
+ SchemaErrorCode.SYNC_CONFLICT,
275
+ {
276
+ objectName: params.objectName,
277
+ attributeName: params.attributeName,
278
+ reason: params.reason
279
+ }
280
+ );
281
+ this.name = "SyncConflictError";
282
+ this.objectName = params.objectName;
283
+ this.attributeName = params.attributeName;
284
+ this.reason = params.reason;
285
+ }
286
+ };
287
+ var SyncCascadeError = class extends SchemaError {
288
+ constructor(objectName, conflictingAttributes) {
289
+ super(
290
+ `Cannot demote object "${objectName}": attributes ${conflictingAttributes.join(", ")} are still declared in code. Remove them from code first, or restore the object.`,
291
+ SchemaErrorCode.SYNC_CASCADE,
292
+ { objectName, conflictingAttributes }
293
+ );
294
+ this.name = "SyncCascadeError";
295
+ this.objectName = objectName;
296
+ this.conflictingAttributes = conflictingAttributes;
297
+ }
298
+ };
299
+ var OrphanSystemAttributeError = class extends SchemaError {
300
+ constructor(objectName, attributeName) {
301
+ super(
302
+ `Attribute "${objectName}.${attributeName}" is system:true but its object parent is system:false. This is an invariant violation.`,
303
+ SchemaErrorCode.ORPHAN_SYSTEM_ATTRIBUTE,
304
+ { objectName, attributeName }
305
+ );
306
+ this.name = "OrphanSystemAttributeError";
307
+ this.objectName = objectName;
308
+ this.attributeName = attributeName;
309
+ }
310
+ };
311
+ var DestructiveSyncNotAllowedError = class extends SchemaError {
312
+ constructor(operations) {
313
+ const summary = operations.map((op) => {
314
+ if (op.type === "remove_attribute") {
315
+ return `- remove_attribute "${op.objectName ?? "?"}.${op.name}"`;
316
+ }
317
+ if (op.type === "remove_object") {
318
+ return "- remove_object";
319
+ }
320
+ return `- ${op.type}`;
321
+ }).join("\n");
322
+ super(
323
+ `Destructive schema operations detected (data will be lost):
324
+ ${summary}
325
+
326
+ To allow Standards to apply these automatically, set the environment variable:
327
+ STANDARDS_ALLOW_DESTRUCTIVE_SYNC=1
328
+
329
+ Otherwise, revert your code changes or back up the data first.`,
330
+ SchemaErrorCode.DESTRUCTIVE_NOT_ALLOWED,
331
+ { operations }
332
+ );
333
+ this.name = "DestructiveSyncNotAllowedError";
334
+ this.operations = operations;
335
+ }
336
+ };
337
+ var MigrationTimeoutError = class extends SchemaError {
338
+ constructor(objectName, migrated, total, maxDurationMs) {
339
+ super(
340
+ `Migration for "${objectName}" exceeded the maximum duration (${maxDurationMs}ms). Migrated ${migrated}/${total} records before timeout. Increase STANDARDS_MIGRATION_MAX_DURATION_MS or split the migration into smaller batches.`,
341
+ SchemaErrorCode.MIGRATION_TIMEOUT,
342
+ { objectName, migrated, total, maxDurationMs }
343
+ );
344
+ this.name = "MigrationTimeoutError";
345
+ this.objectName = objectName;
346
+ this.migrated = migrated;
347
+ this.total = total;
348
+ this.maxDurationMs = maxDurationMs;
349
+ }
350
+ };
351
+ var ChangeTypeNotSupportedError = class extends SchemaError {
352
+ constructor(objectName, attributeName) {
353
+ super(
354
+ `Cannot change type of attribute "${objectName}.${attributeName}" via runtime API. Declare a migration in your schema code:
355
+ object("${objectName}").migration(N, (m) =>
356
+ m.changeType("${attributeName}", from, to, { transform: (v) => ... })
357
+ )`,
358
+ SchemaErrorCode.CHANGE_TYPE_NOT_SUPPORTED,
359
+ { objectName, attributeName }
360
+ );
361
+ this.name = "ChangeTypeNotSupportedError";
362
+ this.objectName = objectName;
363
+ this.attributeName = attributeName;
364
+ }
365
+ };
366
+ var DuplicateError = class extends SchemaError {
367
+ constructor(resourceType, resourceName) {
368
+ const code = resourceType === "object" ? SchemaErrorCode.DUPLICATE_OBJECT : SchemaErrorCode.DUPLICATE_ATTRIBUTE;
369
+ super(
370
+ `${resourceType === "object" ? "Object" : "Attribute"} "${resourceName}" already exists`,
371
+ code,
372
+ { resourceType, resourceName }
373
+ );
374
+ this.name = "DuplicateError";
375
+ this.resourceType = resourceType;
376
+ this.resourceName = resourceName;
377
+ }
378
+ };
379
+ function isSchemaError(error) {
380
+ return error instanceof SchemaError;
381
+ }
382
+ function isNotFoundError(error) {
383
+ return error instanceof NotFoundError;
384
+ }
385
+ function isValidationError(error) {
386
+ return error instanceof ValidationError;
387
+ }
388
+ function isProtectedResourceError(error) {
389
+ return error instanceof ProtectedResourceError;
390
+ }
391
+ var ForbiddenError = class extends SchemaError {
392
+ constructor(objectName, action, userId) {
393
+ super(`No ${action} permission on object "${objectName}"`, SchemaErrorCode.FORBIDDEN, {
394
+ objectName,
395
+ action,
396
+ userId
397
+ });
398
+ this.name = "ForbiddenError";
399
+ this.objectName = objectName;
400
+ this.action = action;
401
+ this.userId = userId;
402
+ }
403
+ };
404
+ var ProtectedRoleError = class extends SchemaError {
405
+ constructor(roleName, operation) {
406
+ super(`Cannot ${operation} system role "${roleName}"`, SchemaErrorCode.PROTECTED_ROLE, {
407
+ roleName,
408
+ operation
409
+ });
410
+ this.name = "ProtectedRoleError";
411
+ this.roleName = roleName;
412
+ this.operation = operation;
413
+ }
414
+ };
415
+ var RoleNotFoundError = class extends NotFoundError {
416
+ constructor(roleId) {
417
+ super("Role", roleId, SchemaErrorCode.ROLE_NOT_FOUND);
418
+ this.name = "RoleNotFoundError";
419
+ }
420
+ };
421
+ var ConcurrentModificationError = class extends SchemaError {
422
+ constructor(recordId) {
423
+ super(
424
+ `Record ${recordId} was modified by another request. Please refresh and try again.`,
425
+ SchemaErrorCode.CONFLICT,
426
+ { recordId }
427
+ );
428
+ }
429
+ };
430
+ var StorageError = class extends SchemaError {
431
+ constructor(operation, message, path, cause) {
432
+ const code = operation === "upload" ? SchemaErrorCode.STORAGE_UPLOAD_FAILED : operation === "download" ? SchemaErrorCode.STORAGE_DOWNLOAD_FAILED : operation === "delete" ? SchemaErrorCode.STORAGE_DELETE_FAILED : SchemaErrorCode.STORAGE_URL_FAILED;
433
+ super(`Storage ${operation} failed: ${message}`, code, {
434
+ operation,
435
+ path,
436
+ cause
437
+ });
438
+ this.name = "StorageError";
439
+ this.operation = operation;
440
+ this.path = path;
441
+ this.cause = cause;
442
+ }
443
+ };
444
+ var AccessDeniedError = class extends SchemaError {
445
+ constructor(resource, reason) {
446
+ super(reason ?? `Access denied to resource: ${resource}`, SchemaErrorCode.ACCESS_DENIED, {
447
+ resource,
448
+ reason
449
+ });
450
+ this.name = "AccessDeniedError";
451
+ this.resource = resource;
452
+ this.reason = reason;
453
+ }
454
+ };
455
+ var RepositoryError = class extends SchemaError {
456
+ constructor(operation, entity, message, cause) {
457
+ const code = operation === "create" ? SchemaErrorCode.REPOSITORY_CREATE_FAILED : operation === "update" ? SchemaErrorCode.REPOSITORY_UPDATE_FAILED : operation === "delete" ? SchemaErrorCode.REPOSITORY_DELETE_FAILED : SchemaErrorCode.REPOSITORY_QUERY_FAILED;
458
+ super(`Failed to ${operation} ${entity}: ${message}`, code, {
459
+ operation,
460
+ entity,
461
+ cause
462
+ });
463
+ this.name = "RepositoryError";
464
+ this.operation = operation;
465
+ this.entity = entity;
466
+ this.cause = cause;
467
+ }
468
+ };
469
+ var NotImplementedError = class extends SchemaError {
470
+ constructor(feature, milestone) {
471
+ const message = milestone ? `${feature}: not implemented (${milestone})` : `${feature}: not implemented`;
472
+ super(message, SchemaErrorCode.NOT_IMPLEMENTED, {
473
+ feature,
474
+ milestone
475
+ });
476
+ this.name = "NotImplementedError";
477
+ this.feature = feature;
478
+ this.milestone = milestone;
479
+ }
480
+ };
481
+ var MemoryNotFoundError = class extends NotFoundError {
482
+ constructor(memoryId) {
483
+ super("Memory", memoryId, SchemaErrorCode.MEMORY_NOT_FOUND);
484
+ this.name = "MemoryNotFoundError";
485
+ }
486
+ };
487
+ var RecordReferencedError = class extends SchemaError {
488
+ constructor(recordId, references) {
489
+ const total = references.reduce((sum, r) => sum + r.count, 0);
490
+ super(
491
+ `Cannot delete record: referenced by ${total} record${total > 1 ? "s" : ""}`,
492
+ SchemaErrorCode.RECORD_REFERENCED,
493
+ { recordId, references }
494
+ );
495
+ this.name = "RecordReferencedError";
496
+ this.recordId = recordId;
497
+ this.references = references;
498
+ }
499
+ };
500
+ var AttributeInUseError = class extends SchemaError {
501
+ constructor(attributeName, usage) {
502
+ super(
503
+ `Cannot delete attribute "${attributeName}": used in ${usage}`,
504
+ SchemaErrorCode.ATTRIBUTE_IN_USE,
505
+ { attributeName, usage }
506
+ );
507
+ this.name = "AttributeInUseError";
508
+ this.attributeName = attributeName;
509
+ this.usage = usage;
510
+ }
511
+ };
512
+ var ObjectReferencedError = class extends SchemaError {
513
+ constructor(objectName, referencingObjects) {
514
+ super(
515
+ `Cannot delete object "${objectName}": target of relations in ${referencingObjects.join(", ")}`,
516
+ SchemaErrorCode.OBJECT_REFERENCED,
517
+ { objectName, referencingObjects }
518
+ );
519
+ this.name = "ObjectReferencedError";
520
+ this.objectName = objectName;
521
+ this.referencingObjects = referencingObjects;
522
+ }
523
+ };
524
+ function isRecordReferencedError(error) {
525
+ return error instanceof RecordReferencedError;
526
+ }
527
+ function isAttributeInUseError(error) {
528
+ return error instanceof AttributeInUseError;
529
+ }
530
+ function isObjectReferencedError(error) {
531
+ return error instanceof ObjectReferencedError;
532
+ }
533
+
534
+ // src/validation/object/helpers.ts
535
+ function validateAttribute(attr, value) {
536
+ const validator = createAttributeValidator(attr);
537
+ if (!attr.required && (value === void 0 || value === null)) {
538
+ return { success: true, data: { [attr.name]: value } };
539
+ }
540
+ const result = validator.safeParse(value);
541
+ if (result.success) {
542
+ return {
543
+ success: true,
544
+ data: { [attr.name]: result.data }
545
+ };
546
+ }
547
+ return {
548
+ success: false,
549
+ errors: formatZodErrors(result.error).map((err) => ({
550
+ path: [attr.name, ...err.path],
551
+ message: err.message
552
+ }))
553
+ };
554
+ }
555
+ function validateObject(objectDef, data) {
556
+ const validator = createObjectValidator(objectDef);
557
+ const result = validator.safeParse(data);
558
+ if (result.success) {
559
+ return {
560
+ success: true,
561
+ data: result.data
562
+ };
563
+ }
564
+ return {
565
+ success: false,
566
+ errors: formatZodErrors(result.error)
567
+ };
568
+ }
569
+ function validateObjectOrThrow(objectDef, data) {
570
+ const result = validateObject(objectDef, data);
571
+ if (!result.success) {
572
+ const errors = result.errors ?? [];
573
+ const detail = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
574
+ throw new ValidationError(
575
+ `Validation failed for ${objectDef.label}:
576
+ ${detail}`,
577
+ errors.map((err) => ({ path: err.path, message: err.message }))
578
+ );
579
+ }
580
+ return result.data;
581
+ }
582
+ function validateDraft(objectDef, data) {
583
+ const validator = createDraftValidator(objectDef);
584
+ const result = validator.safeParse(data);
585
+ if (result.success) {
586
+ return {
587
+ success: true,
588
+ data: result.data
589
+ };
590
+ }
591
+ return {
592
+ success: false,
593
+ errors: formatZodErrors(result.error)
594
+ };
595
+ }
596
+ function validateDraftOrThrow(objectDef, data) {
597
+ const result = validateDraft(objectDef, data);
598
+ if (!result.success) {
599
+ const errors = result.errors ?? [];
600
+ const detail = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
601
+ throw new ValidationError(
602
+ `Draft validation failed for ${objectDef.label}:
603
+ ${detail}`,
604
+ errors.map((err) => ({ path: err.path, message: err.message }))
605
+ );
606
+ }
607
+ return result.data;
608
+ }
609
+ function isValuePresent(value) {
610
+ if (value === void 0 || value === null) {
611
+ return false;
612
+ }
613
+ if (typeof value === "string" && value.trim() === "") {
614
+ return false;
615
+ }
616
+ return true;
617
+ }
618
+ function getMissingRequiredAttributes(objectDef, data) {
619
+ const missing = [];
620
+ for (const attr of objectDef.attributes) {
621
+ if (attr.required && !isValuePresent(data[attr.name])) {
622
+ missing.push(attr);
623
+ }
624
+ }
625
+ return missing;
626
+ }
627
+ function isRecordComplete(objectDef, data) {
628
+ const missing = getMissingRequiredAttributes(objectDef, data);
629
+ if (missing.length > 0) {
630
+ return false;
631
+ }
632
+ const validation = validateObject(objectDef, data);
633
+ return validation.success;
634
+ }
635
+ function computeRecordStatus(objectDef, data) {
636
+ return isRecordComplete(objectDef, data) ? "complete" : "draft";
637
+ }
638
+
639
+ export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, computeRecordStatus, createAttributeValidator, createDraftValidator, createFormAttributeValidator, createObjectValidator, getMissingRequiredAttributes, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordComplete, isRecordReferencedError, isSchemaError, isValidationError, validateAttribute, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow };
@@ -32,7 +32,10 @@ declare function validateAttribute(attr: Attribute, value: unknown): ValidationR
32
32
  */
33
33
  declare function validateObject(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
34
34
  /**
35
- * Validate and throw if invalid
35
+ * Validate and throw if invalid.
36
+ *
37
+ * Throws `ValidationError` (code `SCHEMA_VALIDATION_FAILED`) on failure so HTTP
38
+ * adapters can map it to 400. Generic `Error` would bubble up to a 500.
36
39
  */
37
40
  declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
38
41
  /**
@@ -43,6 +46,9 @@ declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record
43
46
  declare function validateDraft(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
44
47
  /**
45
48
  * Validate draft data and throw if format validation fails.
49
+ *
50
+ * Same contract as `validateObjectOrThrow` but skips `required()` checks.
51
+ * Throws `ValidationError` so HTTP adapters map it to 400.
46
52
  */
47
53
  declare function validateDraftOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
48
54
  /**
@@ -32,7 +32,10 @@ declare function validateAttribute(attr: Attribute, value: unknown): ValidationR
32
32
  */
33
33
  declare function validateObject(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
34
34
  /**
35
- * Validate and throw if invalid
35
+ * Validate and throw if invalid.
36
+ *
37
+ * Throws `ValidationError` (code `SCHEMA_VALIDATION_FAILED`) on failure so HTTP
38
+ * adapters can map it to 400. Generic `Error` would bubble up to a 500.
36
39
  */
37
40
  declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
38
41
  /**
@@ -43,6 +46,9 @@ declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record
43
46
  declare function validateDraft(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
44
47
  /**
45
48
  * Validate draft data and throw if format validation fails.
49
+ *
50
+ * Same contract as `validateObjectOrThrow` but skips `required()` checks.
51
+ * Throws `ValidationError` so HTTP adapters map it to 400.
46
52
  */
47
53
  declare function validateDraftOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
48
54
  /**
package/dist/index.d.mts CHANGED
@@ -9,7 +9,7 @@ import z from 'zod';
9
9
  export { V as ValidationMessages } from './types-C5DittlR.mjs';
10
10
  export { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './validation/core/index.mjs';
11
11
  export { parseAttributeConfig } from './validation/config/index.mjs';
12
- export { c as computeRecordStatus, a as createFormAttributeValidator, v as validateDraft, b as validateDraftOrThrow, d as validateObject, e as validateObjectOrThrow } from './helpers-BjuFhbQQ.mjs';
12
+ export { c as computeRecordStatus, a as createFormAttributeValidator, v as validateDraft, b as validateDraftOrThrow, d as validateObject, e as validateObjectOrThrow } from './helpers-HrKmSkLi.mjs';
13
13
 
14
14
  /**
15
15
  * Generic list options for pagination and sorting