@cullet/erp-core 1.1.0 → 1.3.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 (196) hide show
  1. package/KIT_CONTEXT.md +1 -67
  2. package/dist/app-error.d.cts +108 -0
  3. package/dist/application/index.cjs +26 -0
  4. package/dist/application/index.d.cts +2 -0
  5. package/dist/application/index.d.ts +1 -1
  6. package/dist/application/index.js +2 -1
  7. package/dist/domain/index.cjs +16 -0
  8. package/dist/domain/index.d.cts +3 -0
  9. package/dist/domain/index.d.ts +3 -0
  10. package/dist/domain/index.js +3 -0
  11. package/dist/domain-event-contracts.cjs +33 -0
  12. package/dist/domain-event-contracts.cjs.map +1 -0
  13. package/dist/domain-event-contracts.d.cts +27 -0
  14. package/dist/domain-event-contracts.d.ts +27 -0
  15. package/dist/domain-event-contracts.js +22 -0
  16. package/dist/domain-event-contracts.js.map +1 -0
  17. package/dist/domain-exception.cjs +17 -0
  18. package/dist/domain-exception.cjs.map +1 -0
  19. package/dist/domain-exception.d.cts +7 -0
  20. package/dist/domain-exception.d.ts +7 -0
  21. package/dist/domain-exception.js +12 -0
  22. package/dist/domain-exception.js.map +1 -0
  23. package/dist/errors/index.cjs +41 -0
  24. package/dist/errors/index.d.cts +3 -0
  25. package/dist/errors/index.js +1 -1
  26. package/dist/exceptions/index.cjs +17 -0
  27. package/dist/exceptions/index.d.cts +5 -0
  28. package/dist/exceptions/index.d.ts +5 -0
  29. package/dist/exceptions/index.js +7 -0
  30. package/dist/exceptions/validation-field.cjs +3 -0
  31. package/dist/exceptions/validation-field.d.cts +2 -0
  32. package/dist/gate-engine-registry.cjs +308 -0
  33. package/dist/gate-engine-registry.cjs.map +1 -0
  34. package/dist/gate-engine-registry.d.cts +81 -0
  35. package/dist/gate-engine-registry.d.ts +2 -1
  36. package/dist/gate-engine-registry.js +2 -1
  37. package/dist/gate-engine-registry.js.map +1 -1
  38. package/dist/gate-types.d.cts +171 -0
  39. package/dist/gate-types.d.ts +3 -139
  40. package/dist/gate-v1-payload.schema.cjs +638 -0
  41. package/dist/gate-v1-payload.schema.cjs.map +1 -0
  42. package/dist/gate-v1-payload.schema.js +2 -116
  43. package/dist/gate-v1-payload.schema.js.map +1 -1
  44. package/dist/hashing.cjs +66 -0
  45. package/dist/hashing.cjs.map +1 -0
  46. package/dist/immutable.cjs +77 -0
  47. package/dist/immutable.cjs.map +1 -0
  48. package/dist/immutable.d.cts +6 -0
  49. package/dist/immutable.d.ts +6 -0
  50. package/dist/immutable.js +54 -0
  51. package/dist/immutable.js.map +1 -0
  52. package/dist/index.cjs +163 -0
  53. package/dist/index.cjs.map +1 -0
  54. package/dist/index.d.cts +30 -0
  55. package/dist/index.d.ts +15 -160
  56. package/dist/index.js +19 -176
  57. package/dist/index.js.map +1 -1
  58. package/dist/invalid-state-transition-exception.cjs +47 -0
  59. package/dist/invalid-state-transition-exception.cjs.map +1 -0
  60. package/dist/invalid-state-transition-exception.js +30 -0
  61. package/dist/invalid-state-transition-exception.js.map +1 -0
  62. package/dist/invariant-violation-exception.cjs +16 -0
  63. package/dist/invariant-violation-exception.cjs.map +1 -0
  64. package/dist/invariant-violation-exception.js +11 -0
  65. package/dist/invariant-violation-exception.js.map +1 -0
  66. package/dist/not-found-error.cjs +65 -0
  67. package/dist/not-found-error.cjs.map +1 -0
  68. package/dist/not-found-error.js +1 -1
  69. package/dist/outcome.cjs +97 -0
  70. package/dist/outcome.cjs.map +1 -0
  71. package/dist/outcome.d.cts +140 -0
  72. package/dist/outcome.d.ts +140 -0
  73. package/dist/outcome.js +1 -1
  74. package/dist/parse-gate-payload.d.cts +62 -0
  75. package/dist/parse-gate-payload.d.ts +2 -1
  76. package/dist/path.d.cts +90 -0
  77. package/dist/path.d.ts +2 -1
  78. package/dist/plugin.cjs +79 -0
  79. package/dist/plugin.cjs.map +1 -0
  80. package/dist/plugin.d.cts +85 -0
  81. package/dist/plugin.d.ts +85 -0
  82. package/dist/plugin.js +74 -0
  83. package/dist/plugin.js.map +1 -0
  84. package/dist/plugins/index.cjs +3 -0
  85. package/dist/plugins/index.d.cts +2 -0
  86. package/dist/plugins/index.d.ts +2 -0
  87. package/dist/plugins/index.js +2 -0
  88. package/dist/policies/engines/index.cjs +10 -0
  89. package/dist/policies/engines/index.d.cts +4 -0
  90. package/dist/policies/engines/index.d.ts +1 -1
  91. package/dist/policies/engines/v1/gate/index.cjs +91 -0
  92. package/dist/policies/engines/v1/gate/index.cjs.map +1 -0
  93. package/dist/policies/engines/v1/gate/index.d.cts +121 -0
  94. package/dist/policies/engines/v1/gate/index.d.ts +2 -1
  95. package/dist/policies/engines/v1/gate/index.js +2 -1
  96. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  97. package/dist/policies/index.cjs +41 -0
  98. package/dist/policies/index.d.cts +7 -0
  99. package/dist/policies/index.d.ts +2 -1
  100. package/dist/policies/index.js +2 -1
  101. package/dist/policy-service.cjs +1190 -0
  102. package/dist/policy-service.cjs.map +1 -0
  103. package/dist/policy-service.d.cts +559 -0
  104. package/dist/policy-service.d.ts +2 -1
  105. package/dist/policy-service.js +6 -3
  106. package/dist/policy-service.js.map +1 -1
  107. package/dist/result/index.cjs +7 -0
  108. package/dist/result/index.d.cts +2 -0
  109. package/dist/result/index.d.ts +2 -0
  110. package/dist/result/index.js +3 -0
  111. package/dist/result.cjs +135 -0
  112. package/dist/result.cjs.map +1 -0
  113. package/dist/result.js +118 -0
  114. package/dist/result.js.map +1 -0
  115. package/dist/ruleset-registry.cjs +47 -0
  116. package/dist/ruleset-registry.cjs.map +1 -0
  117. package/dist/ruleset-registry.js +42 -0
  118. package/dist/ruleset-registry.js.map +1 -0
  119. package/dist/rulesets/index.cjs +3 -0
  120. package/dist/rulesets/index.d.cts +2 -0
  121. package/dist/rulesets/index.d.ts +2 -0
  122. package/dist/rulesets/index.js +2 -0
  123. package/dist/temporal-guards.cjs +32 -0
  124. package/dist/temporal-guards.cjs.map +1 -0
  125. package/dist/temporal-guards.js +2 -17
  126. package/dist/temporal-guards.js.map +1 -1
  127. package/dist/temporal-use-case.cjs +191 -0
  128. package/dist/temporal-use-case.cjs.map +1 -0
  129. package/dist/temporal-use-case.d.cts +304 -0
  130. package/dist/temporal-use-case.d.ts +4 -9
  131. package/dist/temporal-use-case.js +6 -140
  132. package/dist/temporal-use-case.js.map +1 -1
  133. package/dist/unexpected-error.cjs +208 -0
  134. package/dist/unexpected-error.cjs.map +1 -0
  135. package/dist/unexpected-error.js +179 -0
  136. package/dist/unexpected-error.js.map +1 -0
  137. package/dist/use-case.cjs +96 -0
  138. package/dist/use-case.cjs.map +1 -0
  139. package/dist/use-case.js +91 -0
  140. package/dist/use-case.js.map +1 -0
  141. package/dist/uuid-identifier.cjs +65 -0
  142. package/dist/uuid-identifier.cjs.map +1 -0
  143. package/dist/uuid-identifier.d.cts +230 -0
  144. package/dist/uuid-identifier.d.ts +230 -0
  145. package/dist/uuid-identifier.js +60 -0
  146. package/dist/uuid-identifier.js.map +1 -0
  147. package/dist/validation-code.cjs +60 -0
  148. package/dist/validation-code.cjs.map +1 -0
  149. package/dist/validation-code.d.cts +23 -0
  150. package/dist/validation-code.d.ts +23 -0
  151. package/dist/validation-code.js +1 -177
  152. package/dist/validation-code.js.map +1 -1
  153. package/dist/validation-error.cjs +1020 -0
  154. package/dist/validation-error.cjs.map +1 -0
  155. package/dist/validation-error.d.cts +777 -0
  156. package/dist/validation-error.d.ts +1 -21
  157. package/dist/validation-error.js +1 -1
  158. package/dist/validation-exception.cjs +41 -0
  159. package/dist/validation-exception.cjs.map +1 -0
  160. package/dist/validation-exception.d.cts +50 -0
  161. package/dist/validation-exception.d.ts +50 -0
  162. package/dist/validation-exception.js +8 -2
  163. package/dist/validation-exception.js.map +1 -1
  164. package/dist/validation-field.cjs +28 -0
  165. package/dist/validation-field.cjs.map +1 -0
  166. package/dist/validation-field.d.cts +12 -0
  167. package/dist/value-object-ruleset.contracts.d.cts +36 -0
  168. package/dist/value-object-ruleset.contracts.d.ts +36 -0
  169. package/dist/value-object.cjs +208 -0
  170. package/dist/value-object.cjs.map +1 -0
  171. package/dist/value-object.js +191 -0
  172. package/dist/value-object.js.map +1 -0
  173. package/dist/version.d.cts +10 -0
  174. package/dist/version.d.ts +10 -0
  175. package/dist/versioning/index.cjs +7 -0
  176. package/dist/versioning/index.d.cts +3 -0
  177. package/dist/versioning/index.d.ts +3 -0
  178. package/dist/versioning/index.js +3 -0
  179. package/meta.json +18 -3
  180. package/package.json +165 -17
  181. package/src/core/domain/rulesets/index.ts +7 -0
  182. package/src/core/domain/uuid-identifier.ts +72 -0
  183. package/src/core/domain/value-object.ts +37 -5
  184. package/src/core/exceptions/index.ts +13 -0
  185. package/src/core/index.ts +14 -2
  186. package/src/core/plugins/index.ts +7 -0
  187. package/src/core/plugins/plugin.ts +99 -0
  188. package/src/core/plugins/types.ts +53 -0
  189. package/src/core/versioning/index.ts +14 -0
  190. package/src/domain/index.ts +7 -0
  191. package/src/exceptions/index.ts +1 -0
  192. package/src/plugins/index.ts +1 -0
  193. package/src/result/index.ts +2 -0
  194. package/src/rulesets/index.ts +1 -0
  195. package/src/version.ts +1 -1
  196. package/src/versioning/index.ts +1 -0
@@ -1,6 +1,21 @@
1
+ import { PluginManager } from "../plugins/index.js";
1
2
  import { type DeepReadonly, makeImmutable } from "../shared/immutable.js";
2
3
  import { type ContractVersion, version } from "../versioning/version.js";
3
4
 
5
+ /**
6
+ * Extension point for value-object equality. A plugin implementing this
7
+ * contract overrides how any two value objects are compared, letting the host
8
+ * application swap in a structural comparator (e.g. `lodash.isEqual` over the
9
+ * wrapped `value`) without every value object having to implement `equals` by
10
+ * hand.
11
+ */
12
+ type ValueObjectPluginContract = {
13
+ equals: (
14
+ a: ValueObject<unknown, unknown>,
15
+ b: ValueObject<unknown, unknown>,
16
+ ) => boolean;
17
+ };
18
+
4
19
  /**
5
20
  * Base class for value objects — domain concepts defined entirely by their
6
21
  * contents, with no identity of their own. Two value objects are
@@ -20,6 +35,15 @@ import { type ContractVersion, version } from "../versioning/version.js";
20
35
  abstract class ValueObject<T, P> {
21
36
  declare public static readonly CONTRACT_VERSION: ContractVersion;
22
37
 
38
+ /**
39
+ * Registry of equality plugins shared by every value object. Empty by
40
+ * default — when nothing is registered, {@link equals} falls back to a
41
+ * structural comparison of the wrapped `value`. Hosts register a plugin
42
+ * (e.g. `lodash.isEqual`) once at startup to customise equality globally.
43
+ */
44
+ public static readonly plugins =
45
+ new PluginManager<ValueObjectPluginContract>();
46
+
23
47
  /** The wrapped data, deep-frozen so it can never be mutated after construction. */
24
48
  public readonly value: DeepReadonly<T>;
25
49
 
@@ -65,11 +89,19 @@ abstract class ValueObject<T, P> {
65
89
 
66
90
  /**
67
91
  * Compares this value object with another by content. Because value objects
68
- * carry no identity, subclasses implement equality over the wrapped data
69
- * (typically the primitive form), so two independently constructed instances
70
- * holding the same data are considered equal.
92
+ * carry no identity, two independently constructed instances holding the
93
+ * same data are considered equal.
94
+ *
95
+ * Delegates to the registered equality {@link plugins}; with no plugin
96
+ * registered it falls back to comparing the serialized wrapped `value`.
97
+ * Subclasses may still override for a faster or domain-specific comparison.
71
98
  */
72
- public abstract equals(other: this): boolean;
99
+ public equals(other: this): boolean {
100
+ return ValueObject.plugins.invoke("equals", [this, other], {
101
+ fallback: (a, b) =>
102
+ JSON.stringify(a.value) === JSON.stringify(b.value),
103
+ });
104
+ }
73
105
 
74
106
  /**
75
107
  * Projects the value object down to a plain, serializable primitive form —
@@ -78,4 +110,4 @@ abstract class ValueObject<T, P> {
78
110
  public abstract toPrimitive(): P;
79
111
  }
80
112
 
81
- export { type DeepReadonly, ValueObject };
113
+ export { type DeepReadonly, ValueObject, type ValueObjectPluginContract };
@@ -0,0 +1,13 @@
1
+ export { BusinessRuleViolationException } from "./business-rule-violation-exception.js";
2
+ export { DomainException } from "./domain-exception.js";
3
+ export { EntityNotFoundException } from "./entity-not-found-exception.js";
4
+ export { InvalidStateTransitionException } from "./invalid-state-transition-exception.js";
5
+ export { InvariantViolationException } from "./invariant-violation-exception.js";
6
+ export { ValidationCode } from "./validation-code.js";
7
+ export {
8
+ InvalidValueException,
9
+ MultipleValidationException,
10
+ ValidationException,
11
+ type ValidationViolation,
12
+ } from "./validation-exception.js";
13
+ export { ValidationField } from "./validation-field.js";
package/src/core/index.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  export * from "./errors/index.js";
2
- export * from "./exceptions/validation-field.js";
2
+ export * from "./exceptions/index.js";
3
3
  export * from "./application/index.js";
4
4
  export { Entity, type EntityState } from "./domain/entity.js";
5
- export { ValueObject, type DeepReadonly } from "./domain/value-object.js";
5
+ export { UuidIdentifier } from "./domain/uuid-identifier.js";
6
+ export {
7
+ ValueObject,
8
+ type DeepReadonly,
9
+ type ValueObjectPluginContract,
10
+ } from "./domain/value-object.js";
11
+ export * from "./domain/rulesets/index.js";
12
+ export * from "./plugins/index.js";
13
+ export * from "./versioning/index.js";
14
+ // NOTE: `./policies` re-exports Result/Ok/Err/Outcome/CommonOutcomeStatus and
15
+ // transitively pulls in `zod` (the gate/compute engines). Consumers that only
16
+ // need the zod-free primitives should import the dedicated subpaths
17
+ // (`@cullet/erp-core/{domain,result,exceptions,rulesets,versioning,plugins}`).
6
18
  export * from "./policies/index.js";
@@ -0,0 +1,7 @@
1
+ export { PluginManager } from "./plugin.js";
2
+ export type {
3
+ BasePlugin,
4
+ InvokeOptions,
5
+ PipelineReducer,
6
+ PluginContract,
7
+ } from "./types.js";
@@ -0,0 +1,99 @@
1
+ import {
2
+ type BasePlugin,
3
+ type InvokeOptions,
4
+ type PipelineReducer,
5
+ type PluginContract,
6
+ } from "./types.js";
7
+
8
+ /**
9
+ * Registry that holds a set of plugins implementing a shared {@link PluginContract}
10
+ * and resolves which of them answer a given extension point.
11
+ *
12
+ * Plugins are kept sorted by priority (descending). For a given method,
13
+ * {@link invoke} either delegates to the highest-priority enabled plugin
14
+ * (`'first'`) or folds every enabled plugin into a single value (`'pipeline'`).
15
+ * When no plugin is enabled, the supplied `fallback` runs instead, so the host
16
+ * always has defined behaviour even with an empty registry.
17
+ *
18
+ * @typeParam P - The plugin contract this manager coordinates.
19
+ */
20
+ class PluginManager<P extends PluginContract> {
21
+ /** Internal list, kept sorted by priority (desc). */
22
+ private plugins: (P & BasePlugin)[] = [];
23
+
24
+ /** Registers one or more plugins and re-sorts by priority. */
25
+ public register(...plugins: (P & BasePlugin)[]): void {
26
+ this.plugins.push(...plugins);
27
+ this.reorder();
28
+ }
29
+
30
+ /** Removes a previously registered plugin by name. */
31
+ public unregister(name: string): void {
32
+ this.plugins = this.plugins.filter((p) => p.name !== name);
33
+ }
34
+
35
+ /** Enables a registered plugin by name. */
36
+ public enable(name: string): void {
37
+ const plugin = this.plugins.find((p) => p.name === name);
38
+ if (plugin) plugin.enabled = true;
39
+ }
40
+
41
+ /** Disables a registered plugin by name (without removing it). */
42
+ public disable(name: string): void {
43
+ const plugin = this.plugins.find((p) => p.name === name);
44
+ if (plugin) plugin.enabled = false;
45
+ }
46
+
47
+ /** Lists enabled plugins only, already in priority order. */
48
+ public list(): readonly (P & BasePlugin)[] {
49
+ return this.plugins.filter((p) => p.enabled !== false);
50
+ }
51
+
52
+ /**
53
+ * Resolves `method` against the registered plugins.
54
+ *
55
+ * In `'first'` mode the highest-priority enabled plugin that implements
56
+ * `method` answers. In `'pipeline'` mode every enabled plugin runs and the
57
+ * results are folded with `reducer` (defaults to "keep the last result").
58
+ * When no enabled plugin implements `method`, `fallback` is called.
59
+ */
60
+ public invoke<K extends keyof P>(
61
+ method: K,
62
+ args: Parameters<P[K]>,
63
+ opts: InvokeOptions<P, K>,
64
+ ): ReturnType<P[K]> {
65
+ const { mode = "first", fallback, reducer } = opts;
66
+ const enabled = this.list().filter((p) => method in p) as Array<
67
+ P & BasePlugin
68
+ >;
69
+
70
+ if (enabled.length === 0) {
71
+ return (fallback as P[K])(...args);
72
+ }
73
+
74
+ if (mode === "first") {
75
+ const fn = enabled[0][method] as P[K];
76
+ return fn(...args);
77
+ }
78
+
79
+ const defaultReducer: PipelineReducer<ReturnType<P[K]>, P> = (
80
+ _,
81
+ curr,
82
+ ) => curr;
83
+ const red = reducer ?? defaultReducer;
84
+
85
+ let acc: ReturnType<P[K]> = enabled[0][method]!(...args);
86
+ enabled.slice(1).forEach((plugin, idx) => {
87
+ const res = plugin[method]!(...args);
88
+ acc = red(acc, res, plugin, idx + 1);
89
+ });
90
+ return acc;
91
+ }
92
+
93
+ /** Re-sorts the internal list by priority (desc; default priority = 0). */
94
+ private reorder(): void {
95
+ this.plugins.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
96
+ }
97
+ }
98
+
99
+ export { PluginManager };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Common shape every plugin shares, regardless of the contract it implements.
3
+ * Carries the metadata the {@link PluginManager} uses to identify, order and
4
+ * toggle plugins.
5
+ */
6
+ interface BasePlugin {
7
+ /** Unique identifier, used for logs / debugging and for enable/disable. */
8
+ readonly name: string;
9
+ /** Weight; the highest priority wins (default = 0). */
10
+ readonly priority?: number;
11
+ /** Shortcut to disable a plugin without removing it. */
12
+ enabled?: boolean;
13
+ }
14
+
15
+ /**
16
+ * A plugin contract is a record whose values are the methods plugins may
17
+ * implement for a given extension point.
18
+ *
19
+ * `any` here is intentional: it is the only way to express the constraint
20
+ * "a record whose values are arbitrary functions". Using `unknown` for the
21
+ * parameters breaks assignment of concrete contracts by contravariance —
22
+ * TypeScript rejects functions with specific parameters as a subtype of
23
+ * `(...args: unknown[]) => unknown`.
24
+ */
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ type PluginContract = Record<string, (...args: any[]) => any>;
27
+
28
+ /**
29
+ * Reducer used in `pipeline` mode to combine the result of each plugin into a
30
+ * single accumulated value.
31
+ */
32
+ type PipelineReducer<R, P extends PluginContract> = (
33
+ accumulated: R,
34
+ current: R,
35
+ plugin: P & BasePlugin,
36
+ index: number,
37
+ ) => R;
38
+
39
+ /** Options accepted by {@link PluginManager.invoke}. */
40
+ interface InvokeOptions<P extends PluginContract, K extends keyof P> {
41
+ /**
42
+ * `'first'` → returns the first enabled plugin with the highest priority.
43
+ * `'pipeline'` → runs every enabled plugin, combining results via `reducer`.
44
+ * default = `'first'`.
45
+ */
46
+ mode?: "first" | "pipeline";
47
+ /** Executed when no plugin is enabled for the method. */
48
+ fallback: P[K];
49
+ /** Reducer used only when `mode = "pipeline"`. */
50
+ reducer?: PipelineReducer<ReturnType<P[K]>, P>;
51
+ }
52
+
53
+ export type { BasePlugin, InvokeOptions, PipelineReducer, PluginContract };
@@ -0,0 +1,14 @@
1
+ export {
2
+ buildDomainEventContractVersions,
3
+ createDomainEventEnvelope,
4
+ type CreateDomainEventEnvelopeInput,
5
+ type DomainEventContractSelection,
6
+ type DomainEventContractVersions,
7
+ type DomainEventEnvelope,
8
+ } from "./domain-event-contracts.js";
9
+ export {
10
+ CONTRACT_VERSION_PROPERTY,
11
+ type ContractVersion,
12
+ version,
13
+ type VersionedTarget,
14
+ } from "./version.js";
@@ -0,0 +1,7 @@
1
+ export { Entity, type EntityState } from "../core/domain/entity.js";
2
+ export { UuidIdentifier } from "../core/domain/uuid-identifier.js";
3
+ export {
4
+ type DeepReadonly,
5
+ ValueObject,
6
+ type ValueObjectPluginContract,
7
+ } from "../core/domain/value-object.js";
@@ -0,0 +1 @@
1
+ export * from "../core/exceptions/index.js";
@@ -0,0 +1 @@
1
+ export * from "../core/plugins/index.js";
@@ -0,0 +1,2 @@
1
+ export { type CommonOutcomeStatus, Outcome } from "../core/result/outcome.js";
2
+ export { Err, Ok, Result } from "../core/result/result.js";
@@ -0,0 +1 @@
1
+ export * from "../core/domain/rulesets/index.js";
package/src/version.ts CHANGED
@@ -4,4 +4,4 @@
4
4
  // Mantemos a versao aqui, dentro de src/, para que a copia full-control seja
5
5
  // auto-contida: ao copiar so o conteudo de src/, o entry nao depende de um
6
6
  // `../package.json` que deixaria de existir no projeto consumidor.
7
- export const version = "1.1.0";
7
+ export const version = "1.3.0";
@@ -0,0 +1 @@
1
+ export * from "../core/versioning/index.js";