@fabricorg/platform 1.9.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/README.md +48 -2
- package/dist/actions/index.cjs +45 -26
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.d.cts +225 -226
- package/dist/actions/index.d.ts +225 -226
- package/dist/actions/index.js +41 -2
- package/dist/actions/index.js.map +1 -1
- package/dist/adapters/index.cjs +696 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +367 -365
- package/dist/adapters/index.d.ts +367 -365
- package/dist/adapters/index.js +682 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/agent-hitl/index.cjs +21 -10
- package/dist/agent-hitl/index.cjs.map +1 -1
- package/dist/agent-hitl/index.d.cts +30 -30
- package/dist/agent-hitl/index.d.ts +30 -30
- package/dist/agent-hitl/index.js +21 -2
- package/dist/agent-hitl/index.js.map +1 -1
- package/dist/certification/index.cjs +109 -24
- package/dist/certification/index.cjs.map +1 -1
- package/dist/certification/index.d.cts +33 -39
- package/dist/certification/index.d.ts +33 -39
- package/dist/certification/index.js +107 -8
- package/dist/certification/index.js.map +1 -1
- package/dist/discovery/index.cjs +12 -10
- package/dist/discovery/index.cjs.map +1 -1
- package/dist/discovery/index.d.cts +2 -10
- package/dist/discovery/index.d.ts +2 -10
- package/dist/discovery/index.js +12 -2
- package/dist/discovery/index.js.map +1 -1
- package/dist/engine-B4csEOEc.js +223 -0
- package/dist/engine-B4csEOEc.js.map +1 -0
- package/dist/engine-BqScuhrT.cjs +246 -0
- package/dist/engine-BqScuhrT.cjs.map +1 -0
- package/dist/events/index.cjs +39 -10
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +43 -43
- package/dist/events/index.d.ts +43 -43
- package/dist/events/index.js +39 -2
- package/dist/events/index.js.map +1 -1
- package/dist/evidence/index.cjs +12 -50
- package/dist/evidence/index.d.cts +2 -229
- package/dist/evidence/index.d.ts +2 -229
- package/dist/evidence/index.js +1 -5
- package/dist/evidence-BuCICb0c.js +516 -0
- package/dist/evidence-BuCICb0c.js.map +1 -0
- package/dist/evidence-Cq48eDvA.cjs +575 -0
- package/dist/evidence-Cq48eDvA.cjs.map +1 -0
- package/dist/governance/index.cjs +24 -18
- package/dist/governance/index.cjs.map +1 -1
- package/dist/governance/index.d.cts +80 -83
- package/dist/governance/index.d.ts +80 -83
- package/dist/governance/index.js +22 -2
- package/dist/governance/index.js.map +1 -1
- package/dist/ids/index.cjs +52 -22
- package/dist/ids/index.cjs.map +1 -1
- package/dist/ids/index.d.cts +17 -17
- package/dist/ids/index.d.ts +17 -17
- package/dist/ids/index.js +49 -2
- package/dist/ids/index.js.map +1 -1
- package/dist/index-9jasmw76.d.cts +124 -0
- package/dist/index-BXpeFdk2.d.cts +190 -0
- package/dist/index-BXpeFdk2.d.ts +190 -0
- package/dist/index-BnbsKZsT.d.cts +231 -0
- package/dist/index-CIl1rYRv.d.cts +11 -0
- package/dist/index-CIl1rYRv.d.ts +11 -0
- package/dist/index-CVHA1ypT.d.cts +262 -0
- package/dist/index-DZ4mnNb7.d.cts +78 -0
- package/dist/index-DZ4mnNb7.d.ts +78 -0
- package/dist/index-IqcDvl69.d.ts +124 -0
- package/dist/index-fmUiRBXu.d.cts +57 -0
- package/dist/index-fmUiRBXu.d.ts +57 -0
- package/dist/index-sPUPs8pr.d.ts +262 -0
- package/dist/index-z9-CYOIo.d.ts +231 -0
- package/dist/index.cjs +111 -385
- package/dist/index.d.cts +18 -17
- package/dist/index.d.ts +18 -17
- package/dist/index.js +19 -20
- package/dist/manifest/index.cjs +224 -35
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +130 -131
- package/dist/manifest/index.d.ts +130 -131
- package/dist/manifest/index.js +219 -7
- package/dist/manifest/index.js.map +1 -1
- package/dist/modules/index.cjs +281 -42
- package/dist/modules/index.cjs.map +1 -1
- package/dist/modules/index.d.cts +157 -159
- package/dist/modules/index.d.ts +157 -159
- package/dist/modules/index.js +274 -6
- package/dist/modules/index.js.map +1 -1
- package/dist/objects/index.cjs +355 -22
- package/dist/objects/index.cjs.map +1 -1
- package/dist/objects/index.d.cts +2 -77
- package/dist/objects/index.d.ts +2 -77
- package/dist/objects/index.js +352 -2
- package/dist/objects/index.js.map +1 -1
- package/dist/policies/index.cjs +14 -48
- package/dist/policies/index.d.cts +2 -247
- package/dist/policies/index.d.ts +2 -247
- package/dist/policies/index.js +1 -3
- package/dist/policies-DH_GCXQ-.js +627 -0
- package/dist/policies-DH_GCXQ-.js.map +1 -0
- package/dist/policies-Nxbp1CH8.cjs +698 -0
- package/dist/policies-Nxbp1CH8.cjs.map +1 -0
- package/dist/privacy/index.cjs +26 -43
- package/dist/privacy/index.cjs.map +1 -1
- package/dist/privacy/index.d.cts +2 -189
- package/dist/privacy/index.d.ts +2 -189
- package/dist/privacy/index.js +18 -3
- package/dist/privacy/index.js.map +1 -1
- package/dist/projections/index.cjs +241 -23
- package/dist/projections/index.cjs.map +1 -1
- package/dist/projections/index.d.cts +2 -125
- package/dist/projections/index.d.ts +2 -125
- package/dist/projections/index.js +238 -3
- package/dist/projections/index.js.map +1 -1
- package/dist/state-machines/index.cjs +76 -18
- package/dist/state-machines/index.cjs.map +1 -1
- package/dist/state-machines/index.d.cts +2 -55
- package/dist/state-machines/index.d.ts +2 -55
- package/dist/state-machines/index.js +74 -2
- package/dist/state-machines/index.js.map +1 -1
- package/dist/testing/index.cjs +27 -19
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +17 -19
- package/dist/testing/index.d.ts +17 -19
- package/dist/testing/index.js +25 -3
- package/dist/testing/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-2AE6TMAX.cjs +0 -44
- package/dist/chunk-2AE6TMAX.cjs.map +0 -1
- package/dist/chunk-6HY35TKB.cjs +0 -491
- package/dist/chunk-6HY35TKB.cjs.map +0 -1
- package/dist/chunk-6UGEIDLC.cjs +0 -26
- package/dist/chunk-6UGEIDLC.cjs.map +0 -1
- package/dist/chunk-7GAWSUOG.js +0 -64
- package/dist/chunk-7GAWSUOG.js.map +0 -1
- package/dist/chunk-AFXFAEWA.js +0 -673
- package/dist/chunk-AFXFAEWA.js.map +0 -1
- package/dist/chunk-AFXKSIVI.cjs +0 -540
- package/dist/chunk-AFXKSIVI.cjs.map +0 -1
- package/dist/chunk-B5DOGDPG.js +0 -42
- package/dist/chunk-B5DOGDPG.js.map +0 -1
- package/dist/chunk-BJGZE3GE.js +0 -20
- package/dist/chunk-BJGZE3GE.js.map +0 -1
- package/dist/chunk-CRZXTZ36.cjs +0 -258
- package/dist/chunk-CRZXTZ36.cjs.map +0 -1
- package/dist/chunk-D4SWRBUH.cjs +0 -22
- package/dist/chunk-D4SWRBUH.cjs.map +0 -1
- package/dist/chunk-DBTAUI6C.cjs +0 -395
- package/dist/chunk-DBTAUI6C.cjs.map +0 -1
- package/dist/chunk-EMSAFNPX.js +0 -98
- package/dist/chunk-EMSAFNPX.js.map +0 -1
- package/dist/chunk-F3E5SXPN.cjs +0 -28
- package/dist/chunk-F3E5SXPN.cjs.map +0 -1
- package/dist/chunk-HEYMMVDP.js +0 -480
- package/dist/chunk-HEYMMVDP.js.map +0 -1
- package/dist/chunk-IFW43ELT.cjs +0 -331
- package/dist/chunk-IFW43ELT.cjs.map +0 -1
- package/dist/chunk-LFE74IJX.js +0 -20
- package/dist/chunk-LFE74IJX.js.map +0 -1
- package/dist/chunk-LZSE6QGQ.cjs +0 -60
- package/dist/chunk-LZSE6QGQ.cjs.map +0 -1
- package/dist/chunk-MCWSUGB3.cjs +0 -102
- package/dist/chunk-MCWSUGB3.cjs.map +0 -1
- package/dist/chunk-MLBALEUR.js +0 -290
- package/dist/chunk-MLBALEUR.js.map +0 -1
- package/dist/chunk-NNXQZPB3.cjs +0 -31
- package/dist/chunk-NNXQZPB3.cjs.map +0 -1
- package/dist/chunk-OFCCZ27Z.js +0 -26
- package/dist/chunk-OFCCZ27Z.js.map +0 -1
- package/dist/chunk-PDN5DOLQ.js +0 -242
- package/dist/chunk-PDN5DOLQ.js.map +0 -1
- package/dist/chunk-PIDZQAEL.js +0 -50
- package/dist/chunk-PIDZQAEL.js.map +0 -1
- package/dist/chunk-Q4Q4JPR3.js +0 -524
- package/dist/chunk-Q4Q4JPR3.js.map +0 -1
- package/dist/chunk-RALMUSOX.js +0 -55
- package/dist/chunk-RALMUSOX.js.map +0 -1
- package/dist/chunk-SNTV45LH.cjs +0 -295
- package/dist/chunk-SNTV45LH.cjs.map +0 -1
- package/dist/chunk-TBS2S5AX.cjs +0 -40
- package/dist/chunk-TBS2S5AX.cjs.map +0 -1
- package/dist/chunk-TYNIFC7J.js +0 -253
- package/dist/chunk-TYNIFC7J.js.map +0 -1
- package/dist/chunk-UGWGHTNC.cjs +0 -56
- package/dist/chunk-UGWGHTNC.cjs.map +0 -1
- package/dist/chunk-WI7CWNYI.cjs +0 -68
- package/dist/chunk-WI7CWNYI.cjs.map +0 -1
- package/dist/chunk-WNZP53GI.js +0 -386
- package/dist/chunk-WNZP53GI.js.map +0 -1
- package/dist/chunk-WQ3BYI7T.cjs +0 -249
- package/dist/chunk-WQ3BYI7T.cjs.map +0 -1
- package/dist/chunk-Y2PJLRIY.js +0 -36
- package/dist/chunk-Y2PJLRIY.js.map +0 -1
- package/dist/chunk-YGIPN3TU.cjs +0 -684
- package/dist/chunk-YGIPN3TU.cjs.map +0 -1
- package/dist/chunk-ZAEVQSB5.js +0 -326
- package/dist/chunk-ZAEVQSB5.js.map +0 -1
- package/dist/chunk-ZMQTV5OJ.js +0 -27
- package/dist/chunk-ZMQTV5OJ.js.map +0 -1
- package/dist/evidence/index.cjs.map +0 -1
- package/dist/evidence/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/policies/index.cjs.map +0 -1
- package/dist/policies/index.js.map +0 -1
package/dist/manifest/index.js
CHANGED
|
@@ -1,8 +1,220 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { assertSurfaceDeclaration } from "../discovery/index.js";
|
|
2
|
+
import { getEventTypeName, getModuleDependencyNamespace, getObjectTypeName } from "../modules/index.js";
|
|
3
|
+
//#region manifest/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Version of the module manifest contract. Bump when the serialized shape
|
|
6
|
+
* changes in a way consumers must detect.
|
|
7
|
+
*/
|
|
8
|
+
const MODULE_MANIFEST_VERSION = 2;
|
|
9
|
+
function normalizeModuleManifest(manifest) {
|
|
10
|
+
const version = manifest.manifestVersion;
|
|
11
|
+
if (version !== 1 && version !== 2) throw new Error(`Unsupported module manifest version: ${String(version)}`);
|
|
12
|
+
const views = "views" in manifest && Array.isArray(manifest.views) ? manifest.views : [];
|
|
13
|
+
if (Array.isArray(manifest.actions)) for (const [index, action] of manifest.actions.entries()) assertSurfaceDeclaration(action, `Module "${manifest.namespace}" action[${index}] "${action?.actionId ?? "unknown"}"`);
|
|
14
|
+
for (const [index, view] of views.entries()) assertSurfaceDeclaration(view, `Module "${manifest.namespace}" view[${index}] "${view?.name ?? "unknown"}"`);
|
|
15
|
+
return {
|
|
16
|
+
...manifest,
|
|
17
|
+
manifestVersion: 2,
|
|
18
|
+
views
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function normalizeModuleManifestBundle(bundle) {
|
|
22
|
+
const version = bundle.manifestVersion;
|
|
23
|
+
if (version !== 1 && version !== 2) throw new Error(`Unsupported module manifest bundle version: ${String(version)}`);
|
|
24
|
+
return {
|
|
25
|
+
manifestVersion: 2,
|
|
26
|
+
modules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest))
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function isJsonSchemaExportableValidator(schema) {
|
|
30
|
+
return typeof schema.toJSONSchema === "function";
|
|
31
|
+
}
|
|
32
|
+
function isRecord(value) {
|
|
33
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
function exportDependency(dependency) {
|
|
36
|
+
const namespace = getModuleDependencyNamespace(dependency);
|
|
37
|
+
if (typeof dependency === "string") return { namespace };
|
|
38
|
+
const normalized = { namespace };
|
|
39
|
+
if (dependency.version !== void 0) normalized.version = dependency.version;
|
|
40
|
+
if (dependency.optional !== void 0) normalized.optional = dependency.optional;
|
|
41
|
+
return normalized;
|
|
42
|
+
}
|
|
43
|
+
function exportObjectType(objectType) {
|
|
44
|
+
if (typeof objectType === "string") return { type: objectType };
|
|
45
|
+
const normalized = { type: getObjectTypeName(objectType) };
|
|
46
|
+
if (objectType.displayName !== void 0) normalized.displayName = objectType.displayName;
|
|
47
|
+
if (objectType.idPrefix !== void 0) normalized.idPrefix = objectType.idPrefix;
|
|
48
|
+
if (objectType.schema !== void 0) normalized.schema = cloneJson(objectType.schema);
|
|
49
|
+
if (objectType.semantics !== void 0) normalized.semantics = cloneJson(objectType.semantics);
|
|
50
|
+
if (objectType.relations !== void 0) normalized.relations = objectType.relations.map((relation) => ({ ...relation }));
|
|
51
|
+
if (objectType.invariants !== void 0) normalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));
|
|
52
|
+
return normalized;
|
|
53
|
+
}
|
|
54
|
+
function cloneJson(value) {
|
|
55
|
+
if (Array.isArray(value)) return value.map((item) => cloneJson(item));
|
|
56
|
+
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, cloneJson(child)]));
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
function exportEventType(eventType) {
|
|
60
|
+
if (typeof eventType === "string") return {
|
|
61
|
+
eventType,
|
|
62
|
+
schemaVersion: 1
|
|
63
|
+
};
|
|
64
|
+
const normalized = {
|
|
65
|
+
eventType: getEventTypeName(eventType),
|
|
66
|
+
schemaVersion: eventType.schemaVersion
|
|
67
|
+
};
|
|
68
|
+
if (eventType.description !== void 0) normalized.description = eventType.description;
|
|
69
|
+
if (eventType.schema !== void 0) normalized.schema = cloneJson(eventType.schema);
|
|
70
|
+
return normalized;
|
|
71
|
+
}
|
|
72
|
+
function exportAction(action) {
|
|
73
|
+
assertSurfaceDeclaration(action, `Action "${action?.actionId ?? "unknown"}"`);
|
|
74
|
+
const manifest = {
|
|
75
|
+
actionId: action.actionId,
|
|
76
|
+
version: action.version,
|
|
77
|
+
kind: action.kind ?? "atomic",
|
|
78
|
+
idempotent: action.idempotent,
|
|
79
|
+
mutatesDomain: action.mutatesDomain,
|
|
80
|
+
emitsEvents: [...action.emitsEvents]
|
|
81
|
+
};
|
|
82
|
+
if (action.surface !== void 0) manifest.surface = action.surface;
|
|
83
|
+
if (action.surfaceReason !== void 0) manifest.surfaceReason = action.surfaceReason;
|
|
84
|
+
if (action.policies !== void 0) manifest.policies = [...action.policies];
|
|
85
|
+
if (action.requiredRoles !== void 0) manifest.requiredRoles = [...action.requiredRoles];
|
|
86
|
+
if (action.requiredPermissions !== void 0) manifest.requiredPermissions = [...action.requiredPermissions];
|
|
87
|
+
if (action.eventPhase !== void 0) manifest.eventPhase = action.eventPhase;
|
|
88
|
+
if (action.execution !== void 0) manifest.execution = cloneJson(action.execution);
|
|
89
|
+
if (isJsonSchemaExportableValidator(action.schema)) try {
|
|
90
|
+
manifest.parameterSchema = action.schema.toJSONSchema();
|
|
91
|
+
manifest.parameterSchemaFormat = "json-schema";
|
|
92
|
+
} catch {}
|
|
93
|
+
if (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) try {
|
|
94
|
+
manifest.resultSchema = action.resultSchema.toJSONSchema();
|
|
95
|
+
manifest.resultSchemaFormat = "json-schema";
|
|
96
|
+
} catch {}
|
|
97
|
+
if (action.stateMachine !== void 0) {
|
|
98
|
+
const binding = { entityType: action.stateMachine.entityType };
|
|
99
|
+
if (typeof action.stateMachine.targetState === "string") binding.targetState = action.stateMachine.targetState;
|
|
100
|
+
manifest.stateMachine = binding;
|
|
101
|
+
}
|
|
102
|
+
if (action.adapterSteps !== void 0) manifest.adapterSteps = action.adapterSteps.map((step) => {
|
|
103
|
+
const exported = {
|
|
104
|
+
adapterType: step.adapterType,
|
|
105
|
+
operation: step.operation
|
|
106
|
+
};
|
|
107
|
+
if (step.retryPolicy !== void 0) exported.retryPolicy = { ...step.retryPolicy };
|
|
108
|
+
return exported;
|
|
109
|
+
});
|
|
110
|
+
return manifest;
|
|
111
|
+
}
|
|
112
|
+
function exportPolicy(policy) {
|
|
113
|
+
if (!isRecord(policy) || typeof policy.policyId !== "string") return;
|
|
114
|
+
if (typeof policy.evaluate === "function") {
|
|
115
|
+
const exported = {
|
|
116
|
+
type: "code",
|
|
117
|
+
policyId: policy.policyId,
|
|
118
|
+
version: typeof policy.version === "number" ? policy.version : 1
|
|
119
|
+
};
|
|
120
|
+
if (typeof policy.previewSafe === "boolean") exported.previewSafe = policy.previewSafe;
|
|
121
|
+
return exported;
|
|
122
|
+
}
|
|
123
|
+
if (typeof policy.kind === "string" && typeof policy.policyVersion === "number") {
|
|
124
|
+
const exported = {
|
|
125
|
+
type: "data",
|
|
126
|
+
policyId: policy.policyId,
|
|
127
|
+
policyVersion: policy.policyVersion,
|
|
128
|
+
kind: policy.kind
|
|
129
|
+
};
|
|
130
|
+
if (isRecord(policy.dataDefinition)) exported.dataDefinition = policy.dataDefinition;
|
|
131
|
+
if (typeof policy.codeEvaluatorPolicyId === "string") exported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;
|
|
132
|
+
if (isRecord(policy.fallback)) exported.fallback = policy.fallback;
|
|
133
|
+
return exported;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function exportStateMachine(machine) {
|
|
137
|
+
if (!isRecord(machine) || typeof machine.entityType !== "string" || !isRecord(machine.states) || !Array.isArray(machine.transitions)) return;
|
|
138
|
+
const definition = machine;
|
|
139
|
+
return {
|
|
140
|
+
entityType: definition.entityType,
|
|
141
|
+
states: Object.values(definition.states),
|
|
142
|
+
transitions: definition.transitions.map((transition) => ({
|
|
143
|
+
from: transition.from,
|
|
144
|
+
to: transition.to,
|
|
145
|
+
causedByAction: transition.causedByAction,
|
|
146
|
+
hasGuard: typeof transition.guard === "function"
|
|
147
|
+
}))
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function exportView(view) {
|
|
151
|
+
assertSurfaceDeclaration(view, `View "${view?.name ?? "unknown"}"`);
|
|
152
|
+
const output = {
|
|
153
|
+
name: view.name,
|
|
154
|
+
version: view.version,
|
|
155
|
+
shape: cloneJson(view.shape),
|
|
156
|
+
consumes: view.consumes.map((consumption) => ({
|
|
157
|
+
eventType: consumption.eventType,
|
|
158
|
+
schemaVersions: [...consumption.schemaVersions]
|
|
159
|
+
})),
|
|
160
|
+
scope: view.scope,
|
|
161
|
+
snapshotVersion: view.snapshotVersion
|
|
162
|
+
};
|
|
163
|
+
if (view.surface !== void 0) output.surface = view.surface;
|
|
164
|
+
if (view.surfaceReason !== void 0) output.surfaceReason = view.surfaceReason;
|
|
165
|
+
if (view.parameterSchema !== void 0) output.parameterSchema = cloneJson(view.parameterSchema);
|
|
166
|
+
if (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];
|
|
167
|
+
if (view.usage) output.usage = cloneJson(view.usage);
|
|
168
|
+
return output;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Export a stable, JSON-serializable manifest of a module's ontology.
|
|
172
|
+
*
|
|
173
|
+
* This is a pure function of the module object: it does not read or mutate the
|
|
174
|
+
* global module/action/policy/state-machine registries, and the module does
|
|
175
|
+
* not need to be registered first. Declaration order is preserved everywhere
|
|
176
|
+
* (nothing is sorted), so the same module object always produces a
|
|
177
|
+
* byte-identical `JSON.stringify` result.
|
|
178
|
+
*
|
|
179
|
+
* The manifest contains definitions only — never raw parameter values,
|
|
180
|
+
* secrets, or runtime data. Function fields are elided (`handler`,
|
|
181
|
+
* policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,
|
|
182
|
+
* adapter `getInput`).
|
|
183
|
+
*/
|
|
184
|
+
function exportModuleManifest(module) {
|
|
185
|
+
const manifest = {
|
|
186
|
+
manifestVersion: 2,
|
|
187
|
+
namespace: module.namespace,
|
|
188
|
+
dependencies: (module.dependencies ?? []).map(exportDependency),
|
|
189
|
+
objectTypes: (module.objectTypes ?? []).map(exportObjectType),
|
|
190
|
+
subjectTypes: [...module.subjectTypes ?? []],
|
|
191
|
+
idPrefixes: (module.idPrefixes ?? []).map((registration) => ({
|
|
192
|
+
prefix: registration.prefix,
|
|
193
|
+
name: registration.name
|
|
194
|
+
})),
|
|
195
|
+
eventTypes: (module.eventTypes ?? []).map(exportEventType),
|
|
196
|
+
actions: (module.actions ?? []).map(exportAction),
|
|
197
|
+
policies: (module.policies ?? []).map(exportPolicy).filter((policy) => policy !== void 0),
|
|
198
|
+
stateMachines: (module.stateMachines ?? []).map(exportStateMachine).filter((machine) => machine !== void 0),
|
|
199
|
+
views: (module.views ?? []).map(exportView)
|
|
200
|
+
};
|
|
201
|
+
if (module.version !== void 0) manifest.version = module.version;
|
|
202
|
+
if (module.displayName !== void 0) manifest.displayName = module.displayName;
|
|
203
|
+
if (module.description !== void 0) manifest.description = module.description;
|
|
204
|
+
if (module.capability !== void 0) manifest.capability = cloneJson(module.capability);
|
|
205
|
+
return manifest;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Export manifests for a set of modules, preserving the input order.
|
|
209
|
+
* Like {@link exportModuleManifest}, this is pure and registry-free.
|
|
210
|
+
*/
|
|
211
|
+
function exportModuleManifestBundle(modules) {
|
|
212
|
+
return {
|
|
213
|
+
manifestVersion: 2,
|
|
214
|
+
modules: modules.map(exportModuleManifest)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
export { MODULE_MANIFEST_VERSION, exportModuleManifest, exportModuleManifestBundle, isJsonSchemaExportableValidator, normalizeModuleManifest, normalizeModuleManifestBundle };
|
|
219
|
+
|
|
8
220
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../manifest/index.ts"],"sourcesContent":["import { assertSurfaceDeclaration, type SurfaceDeclaration } from \"../discovery\";\nimport type {\n\tActionExecutionContract,\n\tActionDefinition,\n\tAdapterStepRetryPolicy,\n\tSchemaValidator,\n} from \"../actions\";\nimport {\n\tgetEventTypeName,\n\tgetModuleDependencyNamespace,\n\tgetObjectTypeName,\n\ttype FabricModule,\n\ttype CapabilityMetadata,\n\ttype DeclarativeInvariant,\n\ttype ModuleDependency,\n\ttype ModuleDependencyInput,\n\ttype ObjectRelationDefinition,\n} from \"../modules\";\nimport type { JsonValue, PortableJsonSchema } from \"../objects\";\nimport type {\n\tDataPolicyDefinition,\n\tPolicyFallbackDefinition,\n\tPolicyKind,\n} from \"../policies\";\nimport type { StateDefinition, StateMachineDefinition } from \"../state-machines\";\nimport type { ViewContract } from \"../projections\";\n\n/**\n * Version of the module manifest contract. Bump when the serialized shape\n * changes in a way consumers must detect.\n */\nexport const MODULE_MANIFEST_VERSION = 2 as const;\n\nexport interface ModuleManifestObjectType {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport interface ModuleManifestIdPrefix {\n\tprefix: string;\n\tname: string;\n}\n\nexport interface ModuleManifestEventType {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport interface ModuleManifestActionStateMachine {\n\tentityType: string;\n\t/** Present only when the binding declares a static target state. */\n\ttargetState?: string;\n}\n\nexport interface ModuleManifestAdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n}\n\nexport interface ModuleManifestAction extends SurfaceDeclaration {\n\tactionId: string;\n\tversion: number;\n\tkind: \"atomic\" | \"saga\";\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\temitsEvents: string[];\n\tpolicies?: string[];\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\texecution?: ActionExecutionContract;\n\t/**\n\t * JSON Schema for the action parameters, present only when the action's\n\t * `schema` validator implements {@link JsonSchemaExportableValidator}.\n\t */\n\tparameterSchema?: unknown;\n\tparameterSchemaFormat?: \"json-schema\";\n\tresultSchema?: unknown;\n\tresultSchemaFormat?: \"json-schema\";\n\tstateMachine?: ModuleManifestActionStateMachine;\n\tadapterSteps?: ModuleManifestAdapterStep[];\n}\n\nexport interface ModuleManifestCodePolicy {\n\ttype: \"code\";\n\tpolicyId: string;\n\tversion: number;\n\tpreviewSafe?: boolean;\n}\n\nexport interface ModuleManifestDataPolicy {\n\ttype: \"data\";\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tkind: PolicyKind;\n\tdataDefinition?: DataPolicyDefinition;\n\tcodeEvaluatorPolicyId?: string;\n\tfallback?: PolicyFallbackDefinition;\n}\n\nexport type ModuleManifestPolicy = ModuleManifestCodePolicy | ModuleManifestDataPolicy;\n\nexport interface ModuleManifestStateMachineTransition {\n\tfrom: string;\n\tto: string;\n\tcausedByAction: string;\n\t/** `true` when the transition declares a guard function. The guard itself is never serialized. */\n\thasGuard: boolean;\n}\n\nexport interface ModuleManifestStateMachine {\n\tentityType: string;\n\t/** States in declaration order (`Object.values` order of the definition record). */\n\tstates: StateDefinition[];\n\ttransitions: ModuleManifestStateMachineTransition[];\n}\n\nexport interface ModuleManifestView extends SurfaceDeclaration {\n\tname: string;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tparameterSchema?: PortableJsonSchema;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\tusage?: ViewContract[\"usage\"];\n}\n\n/**\n * Stable, JSON-serializable description of a {@link FabricModule}'s ontology:\n * object types, subject types, id prefixes, event types, actions, policies,\n * and state machines. Intended for downstream tooling (semantics exporters,\n * docs generators, tool generators) that cannot consume live module code.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields (`handler`, `evaluate`, `guard`,\n * dynamic `targetState`, adapter `getInput`) are never serialized.\n */\nexport interface ModuleManifest {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\tnamespace: string;\n\tversion?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies: ModuleDependency[];\n\tobjectTypes: ModuleManifestObjectType[];\n\tsubjectTypes: string[];\n\tidPrefixes: ModuleManifestIdPrefix[];\n\teventTypes: ModuleManifestEventType[];\n\tactions: ModuleManifestAction[];\n\tpolicies: ModuleManifestPolicy[];\n\tstateMachines: ModuleManifestStateMachine[];\n\tviews: ModuleManifestView[];\n}\n\nexport interface ModuleManifestBundle {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\t/** Manifests in the input module order. */\n\tmodules: ModuleManifest[];\n}\n\n/** Manifest v1 remains accepted by v2 readers; missing v2 fields normalize to absence. */\nexport type ModuleManifestObjectTypeV1 = Omit<\n\tModuleManifestObjectType,\n\t\"schema\" | \"semantics\" | \"relations\" | \"invariants\"\n>;\nexport type ModuleManifestActionV1 = Omit<\n\tModuleManifestAction,\n\t\"resultSchema\" | \"resultSchemaFormat\"\n>;\nexport type ModuleManifestV1 = Omit<\n\tModuleManifest,\n\t\"manifestVersion\" | \"objectTypes\" | \"actions\" | \"views\"\n> & {\n\tmanifestVersion: 1;\n\tobjectTypes: ModuleManifestObjectTypeV1[];\n\tactions: ModuleManifestActionV1[];\n};\nexport type ModuleManifestBundleV1 = Omit<ModuleManifestBundle, \"manifestVersion\" | \"modules\"> & {\n\tmanifestVersion: 1;\n\tmodules: ModuleManifestV1[];\n};\n\nexport function normalizeModuleManifest(\n\tmanifest: ModuleManifest | ModuleManifestV1,\n): ModuleManifest {\n\tconst version: number = manifest.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest version: ${String(version)}`);\n\t}\n\tconst views = \"views\" in manifest && Array.isArray(manifest.views) ? manifest.views : [];\n\t// Preserve the normalizer's legacy tolerance for absent/non-array fields.\n\tif (Array.isArray(manifest.actions))\n\t\tfor (const [index, action] of manifest.actions.entries())\n\t\t\tassertSurfaceDeclaration(action, `Module \"${manifest.namespace}\" action[${index}] \"${action?.actionId ?? \"unknown\"}\"`);\n\tfor (const [index, view] of views.entries())\n\t\tassertSurfaceDeclaration(view, `Module \"${manifest.namespace}\" view[${index}] \"${view?.name ?? \"unknown\"}\"`);\n\treturn {\n\t\t...manifest,\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tviews,\n\t};\n}\n\nexport function normalizeModuleManifestBundle(\n\tbundle: ModuleManifestBundle | ModuleManifestBundleV1,\n): ModuleManifestBundle {\n\tconst version: number = bundle.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest bundle version: ${String(version)}`);\n\t}\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest)),\n\t};\n}\n\n/**\n * A {@link SchemaValidator} that can also export its parameter schema as JSON\n * Schema (for example a Zod 4 schema via `z.toJSONSchema`). Keeps the platform\n * zero-dependency while letting schema-bearing actions flow into manifests.\n */\nexport interface JsonSchemaExportableValidator extends SchemaValidator {\n\ttoJSONSchema(): Record<string, unknown>;\n}\n\nexport function isJsonSchemaExportableValidator(\n\tschema: SchemaValidator,\n): schema is JsonSchemaExportableValidator {\n\treturn (\n\t\ttypeof (schema as Partial<JsonSchemaExportableValidator>).toJSONSchema === \"function\"\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction exportDependency(dependency: ModuleDependencyInput): ModuleDependency {\n\tconst namespace = getModuleDependencyNamespace(dependency);\n\tif (typeof dependency === \"string\") {\n\t\treturn { namespace };\n\t}\n\tconst normalized: ModuleDependency = { namespace };\n\tif (dependency.version !== undefined) normalized.version = dependency.version;\n\tif (dependency.optional !== undefined) normalized.optional = dependency.optional;\n\treturn normalized;\n}\n\nfunction exportObjectType(\n\tobjectType: NonNullable<FabricModule[\"objectTypes\"]>[number],\n): ModuleManifestObjectType {\n\tif (typeof objectType === \"string\") {\n\t\treturn { type: objectType };\n\t}\n\tconst normalized: ModuleManifestObjectType = { type: getObjectTypeName(objectType) };\n\tif (objectType.displayName !== undefined) normalized.displayName = objectType.displayName;\n\tif (objectType.idPrefix !== undefined) normalized.idPrefix = objectType.idPrefix;\n\tif (objectType.schema !== undefined) normalized.schema = cloneJson(objectType.schema);\n\tif (objectType.semantics !== undefined) normalized.semantics = cloneJson(objectType.semantics);\n\tif (objectType.relations !== undefined) {\n\t\tnormalized.relations = objectType.relations.map((relation) => ({ ...relation }));\n\t}\n\tif (objectType.invariants !== undefined) {\n\t\tnormalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));\n\t}\n\treturn normalized;\n}\n\nfunction cloneJson<T>(value: T): T {\n\tif (Array.isArray(value)) return value.map((item) => cloneJson(item)) as T;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>).map(([key, child]) => [key, cloneJson(child)]),\n\t\t) as T;\n\t}\n\treturn value;\n}\n\nfunction exportEventType(\n\teventType: NonNullable<FabricModule[\"eventTypes\"]>[number],\n): ModuleManifestEventType {\n\tif (typeof eventType === \"string\") {\n\t\t// String registrations carry no explicit schema version; the events\n\t\t// registry treats the bare name as the initial version of the type.\n\t\treturn { eventType, schemaVersion: 1 };\n\t}\n\tconst normalized: ModuleManifestEventType = {\n\t\teventType: getEventTypeName(eventType),\n\t\tschemaVersion: eventType.schemaVersion,\n\t};\n\tif (eventType.description !== undefined) normalized.description = eventType.description;\n\tif (eventType.schema !== undefined) normalized.schema = cloneJson(eventType.schema);\n\treturn normalized;\n}\n\nfunction exportAction(action: ActionDefinition): ModuleManifestAction {\n\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\tconst manifest: ModuleManifestAction = {\n\t\tactionId: action.actionId,\n\t\tversion: action.version,\n\t\tkind: action.kind ?? \"atomic\",\n\t\tidempotent: action.idempotent,\n\t\tmutatesDomain: action.mutatesDomain,\n\t\temitsEvents: [...action.emitsEvents],\n\t};\n\n\tif (action.surface !== undefined) manifest.surface = action.surface;\n\tif (action.surfaceReason !== undefined) manifest.surfaceReason = action.surfaceReason;\n\tif (action.policies !== undefined) manifest.policies = [...action.policies];\n\tif (action.requiredRoles !== undefined) manifest.requiredRoles = [...action.requiredRoles];\n\tif (action.requiredPermissions !== undefined) {\n\t\tmanifest.requiredPermissions = [...action.requiredPermissions];\n\t}\n\tif (action.eventPhase !== undefined) manifest.eventPhase = action.eventPhase;\n\tif (action.execution !== undefined) manifest.execution = cloneJson(action.execution);\n\n\tif (isJsonSchemaExportableValidator(action.schema)) {\n\t\ttry {\n\t\t\tmanifest.parameterSchema = action.schema.toJSONSchema();\n\t\t\tmanifest.parameterSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// Runtime-valid schemas that cannot be represented portably remain executable;\n\t\t\t// build-time consumers see the schema as unavailable rather than crashing export.\n\t\t}\n\t}\n\tif (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) {\n\t\ttry {\n\t\t\tmanifest.resultSchema = action.resultSchema.toJSONSchema();\n\t\t\tmanifest.resultSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// See parameter-schema behavior above.\n\t\t}\n\t}\n\n\tif (action.stateMachine !== undefined) {\n\t\tconst binding: ModuleManifestActionStateMachine = {\n\t\t\tentityType: action.stateMachine.entityType,\n\t\t};\n\t\tif (typeof action.stateMachine.targetState === \"string\") {\n\t\t\tbinding.targetState = action.stateMachine.targetState;\n\t\t}\n\t\tmanifest.stateMachine = binding;\n\t}\n\n\tif (action.adapterSteps !== undefined) {\n\t\tmanifest.adapterSteps = action.adapterSteps.map((step) => {\n\t\t\tconst exported: ModuleManifestAdapterStep = {\n\t\t\t\tadapterType: step.adapterType,\n\t\t\t\toperation: step.operation,\n\t\t\t};\n\t\t\tif (step.retryPolicy !== undefined) exported.retryPolicy = { ...step.retryPolicy };\n\t\t\treturn exported;\n\t\t});\n\t}\n\n\treturn manifest;\n}\n\nfunction exportPolicy(policy: unknown): ModuleManifestPolicy | undefined {\n\tif (!isRecord(policy) || typeof policy.policyId !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\t// Code evaluator: identified by its `evaluate` function (never serialized).\n\tif (typeof policy.evaluate === \"function\") {\n\t\tconst exported: ModuleManifestCodePolicy = {\n\t\t\ttype: \"code\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tversion: typeof policy.version === \"number\" ? policy.version : 1,\n\t\t};\n\t\tif (typeof policy.previewSafe === \"boolean\") exported.previewSafe = policy.previewSafe;\n\t\treturn exported;\n\t}\n\n\t// Declarative runtime policy definition: pure data, serialized as-is.\n\tif (typeof policy.kind === \"string\" && typeof policy.policyVersion === \"number\") {\n\t\tconst exported: ModuleManifestDataPolicy = {\n\t\t\ttype: \"data\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tpolicyVersion: policy.policyVersion,\n\t\t\tkind: policy.kind as PolicyKind,\n\t\t};\n\t\tif (isRecord(policy.dataDefinition)) {\n\t\t\texported.dataDefinition = policy.dataDefinition as unknown as DataPolicyDefinition;\n\t\t}\n\t\tif (typeof policy.codeEvaluatorPolicyId === \"string\") {\n\t\t\texported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;\n\t\t}\n\t\tif (isRecord(policy.fallback)) {\n\t\t\texported.fallback = policy.fallback as unknown as PolicyFallbackDefinition;\n\t\t}\n\t\treturn exported;\n\t}\n\n\t// Unknown policy shape: omit rather than guess.\n\treturn undefined;\n}\n\nfunction exportStateMachine(machine: unknown): ModuleManifestStateMachine | undefined {\n\tif (\n\t\t!isRecord(machine) ||\n\t\ttypeof machine.entityType !== \"string\" ||\n\t\t!isRecord(machine.states) ||\n\t\t!Array.isArray(machine.transitions)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst definition = machine as unknown as StateMachineDefinition;\n\treturn {\n\t\tentityType: definition.entityType,\n\t\tstates: Object.values(definition.states),\n\t\ttransitions: definition.transitions.map((transition) => ({\n\t\t\tfrom: transition.from,\n\t\t\tto: transition.to,\n\t\t\tcausedByAction: transition.causedByAction,\n\t\t\thasGuard: typeof transition.guard === \"function\",\n\t\t})),\n\t};\n}\n\nfunction exportView(view: ViewContract): ModuleManifestView {\n\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\tconst output: ModuleManifestView = {\n\t\tname: view.name,\n\t\tversion: view.version,\n\t\tshape: cloneJson(view.shape),\n\t\tconsumes: view.consumes.map((consumption) => ({\n\t\t\teventType: consumption.eventType,\n\t\t\tschemaVersions: [...consumption.schemaVersions],\n\t\t})),\n\t\tscope: view.scope,\n\t\tsnapshotVersion: view.snapshotVersion,\n\t};\n\tif (view.surface !== undefined) output.surface = view.surface;\n\tif (view.surfaceReason !== undefined) output.surfaceReason = view.surfaceReason;\n\tif (view.parameterSchema !== undefined) output.parameterSchema = cloneJson(view.parameterSchema);\n\tif (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];\n\tif (view.usage) output.usage = cloneJson(view.usage);\n\treturn output;\n}\n\n/**\n * Export a stable, JSON-serializable manifest of a module's ontology.\n *\n * This is a pure function of the module object: it does not read or mutate the\n * global module/action/policy/state-machine registries, and the module does\n * not need to be registered first. Declaration order is preserved everywhere\n * (nothing is sorted), so the same module object always produces a\n * byte-identical `JSON.stringify` result.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields are elided (`handler`,\n * policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,\n * adapter `getInput`).\n */\nexport function exportModuleManifest(module: FabricModule<unknown>): ModuleManifest {\n\tconst manifest: ModuleManifest = {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tnamespace: module.namespace,\n\t\tdependencies: (module.dependencies ?? []).map(exportDependency),\n\t\tobjectTypes: (module.objectTypes ?? []).map(exportObjectType),\n\t\tsubjectTypes: [...(module.subjectTypes ?? [])],\n\t\tidPrefixes: (module.idPrefixes ?? []).map((registration) => ({\n\t\t\tprefix: registration.prefix,\n\t\t\tname: registration.name,\n\t\t})),\n\t\teventTypes: (module.eventTypes ?? []).map(exportEventType),\n\t\tactions: (module.actions ?? []).map(exportAction),\n\t\tpolicies: (module.policies ?? [])\n\t\t\t.map(exportPolicy)\n\t\t\t.filter((policy): policy is ModuleManifestPolicy => policy !== undefined),\n\t\tstateMachines: (module.stateMachines ?? [])\n\t\t\t.map(exportStateMachine)\n\t\t\t.filter((machine): machine is ModuleManifestStateMachine => machine !== undefined),\n\t\tviews: (module.views ?? []).map(exportView),\n\t};\n\n\tif (module.version !== undefined) manifest.version = module.version;\n\tif (module.displayName !== undefined) manifest.displayName = module.displayName;\n\tif (module.description !== undefined) manifest.description = module.description;\n\tif (module.capability !== undefined) manifest.capability = cloneJson(module.capability);\n\n\treturn manifest;\n}\n\n/**\n * Export manifests for a set of modules, preserving the input order.\n * Like {@link exportModuleManifest}, this is pure and registry-free.\n */\nexport function exportModuleManifestBundle(\n\tmodules: FabricModule<unknown>[],\n): ModuleManifestBundle {\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: modules.map(exportModuleManifest),\n\t};\n}\n"],"mappings":"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"}
|
package/dist/modules/index.cjs
CHANGED
|
@@ -1,44 +1,283 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_events_index = require("../events/index.cjs");
|
|
3
|
+
const require_discovery_index = require("../discovery/index.cjs");
|
|
4
|
+
const require_objects_index = require("../objects/index.cjs");
|
|
5
|
+
const require_projections_index = require("../projections/index.cjs");
|
|
6
|
+
//#region modules/index.ts
|
|
7
|
+
function getModuleDependencyNamespace(dependency) {
|
|
8
|
+
return typeof dependency === "string" ? dependency : dependency.namespace;
|
|
9
|
+
}
|
|
10
|
+
function getObjectTypeName(objectType) {
|
|
11
|
+
return typeof objectType === "string" ? objectType : objectType.type;
|
|
12
|
+
}
|
|
13
|
+
function getEventTypeName(eventType) {
|
|
14
|
+
return typeof eventType === "string" ? eventType : eventType.eventType;
|
|
15
|
+
}
|
|
16
|
+
function validateModuleNamespace(namespace) {
|
|
17
|
+
if (!namespace) throw new Error("Module namespace cannot be empty");
|
|
18
|
+
if (!/^[a-z][a-z0-9-]*$/.test(namespace)) throw new Error(`Invalid module namespace: "${namespace}". Must be lowercase letters, numbers, and hyphens only.`);
|
|
19
|
+
}
|
|
20
|
+
function createModuleRegistry(modules = []) {
|
|
21
|
+
const orderedModules = validateAndOrderFabricModules(modules);
|
|
22
|
+
const registered = new Map(orderedModules.map((module) => [module.namespace, module]));
|
|
23
|
+
const actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action])));
|
|
24
|
+
const policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {
|
|
25
|
+
const evaluator = policy;
|
|
26
|
+
return [evaluator.policyId, evaluator];
|
|
27
|
+
})));
|
|
28
|
+
const machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {
|
|
29
|
+
const definition = machine;
|
|
30
|
+
return [definition.entityType, definition];
|
|
31
|
+
})));
|
|
32
|
+
const views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [require_projections_index.viewContractKey(view), view])));
|
|
33
|
+
return {
|
|
34
|
+
modules: registered,
|
|
35
|
+
orderedModules,
|
|
36
|
+
resolveAction: (actionId) => actions.get(actionId),
|
|
37
|
+
resolvePolicy: (policyId) => policies.get(policyId),
|
|
38
|
+
resolveStateMachine: (entityType) => machines.get(entityType),
|
|
39
|
+
resolveView: (name, version) => views.get(`${name}@${version}`)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function validateIdentifierList(values, label, namespace) {
|
|
43
|
+
for (const value of values ?? []) if (!value) throw new Error(`Module "${namespace}" has an empty ${label} entry.`);
|
|
44
|
+
}
|
|
45
|
+
function assertJsonValue(value, path) {
|
|
46
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
47
|
+
if (typeof value === "number" && Number.isFinite(value)) return;
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
value.forEach((item, index) => assertJsonValue(item, `${path}[${index}]`));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (typeof value === "object") {
|
|
53
|
+
for (const [key, child] of Object.entries(value)) assertJsonValue(child, `${path}.${key}`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`${path} must contain JSON-serializable values.`);
|
|
57
|
+
}
|
|
58
|
+
function qualifiedObjectType(namespace, type) {
|
|
59
|
+
return `${namespace}.${type}`;
|
|
60
|
+
}
|
|
61
|
+
function validateObjectDefinition(objectType, namespace, context) {
|
|
62
|
+
if (typeof objectType === "string") return;
|
|
63
|
+
if (objectType.schema !== void 0) require_objects_index.assertPortableJsonSchema(objectType.schema, `Module "${namespace}" object "${objectType.type}" schema`);
|
|
64
|
+
if (objectType.semantics !== void 0) assertJsonValue(objectType.semantics, `Module "${namespace}" object "${objectType.type}" semantics`);
|
|
65
|
+
const relationNames = /* @__PURE__ */ new Set();
|
|
66
|
+
for (const relation of objectType.relations ?? []) {
|
|
67
|
+
if (!/^[a-z][a-zA-Z0-9]*$/.test(relation.name)) throw new Error(`Module "${namespace}" object "${objectType.type}" has invalid relation name "${relation.name}".`);
|
|
68
|
+
if (relationNames.has(relation.name)) throw new Error(`Module "${namespace}" object "${objectType.type}" has duplicate relation "${relation.name}".`);
|
|
69
|
+
relationNames.add(relation.name);
|
|
70
|
+
if (!/^[a-z][a-z0-9-]*\.[A-Z][a-zA-Z0-9]*$/.test(relation.target)) throw new Error(`Relation "${relation.name}" target "${relation.target}" must be module-qualified.`);
|
|
71
|
+
if (context.availableObjectTypes && !context.availableObjectTypes.has(relation.target)) throw new Error(`Relation "${relation.name}" targets missing object type "${relation.target}".`);
|
|
72
|
+
if (relation.required && relation.onTargetDelete === "set-null") throw new Error(`Required relation "${relation.name}" cannot use onTargetDelete "set-null".`);
|
|
73
|
+
}
|
|
74
|
+
const invariantIds = /* @__PURE__ */ new Set();
|
|
75
|
+
for (const invariant of objectType.invariants ?? []) {
|
|
76
|
+
if (!invariant.id.trim() || !invariant.description.trim()) throw new Error(`Module "${namespace}" object "${objectType.type}" has an invariant without an id or description.`);
|
|
77
|
+
if (invariantIds.has(invariant.id)) throw new Error(`Module "${namespace}" object "${objectType.type}" has duplicate invariant "${invariant.id}".`);
|
|
78
|
+
invariantIds.add(invariant.id);
|
|
79
|
+
if (invariant.required && !invariant.enforcementRef?.trim()) throw new Error(`Required invariant "${invariant.id}" must declare enforcementRef.`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function validateCapabilityWorkflows(module, context) {
|
|
83
|
+
const workflows = module.capability?.workflows ?? [];
|
|
84
|
+
const actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));
|
|
85
|
+
const names = /* @__PURE__ */ new Set();
|
|
86
|
+
for (const workflow of workflows) {
|
|
87
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) throw new Error(`Module "${module.namespace}" declares invalid workflow name "${workflow.name}".`);
|
|
88
|
+
if (names.has(workflow.name)) throw new Error(`Module "${module.namespace}" declares duplicate workflow "${workflow.name}".`);
|
|
89
|
+
names.add(workflow.name);
|
|
90
|
+
if (!/^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares invalid task queue "${workflow.taskQueue}".`);
|
|
91
|
+
if (workflow.startedBy !== void 0) {
|
|
92
|
+
if (!(context.plannedEventTypes?.has(workflow.startedBy) ?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy))) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" is started by unknown event type "${workflow.startedBy}".`);
|
|
93
|
+
}
|
|
94
|
+
const timerNames = /* @__PURE__ */ new Set();
|
|
95
|
+
for (const timer of workflow.timers ?? []) {
|
|
96
|
+
if (!timer.name.trim() || !timer.configKey.trim()) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" has a timer without a name or configKey.`);
|
|
97
|
+
if (timerNames.has(timer.name)) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares duplicate timer "${timer.name}".`);
|
|
98
|
+
timerNames.add(timer.name);
|
|
99
|
+
}
|
|
100
|
+
const steps = /* @__PURE__ */ new Set();
|
|
101
|
+
for (const compensation of workflow.compensations ?? []) {
|
|
102
|
+
if (!compensation.step.trim()) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" has a compensation without a step.`);
|
|
103
|
+
if (steps.has(compensation.step)) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares duplicate compensation for step "${compensation.step}".`);
|
|
104
|
+
steps.add(compensation.step);
|
|
105
|
+
const compensatingAction = actionsById.get(compensation.actionId);
|
|
106
|
+
if (!compensatingAction) throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" compensates step "${compensation.step}" with unknown action "${compensation.actionId}".`);
|
|
107
|
+
if (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === "prohibited") throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" compensates step "${compensation.step}" with non-idempotent action "${compensation.actionId}"; a reversal must be safely repeatable.`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function validateManifest(module, context = {}) {
|
|
112
|
+
validateModuleNamespace(module.namespace);
|
|
113
|
+
const dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);
|
|
114
|
+
const objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);
|
|
115
|
+
const eventTypes = (module.eventTypes ?? []).map(getEventTypeName);
|
|
116
|
+
if (module.capability) {
|
|
117
|
+
if (!module.capability.displayName.trim() || !module.capability.description.trim()) throw new Error(`Module "${module.namespace}" capability requires displayName and description.`);
|
|
118
|
+
for (const namespace of Object.keys(module.capability.extensions ?? {})) if (!/^[a-z][a-z0-9.-]*\.[a-z0-9.-]+\/v[1-9][0-9]*$/.test(namespace)) throw new Error(`Module "${module.namespace}" capability has invalid extension namespace "${namespace}".`);
|
|
119
|
+
for (const port of module.capability.requirements?.ports ?? []) if (!/^[a-z][a-z0-9-]*(?:\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module "${module.namespace}" capability has invalid port requirement "${port.name}".`);
|
|
120
|
+
validateCapabilityWorkflows(module, context);
|
|
121
|
+
}
|
|
122
|
+
for (const eventType of module.eventTypes ?? []) if (typeof eventType !== "string" && eventType.schema) require_objects_index.assertPortableJsonSchema(eventType.schema, `Event "${eventType.eventType}" schema`);
|
|
123
|
+
for (const action of module.actions ?? []) {
|
|
124
|
+
if (action.execution?.idempotency === "required" && !action.idempotent) throw new Error(`Action "${action.actionId}" requires idempotency but is not declared idempotent.`);
|
|
125
|
+
if (action.execution?.connectivity === "offline-capturable" && action.execution.idempotency === "prohibited") throw new Error(`Offline action "${action.actionId}" cannot prohibit idempotency.`);
|
|
126
|
+
if (action.execution?.completionDeadlineMs !== void 0 && !(typeof action.execution.completionDeadlineMs === "number" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action "${action.actionId}" completionDeadlineMs must be a positive number of milliseconds.`);
|
|
127
|
+
if (action.execution?.completion === "immediate" && action.execution.completionDeadlineMs !== void 0) throw new Error(`Immediate action "${action.actionId}" cannot declare a completion deadline; nothing external completes it.`);
|
|
128
|
+
}
|
|
129
|
+
for (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) require_objects_index.assertPortableJsonSchema(view.usage.collection.filterSchema, `View "${view.name}" filter schema`);
|
|
130
|
+
for (const dependency of dependencies) {
|
|
131
|
+
validateModuleNamespace(dependency);
|
|
132
|
+
if (dependency === module.namespace) throw new Error(`Module "${module.namespace}" cannot depend on itself.`);
|
|
133
|
+
if (context.availableNamespaces && !context.availableNamespaces.has(dependency)) throw new Error(`Module "${module.namespace}" depends on missing module "${dependency}".`);
|
|
134
|
+
}
|
|
135
|
+
validateIdentifierList(objectTypes, "objectTypes", module.namespace);
|
|
136
|
+
validateIdentifierList(module.subjectTypes, "subjectTypes", module.namespace);
|
|
137
|
+
validateIdentifierList(eventTypes, "eventTypes", module.namespace);
|
|
138
|
+
for (const objectType of objectTypes) if (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) throw new Error(`Invalid object type: "${objectType}". Object types must be PascalCase alphanumeric.`);
|
|
139
|
+
for (const objectType of module.objectTypes ?? []) {
|
|
140
|
+
if (typeof objectType !== "string") for (const relation of objectType.relations ?? []) {
|
|
141
|
+
const targetNamespace = relation.target.slice(0, relation.target.indexOf("."));
|
|
142
|
+
if (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) throw new Error(`Module "${module.namespace}" relation "${relation.name}" targets module "${targetNamespace}" without declaring it as a dependency.`);
|
|
143
|
+
}
|
|
144
|
+
validateObjectDefinition(objectType, module.namespace, context);
|
|
145
|
+
}
|
|
146
|
+
for (const action of module.actions ?? []) {
|
|
147
|
+
require_discovery_index.assertSurfaceDeclaration(action, `Action "${action?.actionId ?? "unknown"}"`);
|
|
148
|
+
let parameterSchema;
|
|
149
|
+
try {
|
|
150
|
+
parameterSchema = action.schema.toJSONSchema?.();
|
|
151
|
+
} catch {
|
|
152
|
+
parameterSchema = void 0;
|
|
153
|
+
}
|
|
154
|
+
if (parameterSchema !== void 0) require_objects_index.assertPortableJsonSchema(parameterSchema, `Action "${action.actionId}" parameters`);
|
|
155
|
+
let resultSchema;
|
|
156
|
+
try {
|
|
157
|
+
resultSchema = action.resultSchema?.toJSONSchema?.();
|
|
158
|
+
} catch {
|
|
159
|
+
resultSchema = void 0;
|
|
160
|
+
}
|
|
161
|
+
if (resultSchema !== void 0) require_objects_index.assertPortableJsonSchema(resultSchema, `Action "${action.actionId}" result`);
|
|
162
|
+
if (!/^[a-z][a-z0-9-]*\.[a-z][a-z0-9_]*$/.test(action.actionId)) throw new Error(`Invalid action ID: ${action.actionId}`);
|
|
163
|
+
if (action.namespace !== module.namespace) throw new Error(`Action "${action.actionId}" declares namespace "${action.namespace}" but is registered by module "${module.namespace}".`);
|
|
164
|
+
if (!action.actionId.startsWith(`${module.namespace}.`)) throw new Error(`Action "${action.actionId}" must start with module namespace "${module.namespace}."`);
|
|
165
|
+
if (action.mutatesDomain && action.emitsEvents.length === 0) throw new Error(`Action "${action.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
|
|
166
|
+
if (action.admitSubmission !== void 0 && typeof action.admitSubmission !== "function") throw new Error(`Action "${action.actionId}" declares admitSubmission that is not a function.`);
|
|
167
|
+
}
|
|
168
|
+
const viewKeys = /* @__PURE__ */ new Set();
|
|
169
|
+
for (const view of module.views ?? []) {
|
|
170
|
+
require_discovery_index.assertSurfaceDeclaration(view, `View "${view?.name ?? "unknown"}"`);
|
|
171
|
+
if (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\/[a-z][a-z0-9/_-]*$/.test(view.name)) throw new Error(`View "${view.name}" must start with module namespace "${module.namespace}/" and use lowercase path segments.`);
|
|
172
|
+
if (!view.version.trim()) throw new Error(`View "${view.name}" must declare a version.`);
|
|
173
|
+
const key = `${view.name}@${view.version}`;
|
|
174
|
+
if (viewKeys.has(key)) throw new Error(`Module "${module.namespace}" has duplicate view contract "${key}".`);
|
|
175
|
+
viewKeys.add(key);
|
|
176
|
+
require_objects_index.assertPortableJsonSchema(view.shape, `View "${key}" shape`);
|
|
177
|
+
if (view.parameterSchema !== void 0) require_objects_index.assertPortableJsonSchema(view.parameterSchema, `View "${key}" parameters`);
|
|
178
|
+
if (!Number.isInteger(view.snapshotVersion) || view.snapshotVersion < 1) throw new Error(`View "${key}" snapshotVersion must be a positive integer.`);
|
|
179
|
+
if ((view.compatibleSnapshotVersions?.some((version) => version !== view.snapshotVersion) ?? false) && !view.upgradeSnapshot) throw new Error(`View "${key}" declares older compatible snapshots but no upgradeSnapshot function.`);
|
|
180
|
+
for (const consumption of view.consumes) {
|
|
181
|
+
const isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;
|
|
182
|
+
const isModuleEvent = eventTypes.includes(consumption.eventType);
|
|
183
|
+
if (!isPlanned && !isModuleEvent) throw new Error(`View "${key}" consumes unknown event type "${consumption.eventType}".`);
|
|
184
|
+
if (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) throw new Error(`View "${key}" must declare positive consumed schema versions for "${consumption.eventType}".`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function sortModulesByDependency(modules, registeredNamespaces = /* @__PURE__ */ new Set()) {
|
|
189
|
+
const modulesByNamespace = /* @__PURE__ */ new Map();
|
|
190
|
+
for (const module of modules) {
|
|
191
|
+
validateModuleNamespace(module.namespace);
|
|
192
|
+
if (modulesByNamespace.has(module.namespace)) throw new Error(`Duplicate FabricModule namespace "${module.namespace}".`);
|
|
193
|
+
modulesByNamespace.set(module.namespace, module);
|
|
194
|
+
}
|
|
195
|
+
const sorted = [];
|
|
196
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
197
|
+
const visited = /* @__PURE__ */ new Set();
|
|
198
|
+
function visit(module, path) {
|
|
199
|
+
if (visited.has(module.namespace)) return;
|
|
200
|
+
if (visiting.has(module.namespace)) throw new Error(`Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(" -> ")}`);
|
|
201
|
+
visiting.add(module.namespace);
|
|
202
|
+
for (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {
|
|
203
|
+
const dependencyModule = modulesByNamespace.get(dependency);
|
|
204
|
+
if (!dependencyModule) {
|
|
205
|
+
if (registeredNamespaces.has(dependency)) continue;
|
|
206
|
+
throw new Error(`Module "${module.namespace}" depends on missing module "${dependency}".`);
|
|
207
|
+
}
|
|
208
|
+
visit(dependencyModule, [...path, module.namespace]);
|
|
209
|
+
}
|
|
210
|
+
visiting.delete(module.namespace);
|
|
211
|
+
visited.add(module.namespace);
|
|
212
|
+
sorted.push(module);
|
|
213
|
+
}
|
|
214
|
+
for (const module of modules) visit(module, []);
|
|
215
|
+
return sorted;
|
|
216
|
+
}
|
|
217
|
+
function assertAcyclicRelations(modules) {
|
|
218
|
+
const relationKinds = [
|
|
219
|
+
{
|
|
220
|
+
label: "owned containment",
|
|
221
|
+
include: (relation) => relation.semantics === "owned"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
label: "cascade-delete",
|
|
225
|
+
include: (relation) => relation.onTargetDelete === "cascade"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
label: "required-construction",
|
|
229
|
+
include: (relation) => relation.required === true
|
|
230
|
+
}
|
|
231
|
+
];
|
|
232
|
+
for (const kind of relationKinds) {
|
|
233
|
+
const edges = /* @__PURE__ */ new Map();
|
|
234
|
+
for (const module of modules) for (const objectType of module.objectTypes ?? []) {
|
|
235
|
+
if (typeof objectType === "string") continue;
|
|
236
|
+
const source = qualifiedObjectType(module.namespace, objectType.type);
|
|
237
|
+
edges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));
|
|
238
|
+
}
|
|
239
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
240
|
+
const visited = /* @__PURE__ */ new Set();
|
|
241
|
+
const visit = (node, path) => {
|
|
242
|
+
if (visiting.has(node)) throw new Error(`${kind.label} relation cycle detected: ${[...path, node].join(" -> ")}`);
|
|
243
|
+
if (visited.has(node)) return;
|
|
244
|
+
visiting.add(node);
|
|
245
|
+
for (const target of edges.get(node) ?? []) visit(target, [...path, node]);
|
|
246
|
+
visiting.delete(node);
|
|
247
|
+
visited.add(node);
|
|
248
|
+
};
|
|
249
|
+
for (const node of edges.keys()) visit(node, []);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function validateAndOrderFabricModules(modules) {
|
|
253
|
+
const availableNamespaces = new Set(modules.map((module) => module.namespace));
|
|
254
|
+
const plannedEventTypes = new Set(modules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName)));
|
|
255
|
+
for (const eventType of require_events_index.createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);
|
|
256
|
+
const availableObjectTypes = /* @__PURE__ */ new Set([...modules.flatMap((module) => (module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType))))]);
|
|
257
|
+
for (const module of modules) validateManifest(module, {
|
|
258
|
+
availableNamespaces,
|
|
259
|
+
plannedEventTypes,
|
|
260
|
+
availableObjectTypes
|
|
261
|
+
});
|
|
262
|
+
assertAcyclicRelations(modules);
|
|
263
|
+
return sortModulesByDependency(modules);
|
|
264
|
+
}
|
|
265
|
+
/** @deprecated Use createModuleRegistry(); registration is now explicit and instance-scoped. */
|
|
266
|
+
function registerFabricModules(modules) {
|
|
267
|
+
return validateAndOrderFabricModules(modules);
|
|
268
|
+
}
|
|
269
|
+
/** @deprecated Use createModuleRegistry([module]); registration is now explicit and instance-scoped. */
|
|
270
|
+
function registerFabricModule(module) {
|
|
271
|
+
validateAndOrderFabricModules([module]);
|
|
272
|
+
}
|
|
273
|
+
//#endregion
|
|
274
|
+
exports.createModuleRegistry = createModuleRegistry;
|
|
275
|
+
exports.getEventTypeName = getEventTypeName;
|
|
276
|
+
exports.getModuleDependencyNamespace = getModuleDependencyNamespace;
|
|
277
|
+
exports.getObjectTypeName = getObjectTypeName;
|
|
278
|
+
exports.registerFabricModule = registerFabricModule;
|
|
279
|
+
exports.registerFabricModules = registerFabricModules;
|
|
280
|
+
exports.validateAndOrderFabricModules = validateAndOrderFabricModules;
|
|
281
|
+
exports.validateModuleNamespace = validateModuleNamespace;
|
|
2
282
|
|
|
3
|
-
var chunkDBTAUI6C_cjs = require('../chunk-DBTAUI6C.cjs');
|
|
4
|
-
require('../chunk-IFW43ELT.cjs');
|
|
5
|
-
require('../chunk-SNTV45LH.cjs');
|
|
6
|
-
require('../chunk-D4SWRBUH.cjs');
|
|
7
|
-
require('../chunk-2AE6TMAX.cjs');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Object.defineProperty(exports, "createModuleRegistry", {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
get: function () { return chunkDBTAUI6C_cjs.createModuleRegistry; }
|
|
14
|
-
});
|
|
15
|
-
Object.defineProperty(exports, "getEventTypeName", {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
get: function () { return chunkDBTAUI6C_cjs.getEventTypeName; }
|
|
18
|
-
});
|
|
19
|
-
Object.defineProperty(exports, "getModuleDependencyNamespace", {
|
|
20
|
-
enumerable: true,
|
|
21
|
-
get: function () { return chunkDBTAUI6C_cjs.getModuleDependencyNamespace; }
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(exports, "getObjectTypeName", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
get: function () { return chunkDBTAUI6C_cjs.getObjectTypeName; }
|
|
26
|
-
});
|
|
27
|
-
Object.defineProperty(exports, "registerFabricModule", {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
get: function () { return chunkDBTAUI6C_cjs.registerFabricModule; }
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(exports, "registerFabricModules", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
get: function () { return chunkDBTAUI6C_cjs.registerFabricModules; }
|
|
34
|
-
});
|
|
35
|
-
Object.defineProperty(exports, "validateAndOrderFabricModules", {
|
|
36
|
-
enumerable: true,
|
|
37
|
-
get: function () { return chunkDBTAUI6C_cjs.validateAndOrderFabricModules; }
|
|
38
|
-
});
|
|
39
|
-
Object.defineProperty(exports, "validateModuleNamespace", {
|
|
40
|
-
enumerable: true,
|
|
41
|
-
get: function () { return chunkDBTAUI6C_cjs.validateModuleNamespace; }
|
|
42
|
-
});
|
|
43
|
-
//# sourceMappingURL=index.cjs.map
|
|
44
283
|
//# sourceMappingURL=index.cjs.map
|