@lucern/graph-primitives 0.1.0-alpha.2
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/README.md +29 -0
- package/dist/beliefDecay-Q_26RTc-.d.ts +72 -0
- package/dist/beliefDecay.d.ts +2 -0
- package/dist/beliefDecay.js +1628 -0
- package/dist/beliefDecay.js.map +1 -0
- package/dist/beliefEvidenceLinks-42FlR48t.d.ts +77 -0
- package/dist/beliefEvidenceLinks.d.ts +1 -0
- package/dist/beliefEvidenceLinks.js +1978 -0
- package/dist/beliefEvidenceLinks.js.map +1 -0
- package/dist/beliefLifecycle-C-AehZgF.d.ts +43 -0
- package/dist/beliefLifecycle.d.ts +1 -0
- package/dist/beliefLifecycle.js +98 -0
- package/dist/beliefLifecycle.js.map +1 -0
- package/dist/confidencePropagationDispatch.d.ts +46 -0
- package/dist/confidencePropagationDispatch.js +744 -0
- package/dist/confidencePropagationDispatch.js.map +1 -0
- package/dist/contradictions-Hdwl7zid.d.ts +71 -0
- package/dist/contradictions.d.ts +1 -0
- package/dist/contradictions.js +1557 -0
- package/dist/contradictions.js.map +1 -0
- package/dist/convex.d.ts +23 -0
- package/dist/convex.js +17 -0
- package/dist/convex.js.map +1 -0
- package/dist/edgeValidation-CeI0wc0r.d.ts +35 -0
- package/dist/edgeValidation.d.ts +2 -0
- package/dist/edgeValidation.js +307 -0
- package/dist/edgeValidation.js.map +1 -0
- package/dist/edges/contains.d.ts +6 -0
- package/dist/edges/contains.js +14 -0
- package/dist/edges/contains.js.map +1 -0
- package/dist/edges/contradicts.d.ts +6 -0
- package/dist/edges/contradicts.js +183 -0
- package/dist/edges/contradicts.js.map +1 -0
- package/dist/edges/dependsOn.d.ts +6 -0
- package/dist/edges/dependsOn.js +240 -0
- package/dist/edges/dependsOn.js.map +1 -0
- package/dist/edges/derivedFrom.d.ts +6 -0
- package/dist/edges/derivedFrom.js +14 -0
- package/dist/edges/derivedFrom.js.map +1 -0
- package/dist/edges/elaborates.d.ts +6 -0
- package/dist/edges/elaborates.js +100 -0
- package/dist/edges/elaborates.js.map +1 -0
- package/dist/edges/index.d.ts +3 -0
- package/dist/edges/index.js +556 -0
- package/dist/edges/index.js.map +1 -0
- package/dist/edges/informs.d.ts +6 -0
- package/dist/edges/informs.js +112 -0
- package/dist/edges/informs.js.map +1 -0
- package/dist/edges/propagationTypes.d.ts +39 -0
- package/dist/edges/propagationTypes.js +17 -0
- package/dist/edges/propagationTypes.js.map +1 -0
- package/dist/edges/refutes.d.ts +6 -0
- package/dist/edges/refutes.js +108 -0
- package/dist/edges/refutes.js.map +1 -0
- package/dist/edges/supports.d.ts +6 -0
- package/dist/edges/supports.js +193 -0
- package/dist/edges/supports.js.map +1 -0
- package/dist/edges/tests.d.ts +6 -0
- package/dist/edges/tests.js +14 -0
- package/dist/edges/tests.js.map +1 -0
- package/dist/edges/utils.d.ts +12 -0
- package/dist/edges/utils.js +188 -0
- package/dist/edges/utils.js.map +1 -0
- package/dist/embeddingTrigger.d.ts +24 -0
- package/dist/embeddingTrigger.js +24 -0
- package/dist/embeddingTrigger.js.map +1 -0
- package/dist/entityBridge-DMaKooYn.d.ts +59 -0
- package/dist/entityBridge.d.ts +1 -0
- package/dist/entityBridge.js +663 -0
- package/dist/entityBridge.js.map +1 -0
- package/dist/entityLifecycle-BkhRJ-XI.d.ts +69 -0
- package/dist/entityLifecycle.d.ts +1 -0
- package/dist/entityLifecycle.js +2083 -0
- package/dist/entityLifecycle.js.map +1 -0
- package/dist/entityValidation-KLZ_Xl2D.d.ts +50 -0
- package/dist/entityValidation.d.ts +3 -0
- package/dist/entityValidation.js +71 -0
- package/dist/entityValidation.js.map +1 -0
- package/dist/epistemicAnswers-DSP1slZ9.d.ts +67 -0
- package/dist/epistemicAnswers.d.ts +1 -0
- package/dist/epistemicAnswers.js +1650 -0
- package/dist/epistemicAnswers.js.map +1 -0
- package/dist/epistemicBeliefs-DtFVTp-k.d.ts +377 -0
- package/dist/epistemicBeliefs.d.ts +5 -0
- package/dist/epistemicBeliefs.js +6386 -0
- package/dist/epistemicBeliefs.js.map +1 -0
- package/dist/epistemicContractHelpers.d.ts +1 -0
- package/dist/epistemicContractHelpers.js +320 -0
- package/dist/epistemicContractHelpers.js.map +1 -0
- package/dist/epistemicContracts.d.ts +77 -0
- package/dist/epistemicContracts.js +8436 -0
- package/dist/epistemicContracts.js.map +1 -0
- package/dist/epistemicEdges-DcA8ErUG.d.ts +191 -0
- package/dist/epistemicEdges.d.ts +2 -0
- package/dist/epistemicEdges.js +2749 -0
- package/dist/epistemicEdges.js.map +1 -0
- package/dist/epistemicEvidence-Bo638XDP.d.ts +128 -0
- package/dist/epistemicEvidence.d.ts +3 -0
- package/dist/epistemicEvidence.js +3282 -0
- package/dist/epistemicEvidence.js.map +1 -0
- package/dist/epistemicHelpers-Bd9xbaib.d.ts +329 -0
- package/dist/epistemicHelpers.d.ts +4 -0
- package/dist/epistemicHelpers.js +999 -0
- package/dist/epistemicHelpers.js.map +1 -0
- package/dist/epistemicLinking-CyeLOIzN.d.ts +35 -0
- package/dist/epistemicLinking.d.ts +1 -0
- package/dist/epistemicLinking.js +1391 -0
- package/dist/epistemicLinking.js.map +1 -0
- package/dist/epistemicNodes-BpD6Koud.d.ts +167 -0
- package/dist/epistemicNodes.d.ts +2 -0
- package/dist/epistemicNodes.js +2942 -0
- package/dist/epistemicNodes.js.map +1 -0
- package/dist/epistemicQuestions-CmEeY6zQ.d.ts +214 -0
- package/dist/epistemicQuestions.d.ts +3 -0
- package/dist/epistemicQuestions.js +4993 -0
- package/dist/epistemicQuestions.js.map +1 -0
- package/dist/epistemicSources-ZazxHOK1.d.ts +25 -0
- package/dist/epistemicSources.d.ts +1 -0
- package/dist/epistemicSources.js +2025 -0
- package/dist/epistemicSources.js.map +1 -0
- package/dist/evaluators/index.d.ts +9 -0
- package/dist/evaluators/index.js +8440 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/lintCheckerEvaluator.d.ts +11 -0
- package/dist/evaluators/lintCheckerEvaluator.js +155 -0
- package/dist/evaluators/lintCheckerEvaluator.js.map +1 -0
- package/dist/evaluators/sentryCheckerEvaluator.d.ts +11 -0
- package/dist/evaluators/sentryCheckerEvaluator.js +126 -0
- package/dist/evaluators/sentryCheckerEvaluator.js.map +1 -0
- package/dist/evaluators/shared.d.ts +27 -0
- package/dist/evaluators/shared.js +92 -0
- package/dist/evaluators/shared.js.map +1 -0
- package/dist/evaluators/testRunnerEvaluator.d.ts +17 -0
- package/dist/evaluators/testRunnerEvaluator.js +232 -0
- package/dist/evaluators/testRunnerEvaluator.js.map +1 -0
- package/dist/evaluators/tscCheckerEvaluator.d.ts +11 -0
- package/dist/evaluators/tscCheckerEvaluator.js +189 -0
- package/dist/evaluators/tscCheckerEvaluator.js.map +1 -0
- package/dist/globalId-DKh9d_uD.d.ts +20 -0
- package/dist/globalId.d.ts +1 -0
- package/dist/globalId.js +15 -0
- package/dist/globalId.js.map +1 -0
- package/dist/graphTypes-CpgIuCdo.d.ts +52 -0
- package/dist/graphTypes.d.ts +1 -0
- package/dist/graphTypes.js +120 -0
- package/dist/graphTypes.js.map +1 -0
- package/dist/helpers-BYHIk5vU.d.ts +27 -0
- package/dist/helpers.d.ts +4 -0
- package/dist/helpers.js +313 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index-Dct1T70K.d.ts +25 -0
- package/dist/index-Dq-7R-gi.d.ts +31 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +22294 -0
- package/dist/index.js.map +1 -0
- package/dist/invariantEnforcement.d.ts +52 -0
- package/dist/invariantEnforcement.js +231 -0
- package/dist/invariantEnforcement.js.map +1 -0
- package/dist/logicalRoleInference-CJxqWi3u.d.ts +16 -0
- package/dist/logicalRoleInference.d.ts +3 -0
- package/dist/logicalRoleInference.js +64 -0
- package/dist/logicalRoleInference.js.map +1 -0
- package/dist/matcherFeedbackUtils.d.ts +33 -0
- package/dist/matcherFeedbackUtils.js +95 -0
- package/dist/matcherFeedbackUtils.js.map +1 -0
- package/dist/ontology-matching-Buhu23ss.d.ts +48 -0
- package/dist/ontology-matching.d.ts +2 -0
- package/dist/ontology-matching.js +346 -0
- package/dist/ontology-matching.js.map +1 -0
- package/dist/ontologyApproval-Ba0Jjk1k.d.ts +26 -0
- package/dist/ontologyApproval.d.ts +1 -0
- package/dist/ontologyApproval.js +78 -0
- package/dist/ontologyApproval.js.map +1 -0
- package/dist/ontologyDefinitions.d.ts +72 -0
- package/dist/ontologyDefinitions.js +635 -0
- package/dist/ontologyDefinitions.js.map +1 -0
- package/dist/ontologyHelpers.d.ts +79 -0
- package/dist/ontologyHelpers.js +81 -0
- package/dist/ontologyHelpers.js.map +1 -0
- package/dist/ontologyRegistry-B67rPJ16.d.ts +31 -0
- package/dist/ontologyRegistry.d.ts +1 -0
- package/dist/ontologyRegistry.js +296 -0
- package/dist/ontologyRegistry.js.map +1 -0
- package/dist/projectionReconciliation-CxrXYGaB.d.ts +20 -0
- package/dist/projectionReconciliation.d.ts +1 -0
- package/dist/projectionReconciliation.js +261 -0
- package/dist/projectionReconciliation.js.map +1 -0
- package/dist/projectionStaleness-CAdpIsaW.d.ts +51 -0
- package/dist/projectionStaleness.d.ts +1 -0
- package/dist/projectionStaleness.js +57 -0
- package/dist/projectionStaleness.js.map +1 -0
- package/dist/questionEvidenceLinks-BdQD0TkM.d.ts +34 -0
- package/dist/questionEvidenceLinks.d.ts +1 -0
- package/dist/questionEvidenceLinks.js +1690 -0
- package/dist/questionEvidenceLinks.js.map +1 -0
- package/dist/resolverTypes-CC8Ea2E2.d.ts +20 -0
- package/dist/resolverTypes.d.ts +4 -0
- package/dist/resolverTypes.js +3 -0
- package/dist/resolverTypes.js.map +1 -0
- package/dist/resolvers-Br1a6eLV.d.ts +14 -0
- package/dist/resolvers.d.ts +5 -0
- package/dist/resolvers.js +308 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/scopeResolverCompat.d.ts +26 -0
- package/dist/scopeResolverCompat.js +242 -0
- package/dist/scopeResolverCompat.js.map +1 -0
- package/dist/text-matching-CMn2WnVD.d.ts +40 -0
- package/dist/text-matching.d.ts +2 -0
- package/dist/text-matching.js +246 -0
- package/dist/text-matching.js.map +1 -0
- package/dist/topicOntologyResolver.d.ts +80 -0
- package/dist/topicOntologyResolver.js +67 -0
- package/dist/topicOntologyResolver.js.map +1 -0
- package/dist/topicProjectOverlay.d.ts +92 -0
- package/dist/topicProjectOverlay.js +249 -0
- package/dist/topicProjectOverlay.js.map +1 -0
- package/dist/topicScope-By_zp4tt.d.ts +34 -0
- package/dist/topicScope.d.ts +3 -0
- package/dist/topicScope.js +206 -0
- package/dist/topicScope.js.map +1 -0
- package/dist/workspaceIsolation.d.ts +44 -0
- package/dist/workspaceIsolation.js +950 -0
- package/dist/workspaceIsolation.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
import { v } from 'convex/values';
|
|
2
|
+
import { componentsGeneric, queryGeneric, mutationGeneric } from 'convex/server';
|
|
3
|
+
|
|
4
|
+
// src/ontologyDefinitions.ts
|
|
5
|
+
|
|
6
|
+
// ../access-control/src/auth.ts
|
|
7
|
+
async function getCurrentUserId(ctx) {
|
|
8
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
9
|
+
return identity?.subject ?? null;
|
|
10
|
+
}
|
|
11
|
+
var permissiveReturn = v.optional(v.any());
|
|
12
|
+
var looseJsonObject = v.record(v.string(), v.any());
|
|
13
|
+
var looseJsonArray = v.array(v.any());
|
|
14
|
+
v.union(
|
|
15
|
+
v.string(),
|
|
16
|
+
v.number(),
|
|
17
|
+
v.boolean(),
|
|
18
|
+
v.null(),
|
|
19
|
+
looseJsonObject,
|
|
20
|
+
looseJsonArray
|
|
21
|
+
);
|
|
22
|
+
componentsGeneric();
|
|
23
|
+
var mutation = mutationGeneric;
|
|
24
|
+
var query = queryGeneric;
|
|
25
|
+
|
|
26
|
+
// src/ontologyHelpers.ts
|
|
27
|
+
var ONTOLOGY_KEY_REGEX = /^[a-z][a-z0-9-]*[a-z0-9]$/;
|
|
28
|
+
function validateOntologyKey(key) {
|
|
29
|
+
const normalized = key.trim().toLowerCase();
|
|
30
|
+
if (normalized.length < 2) {
|
|
31
|
+
return {
|
|
32
|
+
valid: false,
|
|
33
|
+
normalized,
|
|
34
|
+
error: "Ontology key must be at least 2 characters."
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (normalized.length > 64) {
|
|
38
|
+
return {
|
|
39
|
+
valid: false,
|
|
40
|
+
normalized,
|
|
41
|
+
error: "Ontology key must be at most 64 characters."
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (!ONTOLOGY_KEY_REGEX.test(normalized)) {
|
|
45
|
+
return {
|
|
46
|
+
valid: false,
|
|
47
|
+
normalized,
|
|
48
|
+
error: "Ontology key must start with a letter, contain only lowercase letters, digits, and hyphens, and not end with a hyphen."
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return { valid: true, normalized };
|
|
52
|
+
}
|
|
53
|
+
function validateVersionString(version) {
|
|
54
|
+
return /^\d+\.\d+\.\d+$/.test(version);
|
|
55
|
+
}
|
|
56
|
+
function mergeOntologyLayers(parent, child, parentKey, childKey) {
|
|
57
|
+
const entityMap = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const et of parent.entityTypes) {
|
|
59
|
+
entityMap.set(et.value, et);
|
|
60
|
+
}
|
|
61
|
+
for (const et of child.entityTypes) {
|
|
62
|
+
entityMap.set(et.value, et);
|
|
63
|
+
}
|
|
64
|
+
const edgeMap = /* @__PURE__ */ new Map();
|
|
65
|
+
for (const edge of parent.edgeTypes) {
|
|
66
|
+
edgeMap.set(edge.value, edge);
|
|
67
|
+
}
|
|
68
|
+
for (const edge of child.edgeTypes) {
|
|
69
|
+
edgeMap.set(edge.value, edge);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
entityTypes: Array.from(entityMap.values()),
|
|
73
|
+
edgeTypes: Array.from(edgeMap.values()),
|
|
74
|
+
layers: [parentKey, childKey]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/ontologyDefinitions.ts
|
|
79
|
+
async function requireAuth(ctx) {
|
|
80
|
+
const userId = await getCurrentUserId(ctx);
|
|
81
|
+
if (!userId) {
|
|
82
|
+
throw new Error("Authentication required.");
|
|
83
|
+
}
|
|
84
|
+
return userId;
|
|
85
|
+
}
|
|
86
|
+
async function logAudit(ctx, args) {
|
|
87
|
+
await ctx.db.insert("epistemicAudit", {
|
|
88
|
+
entityType: args.entityType,
|
|
89
|
+
entityId: args.entityId,
|
|
90
|
+
changeType: args.changeType,
|
|
91
|
+
changedAt: Date.now(),
|
|
92
|
+
changedBy: args.changedBy,
|
|
93
|
+
isAgent: false,
|
|
94
|
+
previousState: args.previousState ?? null,
|
|
95
|
+
newState: args.newState ?? null
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
var getOntologyDefinition = query({
|
|
99
|
+
args: { id: v.id("ontologyDefinitions") },
|
|
100
|
+
returns: permissiveReturn,
|
|
101
|
+
handler: async (ctx, args) => {
|
|
102
|
+
return await ctx.db.get(args.id);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
var getOntologyDefinitionByKey = query({
|
|
106
|
+
args: {
|
|
107
|
+
ontologyKey: v.string(),
|
|
108
|
+
tenantId: v.optional(v.string())
|
|
109
|
+
},
|
|
110
|
+
returns: permissiveReturn,
|
|
111
|
+
handler: async (ctx, args) => {
|
|
112
|
+
if (args.tenantId) {
|
|
113
|
+
return await ctx.db.query("ontologyDefinitions").withIndex(
|
|
114
|
+
"by_tenant_ontologyKey",
|
|
115
|
+
(q) => q.eq("tenantId", args.tenantId).eq("ontologyKey", args.ontologyKey)
|
|
116
|
+
).first();
|
|
117
|
+
}
|
|
118
|
+
return await ctx.db.query("ontologyDefinitions").withIndex(
|
|
119
|
+
"by_tenant_ontologyKey",
|
|
120
|
+
(q) => q.eq("tenantId", void 0).eq("ontologyKey", args.ontologyKey)
|
|
121
|
+
).first();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
var listOntologyDefinitions = query({
|
|
125
|
+
args: {
|
|
126
|
+
tenantId: v.optional(v.string()),
|
|
127
|
+
tier: v.optional(
|
|
128
|
+
v.union(v.literal("platform"), v.literal("pack"), v.literal("tenant"))
|
|
129
|
+
),
|
|
130
|
+
status: v.optional(
|
|
131
|
+
v.union(
|
|
132
|
+
v.literal("draft"),
|
|
133
|
+
v.literal("active"),
|
|
134
|
+
v.literal("deprecated"),
|
|
135
|
+
v.literal("archived")
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
},
|
|
139
|
+
returns: permissiveReturn,
|
|
140
|
+
handler: async (ctx, args) => {
|
|
141
|
+
if (args.tenantId && args.status) {
|
|
142
|
+
const status = args.status;
|
|
143
|
+
return await ctx.db.query("ontologyDefinitions").withIndex(
|
|
144
|
+
"by_tenant_status",
|
|
145
|
+
(q) => q.eq("tenantId", args.tenantId).eq("status", status)
|
|
146
|
+
).collect();
|
|
147
|
+
}
|
|
148
|
+
if (args.status) {
|
|
149
|
+
const status = args.status;
|
|
150
|
+
return await ctx.db.query("ontologyDefinitions").withIndex("by_status", (q) => q.eq("status", status)).collect();
|
|
151
|
+
}
|
|
152
|
+
if (args.tier) {
|
|
153
|
+
const tier = args.tier;
|
|
154
|
+
return await ctx.db.query("ontologyDefinitions").withIndex("by_tier", (q) => q.eq("tier", tier)).collect();
|
|
155
|
+
}
|
|
156
|
+
return await ctx.db.query("ontologyDefinitions").collect();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
var getOntologyVersion = query({
|
|
160
|
+
args: {
|
|
161
|
+
ontologyKey: v.string(),
|
|
162
|
+
version: v.string()
|
|
163
|
+
},
|
|
164
|
+
returns: permissiveReturn,
|
|
165
|
+
handler: async (ctx, args) => {
|
|
166
|
+
return await ctx.db.query("ontologyVersions").withIndex(
|
|
167
|
+
"by_ontologyKey_version",
|
|
168
|
+
(q) => q.eq("ontologyKey", args.ontologyKey).eq("version", args.version)
|
|
169
|
+
).first();
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
var listOntologyVersions = query({
|
|
173
|
+
args: {
|
|
174
|
+
ontologyId: v.id("ontologyDefinitions"),
|
|
175
|
+
status: v.optional(
|
|
176
|
+
v.union(
|
|
177
|
+
v.literal("draft"),
|
|
178
|
+
v.literal("published"),
|
|
179
|
+
v.literal("deprecated")
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
},
|
|
183
|
+
returns: permissiveReturn,
|
|
184
|
+
handler: async (ctx, args) => {
|
|
185
|
+
const all = await ctx.db.query("ontologyVersions").withIndex("by_ontologyId", (q) => q.eq("ontologyId", args.ontologyId)).collect();
|
|
186
|
+
if (args.status) {
|
|
187
|
+
return all.filter((versionDoc) => versionDoc.status === args.status);
|
|
188
|
+
}
|
|
189
|
+
return all;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
var getPublishedVersion = query({
|
|
193
|
+
args: { ontologyId: v.id("ontologyDefinitions") },
|
|
194
|
+
returns: permissiveReturn,
|
|
195
|
+
handler: async (ctx, args) => {
|
|
196
|
+
const published = await ctx.db.query("ontologyVersions").withIndex("by_ontologyId", (q) => q.eq("ontologyId", args.ontologyId)).collect();
|
|
197
|
+
const publishedOnly = published.filter(
|
|
198
|
+
(versionDoc) => versionDoc.status === "published"
|
|
199
|
+
);
|
|
200
|
+
if (publishedOnly.length === 0) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
publishedOnly.sort((a, b) => (b.publishedAt ?? 0) - (a.publishedAt ?? 0));
|
|
204
|
+
return publishedOnly[0];
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
var resolveEffectiveOntology = query({
|
|
208
|
+
args: { ontologyId: v.id("ontologyDefinitions") },
|
|
209
|
+
returns: permissiveReturn,
|
|
210
|
+
handler: async (ctx, args) => {
|
|
211
|
+
const MAX_DEPTH = 3;
|
|
212
|
+
const chain = [];
|
|
213
|
+
let currentId = args.ontologyId;
|
|
214
|
+
for (let depth = 0; depth < MAX_DEPTH && currentId; depth++) {
|
|
215
|
+
const ontologyId = currentId;
|
|
216
|
+
const def = await ctx.db.get(ontologyId);
|
|
217
|
+
if (!def) {
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
const defTyped = def;
|
|
221
|
+
const versions = await ctx.db.query("ontologyVersions").withIndex("by_ontologyId", (q) => q.eq("ontologyId", ontologyId)).collect();
|
|
222
|
+
const published = versions.filter((ver) => ver.status === "published").sort(
|
|
223
|
+
(a, b) => (b.publishedAt ?? 0) - (a.publishedAt ?? 0)
|
|
224
|
+
);
|
|
225
|
+
chain.unshift({
|
|
226
|
+
def: defTyped,
|
|
227
|
+
version: published[0] ?? null
|
|
228
|
+
});
|
|
229
|
+
currentId = defTyped.parentOntologyId;
|
|
230
|
+
}
|
|
231
|
+
if (chain.length === 0) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
let merged = {
|
|
235
|
+
entityTypes: [],
|
|
236
|
+
edgeTypes: [],
|
|
237
|
+
layers: []
|
|
238
|
+
};
|
|
239
|
+
for (const { def, version } of chain) {
|
|
240
|
+
if (!version) {
|
|
241
|
+
merged.layers.push(def.ontologyKey);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const previousLayerKey = merged.layers.at(-1) ?? def.ontologyKey;
|
|
245
|
+
merged = mergeOntologyLayers(
|
|
246
|
+
merged,
|
|
247
|
+
{
|
|
248
|
+
entityTypes: version.entityTypes,
|
|
249
|
+
edgeTypes: version.edgeTypes
|
|
250
|
+
},
|
|
251
|
+
previousLayerKey,
|
|
252
|
+
def.ontologyKey
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
return merged;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
var createOntologyDefinition = mutation({
|
|
259
|
+
args: {
|
|
260
|
+
ontologyKey: v.string(),
|
|
261
|
+
name: v.string(),
|
|
262
|
+
description: v.optional(v.string()),
|
|
263
|
+
tenantId: v.optional(v.string()),
|
|
264
|
+
tier: v.union(
|
|
265
|
+
v.literal("platform"),
|
|
266
|
+
v.literal("pack"),
|
|
267
|
+
v.literal("tenant")
|
|
268
|
+
),
|
|
269
|
+
parentOntologyId: v.optional(v.id("ontologyDefinitions"))
|
|
270
|
+
},
|
|
271
|
+
returns: permissiveReturn,
|
|
272
|
+
handler: async (ctx, args) => {
|
|
273
|
+
const userId = await requireAuth(ctx);
|
|
274
|
+
const keyResult = validateOntologyKey(args.ontologyKey);
|
|
275
|
+
if (!keyResult.valid) {
|
|
276
|
+
throw new Error(keyResult.error ?? "Invalid ontology key");
|
|
277
|
+
}
|
|
278
|
+
const existing = await ctx.db.query("ontologyDefinitions").withIndex(
|
|
279
|
+
"by_tenant_ontologyKey",
|
|
280
|
+
(q) => q.eq("tenantId", args.tenantId).eq("ontologyKey", keyResult.normalized)
|
|
281
|
+
).first();
|
|
282
|
+
if (existing) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
`Ontology "${keyResult.normalized}" already exists for tenant ${args.tenantId ?? "(platform)"}.`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
if (args.parentOntologyId) {
|
|
288
|
+
const parent = await ctx.db.get(args.parentOntologyId);
|
|
289
|
+
if (!parent) {
|
|
290
|
+
throw new Error("Parent ontology definition not found.");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const now = Date.now();
|
|
294
|
+
const id = await ctx.db.insert("ontologyDefinitions", {
|
|
295
|
+
ontologyKey: keyResult.normalized,
|
|
296
|
+
name: args.name,
|
|
297
|
+
description: args.description,
|
|
298
|
+
tenantId: args.tenantId,
|
|
299
|
+
tier: args.tier,
|
|
300
|
+
parentOntologyId: args.parentOntologyId,
|
|
301
|
+
status: "draft",
|
|
302
|
+
createdBy: userId,
|
|
303
|
+
createdAt: now,
|
|
304
|
+
updatedAt: now
|
|
305
|
+
});
|
|
306
|
+
await logAudit(ctx, {
|
|
307
|
+
entityType: "ontologyDefinition",
|
|
308
|
+
entityId: id,
|
|
309
|
+
changeType: "created",
|
|
310
|
+
changedBy: userId,
|
|
311
|
+
previousState: null,
|
|
312
|
+
newState: {
|
|
313
|
+
ontologyKey: keyResult.normalized,
|
|
314
|
+
name: args.name,
|
|
315
|
+
tier: args.tier
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return { id, ontologyKey: keyResult.normalized };
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
var updateOntologyDefinition = mutation({
|
|
322
|
+
args: {
|
|
323
|
+
id: v.id("ontologyDefinitions"),
|
|
324
|
+
name: v.optional(v.string()),
|
|
325
|
+
description: v.optional(v.string()),
|
|
326
|
+
status: v.optional(
|
|
327
|
+
v.union(v.literal("draft"), v.literal("active"), v.literal("deprecated"))
|
|
328
|
+
)
|
|
329
|
+
},
|
|
330
|
+
returns: permissiveReturn,
|
|
331
|
+
handler: async (ctx, args) => {
|
|
332
|
+
const userId = await requireAuth(ctx);
|
|
333
|
+
const def = await ctx.db.get(args.id);
|
|
334
|
+
if (!def) {
|
|
335
|
+
throw new Error("Ontology definition not found.");
|
|
336
|
+
}
|
|
337
|
+
if (def.status === "archived") {
|
|
338
|
+
throw new Error("Cannot update an archived ontology definition.");
|
|
339
|
+
}
|
|
340
|
+
const previousState = {
|
|
341
|
+
name: def.name,
|
|
342
|
+
description: def.description,
|
|
343
|
+
status: def.status
|
|
344
|
+
};
|
|
345
|
+
const patch = { updatedAt: Date.now() };
|
|
346
|
+
if (args.name !== void 0) {
|
|
347
|
+
patch.name = args.name;
|
|
348
|
+
}
|
|
349
|
+
if (args.description !== void 0) {
|
|
350
|
+
patch.description = args.description;
|
|
351
|
+
}
|
|
352
|
+
if (args.status !== void 0) {
|
|
353
|
+
patch.status = args.status;
|
|
354
|
+
}
|
|
355
|
+
await ctx.db.patch(args.id, patch);
|
|
356
|
+
await logAudit(ctx, {
|
|
357
|
+
entityType: "ontologyDefinition",
|
|
358
|
+
entityId: args.id,
|
|
359
|
+
changeType: "updated",
|
|
360
|
+
changedBy: userId,
|
|
361
|
+
previousState,
|
|
362
|
+
newState: patch
|
|
363
|
+
});
|
|
364
|
+
return { success: true };
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
var archiveOntologyDefinition = mutation({
|
|
368
|
+
args: { id: v.id("ontologyDefinitions") },
|
|
369
|
+
returns: permissiveReturn,
|
|
370
|
+
handler: async (ctx, args) => {
|
|
371
|
+
const userId = await requireAuth(ctx);
|
|
372
|
+
const def = await ctx.db.get(args.id);
|
|
373
|
+
if (!def) {
|
|
374
|
+
throw new Error("Ontology definition not found.");
|
|
375
|
+
}
|
|
376
|
+
if (def.status === "archived") {
|
|
377
|
+
return { success: true };
|
|
378
|
+
}
|
|
379
|
+
await ctx.db.patch(args.id, { status: "archived", updatedAt: Date.now() });
|
|
380
|
+
await logAudit(ctx, {
|
|
381
|
+
entityType: "ontologyDefinition",
|
|
382
|
+
entityId: args.id,
|
|
383
|
+
changeType: "archived",
|
|
384
|
+
changedBy: userId,
|
|
385
|
+
previousState: { status: def.status },
|
|
386
|
+
newState: { status: "archived" }
|
|
387
|
+
});
|
|
388
|
+
return { success: true };
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
var createOntologyVersion = mutation({
|
|
392
|
+
args: {
|
|
393
|
+
ontologyId: v.id("ontologyDefinitions"),
|
|
394
|
+
version: v.string(),
|
|
395
|
+
entityTypes: v.array(
|
|
396
|
+
v.object({
|
|
397
|
+
value: v.string(),
|
|
398
|
+
label: v.string(),
|
|
399
|
+
description: v.optional(v.string()),
|
|
400
|
+
schema: v.optional(v.any()),
|
|
401
|
+
subtypes: v.optional(
|
|
402
|
+
v.array(
|
|
403
|
+
v.object({
|
|
404
|
+
value: v.string(),
|
|
405
|
+
label: v.string(),
|
|
406
|
+
description: v.optional(v.string())
|
|
407
|
+
})
|
|
408
|
+
)
|
|
409
|
+
)
|
|
410
|
+
})
|
|
411
|
+
),
|
|
412
|
+
edgeTypes: v.array(
|
|
413
|
+
v.object({
|
|
414
|
+
value: v.string(),
|
|
415
|
+
label: v.string(),
|
|
416
|
+
description: v.optional(v.string()),
|
|
417
|
+
sourceTypes: v.optional(v.array(v.string())),
|
|
418
|
+
targetTypes: v.optional(v.array(v.string())),
|
|
419
|
+
constraintSeverity: v.optional(
|
|
420
|
+
v.union(v.literal("warn"), v.literal("info"))
|
|
421
|
+
)
|
|
422
|
+
})
|
|
423
|
+
),
|
|
424
|
+
releaseNotes: v.optional(v.string())
|
|
425
|
+
},
|
|
426
|
+
returns: permissiveReturn,
|
|
427
|
+
handler: async (ctx, args) => {
|
|
428
|
+
const userId = await requireAuth(ctx);
|
|
429
|
+
if (!validateVersionString(args.version)) {
|
|
430
|
+
throw new Error(
|
|
431
|
+
`Invalid version string "${args.version}". Must be in X.Y.Z format.`
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
const def = await ctx.db.get(args.ontologyId);
|
|
435
|
+
if (!def) {
|
|
436
|
+
throw new Error("Ontology definition not found.");
|
|
437
|
+
}
|
|
438
|
+
if (def.status === "archived") {
|
|
439
|
+
throw new Error("Cannot add versions to an archived ontology.");
|
|
440
|
+
}
|
|
441
|
+
const existing = await ctx.db.query("ontologyVersions").withIndex(
|
|
442
|
+
"by_ontologyKey_version",
|
|
443
|
+
(q) => q.eq("ontologyKey", def.ontologyKey).eq("version", args.version)
|
|
444
|
+
).first();
|
|
445
|
+
if (existing) {
|
|
446
|
+
throw new Error(
|
|
447
|
+
`Version "${args.version}" already exists for ontology "${def.ontologyKey}".`
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
const now = Date.now();
|
|
451
|
+
const id = await ctx.db.insert("ontologyVersions", {
|
|
452
|
+
ontologyId: args.ontologyId,
|
|
453
|
+
ontologyKey: def.ontologyKey,
|
|
454
|
+
version: args.version,
|
|
455
|
+
status: "draft",
|
|
456
|
+
entityTypes: args.entityTypes,
|
|
457
|
+
edgeTypes: args.edgeTypes,
|
|
458
|
+
releaseNotes: args.releaseNotes,
|
|
459
|
+
createdAt: now
|
|
460
|
+
});
|
|
461
|
+
await logAudit(ctx, {
|
|
462
|
+
entityType: "ontologyVersion",
|
|
463
|
+
entityId: id,
|
|
464
|
+
changeType: "created",
|
|
465
|
+
changedBy: userId,
|
|
466
|
+
previousState: null,
|
|
467
|
+
newState: {
|
|
468
|
+
ontologyKey: def.ontologyKey,
|
|
469
|
+
version: args.version,
|
|
470
|
+
entityTypeCount: args.entityTypes.length,
|
|
471
|
+
edgeTypeCount: args.edgeTypes.length
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
return { id, version: args.version };
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
var updateDraftVersion = mutation({
|
|
478
|
+
args: {
|
|
479
|
+
id: v.id("ontologyVersions"),
|
|
480
|
+
entityTypes: v.optional(
|
|
481
|
+
v.array(
|
|
482
|
+
v.object({
|
|
483
|
+
value: v.string(),
|
|
484
|
+
label: v.string(),
|
|
485
|
+
description: v.optional(v.string()),
|
|
486
|
+
schema: v.optional(v.any()),
|
|
487
|
+
subtypes: v.optional(
|
|
488
|
+
v.array(
|
|
489
|
+
v.object({
|
|
490
|
+
value: v.string(),
|
|
491
|
+
label: v.string(),
|
|
492
|
+
description: v.optional(v.string())
|
|
493
|
+
})
|
|
494
|
+
)
|
|
495
|
+
)
|
|
496
|
+
})
|
|
497
|
+
)
|
|
498
|
+
),
|
|
499
|
+
edgeTypes: v.optional(
|
|
500
|
+
v.array(
|
|
501
|
+
v.object({
|
|
502
|
+
value: v.string(),
|
|
503
|
+
label: v.string(),
|
|
504
|
+
description: v.optional(v.string()),
|
|
505
|
+
sourceTypes: v.optional(v.array(v.string())),
|
|
506
|
+
targetTypes: v.optional(v.array(v.string())),
|
|
507
|
+
constraintSeverity: v.optional(
|
|
508
|
+
v.union(v.literal("warn"), v.literal("info"))
|
|
509
|
+
)
|
|
510
|
+
})
|
|
511
|
+
)
|
|
512
|
+
),
|
|
513
|
+
releaseNotes: v.optional(v.string())
|
|
514
|
+
},
|
|
515
|
+
returns: permissiveReturn,
|
|
516
|
+
handler: async (ctx, args) => {
|
|
517
|
+
const userId = await requireAuth(ctx);
|
|
518
|
+
const ver = await ctx.db.get(args.id);
|
|
519
|
+
if (!ver) {
|
|
520
|
+
throw new Error("Ontology version not found.");
|
|
521
|
+
}
|
|
522
|
+
if (ver.status !== "draft") {
|
|
523
|
+
throw new Error(
|
|
524
|
+
`Cannot update a ${ver.status} version. Only draft versions are editable.`
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
const patch = {};
|
|
528
|
+
if (args.entityTypes !== void 0) {
|
|
529
|
+
patch.entityTypes = args.entityTypes;
|
|
530
|
+
}
|
|
531
|
+
if (args.edgeTypes !== void 0) {
|
|
532
|
+
patch.edgeTypes = args.edgeTypes;
|
|
533
|
+
}
|
|
534
|
+
if (args.releaseNotes !== void 0) {
|
|
535
|
+
patch.releaseNotes = args.releaseNotes;
|
|
536
|
+
}
|
|
537
|
+
await ctx.db.patch(args.id, patch);
|
|
538
|
+
await logAudit(ctx, {
|
|
539
|
+
entityType: "ontologyVersion",
|
|
540
|
+
entityId: args.id,
|
|
541
|
+
changeType: "updated",
|
|
542
|
+
changedBy: userId,
|
|
543
|
+
previousState: { status: ver.status },
|
|
544
|
+
newState: patch
|
|
545
|
+
});
|
|
546
|
+
return { success: true };
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
var publishOntologyVersion = mutation({
|
|
550
|
+
args: {
|
|
551
|
+
id: v.id("ontologyVersions"),
|
|
552
|
+
ontologyId: v.optional(v.id("ontologyDefinitions"))
|
|
553
|
+
},
|
|
554
|
+
returns: permissiveReturn,
|
|
555
|
+
handler: async (ctx, args) => {
|
|
556
|
+
const userId = await requireAuth(ctx);
|
|
557
|
+
const ver = await ctx.db.get(args.id);
|
|
558
|
+
if (!ver) {
|
|
559
|
+
throw new Error("Ontology version not found.");
|
|
560
|
+
}
|
|
561
|
+
if (args.ontologyId && ver.ontologyId !== args.ontologyId) {
|
|
562
|
+
throw new Error(
|
|
563
|
+
"Version does not belong to the specified ontology definition."
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
if (ver.status !== "draft") {
|
|
567
|
+
throw new Error(
|
|
568
|
+
`Cannot publish a ${ver.status} version. Only draft versions can be published.`
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
const now = Date.now();
|
|
572
|
+
await ctx.db.patch(args.id, {
|
|
573
|
+
status: "published",
|
|
574
|
+
publishedBy: userId,
|
|
575
|
+
publishedAt: now
|
|
576
|
+
});
|
|
577
|
+
const def = await ctx.db.get(ver.ontologyId);
|
|
578
|
+
if (def && def.status === "draft") {
|
|
579
|
+
await ctx.db.patch(ver.ontologyId, {
|
|
580
|
+
status: "active",
|
|
581
|
+
updatedAt: now
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
await logAudit(ctx, {
|
|
585
|
+
entityType: "ontologyVersion",
|
|
586
|
+
entityId: args.id,
|
|
587
|
+
changeType: "published",
|
|
588
|
+
changedBy: userId,
|
|
589
|
+
previousState: { status: "draft" },
|
|
590
|
+
newState: { status: "published", publishedAt: now }
|
|
591
|
+
});
|
|
592
|
+
return { success: true, publishedAt: now };
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
var deprecateOntologyVersion = mutation({
|
|
596
|
+
args: {
|
|
597
|
+
id: v.id("ontologyVersions"),
|
|
598
|
+
ontologyId: v.optional(v.id("ontologyDefinitions"))
|
|
599
|
+
},
|
|
600
|
+
returns: permissiveReturn,
|
|
601
|
+
handler: async (ctx, args) => {
|
|
602
|
+
const userId = await requireAuth(ctx);
|
|
603
|
+
const ver = await ctx.db.get(args.id);
|
|
604
|
+
if (!ver) {
|
|
605
|
+
throw new Error("Ontology version not found.");
|
|
606
|
+
}
|
|
607
|
+
if (args.ontologyId && ver.ontologyId !== args.ontologyId) {
|
|
608
|
+
throw new Error(
|
|
609
|
+
"Version does not belong to the specified ontology definition."
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
if (ver.status === "deprecated") {
|
|
613
|
+
return { success: true };
|
|
614
|
+
}
|
|
615
|
+
if (ver.status !== "published") {
|
|
616
|
+
throw new Error(
|
|
617
|
+
`Cannot deprecate a ${ver.status} version. Only published versions can be deprecated.`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
await ctx.db.patch(args.id, { status: "deprecated" });
|
|
621
|
+
await logAudit(ctx, {
|
|
622
|
+
entityType: "ontologyVersion",
|
|
623
|
+
entityId: args.id,
|
|
624
|
+
changeType: "deprecated",
|
|
625
|
+
changedBy: userId,
|
|
626
|
+
previousState: { status: "published" },
|
|
627
|
+
newState: { status: "deprecated" }
|
|
628
|
+
});
|
|
629
|
+
return { success: true };
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
export { archiveOntologyDefinition, createOntologyDefinition, createOntologyVersion, deprecateOntologyVersion, getOntologyDefinition, getOntologyDefinitionByKey, getOntologyVersion, getPublishedVersion, listOntologyDefinitions, listOntologyVersions, publishOntologyVersion, resolveEffectiveOntology, updateDraftVersion, updateOntologyDefinition };
|
|
634
|
+
//# sourceMappingURL=ontologyDefinitions.js.map
|
|
635
|
+
//# sourceMappingURL=ontologyDefinitions.js.map
|