@afora/core 0.0.7 → 0.0.9

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.
Files changed (99) hide show
  1. package/README.md +157 -25
  2. package/dist/adapters.d.ts +25 -0
  3. package/dist/adapters.js +56 -0
  4. package/dist/core/application/exceptions.d.ts +17 -0
  5. package/dist/core/application/migrate.d.ts +19 -0
  6. package/dist/core/application/schema.d.ts +30 -0
  7. package/dist/core/application/start.d.ts +7 -0
  8. package/dist/core/application/types/application.interface.d.ts +73 -2
  9. package/dist/core/auth/jwt.d.ts +30 -0
  10. package/dist/core/auth/types/jwt.interface.d.ts +66 -0
  11. package/dist/core/blueprint/exceptions.d.ts +5 -0
  12. package/dist/core/blueprint/optional.d.ts +3 -1
  13. package/dist/core/blueprint/types/blueprint.interface.d.ts +79 -5
  14. package/dist/core/blueprint/variant.d.ts +32 -0
  15. package/dist/core/command/types/command.interface.d.ts +7 -0
  16. package/dist/core/entity/abstract-entity.d.ts +33 -1
  17. package/dist/core/entity/entity.d.ts +1 -1
  18. package/dist/core/entity/event.d.ts +13 -2
  19. package/dist/core/entity/exceptions.d.ts +17 -0
  20. package/dist/core/entity/trust.d.ts +24 -0
  21. package/dist/core/entity/types/entity.interface.d.ts +96 -2
  22. package/dist/core/entity/version.d.ts +13 -0
  23. package/dist/core/event-policy/event-policy.d.ts +25 -0
  24. package/dist/core/event-policy/exceptions.d.ts +11 -0
  25. package/dist/core/event-policy/publish.d.ts +17 -0
  26. package/dist/core/event-policy/publishers.d.ts +18 -0
  27. package/dist/core/event-policy/types/event-policy.interface.d.ts +72 -0
  28. package/dist/core/output/access.d.ts +16 -0
  29. package/dist/core/output/coerce.d.ts +9 -0
  30. package/dist/core/output/exceptions.d.ts +16 -0
  31. package/dist/core/output/http.d.ts +36 -0
  32. package/dist/core/output/openapi-sink.d.ts +160 -39
  33. package/dist/core/output/stage.d.ts +7 -2
  34. package/dist/core/output/status.d.ts +2 -2
  35. package/dist/core/output/types/http.interface.d.ts +130 -0
  36. package/dist/core/output/types/output.interface.d.ts +25 -5
  37. package/dist/core/parse/issue.d.ts +28 -3
  38. package/dist/core/parse/parse.d.ts +19 -0
  39. package/dist/core/parse/strip.d.ts +13 -0
  40. package/dist/core/property/abstract-property.d.ts +9 -0
  41. package/dist/core/property/define-property.d.ts +34 -6
  42. package/dist/core/property/types/property-options.interface.d.ts +10 -0
  43. package/dist/core/property/types/property-type.interface.d.ts +4 -0
  44. package/dist/core/record/abstract-record.d.ts +7 -0
  45. package/dist/core/record/types/record.interface.d.ts +12 -1
  46. package/dist/core/repository/exceptions.d.ts +43 -0
  47. package/dist/core/repository/in-memory.d.ts +16 -3
  48. package/dist/core/repository/migrate.d.ts +20 -0
  49. package/dist/core/repository/plan.d.ts +20 -0
  50. package/dist/core/repository/provider.d.ts +1 -1
  51. package/dist/core/repository/query.d.ts +9 -2
  52. package/dist/core/repository/repository.d.ts +40 -8
  53. package/dist/core/repository/state.d.ts +32 -2
  54. package/dist/core/repository/types/query.interface.d.ts +106 -5
  55. package/dist/core/repository/types/repository.interface.d.ts +139 -7
  56. package/dist/core/repository/types/schema.interface.d.ts +126 -0
  57. package/dist/core/repository/upcast.d.ts +64 -0
  58. package/dist/core/schema/schema.d.ts +28 -0
  59. package/dist/core/symbols/kind.d.ts +1 -1
  60. package/dist/core/use-case/access.d.ts +12 -0
  61. package/dist/core/use-case/decorators.d.ts +40 -0
  62. package/dist/core/use-case/route.d.ts +18 -0
  63. package/dist/core/use-case/steps/types/check.interface.d.ts +214 -0
  64. package/dist/core/use-case/types/access.interface.d.ts +39 -0
  65. package/dist/core/use-case/types/route.interface.d.ts +66 -0
  66. package/dist/core/use-case/use-case.d.ts +52 -2
  67. package/dist/experimental.d.ts +13 -1
  68. package/dist/experimental.js +64 -26
  69. package/dist/index-3aae5jfq.js +2997 -0
  70. package/dist/index-hg1z2s2v.js +1055 -0
  71. package/dist/index-ny3as79r.js +4567 -0
  72. package/dist/index-xegv6a1p.js +4291 -0
  73. package/dist/index-y280ew0k.js +396 -0
  74. package/dist/index.d.ts +55 -48
  75. package/dist/index.js +141 -169
  76. package/dist/std/blueprint-plugin.d.ts +6 -2
  77. package/dist/std/blueprint.d.ts +3 -0
  78. package/dist/std/entity.d.ts +2 -1
  79. package/dist/std/event-policies.d.ts +2 -0
  80. package/dist/std/properties/exceptions.d.ts +11 -0
  81. package/dist/std/properties/json.d.ts +54 -0
  82. package/dist/std/properties/password.d.ts +0 -2
  83. package/dist/std/properties/time.d.ts +4 -0
  84. package/dist/std/record-plugins.d.ts +2 -2
  85. package/dist/std/resource.d.ts +31 -0
  86. package/dist/std/runtime.d.ts +6 -0
  87. package/dist/std/use-cases/auth.d.ts +5 -1
  88. package/dist/std/use-cases/crud.d.ts +6 -4
  89. package/dist/std/use-cases/index.d.ts +1 -1
  90. package/dist/std/use-cases/shared.d.ts +34 -6
  91. package/dist/std/use-cases/types.d.ts +197 -22
  92. package/dist/testing/http-provider-contract.d.ts +32 -0
  93. package/dist/testing/index.d.ts +4 -0
  94. package/dist/testing/index.js +839 -3
  95. package/dist/testing/memory-publisher.d.ts +16 -0
  96. package/dist/testing/provider-contract.d.ts +31 -1
  97. package/package.json +17 -3
  98. package/dist/index-q6hggpzw.js +0 -6667
  99. package/dist/index-r78dsvtc.js +0 -1721
@@ -1,1721 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __returnValue = (v) => v;
3
- function __exportSetter(name, newValue) {
4
- this[name] = __returnValue.bind(null, newValue);
5
- }
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true,
11
- configurable: true,
12
- set: __exportSetter.bind(all, name)
13
- });
14
- };
15
-
16
- // src/core/record/exceptions.ts
17
- var exports_exceptions = {};
18
- __export(exports_exceptions, {
19
- IncompatibleRecordPlugin: () => IncompatibleRecordPlugin2,
20
- InvalidRecordDeclaration: () => InvalidRecordDeclaration2,
21
- InvalidRecordPlugin: () => InvalidRecordPlugin2,
22
- InvalidRecordValue: () => InvalidRecordValue2,
23
- RecordPluginConflict: () => RecordPluginConflict2,
24
- ReservedRecordKey: () => ReservedRecordKey2,
25
- UndeclaredRecordProperty: () => UndeclaredRecordProperty2,
26
- UnknownRecordPlugin: () => UnknownRecordPlugin2
27
- });
28
-
29
- // src/core/blueprint/exceptions.ts
30
- var exports_exceptions2 = {};
31
- __export(exports_exceptions2, {
32
- ReservedBlueprintKey: () => ReservedBlueprintKey2,
33
- UndeclaredBlueprintProperty: () => UndeclaredBlueprintProperty2
34
- });
35
-
36
- // src/core/property/exceptions.ts
37
- var exports_exceptions3 = {};
38
- __export(exports_exceptions3, {
39
- InvalidPropertyValue: () => InvalidPropertyValue2,
40
- PropertyRequired: () => PropertyRequired2
41
- });
42
-
43
- // src/core/property/is-property.ts
44
- function isProperty2(value) {
45
- return typeof value === "function" && typeof value.type === "object";
46
- }
47
-
48
- // src/core/schema/schema.ts
49
- import Compile from "typebox/compile";
50
- var KEPT_KEYWORDS = new Set([
51
- "type",
52
- "required",
53
- "$ref",
54
- "$id",
55
- "$anchor",
56
- "$dynamicRef",
57
- "$dynamicAnchor"
58
- ]);
59
- var SCHEMA_KEYWORDS = new Set([
60
- "additionalProperties",
61
- "items",
62
- "additionalItems",
63
- "prefixItems",
64
- "anyOf",
65
- "oneOf",
66
- "allOf",
67
- "contains",
68
- "propertyNames"
69
- ]);
70
- var SCHEMA_MAP_KEYWORDS = new Set([
71
- "properties",
72
- "patternProperties",
73
- "dependentSchemas",
74
- "$defs",
75
- "definitions"
76
- ]);
77
- var JSON_TYPES = new Set([
78
- "null",
79
- "array",
80
- "string",
81
- "number",
82
- "boolean",
83
- "object"
84
- ]);
85
- function typeOfValue(value) {
86
- const type = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
87
- return JSON_TYPES.has(type) ? type : undefined;
88
- }
89
- function shapeOf(schema) {
90
- if (Array.isArray(schema))
91
- return schema.map(shapeOf);
92
- if (typeof schema !== "object" || schema === null)
93
- return schema;
94
- const shape = {};
95
- for (const [key, value] of Object.entries(schema)) {
96
- if (KEPT_KEYWORDS.has(key))
97
- shape[key] = value;
98
- else if (SCHEMA_KEYWORDS.has(key))
99
- shape[key] = shapeOf(value);
100
- else if (SCHEMA_MAP_KEYWORDS.has(key)) {
101
- shape[key] = Object.fromEntries(Object.entries(value).map(([name, item]) => [
102
- name,
103
- shapeOf(item)
104
- ]));
105
- }
106
- }
107
- if (!("type" in shape)) {
108
- const values = "const" in schema ? [schema.const] : schema.enum;
109
- if (Array.isArray(values)) {
110
- const types = values.map(typeOfValue);
111
- if (types.every((type) => type !== undefined)) {
112
- shape.type = [...new Set(types)];
113
- }
114
- }
115
- }
116
- return shape;
117
- }
118
- function describeError(error) {
119
- return `${error.instancePath || "/"}: ${error.message}`;
120
- }
121
-
122
- class AbstractSchema {
123
- _type;
124
- validator;
125
- shapeValidator;
126
- constructor(_type) {
127
- this._type = _type;
128
- }
129
- match(value) {
130
- return this.type.Check(value);
131
- }
132
- matchShape(value) {
133
- this.shapeValidator ??= Compile(shapeOf(this._type));
134
- return this.shapeValidator.Check(value);
135
- }
136
- errors(value) {
137
- return this.type.Errors(value).map(describeError);
138
- }
139
- toString() {
140
- return JSON.stringify(this._type);
141
- }
142
- get type() {
143
- this.validator ??= Compile(this._type);
144
- return this.validator;
145
- }
146
- }
147
- function schemaOf2(name, schema) {
148
-
149
- class Schema extends AbstractSchema {
150
- constructor(type = schema) {
151
- super(type);
152
- }
153
- static fromString(value) {
154
- return new Schema(JSON.parse(value));
155
- }
156
- }
157
- Object.defineProperty(Schema, "name", { value: name });
158
- Object.defineProperty(Schema, Symbol.for("nodejs.util.inspect.custom"), {
159
- value: () => `@afora::schema:${name}`
160
- });
161
- return Schema;
162
- }
163
-
164
- // src/core/symbols/demo.ts
165
- var Demo2 = Symbol("demo");
166
-
167
- // src/core/property/lineage.ts
168
- var lineages = new WeakMap;
169
- function recordPropertyLineage(Property, lineage) {
170
- if (!lineages.has(Property))
171
- lineages.set(Property, lineage);
172
- }
173
- function propertyLineageOf2(Property) {
174
- return typeof Property === "function" ? lineages.get(Property) : undefined;
175
- }
176
-
177
- // src/core/property/refine.ts
178
- var METADATA_KEYS = [
179
- "title",
180
- "description",
181
- "examples",
182
- "deprecated",
183
- "readOnly",
184
- "writeOnly"
185
- ];
186
- var LOWER_BOUNDS = {
187
- min: ["minimum", "minLength"],
188
- exclusiveMin: ["exclusiveMinimum"]
189
- };
190
- var UPPER_BOUNDS = {
191
- max: ["maximum", "maxLength"],
192
- exclusiveMax: ["exclusiveMaximum"]
193
- };
194
- function derivePropertyOf(Property, type) {
195
- const Base = Property;
196
-
197
- class Derived extends Base {
198
- static type = type;
199
- createDefinition() {
200
- const definition = super.createDefinition();
201
- Object.defineProperty(definition, "type", {
202
- value: type,
203
- configurable: true
204
- });
205
- return definition;
206
- }
207
- }
208
- Object.defineProperty(Derived, "name", { value: Property.name });
209
- return Derived;
210
- }
211
- function copyOf(schema) {
212
- return Object.defineProperties({}, Object.getOwnPropertyDescriptors(schema));
213
- }
214
- function addAllOf(schema, constraint) {
215
- schema.allOf = [...schema.allOf ?? [], constraint];
216
- }
217
- function refinedSchemaOf(base, options) {
218
- const schema = copyOf(base);
219
- const keyword = (keys) => keys.length === 1 || schema.type !== "string" ? keys[0] : keys[1];
220
- for (const key of METADATA_KEYS) {
221
- if (options[key] !== undefined)
222
- schema[key] = options[key];
223
- }
224
- for (const [option, keys] of Object.entries(LOWER_BOUNDS)) {
225
- const value = options[option];
226
- if (value === undefined)
227
- continue;
228
- const name = keyword(keys);
229
- const current = schema[name];
230
- schema[name] = current === undefined ? value : Math.max(current, value);
231
- }
232
- for (const [option, keys] of Object.entries(UPPER_BOUNDS)) {
233
- const value = options[option];
234
- if (value === undefined)
235
- continue;
236
- const name = keyword(keys);
237
- const current = schema[name];
238
- schema[name] = current === undefined ? value : Math.min(current, value);
239
- }
240
- if (options.multipleOf !== undefined) {
241
- if (schema.multipleOf === undefined)
242
- schema.multipleOf = options.multipleOf;
243
- else
244
- addAllOf(schema, { multipleOf: options.multipleOf });
245
- }
246
- if (options.pattern !== undefined) {
247
- const pattern = options.pattern instanceof RegExp ? options.pattern.source : options.pattern;
248
- if (schema.pattern === undefined)
249
- schema.pattern = pattern;
250
- else
251
- addAllOf(schema, { pattern });
252
- }
253
- return schema;
254
- }
255
- function refinePropertyOf(Property, options) {
256
- const base = Property.type;
257
- const settings = options;
258
- const schema = refinedSchemaOf(base.schema.type.Type(), settings);
259
- const SchemaConstructor = schemaOf2(base.name, schema);
260
- const examples = settings.examples;
261
- const type = {
262
- ...base,
263
- [Demo2]: settings.default ?? examples?.[0] ?? base[Demo2],
264
- schema: new SchemaConstructor
265
- };
266
- const Refined = derivePropertyOf(Property, type);
267
- recordPropertyLineage(Refined, {
268
- kind: "refined",
269
- base: Property,
270
- options: Object.freeze({ ...settings })
271
- });
272
- return Refined;
273
- }
274
-
275
- // src/core/blueprint/callable.ts
276
- var targets = new WeakMap;
277
- function callableOf(Property) {
278
- const callable = new Proxy(Property, {
279
- apply: (target, _this, [options]) => refinePropertyOf(target, options ?? {})
280
- });
281
- targets.set(callable, Property);
282
- return callable;
283
- }
284
- function fieldOf(field) {
285
- return (isProperty2(field) ? targets.get(field) : undefined) ?? field;
286
- }
287
-
288
- // src/core/symbols/kind.ts
289
- var Kind2 = Symbol("kind");
290
-
291
- // src/core/blueprint/is-blueprint.ts
292
- function isBlueprint2(value) {
293
- return typeof value === "object" && value !== null && value[Kind2] === "blueprint";
294
- }
295
-
296
- // src/core/blueprint/record-field.ts
297
- function isRecordClass2(value) {
298
- return typeof value === "function" && value[Kind2] === "record";
299
- }
300
- function isOptionalRecord2(value) {
301
- return typeof value === "object" && value !== null && value[Kind2] === "record";
302
- }
303
- function recordFieldOf2(field) {
304
- if (isRecordClass2(field))
305
- return { record: field, optional: false };
306
- if (isOptionalRecord2(field))
307
- return field;
308
- return;
309
- }
310
-
311
- // src/core/record/name.ts
312
- var RECORD_NAME = /^[A-Za-z_$][\w$]*$/;
313
- function isRecordName(name) {
314
- return typeof name === "string" && RECORD_NAME.test(name);
315
- }
316
- function recordNameOf2(Class) {
317
- const { recordName, name } = Class;
318
- return typeof recordName === "string" ? recordName : String(name);
319
- }
320
- var declaredNames = new WeakMap;
321
- function declareRecordName(Class, name) {
322
- declaredNames.set(Class, name);
323
- }
324
- function declaredRecordNameOf(Class) {
325
- for (let current = Class;typeof current === "function"; current = Object.getPrototypeOf(current)) {
326
- const own = Object.getOwnPropertyDescriptor(current, "recordName")?.value;
327
- if (typeof own === "string")
328
- return own;
329
- const declared = declaredNames.get(current);
330
- if (declared !== undefined)
331
- return declared;
332
- }
333
- return;
334
- }
335
-
336
- // src/core/parse/issue.ts
337
- function withLazyCause(issue, build) {
338
- let cause;
339
- return Object.defineProperty(issue, "cause", {
340
- get: () => {
341
- cause ??= build();
342
- return cause;
343
- },
344
- enumerable: false,
345
- configurable: true
346
- });
347
- }
348
- function movedIssue(issue, path) {
349
- const moved = { ...issue, path };
350
- const cause = Object.getOwnPropertyDescriptor(issue, "cause");
351
- if (cause && !cause.enumerable)
352
- Object.defineProperty(moved, "cause", cause);
353
- return moved;
354
- }
355
-
356
- // src/core/parse/parse.ts
357
- var NO_KEY = Symbol("no key");
358
- function pathAt(parent, key) {
359
- return key === NO_KEY ? parent : [...parent, key];
360
- }
361
- function rejection(code, message, path, source) {
362
- return { issues: [{ code, message, path, source }] };
363
- }
364
- function underPath(result, path) {
365
- if (!result.issues)
366
- return result;
367
- return {
368
- issues: result.issues.map((issue) => movedIssue(issue, [...path, ...issue.path]))
369
- };
370
- }
371
- function ownIssuesUnderPath(result, path) {
372
- if (!result.issues)
373
- return result;
374
- if (result.issues.some((issue) => Object.isFrozen(issue))) {
375
- return underPath(result, path);
376
- }
377
- for (const issue of result.issues) {
378
- issue.path = [...path, ...issue.path];
379
- }
380
- return result;
381
- }
382
- var entriesOf = new WeakMap;
383
- function fieldsOf(properties) {
384
- let entries = entriesOf.get(properties);
385
- if (!entries) {
386
- entries = Object.entries(properties);
387
- entriesOf.set(properties, entries);
388
- }
389
- return entries;
390
- }
391
- function isPlainObject(value) {
392
- if (typeof value !== "object" || value === null)
393
- return false;
394
- const prototype = Object.getPrototypeOf(value);
395
- return prototype === Object.prototype || prototype === null;
396
- }
397
- function parseCollection(properties, value, path, source) {
398
- return collectionAt(properties, value, path, NO_KEY, source);
399
- }
400
- function collectionAt(properties, value, parent, key, source) {
401
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
402
- return rejection("invalid_type", "must be an object", pathAt(parent, key), source);
403
- }
404
- let issues;
405
- const path = pathAt(parent, key);
406
- for (const name of Object.keys(value)) {
407
- if (Object.hasOwn(properties, name))
408
- continue;
409
- issues ??= [];
410
- issues.push({
411
- code: "undeclared_key",
412
- message: "is not declared",
413
- path: [...path, name],
414
- source
415
- });
416
- }
417
- const handled = {};
418
- for (const [name, field] of fieldsOf(properties)) {
419
- const result = fieldAt(field, value[name], path, name, source);
420
- if (result.issues) {
421
- issues ??= [];
422
- issues.push(...result.issues);
423
- } else if (result.value !== undefined)
424
- handled[name] = result.value;
425
- }
426
- return issues ? { issues } : { value: Object.freeze(handled) };
427
- }
428
- function parseField(field, value, path, source) {
429
- return fieldAt(field, value, path, NO_KEY, source);
430
- }
431
- function fieldAt(field, value, parent, key, source) {
432
- const required = () => rejection("required", "is required", pathAt(parent, key), source);
433
- if (isBlueprintList2(field)) {
434
- if (value === undefined)
435
- return field.optional ? { value } : required();
436
- if (!Array.isArray(value)) {
437
- return rejection("invalid_type", "must be an array", pathAt(parent, key), source);
438
- }
439
- const { minItems, maxItems } = field;
440
- const path = pathAt(parent, key);
441
- let issues;
442
- if (minItems !== undefined && value.length < minItems) {
443
- issues ??= [];
444
- issues.push({
445
- code: "too_few_items",
446
- message: `must have at least ${minItems} items`,
447
- path,
448
- source
449
- });
450
- }
451
- if (maxItems !== undefined && value.length > maxItems) {
452
- issues ??= [];
453
- issues.push({
454
- code: "too_many_items",
455
- message: `must have at most ${maxItems} items`,
456
- path,
457
- source
458
- });
459
- }
460
- const items = [];
461
- for (const [index, item] of value.entries()) {
462
- const result = fieldAt(field.item, item, path, index, source);
463
- if (result.issues) {
464
- issues ??= [];
465
- issues.push(...result.issues);
466
- } else
467
- items.push(result.value);
468
- }
469
- return issues ? { issues } : { value: Object.freeze(items) };
470
- }
471
- if (isBlueprint2(field)) {
472
- if (value === undefined)
473
- return field.optional ? { value } : required();
474
- return collectionAt(field.properties, value, parent, key, source);
475
- }
476
- const record = recordFieldOf2(field);
477
- if (record) {
478
- if (value === undefined)
479
- return record.optional ? { value } : required();
480
- if (value instanceof record.record)
481
- return { value };
482
- if (!isPlainObject(value)) {
483
- return rejection("not_record", `must be an instance of record "${recordNameOf2(record.record)}"`, pathAt(parent, key), source);
484
- }
485
- const result = record.record.safeParse(value);
486
- return result.issues ? underPath(result, pathAt(parent, key)) : result;
487
- }
488
- if (isProperty2(field)) {
489
- const result = field.safeParse(value);
490
- return result.issues ? ownIssuesUnderPath(result, pathAt(parent, key)) : result;
491
- }
492
- return rejection("undeclared_key", "is not declared", pathAt(parent, key), source);
493
- }
494
-
495
- // src/core/standard/standard-schema.ts
496
- var STANDARD_VENDOR = "afora";
497
-
498
- // src/core/standard/standard.ts
499
- function standardOf(parse) {
500
- return Object.freeze({
501
- version: 1,
502
- vendor: STANDARD_VENDOR,
503
- validate: (value) => parse(value)
504
- });
505
- }
506
- function withStandard(target, parse) {
507
- return Object.defineProperty(target, "~standard", {
508
- value: standardOf(parse),
509
- enumerable: false
510
- });
511
- }
512
- var cache = new WeakMap;
513
- function standardOfClass(Class) {
514
- let standard = cache.get(Class);
515
- if (!standard) {
516
- standard = standardOf((value) => Class.safeParse(value));
517
- cache.set(Class, standard);
518
- }
519
- return standard;
520
- }
521
-
522
- // src/core/blueprint/list.ts
523
- function listOf2(item, { minItems, maxItems } = {}) {
524
- return standardListOf({
525
- [Kind2]: "list",
526
- item: fieldOf(item),
527
- optional: false,
528
- minItems,
529
- maxItems
530
- });
531
- }
532
- function standardListOf(list) {
533
- return Object.freeze(withStandard(list, (value) => parseField(list, value, [], "list")));
534
- }
535
- function isBlueprintList2(value) {
536
- return typeof value === "object" && value !== null && value[Kind2] === "list";
537
- }
538
-
539
- // src/core/exception/enums/exception-layers.ts
540
- var ExceptionLayers2;
541
- ((ExceptionLayers) => {
542
- ExceptionLayers["Schema"] = "schema";
543
- ExceptionLayers["Property"] = "property";
544
- ExceptionLayers["Blueprint"] = "blueprint";
545
- ExceptionLayers["Record"] = "record";
546
- ExceptionLayers["Entity"] = "entity";
547
- ExceptionLayers["UseCase"] = "use-case";
548
- ExceptionLayers["Repository"] = "repository";
549
- ExceptionLayers["Environment"] = "environment";
550
- ExceptionLayers["Event"] = "event";
551
- ExceptionLayers["Command"] = "command";
552
- ExceptionLayers["Application"] = "application";
553
- ExceptionLayers["Output"] = "output";
554
- })(ExceptionLayers2 ||= {});
555
-
556
- // src/core/exception/exception.ts
557
- var UNEXPECTED_ERROR2 = "UnexpectedError";
558
-
559
- class Exception2 extends Error {
560
- name;
561
- layer;
562
- source;
563
- details;
564
- cause;
565
- constructor({
566
- layer,
567
- name,
568
- source,
569
- message,
570
- details,
571
- cause
572
- }) {
573
- super(message, cause === undefined ? undefined : { cause });
574
- this.name = name;
575
- this.layer = layer;
576
- this.source = source;
577
- this.details = details;
578
- this.cause = cause;
579
- }
580
- static from(error, scope) {
581
- if (error instanceof Exception2)
582
- return error;
583
- return new Exception2({
584
- ...scope,
585
- name: UNEXPECTED_ERROR2,
586
- message: error instanceof Error ? error.message : String(error),
587
- cause: error
588
- });
589
- }
590
- get frame() {
591
- const { layer, name, source, message, details } = this;
592
- return { layer, name, source, message, details };
593
- }
594
- get trace() {
595
- return this.chain().map((exception) => exception.frame).reverse();
596
- }
597
- get origin() {
598
- return this.chain().at(-1);
599
- }
600
- find(target) {
601
- return this.chain().find((exception) => typeof target === "string" ? exception.name === target : exception instanceof target);
602
- }
603
- is(target) {
604
- return this.find(target) !== undefined;
605
- }
606
- passedThrough(layer) {
607
- return this.chain().some((exception) => exception.layer === layer);
608
- }
609
- propagate({
610
- layer,
611
- source,
612
- name = this.name,
613
- message = this.message,
614
- details
615
- }) {
616
- const keepsClass = name === this.name && details === undefined && isDeclaredInstance(this);
617
- const init = {
618
- layer,
619
- source,
620
- name,
621
- message,
622
- details: keepsClass ? this.details : details,
623
- cause: this
624
- };
625
- return keepsClass ? Reflect.construct(Exception2, [init], this.constructor) : new Exception2(init);
626
- }
627
- toJSON() {
628
- return { ...this.frame, trace: this.trace };
629
- }
630
- toString() {
631
- return this.chain().map((exception, index) => `${index === 0 ? "" : " <- "}${exception.name} [${exception.layer} @ ${exception.source}]: ${exception.message}`).join(`
632
- `);
633
- }
634
- chain() {
635
- const chain = [];
636
- for (let current = this;current instanceof Exception2; current = current.cause) {
637
- chain.push(current);
638
- }
639
- return chain;
640
- }
641
- }
642
- var declarations = new WeakMap;
643
- function isDeclaredInstance(exception) {
644
- for (let current = exception.constructor;typeof current === "function"; current = Object.getPrototypeOf(current)) {
645
- if (declarations.has(current))
646
- return true;
647
- }
648
- return false;
649
- }
650
- function isDeclaredException(value) {
651
- return typeof value === "function" && declarations.has(value);
652
- }
653
- function declaredMessageOf(Declared) {
654
- const { message } = declarations.get(Declared) ?? {};
655
- return typeof message === "string" ? message : undefined;
656
- }
657
- function exceptionOf2({
658
- layer,
659
- name,
660
- message
661
- }) {
662
-
663
- class DeclaredException extends Exception2 {
664
- static layer = layer;
665
- constructor({
666
- source,
667
- details,
668
- cause,
669
- message: custom
670
- }) {
671
- super({
672
- layer,
673
- name,
674
- source,
675
- details,
676
- cause,
677
- message: custom ?? (typeof message === "function" ? message(details, source) : message)
678
- });
679
- }
680
- }
681
- Object.defineProperty(DeclaredException, "name", { value: name });
682
- declarations.set(DeclaredException, { message });
683
- return DeclaredException;
684
- }
685
-
686
- // src/core/symbols/meta.ts
687
- var Meta2 = Symbol("meta");
688
-
689
- // src/core/record/exceptions.ts
690
- var InvalidRecordValue2 = exceptionOf2({
691
- layer: "record" /* Record */,
692
- name: "InvalidRecordValue",
693
- message: ({
694
- key,
695
- errors
696
- }, source) => `Invalid value for ${key ? `"${key}" of ` : ""}record "${source}": ${errors.join("; ")}`
697
- });
698
- var InvalidRecordDeclaration2 = exceptionOf2({
699
- layer: "record" /* Record */,
700
- name: "InvalidRecordDeclaration",
701
- message: (reason, source) => `Invalid declaration of record "${source}": ${reason}`
702
- });
703
- var UndeclaredRecordProperty2 = exceptionOf2({
704
- layer: "record" /* Record */,
705
- name: "UndeclaredRecordProperty",
706
- message: ({ key }, source) => `Property "${key}" is not declared in record "${source}".`
707
- });
708
- var ReservedRecordKey2 = exceptionOf2({
709
- layer: "record" /* Record */,
710
- name: "ReservedRecordKey",
711
- message: ({ key }, source) => `"${key}" is a member of record "${source}" and cannot be a key of its blueprint.`
712
- });
713
- var InvalidRecordPlugin2 = exceptionOf2({
714
- layer: "record" /* Record */,
715
- name: "InvalidRecordPlugin",
716
- message: ({ reason }, source) => `Invalid record plugin "${source}": ${reason}.`
717
- });
718
- var RecordPluginConflict2 = exceptionOf2({
719
- layer: "record" /* Record */,
720
- name: "RecordPluginConflict",
721
- message: ({
722
- plugin,
723
- key,
724
- owner
725
- }, source) => `Plugin "${plugin}" of record "${source}" adds "${key}", which ${owner} already has.`
726
- });
727
- var UnknownRecordPlugin2 = exceptionOf2({
728
- layer: "record" /* Record */,
729
- name: "UnknownRecordPlugin",
730
- message: ({ name }) => `No record plugin named "${name}" in the catalog.`
731
- });
732
- var IncompatibleRecordPlugin2 = exceptionOf2({
733
- layer: "record" /* Record */,
734
- name: "IncompatibleRecordPlugin",
735
- message: ({ reason }, source) => `Record plugin "${source}" does not satisfy the reference: ${reason}.`
736
- });
737
-
738
- // src/core/record/marks.ts
739
- function isMarked(field, mark, { lists = false } = {}) {
740
- if (lists && isBlueprintList2(field))
741
- return isMarked(field.item, mark, { lists });
742
- return isProperty2(field) && field.type[mark] === true;
743
- }
744
-
745
- // src/core/record/mask.ts
746
- var MASK2 = "********";
747
- function maskAll(value) {
748
- if (value === undefined || value === null)
749
- return value;
750
- if (Array.isArray(value))
751
- return Object.freeze(value.map(maskAll));
752
- if (typeof value === "object" && isRecordClass2(value.constructor)) {
753
- return maskAll(value.toJSON());
754
- }
755
- if (typeof value === "object") {
756
- return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, maskAll(item)])));
757
- }
758
- return MASK2;
759
- }
760
- function maskField(field, value, sensitive) {
761
- if (value === undefined)
762
- return value;
763
- if (recordFieldOf2(field)) {
764
- const json = value.toJSON();
765
- return sensitive ? maskAll(json) : json;
766
- }
767
- if (sensitive || isMarked(field, "sensitive"))
768
- return maskAll(value);
769
- if (isBlueprintList2(field) && Array.isArray(value)) {
770
- return Object.freeze(value.map((item) => maskField(field.item, item, false)));
771
- }
772
- if (isBlueprint2(field) && typeof value === "object" && value !== null) {
773
- return maskCollection(field.properties, value);
774
- }
775
- return value;
776
- }
777
- function maskCollection(properties, value, sensitive = []) {
778
- return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [
779
- key,
780
- maskField(properties[key], item, sensitive.includes(key))
781
- ])));
782
- }
783
-
784
- // src/core/record/abstract-record.ts
785
- var values = new WeakMap;
786
- var metadata = new WeakMap;
787
- var RESERVED_RECORD_KEYS2 = Object.freeze([
788
- "onSet",
789
- "onSetAll",
790
- "set",
791
- "toJSON",
792
- "toString",
793
- "toLocaleString",
794
- "valueOf",
795
- "hasOwnProperty",
796
- "propertyIsEnumerable",
797
- "isPrototypeOf",
798
- "__defineGetter__",
799
- "__defineSetter__",
800
- "__lookupGetter__",
801
- "__lookupSetter__",
802
- "__proto__",
803
- "constructor"
804
- ]);
805
- function exposeRecordKeys(prototype, keys) {
806
- for (const key of keys) {
807
- Object.defineProperty(prototype, key, {
808
- get() {
809
- return values.get(this)?.[key];
810
- },
811
- enumerable: true,
812
- configurable: true
813
- });
814
- }
815
- }
816
- var checked = new WeakSet;
817
- function checkMembers(record, keys) {
818
- const Class = record.constructor;
819
- if (checked.has(Class))
820
- return;
821
- for (let prototype = Object.getPrototypeOf(record);prototype !== null && !Object.hasOwn(prototype.constructor, "blueprint"); prototype = Object.getPrototypeOf(prototype)) {
822
- const key = Object.getOwnPropertyNames(prototype).find((name) => keys.includes(name));
823
- if (key !== undefined) {
824
- throw new ReservedRecordKey2({
825
- source: recordNameOf2(Class),
826
- details: { key }
827
- });
828
- }
829
- }
830
- checked.add(Class);
831
- }
832
- function withIssues(details, issues) {
833
- return Object.defineProperty(details, "issues", {
834
- value: Object.freeze([...issues]),
835
- enumerable: false
836
- });
837
- }
838
- function exceptionOfIssues(issues, source) {
839
- const [first] = issues;
840
- const key = first.path.join(".");
841
- if (first.cause) {
842
- return first.cause.propagate({
843
- layer: "record" /* Record */,
844
- source,
845
- details: withIssues({ key }, issues)
846
- });
847
- }
848
- if (first.code === "undeclared_key") {
849
- return new UndeclaredRecordProperty2({
850
- source,
851
- details: withIssues({ key }, issues)
852
- });
853
- }
854
- return new InvalidRecordValue2({
855
- source,
856
- details: withIssues({ key, errors: [first.message] }, issues)
857
- });
858
- }
859
- function issuesOfError(error, source) {
860
- const issues = error?.details?.issues;
861
- if (error instanceof Exception2 && issues)
862
- return issues;
863
- const cause = Exception2.from(error, {
864
- layer: "record" /* Record */,
865
- source
866
- });
867
- return [
868
- {
869
- code: "invalid_value",
870
- message: cause.message,
871
- path: [],
872
- source,
873
- cause
874
- }
875
- ];
876
- }
877
- function parseRecord(Class, value) {
878
- if (value instanceof Class)
879
- return { value };
880
- try {
881
- return { value: new Class(value) };
882
- } catch (error) {
883
- return { issues: issuesOfError(error, recordNameOf2(Class)) };
884
- }
885
- }
886
- function recordValue(record) {
887
- return values.get(record);
888
- }
889
- function recordDataOf(record, options) {
890
- const { properties } = record[Meta2].blueprint;
891
- return dataOfCollection(properties, values.get(record), options);
892
- }
893
- function dataOfCollection(properties, value, options) {
894
- return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [
895
- key,
896
- recordFieldDataOf(properties[key], item, options)
897
- ])));
898
- }
899
- function recordFieldDataOf(field, value, options) {
900
- if (value === undefined || value === null)
901
- return value;
902
- if (value instanceof AbstractRecord2) {
903
- return options?.reference?.(value) ?? recordDataOf(value, options);
904
- }
905
- if (isBlueprintList2(field) && Array.isArray(value)) {
906
- return Object.freeze(value.map((item) => recordFieldDataOf(field.item, item, options)));
907
- }
908
- if (isBlueprint2(field) && typeof value === "object") {
909
- return dataOfCollection(field.properties, value, options);
910
- }
911
- return value;
912
- }
913
- function storeRecordValue(record, key, value) {
914
- const source = recordNameOf2(record.constructor);
915
- const { properties } = record[Meta2].blueprint;
916
- if (!Object.hasOwn(properties, key)) {
917
- throw exceptionOfIssues([
918
- {
919
- code: "undeclared_key",
920
- message: "is not declared",
921
- path: [key],
922
- source
923
- }
924
- ], source);
925
- }
926
- const current = values.get(record);
927
- const previous = current[key];
928
- const result = parseField(properties[key], value, [key], source);
929
- if (result.issues)
930
- throw exceptionOfIssues(result.issues, source);
931
- const next = result.value;
932
- const { [key]: _, ...rest } = current;
933
- values.set(record, Object.freeze(next === undefined ? rest : { ...rest, [key]: next }));
934
- return { next, previous };
935
- }
936
- var RecordPluginHooks = Symbol("recordPluginHooks");
937
- function runRecordEffects(record, key, next, previous) {
938
- const pluginHooks = record.constructor[RecordPluginHooks];
939
- if (pluginHooks !== undefined && pluginHooks.length > 0) {
940
- const name = String(key);
941
- for (const hook of pluginHooks) {
942
- if (!hook.keys.includes(name))
943
- continue;
944
- hook.onSetAll?.call(record, { key, value: next, previous });
945
- hook.onSet?.call(record)[name]?.call(record, next, previous);
946
- }
947
- }
948
- const hooks = record;
949
- hooks.onSetAll({ key, value: next, previous });
950
- hooks.onSet()[key]?.(next, previous);
951
- return record;
952
- }
953
-
954
- class AbstractRecord2 {
955
- get [Meta2]() {
956
- const Class = this.constructor;
957
- let declaration = metadata.get(Class);
958
- if (!declaration) {
959
- const { blueprint, options } = Class;
960
- declaration = Object.freeze({ blueprint, options });
961
- metadata.set(Class, declaration);
962
- }
963
- return declaration;
964
- }
965
- constructor(value) {
966
- checkMembers(this, Object.keys(this[Meta2].blueprint.properties));
967
- const source = recordNameOf2(this.constructor);
968
- const result = parseCollection(this[Meta2].blueprint.properties, value, [], source);
969
- if (result.issues)
970
- throw exceptionOfIssues(result.issues, source);
971
- values.set(this, result.value);
972
- }
973
- static safeParse(value) {
974
- return parseRecord(this, value);
975
- }
976
- static get "~standard"() {
977
- return standardOfClass(this);
978
- }
979
- toJSON() {
980
- return maskCollection(this[Meta2].blueprint.properties, recordValue(this), this[Meta2].options.sensitive);
981
- }
982
- set(key, value) {
983
- const { next, previous } = storeRecordValue(this, String(key), value);
984
- return runRecordEffects(this, key, next, previous);
985
- }
986
- onSetAll(_change) {}
987
- onSet() {
988
- return {};
989
- }
990
- }
991
-
992
- // src/core/record/plugin.ts
993
- var RecordPlugins = Symbol("recordPlugins");
994
- var IdentifiedRecord = Symbol("identifiedRecord");
995
- var SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
996
- function isVersion(version) {
997
- return typeof version === "string" && SEMVER.test(version);
998
- }
999
- function versionParts(version) {
1000
- const [, major, minor, patch] = SEMVER.exec(version);
1001
- return [Number(major), Number(minor), Number(patch)];
1002
- }
1003
- function satisfies(available, requested) {
1004
- const [major, minor, patch] = versionParts(available);
1005
- const [wantedMajor, wantedMinor, wantedPatch] = versionParts(requested);
1006
- if (major !== wantedMajor)
1007
- return false;
1008
- if (major === 0 && minor !== wantedMinor)
1009
- return false;
1010
- if (minor !== wantedMinor)
1011
- return minor > wantedMinor;
1012
- return patch >= wantedPatch;
1013
- }
1014
- var HOOKS = ["onSet", "onSetAll"];
1015
- var internals = new WeakMap;
1016
- function pluginsOf2(value) {
1017
- const Class = typeof value === "function" ? value : typeof value === "object" && value !== null ? value.constructor : undefined;
1018
- return Class?.[RecordPlugins] ?? [];
1019
- }
1020
- function isRecordPlugin2(value) {
1021
- return typeof value === "object" && value !== null && value[Kind2] === "record-plugin";
1022
- }
1023
- function hasPlugin2(value, plugin) {
1024
- const plugins = pluginsOf2(value);
1025
- if (typeof plugin === "string") {
1026
- return plugins.some((applied) => applied.name === plugin);
1027
- }
1028
- if (plugins.includes(plugin))
1029
- return true;
1030
- return typeof value === "function" ? value === plugin.record || value.prototype instanceof plugin.record : value instanceof plugin.record;
1031
- }
1032
- function membersOf(Record, name) {
1033
- const descriptors = {};
1034
- const hooks = {};
1035
- for (let prototype = Record.prototype;prototype !== null && !Object.hasOwn(prototype.constructor, "blueprint"); prototype = Object.getPrototypeOf(prototype)) {
1036
- for (const member of Object.getOwnPropertyNames(prototype)) {
1037
- if (member === "constructor")
1038
- continue;
1039
- const descriptor = Object.getOwnPropertyDescriptor(prototype, member);
1040
- if (HOOKS.includes(member)) {
1041
- hooks[member] ??= descriptor.value;
1042
- continue;
1043
- }
1044
- if (RESERVED_RECORD_KEYS2.includes(member)) {
1045
- throw new InvalidRecordPlugin2({
1046
- source: name,
1047
- details: {
1048
- reason: `"${member}" is a member of every record and cannot be replaced`
1049
- }
1050
- });
1051
- }
1052
- descriptors[member] ??= descriptor;
1053
- }
1054
- }
1055
- return { descriptors: Object.freeze(descriptors), hooks };
1056
- }
1057
- function recordPluginOf2(name, Record, { version = "1.0.0", description } = {}) {
1058
- if (typeof name !== "string" || name.length === 0) {
1059
- throw new InvalidRecordPlugin2({
1060
- source: String(name),
1061
- details: { reason: "its name must be a non-empty string" }
1062
- });
1063
- }
1064
- if (!isRecordClass2(Record)) {
1065
- throw new InvalidRecordPlugin2({
1066
- source: name,
1067
- details: { reason: "it must be made from a class of `recordOf`" }
1068
- });
1069
- }
1070
- if (Record[IdentifiedRecord]) {
1071
- throw new InvalidRecordPlugin2({
1072
- source: name,
1073
- details: {
1074
- reason: "it must be made from a record, not an entity: plugins have no identity"
1075
- }
1076
- });
1077
- }
1078
- if (!isVersion(version)) {
1079
- throw new InvalidRecordPlugin2({
1080
- source: name,
1081
- details: { reason: `"${version}" is not a semantic version` }
1082
- });
1083
- }
1084
- const requires = pluginsOf2(Record);
1085
- const inherited = new Set(requires.flatMap((required) => required.keys));
1086
- const declaration = Record;
1087
- const keys = Object.freeze(Object.keys(declaration.blueprint.properties).filter((key) => !inherited.has(key)));
1088
- const own = membersOf(Record, name);
1089
- const plugin = Object.freeze({
1090
- [Kind2]: "record-plugin",
1091
- name,
1092
- version,
1093
- ...description === undefined ? {} : { description },
1094
- record: Record,
1095
- keys,
1096
- members: Object.freeze(Object.keys(own.descriptors)),
1097
- options: declaration.options,
1098
- requires,
1099
- is: (value) => hasPlugin2(value, plugin),
1100
- toJSON: () => descriptorOf(plugin)
1101
- });
1102
- internals.set(plugin, own);
1103
- return plugin;
1104
- }
1105
- function descriptorOf(plugin) {
1106
- return Object.freeze({
1107
- kind: "record-plugin",
1108
- name: plugin.name,
1109
- version: plugin.version,
1110
- ...plugin.description === undefined ? {} : { description: plugin.description },
1111
- keys: plugin.keys,
1112
- sensitive: plugin.options.sensitive,
1113
- unique: plugin.options.unique,
1114
- change: plugin.options.change,
1115
- members: plugin.members,
1116
- requires: Object.freeze(plugin.requires.map(({ name, version }) => Object.freeze({ name, version })))
1117
- });
1118
- }
1119
- function applyPlugins(blueprint, plugins, name, reserved) {
1120
- const flat = [];
1121
- for (const plugin of plugins) {
1122
- if (!isRecordPlugin2(plugin)) {
1123
- throw new InvalidRecordPlugin2({
1124
- source: name,
1125
- details: {
1126
- reason: "`options.plugins` takes plugins made by `recordPluginOf`"
1127
- }
1128
- });
1129
- }
1130
- for (const applied of [...plugin.requires, plugin]) {
1131
- if (flat.includes(applied))
1132
- continue;
1133
- if (flat.some((other) => other.name === applied.name)) {
1134
- throw new RecordPluginConflict2({
1135
- source: name,
1136
- details: {
1137
- plugin: applied.name,
1138
- key: applied.name,
1139
- owner: "another plugin"
1140
- }
1141
- });
1142
- }
1143
- flat.push(applied);
1144
- }
1145
- }
1146
- const owners = new Map(Object.keys(blueprint.properties).map((key) => [key, `record "${name}"`]));
1147
- for (const member of reserved)
1148
- owners.set(member, `record "${name}"`);
1149
- const claim = (plugin, key) => {
1150
- const owner = owners.get(key);
1151
- if (owner !== undefined) {
1152
- throw new RecordPluginConflict2({
1153
- source: name,
1154
- details: { plugin: plugin.name, key, owner }
1155
- });
1156
- }
1157
- owners.set(key, `plugin "${plugin.name}"`);
1158
- };
1159
- const descriptors = {};
1160
- const hooks = [];
1161
- for (const plugin of flat) {
1162
- for (const key of plugin.keys)
1163
- claim(plugin, key);
1164
- const own = internals.get(plugin);
1165
- for (const member of plugin.members) {
1166
- claim(plugin, member);
1167
- descriptors[member] = own.descriptors[member];
1168
- }
1169
- if (own.hooks.onSet || own.hooks.onSetAll) {
1170
- hooks.push(Object.freeze({
1171
- plugin,
1172
- keys: Object.freeze(Object.keys(plugin.record.blueprint.properties)),
1173
- ...own.hooks
1174
- }));
1175
- }
1176
- }
1177
- return {
1178
- blueprint: flat.length === 0 ? blueprint : blueprint.join(...flat.map((plugin) => plugin.record.blueprint)),
1179
- plugins: Object.freeze(flat),
1180
- sensitive: flat.flatMap((plugin) => plugin.options.sensitive),
1181
- unique: flat.flatMap((plugin) => plugin.options.unique),
1182
- change: flat.flatMap((plugin) => plugin.options.change),
1183
- descriptors,
1184
- hooks: Object.freeze(hooks)
1185
- };
1186
- }
1187
-
1188
- // src/core/record/record.ts
1189
- function recordBuilderOf2(...catalogs) {
1190
- const context = pluginContextOf(catalogs);
1191
- return (blueprint, options = {}) => declareRecord(AbstractRecord2, blueprint, options, "record", [], context);
1192
- }
1193
- function pluginContextOf(catalogs) {
1194
- return Object.freeze(Object.assign({}, ...catalogs.map((catalog) => catalog.plugins)));
1195
- }
1196
- var recordOf3 = recordBuilderOf2();
1197
- function declareRecord(Base, declared, { plugins = [], name: declaredName, ...declaredOptions }, fallback, reserved = [], context = {}) {
1198
- if (declaredName !== undefined && !isRecordName(declaredName)) {
1199
- throw new InvalidRecordDeclaration2({
1200
- source: fallback,
1201
- details: `"name" must be an identifier, got ${JSON.stringify(declaredName)}.`
1202
- });
1203
- }
1204
- const name = declaredName ?? fallback;
1205
- const applied = applyPlugins(declared, typeof plugins === "function" ? plugins(context) : plugins, name, reserved);
1206
- const blueprint = applied.blueprint;
1207
- const sensitive = [
1208
- ...declaredOptions.sensitive ?? [],
1209
- ...applied.sensitive
1210
- ];
1211
- const unique = [...declaredOptions.unique ?? [], ...applied.unique];
1212
- const declaredChange = declaredOptions.change ?? [];
1213
- const keys = Object.keys(blueprint.properties);
1214
- const change = keys.filter((key) => declaredChange.includes(key) || applied.change.includes(key));
1215
- for (const key of [...sensitive, ...unique, ...declaredChange]) {
1216
- if (!keys.includes(key)) {
1217
- throw new UndeclaredRecordProperty2({
1218
- source: name,
1219
- details: { key }
1220
- });
1221
- }
1222
- }
1223
- const methods = change.length > 0 ? [CHANGE_MEMBER] : [];
1224
- for (const member of Object.keys(applied.descriptors)) {
1225
- if (methods.includes(member)) {
1226
- const plugin = applied.plugins.find((plugin) => plugin.members.includes(member));
1227
- throw new RecordPluginConflict2({
1228
- source: name,
1229
- details: {
1230
- plugin: plugin.name,
1231
- key: member,
1232
- owner: `record "${name}" (the \`change\` namespace)`
1233
- }
1234
- });
1235
- }
1236
- }
1237
- for (const key of keys) {
1238
- if (RESERVED_RECORD_KEYS2.includes(key) || reserved.includes(key) || methods.includes(key)) {
1239
- throw new ReservedRecordKey2({ source: name, details: { key } });
1240
- }
1241
- }
1242
- const options = Object.freeze({
1243
- sensitive: Object.freeze(keys.filter((key) => sensitive.includes(key) || isMarked(blueprint.properties[key], "sensitive", { lists: true }))),
1244
- unique: Object.freeze(keys.filter((key) => unique.includes(key) || isMarked(blueprint.properties[key], "unique"))),
1245
- change: Object.freeze([...change])
1246
- });
1247
-
1248
- class DeclaredRecord extends Base {
1249
- static [Kind2] = "record";
1250
- static blueprint = blueprint;
1251
- static options = options;
1252
- static plugins = applied.plugins;
1253
- static [RecordPlugins] = applied.plugins;
1254
- static [RecordPluginHooks] = applied.hooks;
1255
- }
1256
- if (declaredName !== undefined) {
1257
- declareRecordName(DeclaredRecord, declaredName);
1258
- }
1259
- Object.defineProperty(DeclaredRecord, "recordName", {
1260
- get() {
1261
- return declaredName ?? this.name;
1262
- },
1263
- configurable: true
1264
- });
1265
- exposeRecordKeys(DeclaredRecord.prototype, keys);
1266
- for (const [member, descriptor] of Object.entries(applied.descriptors)) {
1267
- Object.defineProperty(DeclaredRecord.prototype, member, descriptor);
1268
- }
1269
- if (change.length > 0) {
1270
- Object.defineProperty(DeclaredRecord.prototype, CHANGE_MEMBER, {
1271
- get() {
1272
- let namespace = changeNamespaces.get(this);
1273
- if (namespace === undefined) {
1274
- namespace = Object.freeze(Object.fromEntries(change.map((key) => [
1275
- key,
1276
- (value) => this.set(key, value)
1277
- ])));
1278
- changeNamespaces.set(this, namespace);
1279
- }
1280
- return namespace;
1281
- },
1282
- configurable: true
1283
- });
1284
- }
1285
- Object.defineProperty(DeclaredRecord, "name", { value: name });
1286
- return DeclaredRecord;
1287
- }
1288
- var CHANGE_MEMBER = "change";
1289
- var changeNamespaces = new WeakMap;
1290
-
1291
- // src/core/blueprint/optional.ts
1292
- import { Type } from "typebox";
1293
- var cache2 = new WeakMap;
1294
- function optionalOf2(given) {
1295
- const field = fieldOf(given);
1296
- const cached = cache2.get(field);
1297
- if (cached)
1298
- return cached;
1299
- if (isOptionalRecord2(field))
1300
- return field;
1301
- if (isRecordClass2(field)) {
1302
- const optional = Object.freeze(withStandard({
1303
- [Kind2]: "record",
1304
- record: field,
1305
- optional: true
1306
- }, (value) => value === undefined ? { value } : field.safeParse(value)));
1307
- cache2.set(field, optional);
1308
- return optional;
1309
- }
1310
- if (isBlueprint2(field)) {
1311
- if (field.optional)
1312
- return field;
1313
- const optional = {
1314
- ...field,
1315
- optional: true,
1316
- safeParse: (value) => value === undefined ? { value } : field.safeParse(value)
1317
- };
1318
- Object.freeze(withStandard(optional, (value) => optional.safeParse(value)));
1319
- cache2.set(field, optional);
1320
- return optional;
1321
- }
1322
- if (isBlueprintList2(field)) {
1323
- if (field.optional)
1324
- return field;
1325
- const optional = standardListOf({ ...field, optional: true });
1326
- cache2.set(field, optional);
1327
- return optional;
1328
- }
1329
- const Property = field;
1330
- if (Property.type.optional)
1331
- return Property;
1332
- const base = Property.type;
1333
- const SchemaConstructor = schemaOf2(base.name, Type.Optional(base.schema.type.Type()));
1334
- const type = {
1335
- ...base,
1336
- schema: new SchemaConstructor,
1337
- optional: true
1338
- };
1339
- const Optional = derivePropertyOf(Property, type);
1340
- recordPropertyLineage(Optional, { kind: "optional", base: Property });
1341
- cache2.set(Property, Optional);
1342
- return Optional;
1343
- }
1344
-
1345
- // src/core/blueprint/exceptions.ts
1346
- var ReservedBlueprintKey2 = exceptionOf2({
1347
- layer: "blueprint" /* Blueprint */,
1348
- name: "ReservedBlueprintKey",
1349
- message: ({ key }) => `"${key}" is reserved and cannot be a plugin property.`
1350
- });
1351
- var UndeclaredBlueprintProperty2 = exceptionOf2({
1352
- layer: "blueprint" /* Blueprint */,
1353
- name: "UndeclaredBlueprintProperty",
1354
- message: ({ key }) => `Property "${key}" of the blueprint is not declared.`
1355
- });
1356
-
1357
- // src/core/property/exceptions.ts
1358
- var PropertyRequired2 = exceptionOf2({
1359
- layer: "property" /* Property */,
1360
- name: "PropertyRequired",
1361
- message: (_, source) => `Property "${source}" is required.`
1362
- });
1363
- var InvalidPropertyValue2 = exceptionOf2({
1364
- layer: "property" /* Property */,
1365
- name: "InvalidPropertyValue",
1366
- message: ({ errors }, source) => `Invalid value for property "${source}": ${errors.join("; ")}`
1367
- });
1368
-
1369
- // src/core/blueprint/blueprint.ts
1370
- import { Type as Type3 } from "typebox";
1371
-
1372
- // src/core/property/property.ts
1373
- import { Type as Type2 } from "typebox";
1374
-
1375
- // src/core/symbols/state.ts
1376
- var State2 = Symbol("state");
1377
-
1378
- // src/core/property/abstract-property.ts
1379
- var parsingDefinitions = new WeakMap;
1380
- function parsingDefinitionOf(Class) {
1381
- let definition = parsingDefinitions.get(Class);
1382
- if (!definition) {
1383
- definition = Object.create(Class.prototype).createDefinition();
1384
- parsingDefinitions.set(Class, definition);
1385
- }
1386
- return definition;
1387
- }
1388
-
1389
- class AbstractProperty2 {
1390
- get [State2]() {
1391
- return this.definition[State2];
1392
- }
1393
- definition;
1394
- value;
1395
- constructor(value) {
1396
- this.definition = this.createDefinition();
1397
- this.value = this.definition.make(value === Demo2 ? this.definition.type[Demo2] : value);
1398
- }
1399
- static demo() {
1400
- return new this(Demo2);
1401
- }
1402
- static safeParse(value) {
1403
- return parsingDefinitionOf(this).parse(value);
1404
- }
1405
- static with(options) {
1406
- return refinePropertyOf(this, options);
1407
- }
1408
- static get "~standard"() {
1409
- return standardOfClass(this);
1410
- }
1411
- }
1412
-
1413
- // src/core/property/enums/property-states.ts
1414
- var PropertyStates2;
1415
- ((PropertyStates) => {
1416
- PropertyStates[PropertyStates["Declared"] = 0] = "Declared";
1417
- PropertyStates[PropertyStates["PreHandling"] = 1] = "PreHandling";
1418
- PropertyStates[PropertyStates["Handling"] = 2] = "Handling";
1419
- PropertyStates[PropertyStates["AfterHandling"] = 3] = "AfterHandling";
1420
- PropertyStates[PropertyStates["Done"] = 4] = "Done";
1421
- })(PropertyStates2 ||= {});
1422
-
1423
- // src/core/property/define-property.ts
1424
- var MISMATCH = Symbol("mismatch");
1425
- function once(build) {
1426
- let result;
1427
- return () => {
1428
- result ??= build();
1429
- return result;
1430
- };
1431
- }
1432
- function segmentsOf(pointer) {
1433
- if (pointer === "")
1434
- return [];
1435
- return pointer.slice(1).split("/").map((segment) => {
1436
- const key = segment.replaceAll("~1", "/").replaceAll("~0", "~");
1437
- return /^(0|[1-9]\d*)$/.test(key) ? Number(key) : key;
1438
- });
1439
- }
1440
-
1441
- class AbstractDefineProperty2 {
1442
- [State2] = 0 /* Declared */;
1443
- make(value) {
1444
- const attempt = this.attempt(value);
1445
- if ("failure" in attempt)
1446
- throw attempt.failure.exception();
1447
- return attempt.value;
1448
- }
1449
- parse(value) {
1450
- const attempt = this.attemptWithoutThrowing(value);
1451
- if (!("failure" in attempt))
1452
- return { value: attempt.value };
1453
- const { exception, raised, issues } = attempt.failure;
1454
- return {
1455
- issues: issues.map((issue) => raised ? { ...issue, cause: exception() } : withLazyCause(issue, exception))
1456
- };
1457
- }
1458
- preHandle(value) {
1459
- return value;
1460
- }
1461
- afterHandle(value) {
1462
- return value;
1463
- }
1464
- handle(value) {
1465
- return this.type.schema.match(value) ? value : MISMATCH;
1466
- }
1467
- attemptWithoutThrowing(value) {
1468
- try {
1469
- return this.attempt(value);
1470
- } catch (error) {
1471
- return {
1472
- failure: this.raise(error instanceof Exception2 ? error : this.invalidValue(error))
1473
- };
1474
- }
1475
- }
1476
- attempt(value) {
1477
- const { name, optional } = this.type;
1478
- this[State2] = 0 /* Declared */;
1479
- if (value === undefined) {
1480
- if (!optional) {
1481
- return {
1482
- failure: {
1483
- exception: () => new PropertyRequired2({ source: name }),
1484
- raised: false,
1485
- issues: [
1486
- {
1487
- message: "is required",
1488
- path: [],
1489
- code: "required",
1490
- source: name
1491
- }
1492
- ]
1493
- }
1494
- };
1495
- }
1496
- this[State2] = 4 /* Done */;
1497
- return { value };
1498
- }
1499
- if (!this.type.schema.matchShape(value)) {
1500
- return { failure: this.mismatch(value) };
1501
- }
1502
- try {
1503
- this[State2] = 1 /* PreHandling */;
1504
- value = this.runHandler(() => this.preHandle(value));
1505
- this[State2] = 2 /* Handling */;
1506
- const handled = this.handle(value);
1507
- if (handled === MISMATCH) {
1508
- return { failure: this.mismatch(value) };
1509
- }
1510
- value = handled;
1511
- this[State2] = 3 /* AfterHandling */;
1512
- value = this.runHandler(() => this.afterHandle(value));
1513
- } catch (error) {
1514
- if (error instanceof Exception2)
1515
- return { failure: this.raise(error) };
1516
- throw error;
1517
- }
1518
- this[State2] = 4 /* Done */;
1519
- return { value };
1520
- }
1521
- runHandler(handler) {
1522
- try {
1523
- return handler();
1524
- } catch (error) {
1525
- if (error instanceof Exception2)
1526
- throw error;
1527
- throw this.invalidValue(error);
1528
- }
1529
- }
1530
- invalidValue(error) {
1531
- return new InvalidPropertyValue2({
1532
- source: this.type.name,
1533
- details: {
1534
- errors: [error instanceof Error ? error.message : String(error)]
1535
- },
1536
- cause: error
1537
- });
1538
- }
1539
- raise(exception) {
1540
- return {
1541
- exception: () => exception,
1542
- raised: true,
1543
- issues: [
1544
- {
1545
- message: exception.message,
1546
- path: [],
1547
- code: "invalid_value",
1548
- source: this.type.name
1549
- }
1550
- ]
1551
- };
1552
- }
1553
- mismatch(value) {
1554
- const { name, schema } = this.type;
1555
- const errors = schema.type.Errors(value);
1556
- const issues = errors.map((error) => ({
1557
- message: error.message,
1558
- path: segmentsOf(error.instancePath),
1559
- code: "invalid_value",
1560
- source: name
1561
- }));
1562
- return {
1563
- exception: once(() => new InvalidPropertyValue2({
1564
- source: name,
1565
- details: { errors: errors.map(describeError) }
1566
- })),
1567
- raised: false,
1568
- issues: issues.length > 0 ? issues : [
1569
- {
1570
- message: "is invalid",
1571
- path: [],
1572
- code: "invalid_value",
1573
- source: name
1574
- }
1575
- ]
1576
- };
1577
- }
1578
- }
1579
-
1580
- // src/core/property/property.ts
1581
- function propertyOf2({
1582
- name,
1583
- schema,
1584
- optional,
1585
- sensitive = false,
1586
- unique = false,
1587
- default: _default,
1588
- preHandle: onPreHandle,
1589
- afterHandle: onAfterHandle
1590
- }) {
1591
- const valueSchema = optional ? Type2.Optional(schema) : schema;
1592
- const SchemaConstructor = schemaOf2(name, valueSchema);
1593
- const type = {
1594
- [Demo2]: _default,
1595
- name,
1596
- schema: new SchemaConstructor,
1597
- optional: optional ?? false,
1598
- sensitive,
1599
- unique
1600
- };
1601
-
1602
- class DefineProperty extends AbstractDefineProperty2 {
1603
- get type() {
1604
- return type;
1605
- }
1606
- preHandle(value) {
1607
- return onPreHandle ? onPreHandle(value) : value;
1608
- }
1609
- afterHandle(value) {
1610
- return onAfterHandle ? onAfterHandle(value) : value;
1611
- }
1612
- }
1613
-
1614
- class Property extends AbstractProperty2 {
1615
- static type = type;
1616
- createDefinition() {
1617
- return new DefineProperty;
1618
- }
1619
- }
1620
- return Property;
1621
- }
1622
-
1623
- // src/core/blueprint/blueprint.ts
1624
- function blueprintBuilderOf2(...base) {
1625
- return (sourcesOrDefine, maybeDefine) => {
1626
- const [sources, define] = typeof sourcesOrDefine === "function" ? [[], sourcesOrDefine] : [
1627
- sourcesOrDefine,
1628
- maybeDefine
1629
- ];
1630
- const all = [...base, ...sources];
1631
- return create(all.flatMap((source) => isBlueprint2(source) ? source.plugins : [source]), { ...define(contextOf(all)) });
1632
- };
1633
- }
1634
- function blueprintFromProperties(plugins, properties) {
1635
- return create(plugins, { ...properties });
1636
- }
1637
- function create(plugins, properties) {
1638
- const shape = {};
1639
- for (const [key, field] of Object.entries(properties)) {
1640
- properties[key] = fieldOf(field);
1641
- shape[key] = schemaOfField(key, properties[key]);
1642
- }
1643
- const SchemaConstructor = schemaOf2("blueprint", Type3.Object(shape));
1644
- const blueprint = {
1645
- [Kind2]: "blueprint",
1646
- plugins: Object.freeze([...new Set(plugins)]),
1647
- properties: Object.freeze(properties),
1648
- schema: new SchemaConstructor,
1649
- optional: false,
1650
- safeParse: (value) => parseCollection(properties, value, [], "blueprint"),
1651
- join: (...others) => create([blueprint, ...others].flatMap((source) => source.plugins), Object.assign({}, ...[blueprint, ...others].map((source) => source.properties)))
1652
- };
1653
- return Object.freeze(withStandard(blueprint, (value) => blueprint.safeParse(value)));
1654
- }
1655
- var HELPERS = { listOf: listOf2, optionalOf: optionalOf2, propertyOf: propertyOf2 };
1656
- var RESERVED_KEYS = ["optional", "list", ...Object.keys(HELPERS)];
1657
- function contextOf(sources) {
1658
- for (const key of RESERVED_KEYS) {
1659
- const reserving = sources.find((source) => Object.hasOwn(source.properties, key));
1660
- if (reserving) {
1661
- throw new ReservedBlueprintKey2({
1662
- source: isBlueprint2(reserving) ? "blueprint" : reserving.name,
1663
- details: { key }
1664
- });
1665
- }
1666
- }
1667
- const factories = Object.assign({}, ...sources.map((source) => isBlueprint2(source) ? {} : source.factories ?? {}));
1668
- for (const key of RESERVED_KEYS) {
1669
- if (Object.hasOwn(factories, key)) {
1670
- const reserving = sources.find((source) => !isBlueprint2(source) && Object.hasOwn(source.factories ?? {}, key));
1671
- throw new ReservedBlueprintKey2({
1672
- source: reserving.name,
1673
- details: { key }
1674
- });
1675
- }
1676
- }
1677
- const available = Object.assign({}, ...sources.map((source) => source.properties));
1678
- for (const key of Object.keys(factories))
1679
- delete available[key];
1680
- const mirror = (fields, map) => Object.fromEntries(Object.entries(fields).map(([key, field]) => [key, map(field)]));
1681
- const list = mirror(available, (field) => listOf2(field));
1682
- const callable = (field) => isProperty2(field) ? callableOf(field) : field;
1683
- return Object.freeze({
1684
- ...mirror(available, callable),
1685
- ...factories,
1686
- ...HELPERS,
1687
- optional: Object.freeze(mirror(available, (field) => callable(optionalOf2(field)))),
1688
- list: Object.freeze({
1689
- ...list,
1690
- optional: Object.freeze(mirror(list, optionalOf2))
1691
- })
1692
- });
1693
- }
1694
- function schemaOfField(key, field) {
1695
- if (isBlueprintList2(field)) {
1696
- const { item, minItems, maxItems } = field;
1697
- const schema = Type3.Array(schemaOfField(key, item), {
1698
- ...minItems === undefined ? {} : { minItems },
1699
- ...maxItems === undefined ? {} : { maxItems }
1700
- });
1701
- return field.optional ? Type3.Optional(schema) : schema;
1702
- }
1703
- if (isBlueprint2(field)) {
1704
- const schema = field.schema.type.Type();
1705
- return field.optional ? Type3.Optional(schema) : schema;
1706
- }
1707
- const record = recordFieldOf2(field);
1708
- if (record) {
1709
- const schema = record.record.blueprint.schema.type.Type();
1710
- return record.optional ? Type3.Optional(schema) : schema;
1711
- }
1712
- if (isProperty2(field)) {
1713
- return field.type.schema.type.Type();
1714
- }
1715
- throw new UndeclaredBlueprintProperty2({
1716
- source: "blueprint",
1717
- details: { key }
1718
- });
1719
- }
1720
-
1721
- export { __export, isProperty2, schemaOf2, Demo2, recordPropertyLineage, propertyLineageOf2, fieldOf, Kind2, isBlueprint2, isRecordClass2, isOptionalRecord2, recordFieldOf2, recordNameOf2, declaredRecordNameOf, listOf2, isBlueprintList2, ExceptionLayers2, UNEXPECTED_ERROR2, Exception2, isDeclaredException, declaredMessageOf, exceptionOf2, Meta2, InvalidRecordValue2, InvalidRecordDeclaration2, UndeclaredRecordProperty2, ReservedRecordKey2, InvalidRecordPlugin2, RecordPluginConflict2, UnknownRecordPlugin2, IncompatibleRecordPlugin2, exports_exceptions, MASK2, RESERVED_RECORD_KEYS2, recordDataOf, recordFieldDataOf, storeRecordValue, runRecordEffects, AbstractRecord2, IdentifiedRecord, isVersion, satisfies, pluginsOf2, isRecordPlugin2, hasPlugin2, recordPluginOf2, recordBuilderOf2, pluginContextOf, recordOf3, declareRecord, optionalOf2, ReservedBlueprintKey2, UndeclaredBlueprintProperty2, exports_exceptions2, PropertyRequired2, InvalidPropertyValue2, exports_exceptions3, State2, AbstractProperty2, PropertyStates2, AbstractDefineProperty2, propertyOf2, blueprintBuilderOf2, blueprintFromProperties };