@cullet/erp-core 1.3.0 → 1.5.0

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 (197) hide show
  1. package/KIT_CONTEXT.md +11 -3
  2. package/README.md +160 -0
  3. package/dist/abac/index.cjs +7 -0
  4. package/dist/abac/index.d.cts +2 -0
  5. package/dist/abac/index.d.ts +2 -0
  6. package/dist/abac/index.js +2 -0
  7. package/dist/app-error.cjs +201 -0
  8. package/dist/app-error.cjs.map +1 -0
  9. package/dist/app-error.js +178 -0
  10. package/dist/app-error.js.map +1 -0
  11. package/dist/application/index.cjs +2 -1
  12. package/dist/application/index.d.cts +2 -1
  13. package/dist/application/index.d.ts +2 -1
  14. package/dist/application/index.js +2 -1
  15. package/dist/authorization-error.cjs +157 -0
  16. package/dist/authorization-error.cjs.map +1 -0
  17. package/dist/authorization-error.d.cts +113 -0
  18. package/dist/authorization-error.d.ts +113 -0
  19. package/dist/authorization-error.js +152 -0
  20. package/dist/authorization-error.js.map +1 -0
  21. package/dist/authorizer.port.d.cts +130 -0
  22. package/dist/authorizer.port.d.ts +130 -0
  23. package/dist/composite-authorizer.d.cts +216 -0
  24. package/dist/composite-authorizer.d.ts +216 -0
  25. package/dist/condition-evaluator.cjs +579 -0
  26. package/dist/condition-evaluator.cjs.map +1 -0
  27. package/dist/condition-evaluator.js +550 -0
  28. package/dist/condition-evaluator.js.map +1 -0
  29. package/dist/{gate-types.d.ts → core-config.d.cts} +78 -77
  30. package/dist/{gate-types.d.cts → core-config.d.ts} +78 -77
  31. package/dist/domain/index.cjs +2 -1
  32. package/dist/domain/index.d.cts +2 -1
  33. package/dist/domain/index.d.ts +2 -1
  34. package/dist/domain/index.js +2 -1
  35. package/dist/domain-event-contracts.cjs +3 -2
  36. package/dist/domain-event-contracts.cjs.map +1 -1
  37. package/dist/domain-event-contracts.js +2 -1
  38. package/dist/domain-event-contracts.js.map +1 -1
  39. package/dist/entity.cjs +122 -0
  40. package/dist/entity.cjs.map +1 -0
  41. package/dist/entity.js +111 -0
  42. package/dist/entity.js.map +1 -0
  43. package/dist/errors/index.cjs +10 -7
  44. package/dist/errors/index.d.cts +2 -1
  45. package/dist/errors/index.d.ts +2 -1
  46. package/dist/errors/index.js +6 -3
  47. package/dist/gate-engine-registry.cjs +5 -4
  48. package/dist/gate-engine-registry.cjs.map +1 -1
  49. package/dist/gate-engine-registry.d.cts +3 -2
  50. package/dist/gate-engine-registry.d.ts +3 -2
  51. package/dist/gate-engine-registry.js +2 -1
  52. package/dist/gate-engine-registry.js.map +1 -1
  53. package/dist/gate-v1-payload.schema.cjs +0 -562
  54. package/dist/gate-v1-payload.schema.cjs.map +1 -1
  55. package/dist/gate-v1-payload.schema.js +1 -533
  56. package/dist/gate-v1-payload.schema.js.map +1 -1
  57. package/dist/hashing.cjs +2 -44
  58. package/dist/hashing.cjs.map +1 -1
  59. package/dist/hashing.js +2 -38
  60. package/dist/hashing.js.map +1 -1
  61. package/dist/index.cjs +36 -17
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +19 -12
  64. package/dist/index.d.ts +19 -12
  65. package/dist/index.js +17 -10
  66. package/dist/index.js.map +1 -1
  67. package/dist/not-found-error.cjs +5 -5
  68. package/dist/not-found-error.cjs.map +1 -1
  69. package/dist/not-found-error.js +1 -1
  70. package/dist/outcome.d.cts +1 -83
  71. package/dist/outcome.d.ts +1 -83
  72. package/dist/parse-gate-payload.d.cts +2 -2
  73. package/dist/parse-gate-payload.d.ts +2 -2
  74. package/dist/path.d.cts +2 -2
  75. package/dist/path.d.ts +2 -2
  76. package/dist/policies/engines/index.d.cts +1 -1
  77. package/dist/policies/engines/index.d.ts +1 -1
  78. package/dist/policies/engines/v1/gate/index.cjs +5 -4
  79. package/dist/policies/engines/v1/gate/index.cjs.map +1 -1
  80. package/dist/policies/engines/v1/gate/index.d.cts +4 -2
  81. package/dist/policies/engines/v1/gate/index.d.ts +4 -2
  82. package/dist/policies/engines/v1/gate/index.js +2 -1
  83. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  84. package/dist/policies/index.cjs +5 -5
  85. package/dist/policies/index.d.cts +3 -2
  86. package/dist/policies/index.d.ts +3 -2
  87. package/dist/policies/index.js +2 -2
  88. package/dist/policy-bridge.cjs +437 -0
  89. package/dist/policy-bridge.cjs.map +1 -0
  90. package/dist/policy-bridge.d.cts +185 -0
  91. package/dist/policy-bridge.d.ts +185 -0
  92. package/dist/policy-bridge.js +396 -0
  93. package/dist/policy-bridge.js.map +1 -0
  94. package/dist/policy-service.cjs +241 -240
  95. package/dist/policy-service.cjs.map +1 -1
  96. package/dist/policy-service.d.cts +2 -2
  97. package/dist/policy-service.d.ts +2 -2
  98. package/dist/policy-service.js +240 -239
  99. package/dist/policy-service.js.map +1 -1
  100. package/dist/rbac/index.cjs +9 -0
  101. package/dist/rbac/index.d.cts +3 -0
  102. package/dist/rbac/index.d.ts +3 -0
  103. package/dist/rbac/index.js +2 -0
  104. package/dist/requested-by.cjs +54 -0
  105. package/dist/requested-by.cjs.map +1 -0
  106. package/dist/requested-by.d.cts +25 -0
  107. package/dist/requested-by.d.ts +25 -0
  108. package/dist/requested-by.js +49 -0
  109. package/dist/requested-by.js.map +1 -0
  110. package/dist/result/index.d.cts +2 -1
  111. package/dist/result/index.d.ts +2 -1
  112. package/dist/result.d.cts +84 -0
  113. package/dist/result.d.ts +84 -0
  114. package/dist/rule.cjs +327 -0
  115. package/dist/rule.cjs.map +1 -0
  116. package/dist/rule.js +298 -0
  117. package/dist/rule.js.map +1 -0
  118. package/dist/stable-stringify.cjs +47 -0
  119. package/dist/stable-stringify.cjs.map +1 -0
  120. package/dist/stable-stringify.js +42 -0
  121. package/dist/stable-stringify.js.map +1 -0
  122. package/dist/temporal-use-case.cjs +6 -53
  123. package/dist/temporal-use-case.cjs.map +1 -1
  124. package/dist/temporal-use-case.d.cts +11 -28
  125. package/dist/temporal-use-case.d.ts +11 -28
  126. package/dist/temporal-use-case.js +7 -48
  127. package/dist/temporal-use-case.js.map +1 -1
  128. package/dist/unexpected-error.cjs +3 -192
  129. package/dist/unexpected-error.cjs.map +1 -1
  130. package/dist/unexpected-error.js +2 -167
  131. package/dist/unexpected-error.js.map +1 -1
  132. package/dist/use-case.cjs +2 -6
  133. package/dist/use-case.cjs.map +1 -1
  134. package/dist/use-case.js +2 -6
  135. package/dist/use-case.js.map +1 -1
  136. package/dist/uuid-identifier.cjs +2 -7
  137. package/dist/uuid-identifier.cjs.map +1 -1
  138. package/dist/uuid-identifier.d.cts +2 -85
  139. package/dist/uuid-identifier.d.ts +2 -85
  140. package/dist/uuid-identifier.js +1 -6
  141. package/dist/uuid-identifier.js.map +1 -1
  142. package/dist/uuid.cjs +18 -0
  143. package/dist/uuid.cjs.map +1 -0
  144. package/dist/uuid.js +13 -0
  145. package/dist/uuid.js.map +1 -0
  146. package/dist/validation-error.cjs +33 -166
  147. package/dist/validation-error.cjs.map +1 -1
  148. package/dist/validation-error.d.cts +12 -103
  149. package/dist/validation-error.d.ts +12 -103
  150. package/dist/validation-error.js +7 -134
  151. package/dist/validation-error.js.map +1 -1
  152. package/dist/value-object.cjs +12 -126
  153. package/dist/value-object.cjs.map +1 -1
  154. package/dist/value-object.d.cts +97 -0
  155. package/dist/value-object.d.ts +97 -0
  156. package/dist/value-object.js +13 -115
  157. package/dist/value-object.js.map +1 -1
  158. package/meta.json +20 -4
  159. package/package.json +27 -1
  160. package/src/abac/index.ts +1 -0
  161. package/src/core/abac/abac-request.ts +29 -0
  162. package/src/core/abac/attributes.ts +39 -0
  163. package/src/core/abac/authorizer.ts +108 -0
  164. package/src/core/abac/combining.ts +63 -0
  165. package/src/core/abac/composite-authorizer.ts +45 -0
  166. package/src/core/abac/domain/policy-set.ts +52 -0
  167. package/src/core/abac/domain/rule.ts +197 -0
  168. package/src/core/abac/index.ts +21 -0
  169. package/src/core/application/commands/requested-by.ts +3 -4
  170. package/src/core/application/ports/abac-authorizer.port.ts +20 -0
  171. package/src/core/application/ports/authorizer.port.ts +22 -0
  172. package/src/core/application/queries/query.ts +6 -1
  173. package/src/core/application/use-case.ts +1 -1
  174. package/src/core/domain/entity.ts +1 -1
  175. package/src/core/domain/uuid-identifier.ts +1 -8
  176. package/src/core/domain/value-object.ts +12 -3
  177. package/src/core/errors/authorization-error.ts +26 -0
  178. package/src/core/errors/error-codes.ts +1 -0
  179. package/src/core/errors/utils/json-safe.ts +20 -11
  180. package/src/core/index.ts +7 -0
  181. package/src/core/policies/engines/v1/condition-evaluator.ts +56 -1
  182. package/src/core/rbac/access-request.ts +32 -0
  183. package/src/core/rbac/authorizer.ts +91 -0
  184. package/src/core/rbac/domain/grant.ts +96 -0
  185. package/src/core/rbac/domain/permission-set.ts +67 -0
  186. package/src/core/rbac/domain/permission.ts +119 -0
  187. package/src/core/rbac/domain/role.ts +101 -0
  188. package/src/core/rbac/domain/scope.ts +84 -0
  189. package/src/core/rbac/index.ts +15 -0
  190. package/src/core/rbac/policy-bridge.ts +44 -0
  191. package/src/core/shared/hashing.ts +1 -55
  192. package/src/core/shared/stable-stringify.ts +57 -0
  193. package/src/core/shared/uuid.ts +11 -0
  194. package/src/examples/application/authorize-cancel-order-abac.example.ts +107 -0
  195. package/src/examples/application/authorize-cancel-order.example.ts +101 -0
  196. package/src/rbac/index.ts +1 -0
  197. package/src/version.ts +1 -1
@@ -1,6 +1,5 @@
1
1
  import { n as ContractVersion } from "./version.cjs";
2
- import { t as DeepReadonly } from "./immutable.cjs";
3
- import { t as PluginManager } from "./plugin.cjs";
2
+ import { t as ValueObject } from "./value-object.cjs";
4
3
 
5
4
  //#region src/core/domain/entity.d.ts
6
5
 
@@ -96,88 +95,6 @@ declare abstract class Entity<TIdentifier> {
96
95
  protected markAsModified(updatedAt?: Date): number;
97
96
  }
98
97
  //#endregion
99
- //#region src/core/domain/value-object.d.ts
100
- /**
101
- * Extension point for value-object equality. A plugin implementing this
102
- * contract overrides how any two value objects are compared, letting the host
103
- * application swap in a structural comparator (e.g. `lodash.isEqual` over the
104
- * wrapped `value`) without every value object having to implement `equals` by
105
- * hand.
106
- */
107
- type ValueObjectPluginContract = {
108
- equals: (a: ValueObject<unknown, unknown>, b: ValueObject<unknown, unknown>) => boolean;
109
- };
110
- /**
111
- * Base class for value objects — domain concepts defined entirely by their
112
- * contents, with no identity of their own. Two value objects are
113
- * interchangeable when they hold equal data, which is the opposite of an
114
- * {@link Entity} (compared by id). Money, a CPF, a date range: replacing one
115
- * instance with an equal one changes nothing about the model.
116
- *
117
- * Immutability is the defining guarantee here. The wrapped `value` is
118
- * deep-frozen on construction, so a value object can be shared freely without
119
- * any risk of a consumer mutating shared state. Subclasses seal the instance
120
- * itself with {@link finalize} once their own fields are set.
121
- *
122
- * @typeParam T - The shape of the wrapped data.
123
- * @typeParam P - The primitive form produced by {@link toPrimitive} / {@link toJSON}.
124
- */
125
- declare abstract class ValueObject<T, P> {
126
- static readonly CONTRACT_VERSION: ContractVersion;
127
- /**
128
- * Registry of equality plugins shared by every value object. Empty by
129
- * default — when nothing is registered, {@link equals} falls back to a
130
- * structural comparison of the wrapped `value`. Hosts register a plugin
131
- * (e.g. `lodash.isEqual`) once at startup to customise equality globally.
132
- */
133
- static readonly plugins: PluginManager<ValueObjectPluginContract>;
134
- /** The wrapped data, deep-frozen so it can never be mutated after construction. */
135
- readonly value: DeepReadonly<T>;
136
- /**
137
- * Wraps `value`, deep-freezing it so the value object is immutable from the
138
- * moment it exists. Declared `protected` because value objects are built
139
- * through a validating subclass factory, never instantiated directly.
140
- */
141
- protected constructor(value: T);
142
- /**
143
- * The schema/contract version stamped on this value-object type by the
144
- * `@version` decorator — used to detect state persisted under an older shape.
145
- */
146
- get contractVersion(): ContractVersion;
147
- /**
148
- * Freezes the instance shell, blocking reassignment of any own field.
149
- *
150
- * `value` is already deep-frozen by the constructor, so the wrapped data is
151
- * immutable regardless. The instance itself is NOT frozen automatically
152
- * because a subclass may still need to assign its own fields after
153
- * `super(value)` runs. Call `finalize()` at the very end of the subclass
154
- * constructor (after all fields are set) to make the whole value object
155
- * immutable.
156
- */
157
- protected finalize(): void;
158
- /**
159
- * Hook for `JSON.stringify`. Delegates to {@link toPrimitive} so a value
160
- * object serializes to its primitive form rather than exposing the internal
161
- * `value` wrapper.
162
- */
163
- toJSON(): P;
164
- /**
165
- * Compares this value object with another by content. Because value objects
166
- * carry no identity, two independently constructed instances holding the
167
- * same data are considered equal.
168
- *
169
- * Delegates to the registered equality {@link plugins}; with no plugin
170
- * registered it falls back to comparing the serialized wrapped `value`.
171
- * Subclasses may still override for a faster or domain-specific comparison.
172
- */
173
- equals(other: this): boolean;
174
- /**
175
- * Projects the value object down to a plain, serializable primitive form —
176
- * the representation suitable for persistence, transport, or comparison.
177
- */
178
- abstract toPrimitive(): P;
179
- }
180
- //#endregion
181
98
  //#region src/core/domain/uuid-identifier.d.ts
182
99
  /**
183
100
  * Base class for UUID-backed identity value objects.
@@ -226,5 +143,5 @@ declare abstract class UuidIdentifier<TBrand extends string = string> extends Va
226
143
  static isValid(candidate: string): boolean;
227
144
  }
228
145
  //#endregion
229
- export { EntityState as a, Entity as i, ValueObject as n, ValueObjectPluginContract as r, UuidIdentifier as t };
146
+ export { Entity as n, EntityState as r, UuidIdentifier as t };
230
147
  //# sourceMappingURL=uuid-identifier.d.cts.map
@@ -1,6 +1,5 @@
1
1
  import { n as ContractVersion } from "./version.js";
2
- import { t as DeepReadonly } from "./immutable.js";
3
- import { t as PluginManager } from "./plugin.js";
2
+ import { t as ValueObject } from "./value-object.js";
4
3
 
5
4
  //#region src/core/domain/entity.d.ts
6
5
 
@@ -96,88 +95,6 @@ declare abstract class Entity<TIdentifier> {
96
95
  protected markAsModified(updatedAt?: Date): number;
97
96
  }
98
97
  //#endregion
99
- //#region src/core/domain/value-object.d.ts
100
- /**
101
- * Extension point for value-object equality. A plugin implementing this
102
- * contract overrides how any two value objects are compared, letting the host
103
- * application swap in a structural comparator (e.g. `lodash.isEqual` over the
104
- * wrapped `value`) without every value object having to implement `equals` by
105
- * hand.
106
- */
107
- type ValueObjectPluginContract = {
108
- equals: (a: ValueObject<unknown, unknown>, b: ValueObject<unknown, unknown>) => boolean;
109
- };
110
- /**
111
- * Base class for value objects — domain concepts defined entirely by their
112
- * contents, with no identity of their own. Two value objects are
113
- * interchangeable when they hold equal data, which is the opposite of an
114
- * {@link Entity} (compared by id). Money, a CPF, a date range: replacing one
115
- * instance with an equal one changes nothing about the model.
116
- *
117
- * Immutability is the defining guarantee here. The wrapped `value` is
118
- * deep-frozen on construction, so a value object can be shared freely without
119
- * any risk of a consumer mutating shared state. Subclasses seal the instance
120
- * itself with {@link finalize} once their own fields are set.
121
- *
122
- * @typeParam T - The shape of the wrapped data.
123
- * @typeParam P - The primitive form produced by {@link toPrimitive} / {@link toJSON}.
124
- */
125
- declare abstract class ValueObject<T, P> {
126
- static readonly CONTRACT_VERSION: ContractVersion;
127
- /**
128
- * Registry of equality plugins shared by every value object. Empty by
129
- * default — when nothing is registered, {@link equals} falls back to a
130
- * structural comparison of the wrapped `value`. Hosts register a plugin
131
- * (e.g. `lodash.isEqual`) once at startup to customise equality globally.
132
- */
133
- static readonly plugins: PluginManager<ValueObjectPluginContract>;
134
- /** The wrapped data, deep-frozen so it can never be mutated after construction. */
135
- readonly value: DeepReadonly<T>;
136
- /**
137
- * Wraps `value`, deep-freezing it so the value object is immutable from the
138
- * moment it exists. Declared `protected` because value objects are built
139
- * through a validating subclass factory, never instantiated directly.
140
- */
141
- protected constructor(value: T);
142
- /**
143
- * The schema/contract version stamped on this value-object type by the
144
- * `@version` decorator — used to detect state persisted under an older shape.
145
- */
146
- get contractVersion(): ContractVersion;
147
- /**
148
- * Freezes the instance shell, blocking reassignment of any own field.
149
- *
150
- * `value` is already deep-frozen by the constructor, so the wrapped data is
151
- * immutable regardless. The instance itself is NOT frozen automatically
152
- * because a subclass may still need to assign its own fields after
153
- * `super(value)` runs. Call `finalize()` at the very end of the subclass
154
- * constructor (after all fields are set) to make the whole value object
155
- * immutable.
156
- */
157
- protected finalize(): void;
158
- /**
159
- * Hook for `JSON.stringify`. Delegates to {@link toPrimitive} so a value
160
- * object serializes to its primitive form rather than exposing the internal
161
- * `value` wrapper.
162
- */
163
- toJSON(): P;
164
- /**
165
- * Compares this value object with another by content. Because value objects
166
- * carry no identity, two independently constructed instances holding the
167
- * same data are considered equal.
168
- *
169
- * Delegates to the registered equality {@link plugins}; with no plugin
170
- * registered it falls back to comparing the serialized wrapped `value`.
171
- * Subclasses may still override for a faster or domain-specific comparison.
172
- */
173
- equals(other: this): boolean;
174
- /**
175
- * Projects the value object down to a plain, serializable primitive form —
176
- * the representation suitable for persistence, transport, or comparison.
177
- */
178
- abstract toPrimitive(): P;
179
- }
180
- //#endregion
181
98
  //#region src/core/domain/uuid-identifier.d.ts
182
99
  /**
183
100
  * Base class for UUID-backed identity value objects.
@@ -226,5 +143,5 @@ declare abstract class UuidIdentifier<TBrand extends string = string> extends Va
226
143
  static isValid(candidate: string): boolean;
227
144
  }
228
145
  //#endregion
229
- export { EntityState as a, Entity as i, ValueObject as n, ValueObjectPluginContract as r, UuidIdentifier as t };
146
+ export { Entity as n, EntityState as r, UuidIdentifier as t };
230
147
  //# sourceMappingURL=uuid-identifier.d.ts.map
@@ -1,12 +1,7 @@
1
+ import { t as UUID_PATTERN } from "./uuid.js";
1
2
  import { t as ValueObject } from "./value-object.js";
2
3
  //#region src/core/domain/uuid-identifier.ts
3
4
  /**
4
- * Canonical RFC-4122 UUID (versions 1–5), matched case-insensitively. Declared
5
- * once here so the dozens of typed identifiers a domain accumulates never have
6
- * to re-state the pattern.
7
- */
8
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
9
- /**
10
5
  * Base class for UUID-backed identity value objects.
11
6
  *
12
7
  * A domain typically has many of these — `OrderId`, `CustomerId`, `InvoiceId` —
@@ -1 +1 @@
1
- {"version":3,"file":"uuid-identifier.js","names":[],"sources":["../src/core/domain/uuid-identifier.ts"],"sourcesContent":["import { ValueObject } from \"./value-object.js\";\n\n/**\n * Canonical RFC-4122 UUID (versions 1–5), matched case-insensitively. Declared\n * once here so the dozens of typed identifiers a domain accumulates never have\n * to re-state the pattern.\n */\nconst UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Base class for UUID-backed identity value objects.\n *\n * A domain typically has many of these — `OrderId`, `CustomerId`, `InvoiceId` —\n * all wrapping the same `string` shape. Two problems follow: the UUID format\n * check gets copy-pasted into every one, and because the wrapped shape is\n * identical, TypeScript's structural typing would happily accept an `OrderId`\n * where a `CustomerId` is expected. `UuidIdentifier` solves both: the format\n * lives here once ({@link isValid}), and the `TBrand` phantom tag makes each\n * subtype nominally distinct so the ids cannot be swapped for one another.\n *\n * It deliberately does not impose a factory. Identifiers vary in how they\n * report an invalid value (their own exception type, their own message), so a\n * concrete id adds a validating `create` that calls {@link isValid} plus a\n * `reconstitute` that trusts an already-persisted value:\n *\n * ```ts\n * class OrderId extends UuidIdentifier<\"OrderId\"> {\n * private constructor(value: string) { super(value); }\n * static create(raw: string): OrderId {\n * if (!UuidIdentifier.isValid(raw)) throw new InvalidOrderIdError(raw);\n * return new OrderId(raw);\n * }\n * static reconstitute(value: string): OrderId { return new OrderId(value); }\n * }\n * ```\n *\n * @typeParam TBrand - A unique string literal that nominally tags the subtype.\n */\nabstract class UuidIdentifier<\n TBrand extends string = string,\n> extends ValueObject<string, string> {\n /**\n * Phantom brand. Never assigned at runtime (`declare`), it exists only so\n * two identifiers with different brands are not interchangeable at the type\n * level despite sharing the same `string` value.\n */\n protected declare readonly __brand: TBrand;\n\n protected constructor(value: string) {\n super(value);\n }\n\n public toPrimitive(): string {\n return this.value;\n }\n\n /** The wrapped UUID string — convenient for logging and interpolation. */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Whether `candidate` is a canonical UUID (versions 1–5). The single source\n * of truth for the format; concrete identifiers call this from `create`.\n */\n public static isValid(candidate: string): boolean {\n return UUID_PATTERN.test(candidate);\n }\n}\n\nexport { UuidIdentifier };\n"],"mappings":";;;;;;;AAOA,MAAM,eACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BJ,IAAe,iBAAf,cAEU,YAA4B;CAQlC,YAAsB,OAAe;EACjC,MAAM,KAAK;CACf;CAEA,cAA6B;EACzB,OAAO,KAAK;CAChB;;CAGA,WAA0B;EACtB,OAAO,KAAK;CAChB;;;;;CAMA,OAAc,QAAQ,WAA4B;EAC9C,OAAO,aAAa,KAAK,SAAS;CACtC;AACJ"}
1
+ {"version":3,"file":"uuid-identifier.js","names":[],"sources":["../src/core/domain/uuid-identifier.ts"],"sourcesContent":["import { UUID_PATTERN } from \"../shared/uuid.js\";\nimport { ValueObject } from \"./value-object.js\";\n\n/**\n * Base class for UUID-backed identity value objects.\n *\n * A domain typically has many of these — `OrderId`, `CustomerId`, `InvoiceId` —\n * all wrapping the same `string` shape. Two problems follow: the UUID format\n * check gets copy-pasted into every one, and because the wrapped shape is\n * identical, TypeScript's structural typing would happily accept an `OrderId`\n * where a `CustomerId` is expected. `UuidIdentifier` solves both: the format\n * lives here once ({@link isValid}), and the `TBrand` phantom tag makes each\n * subtype nominally distinct so the ids cannot be swapped for one another.\n *\n * It deliberately does not impose a factory. Identifiers vary in how they\n * report an invalid value (their own exception type, their own message), so a\n * concrete id adds a validating `create` that calls {@link isValid} plus a\n * `reconstitute` that trusts an already-persisted value:\n *\n * ```ts\n * class OrderId extends UuidIdentifier<\"OrderId\"> {\n * private constructor(value: string) { super(value); }\n * static create(raw: string): OrderId {\n * if (!UuidIdentifier.isValid(raw)) throw new InvalidOrderIdError(raw);\n * return new OrderId(raw);\n * }\n * static reconstitute(value: string): OrderId { return new OrderId(value); }\n * }\n * ```\n *\n * @typeParam TBrand - A unique string literal that nominally tags the subtype.\n */\nabstract class UuidIdentifier<\n TBrand extends string = string,\n> extends ValueObject<string, string> {\n /**\n * Phantom brand. Never assigned at runtime (`declare`), it exists only so\n * two identifiers with different brands are not interchangeable at the type\n * level despite sharing the same `string` value.\n */\n protected declare readonly __brand: TBrand;\n\n protected constructor(value: string) {\n super(value);\n }\n\n public toPrimitive(): string {\n return this.value;\n }\n\n /** The wrapped UUID string — convenient for logging and interpolation. */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Whether `candidate` is a canonical UUID (versions 1–5). The single source\n * of truth for the format; concrete identifiers call this from `create`.\n */\n public static isValid(candidate: string): boolean {\n return UUID_PATTERN.test(candidate);\n }\n}\n\nexport { UuidIdentifier };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAe,iBAAf,cAEU,YAA4B;CAQlC,YAAsB,OAAe;EACjC,MAAM,KAAK;CACf;CAEA,cAA6B;EACzB,OAAO,KAAK;CAChB;;CAGA,WAA0B;EACtB,OAAO,KAAK;CAChB;;;;;CAMA,OAAc,QAAQ,WAA4B;EAC9C,OAAO,aAAa,KAAK,SAAS;CACtC;AACJ"}
package/dist/uuid.cjs ADDED
@@ -0,0 +1,18 @@
1
+ //#region src/core/shared/uuid.ts
2
+ /**
3
+ * Canonical RFC-4122 UUID (versions 1–5, variant 8/9/a/b), matched
4
+ * case-insensitively. The single source of truth for the UUID format —
5
+ * `UuidIdentifier` (domain ids) and `RequestedBy` (command actor) both
6
+ * validate against this pattern, so an identity accepted at the application
7
+ * boundary is always one the domain also considers valid.
8
+ */
9
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10
+ //#endregion
11
+ Object.defineProperty(exports, "UUID_PATTERN", {
12
+ enumerable: true,
13
+ get: function() {
14
+ return UUID_PATTERN;
15
+ }
16
+ });
17
+
18
+ //# sourceMappingURL=uuid.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.cjs","names":[],"sources":["../src/core/shared/uuid.ts"],"sourcesContent":["/**\n * Canonical RFC-4122 UUID (versions 1–5, variant 8/9/a/b), matched\n * case-insensitively. The single source of truth for the UUID format —\n * `UuidIdentifier` (domain ids) and `RequestedBy` (command actor) both\n * validate against this pattern, so an identity accepted at the application\n * boundary is always one the domain also considers valid.\n */\nconst UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport { UUID_PATTERN };\n"],"mappings":";;;;;;;;AAOA,MAAM,eACF"}
package/dist/uuid.js ADDED
@@ -0,0 +1,13 @@
1
+ //#region src/core/shared/uuid.ts
2
+ /**
3
+ * Canonical RFC-4122 UUID (versions 1–5, variant 8/9/a/b), matched
4
+ * case-insensitively. The single source of truth for the UUID format —
5
+ * `UuidIdentifier` (domain ids) and `RequestedBy` (command actor) both
6
+ * validate against this pattern, so an identity accepted at the application
7
+ * boundary is always one the domain also considers valid.
8
+ */
9
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10
+ //#endregion
11
+ export { UUID_PATTERN as t };
12
+
13
+ //# sourceMappingURL=uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.js","names":[],"sources":["../src/core/shared/uuid.ts"],"sourcesContent":["/**\n * Canonical RFC-4122 UUID (versions 1–5, variant 8/9/a/b), matched\n * case-insensitively. The single source of truth for the UUID format —\n * `UuidIdentifier` (domain ids) and `RequestedBy` (command actor) both\n * validate against this pattern, so an identity accepted at the application\n * boundary is always one the domain also considers valid.\n */\nconst UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport { UUID_PATTERN };\n"],"mappings":";;;;;;;;AAOA,MAAM,eACF"}