@x12i/memorix-service 0.0.0-bootstrap.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/app.d.ts +21 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +67 -0
- package/dist/app.js.map +1 -0
- package/dist/catalog-bridge.d.ts +7 -0
- package/dist/catalog-bridge.d.ts.map +1 -0
- package/dist/catalog-bridge.js +155 -0
- package/dist/catalog-bridge.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +36 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +79 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/isolation.d.ts +63 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +175 -0
- package/dist/isolation.js.map +1 -0
- package/dist/known-packs.d.ts +5 -0
- package/dist/known-packs.d.ts.map +1 -0
- package/dist/known-packs.js +26 -0
- package/dist/known-packs.js.map +1 -0
- package/dist/mongo-metadata-store.d.ts +17 -0
- package/dist/mongo-metadata-store.d.ts.map +1 -0
- package/dist/mongo-metadata-store.js +81 -0
- package/dist/mongo-metadata-store.js.map +1 -0
- package/dist/openapi/openapi.json +6431 -0
- package/dist/platform.d.ts +52 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +246 -0
- package/dist/platform.js.map +1 -0
- package/dist/relationships/operator-links.d.ts +23 -0
- package/dist/relationships/operator-links.d.ts.map +1 -0
- package/dist/relationships/operator-links.js +41 -0
- package/dist/relationships/operator-links.js.map +1 -0
- package/dist/request-scope.d.ts +7 -0
- package/dist/request-scope.d.ts.map +1 -0
- package/dist/request-scope.js +24 -0
- package/dist/request-scope.js.map +1 -0
- package/dist/routes/data.d.ts +4 -0
- package/dist/routes/data.d.ts.map +1 -0
- package/dist/routes/data.js +237 -0
- package/dist/routes/data.js.map +1 -0
- package/dist/routes/intelligence.d.ts +5 -0
- package/dist/routes/intelligence.d.ts.map +1 -0
- package/dist/routes/intelligence.js +94 -0
- package/dist/routes/intelligence.js.map +1 -0
- package/dist/routes/memory.d.ts +4 -0
- package/dist/routes/memory.d.ts.map +1 -0
- package/dist/routes/memory.js +80 -0
- package/dist/routes/memory.js.map +1 -0
- package/dist/routes/metadata.d.ts +4 -0
- package/dist/routes/metadata.d.ts.map +1 -0
- package/dist/routes/metadata.js +104 -0
- package/dist/routes/metadata.js.map +1 -0
- package/dist/routes/operations.d.ts +4 -0
- package/dist/routes/operations.d.ts.map +1 -0
- package/dist/routes/operations.js +66 -0
- package/dist/routes/operations.js.map +1 -0
- package/dist/routes/pipelines.d.ts +4 -0
- package/dist/routes/pipelines.d.ts.map +1 -0
- package/dist/routes/pipelines.js +128 -0
- package/dist/routes/pipelines.js.map +1 -0
- package/dist/routes/relationships.d.ts +4 -0
- package/dist/routes/relationships.d.ts.map +1 -0
- package/dist/routes/relationships.js +138 -0
- package/dist/routes/relationships.js.map +1 -0
- package/dist/routes/workflow.d.ts +4 -0
- package/dist/routes/workflow.d.ts.map +1 -0
- package/dist/routes/workflow.js +104 -0
- package/dist/routes/workflow.js.map +1 -0
- package/dist/scope.d.ts +19 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +53 -0
- package/dist/scope.js.map +1 -0
- package/openapi/openapi.json +6431 -0
- package/package.json +65 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database isolation guard for G10/G11/G12 acceptance.
|
|
3
|
+
* Org patterns: g10ops*|g11ops*|g12ops* — never neo/fieldstone/prior orgs.
|
|
4
|
+
* Cleanup may only drop DBs recorded in this run's creation ledger.
|
|
5
|
+
*/
|
|
6
|
+
import { randomBytes } from "node:crypto";
|
|
7
|
+
import { databaseNameFor } from "@x12i/memorix-data";
|
|
8
|
+
export const G10_ORG_PREFIX = "g10ops";
|
|
9
|
+
export const G11_ORG_PREFIX = "g11ops";
|
|
10
|
+
export const G12_ORG_PREFIX = "g12ops";
|
|
11
|
+
export const G10_ORG_PATTERN = /^g10ops[a-z0-9]+$/;
|
|
12
|
+
export const G11_ORG_PATTERN = /^g11ops[a-z0-9]+$/;
|
|
13
|
+
export const G12_ORG_PATTERN = /^g12ops[a-z0-9]+$/;
|
|
14
|
+
export const ACCEPTANCE_ORG_PATTERN = /^g1[012]ops[a-z0-9]+$/;
|
|
15
|
+
export const FORBIDDEN_ORG_SUBSTRINGS = ["neo", "fieldstone"];
|
|
16
|
+
export class IsolationError extends Error {
|
|
17
|
+
code = "DB_ISOLATION_VIOLATION";
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "IsolationError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function assertSafeG10OrgId(orgId) {
|
|
24
|
+
assertSafeAcceptanceOrgId(orgId, "g10");
|
|
25
|
+
}
|
|
26
|
+
export function assertSafeG11OrgId(orgId) {
|
|
27
|
+
assertSafeAcceptanceOrgId(orgId, "g11");
|
|
28
|
+
}
|
|
29
|
+
export function assertSafeG12OrgId(orgId) {
|
|
30
|
+
assertSafeAcceptanceOrgId(orgId, "g12");
|
|
31
|
+
}
|
|
32
|
+
export function assertSafeAcceptanceOrgId(orgId, gate = "any") {
|
|
33
|
+
const pattern = gate === "g10"
|
|
34
|
+
? G10_ORG_PATTERN
|
|
35
|
+
: gate === "g11"
|
|
36
|
+
? G11_ORG_PATTERN
|
|
37
|
+
: gate === "g12"
|
|
38
|
+
? G12_ORG_PATTERN
|
|
39
|
+
: ACCEPTANCE_ORG_PATTERN;
|
|
40
|
+
if (!pattern.test(orgId)) {
|
|
41
|
+
throw new IsolationError(`orgId must match ${pattern}: got ${JSON.stringify(orgId)}`);
|
|
42
|
+
}
|
|
43
|
+
const lower = orgId.toLowerCase();
|
|
44
|
+
for (const bad of FORBIDDEN_ORG_SUBSTRINGS) {
|
|
45
|
+
if (lower.includes(bad)) {
|
|
46
|
+
throw new IsolationError(`orgId must not contain forbidden token "${bad}"`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (orgId === "neo" || orgId === "fieldstone") {
|
|
50
|
+
throw new IsolationError(`forbidden orgId ${orgId}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function generateG10OrgId(token) {
|
|
54
|
+
return generateAcceptanceOrgId("g10ops", token);
|
|
55
|
+
}
|
|
56
|
+
export function generateG11OrgId(token) {
|
|
57
|
+
return generateAcceptanceOrgId("g11ops", token);
|
|
58
|
+
}
|
|
59
|
+
export function generateG12OrgId(token) {
|
|
60
|
+
return generateAcceptanceOrgId("g12ops", token);
|
|
61
|
+
}
|
|
62
|
+
function generateAcceptanceOrgId(prefix, token) {
|
|
63
|
+
const t = (token ?? randomBytes(6).toString("hex")).toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
64
|
+
const orgId = `${prefix}${t}`;
|
|
65
|
+
const gate = prefix === "g10ops" ? "g10" : prefix === "g11ops" ? "g11" : "g12";
|
|
66
|
+
assertSafeAcceptanceOrgId(orgId, gate);
|
|
67
|
+
return orgId;
|
|
68
|
+
}
|
|
69
|
+
export function allowedDatabasesForOrg(orgId) {
|
|
70
|
+
assertSafeAcceptanceOrgId(orgId);
|
|
71
|
+
return [
|
|
72
|
+
databaseNameFor(orgId, "entity"),
|
|
73
|
+
databaseNameFor(orgId, "event"),
|
|
74
|
+
databaseNameFor(orgId, "knowledge"),
|
|
75
|
+
databaseNameFor(orgId, "operational"),
|
|
76
|
+
`${orgId}_metadata`,
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
/** Read-only list of DB names that already exist for this org prefix. */
|
|
80
|
+
export async function preflightOrgDatabases(client, orgId) {
|
|
81
|
+
assertSafeAcceptanceOrgId(orgId);
|
|
82
|
+
const allowed = new Set(allowedDatabasesForOrg(orgId));
|
|
83
|
+
const admin = client.db().admin();
|
|
84
|
+
const { databases } = await admin.listDatabases();
|
|
85
|
+
const existing = databases
|
|
86
|
+
.map((d) => d.name)
|
|
87
|
+
.filter((name) => allowed.has(name) || name.startsWith(`${orgId}_`));
|
|
88
|
+
return { existing, conflict: existing.length > 0 };
|
|
89
|
+
}
|
|
90
|
+
export async function beginIsolationSession(client, opts) {
|
|
91
|
+
const max = opts?.maxAttempts ?? 8;
|
|
92
|
+
const prefix = opts?.prefix ?? "g10ops";
|
|
93
|
+
for (let i = 0; i < max; i++) {
|
|
94
|
+
const token = opts?.token && i === 0 ? opts.token : undefined;
|
|
95
|
+
const orgId = prefix === "g12ops"
|
|
96
|
+
? generateG12OrgId(token)
|
|
97
|
+
: prefix === "g11ops"
|
|
98
|
+
? generateG11OrgId(token)
|
|
99
|
+
: generateG10OrgId(token);
|
|
100
|
+
const { existing, conflict } = await preflightOrgDatabases(client, orgId);
|
|
101
|
+
if (conflict)
|
|
102
|
+
continue;
|
|
103
|
+
const allowed = allowedDatabasesForOrg(orgId);
|
|
104
|
+
return {
|
|
105
|
+
orgId,
|
|
106
|
+
agentIds: ["ops"],
|
|
107
|
+
allowedDatabaseNames: allowed,
|
|
108
|
+
createdDatabaseNames: [],
|
|
109
|
+
preflightExisting: existing,
|
|
110
|
+
isolatedMetadataDb: `${orgId}_metadata`,
|
|
111
|
+
zeroPreexistingMutated: true,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
throw new IsolationError(`could not allocate unused ${prefix} orgId after retries`);
|
|
115
|
+
}
|
|
116
|
+
export async function beginG11IsolationSession(client, opts) {
|
|
117
|
+
return beginIsolationSession(client, { ...opts, prefix: "g11ops" });
|
|
118
|
+
}
|
|
119
|
+
export async function beginG12IsolationSession(client, opts) {
|
|
120
|
+
return beginIsolationSession(client, { ...opts, prefix: "g12ops" });
|
|
121
|
+
}
|
|
122
|
+
export function recordCreatedDatabase(session, dbName) {
|
|
123
|
+
assertSafeAcceptanceOrgId(session.orgId);
|
|
124
|
+
if (!session.allowedDatabaseNames.includes(dbName)) {
|
|
125
|
+
throw new IsolationError(`cannot create database outside ledger allow-list: ${dbName}`);
|
|
126
|
+
}
|
|
127
|
+
if (!session.createdDatabaseNames.includes(dbName)) {
|
|
128
|
+
session.createdDatabaseNames.push(dbName);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Drop only DBs recorded in this session's creation ledger (collections then empty DB if permitted). */
|
|
132
|
+
export async function cleanupIsolationSession(client, session) {
|
|
133
|
+
assertSafeAcceptanceOrgId(session.orgId);
|
|
134
|
+
const dropped = [];
|
|
135
|
+
for (const name of session.createdDatabaseNames) {
|
|
136
|
+
if (!name.startsWith(session.orgId + "_")) {
|
|
137
|
+
throw new IsolationError(`refusing drop outside org prefix: ${name}`);
|
|
138
|
+
}
|
|
139
|
+
if (!session.allowedDatabaseNames.includes(name)) {
|
|
140
|
+
throw new IsolationError(`refusing drop not on allow-list: ${name}`);
|
|
141
|
+
}
|
|
142
|
+
const db = client.db(name);
|
|
143
|
+
const cols = await db.collections();
|
|
144
|
+
for (const col of cols) {
|
|
145
|
+
try {
|
|
146
|
+
await col.drop();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
/* ignore */
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
await db.dropDatabase();
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Some deployments deny dropDatabase; collection drops above still clear run data.
|
|
157
|
+
}
|
|
158
|
+
dropped.push(name);
|
|
159
|
+
}
|
|
160
|
+
return dropped;
|
|
161
|
+
}
|
|
162
|
+
export function isolationEvidence(session, extra) {
|
|
163
|
+
return {
|
|
164
|
+
orgId: session.orgId,
|
|
165
|
+
agentIds: session.agentIds,
|
|
166
|
+
allowedDatabaseNames: session.allowedDatabaseNames,
|
|
167
|
+
preflightExisting: session.preflightExisting,
|
|
168
|
+
createdDatabaseNames: session.createdDatabaseNames,
|
|
169
|
+
cleanupTargets: [...session.createdDatabaseNames],
|
|
170
|
+
isolatedMetadataDb: session.isolatedMetadataDb,
|
|
171
|
+
zeroPreexistingMutated: session.zeroPreexistingMutated,
|
|
172
|
+
...extra,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=isolation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolation.js","sourceRoot":"","sources":["../src/isolation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAC;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,YAAY,CAAU,CAAC;AAoBvE,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,GAAG,wBAAwB,CAAC;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAa,EACb,OAAsC,KAAK;IAE3C,MAAM,OAAO,GACX,IAAI,KAAK,KAAK;QACZ,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,IAAI,KAAK,KAAK;YACd,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,IAAI,KAAK,KAAK;gBACd,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,sBAAsB,CAAC;IACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,cAAc,CACtB,oBAAoB,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,cAAc,CAAC,2CAA2C,GAAG,GAAG,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;QAC9C,MAAM,IAAI,cAAc,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAsC,EACtC,KAAc;IAEd,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/E,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO;QACL,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC;QAChC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC;QAC/B,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC;QACnC,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC;QACrC,GAAG,KAAK,WAAW;KACpB,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAmB,EACnB,KAAa;IAEb,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;IAClC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,SAAS;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;IACvE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAmB,EACnB,IAIC;IAED,MAAM,GAAG,GAAG,IAAI,EAAE,WAAW,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,QAAQ,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9D,MAAM,KAAK,GACT,MAAM,KAAK,QAAQ;YACjB,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;YACzB,CAAC,CAAC,MAAM,KAAK,QAAQ;gBACnB,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1E,IAAI,QAAQ;YAAE,SAAS;QACvB,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO;YACL,KAAK;YACL,QAAQ,EAAE,CAAC,KAAK,CAAC;YACjB,oBAAoB,EAAE,OAAO;YAC7B,oBAAoB,EAAE,EAAE;YACxB,iBAAiB,EAAE,QAAQ;YAC3B,kBAAkB,EAAE,GAAG,KAAK,WAAW;YACvC,sBAAsB,EAAE,IAAI;SAC7B,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,cAAc,CAAC,6BAA6B,MAAM,sBAAsB,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAmB,EACnB,IAA+C;IAE/C,OAAO,qBAAqB,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAmB,EACnB,IAA+C;IAE/C,OAAO,qBAAqB,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAyB,EAAE,MAAc;IAC7E,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,cAAc,CAAC,qDAAqD,MAAM,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAmB,EACnB,OAAyB;IAEzB,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,cAAc,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,cAAc,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,mFAAmF;QACrF,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAyB,EAAE,KAA+B;IAC1F,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,cAAc,EAAE,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACjD,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;QACtD,GAAG,KAAK;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MetadataPack } from "@x12i/memorix-metadata";
|
|
2
|
+
/** Load a known disk pack (ops) for explicit install — never auto-installs. */
|
|
3
|
+
export declare function loadKnownMetadataPack(packId: string): MetadataPack;
|
|
4
|
+
export declare function listKnownPackIds(): string[];
|
|
5
|
+
//# sourceMappingURL=known-packs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"known-packs.d.ts","sourceRoot":"","sources":["../src/known-packs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAU3D,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAkBlE;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { ServiceError } from "./errors.js";
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const REPO_ROOT = resolve(__dirname, "../..");
|
|
7
|
+
const KNOWN_PACKS = {
|
|
8
|
+
ops: resolve(REPO_ROOT, "memorix-metadata/examples/ops/normalized/pack.json"),
|
|
9
|
+
};
|
|
10
|
+
/** Load a known disk pack (ops) for explicit install — never auto-installs. */
|
|
11
|
+
export function loadKnownMetadataPack(packId) {
|
|
12
|
+
const path = KNOWN_PACKS[packId];
|
|
13
|
+
if (!path) {
|
|
14
|
+
throw new ServiceError("UNKNOWN_PACK", `unknown packId "${packId}"; known: ${Object.keys(KNOWN_PACKS).join(", ")}`, 400);
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
throw new ServiceError("PACK_LOAD_FAILED", `failed to load pack ${packId}: ${err instanceof Error ? err.message : String(err)}`, 500);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function listKnownPackIds() {
|
|
24
|
+
return Object.keys(KNOWN_PACKS);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=known-packs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"known-packs.js","sourceRoot":"","sources":["../src/known-packs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE9C,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,oDAAoD,CAAC;CAC9E,CAAC;AAEF,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,YAAY,CACpB,cAAc,EACd,mBAAmB,MAAM,aAAa,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC3E,GAAG,CACJ,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAiB,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,uBAAuB,MAAM,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACpF,GAAG,CACJ,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable MetadataStore adapter for production.
|
|
3
|
+
* Implements the accepted @x12i/memorix-metadata-runtime store contract
|
|
4
|
+
* against Mongo — does not invent new metadata semantics.
|
|
5
|
+
*
|
|
6
|
+
* Mutations update an in-process snapshot and enqueue durable flush.
|
|
7
|
+
* Platform must await hydrate() before serving traffic and drain() on close.
|
|
8
|
+
*/
|
|
9
|
+
import type { Db } from "mongodb";
|
|
10
|
+
import type { MetadataStore } from "@x12i/memorix-metadata-runtime";
|
|
11
|
+
export type DurableMetadataStore = MetadataStore & {
|
|
12
|
+
hydrate(): Promise<void>;
|
|
13
|
+
drain(): Promise<void>;
|
|
14
|
+
readonly durable: true;
|
|
15
|
+
};
|
|
16
|
+
export declare function createMongoMetadataStore(db: Db): DurableMetadataStore;
|
|
17
|
+
//# sourceMappingURL=mongo-metadata-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-metadata-store.d.ts","sourceRoot":"","sources":["../src/mongo-metadata-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,gCAAgC,CAAC;AAcxC,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IACjD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;CACxB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,EAAE,GAAG,oBAAoB,CAuFrE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createInMemoryMetadataStore } from "@x12i/memorix-metadata-runtime";
|
|
2
|
+
const AGENTS = "memorix_metadata_agents";
|
|
3
|
+
const LEDGER = "memorix_metadata_install_ledger";
|
|
4
|
+
export function createMongoMetadataStore(db) {
|
|
5
|
+
const memory = createInMemoryMetadataStore();
|
|
6
|
+
let pendingFlush = Promise.resolve();
|
|
7
|
+
async function flush() {
|
|
8
|
+
const agentIds = memory.listAgentIds();
|
|
9
|
+
const bulkAgents = db.collection(AGENTS);
|
|
10
|
+
await bulkAgents.deleteMany({});
|
|
11
|
+
if (agentIds.length) {
|
|
12
|
+
await bulkAgents.insertMany(agentIds.map((agentId) => {
|
|
13
|
+
const pack = memory.getAgentPack(agentId);
|
|
14
|
+
return {
|
|
15
|
+
_id: agentId,
|
|
16
|
+
checksum: pack.checksum,
|
|
17
|
+
definitions: pack.definitions,
|
|
18
|
+
};
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
const ledger = memory.getLedger();
|
|
22
|
+
const bulkLedger = db.collection(LEDGER);
|
|
23
|
+
await bulkLedger.deleteMany({});
|
|
24
|
+
if (ledger.length) {
|
|
25
|
+
await bulkLedger.insertMany(ledger.map((e) => ({ ...e })));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function enqueueFlush() {
|
|
29
|
+
pendingFlush = pendingFlush.then(flush, flush);
|
|
30
|
+
}
|
|
31
|
+
const api = {
|
|
32
|
+
durable: true,
|
|
33
|
+
listAgentIds() {
|
|
34
|
+
return memory.listAgentIds();
|
|
35
|
+
},
|
|
36
|
+
getAgentPack(agentId) {
|
|
37
|
+
return memory.getAgentPack(agentId);
|
|
38
|
+
},
|
|
39
|
+
replaceAgentPack(agentId, checksum, definitions, installedAt) {
|
|
40
|
+
memory.replaceAgentPack(agentId, checksum, definitions, installedAt);
|
|
41
|
+
enqueueFlush();
|
|
42
|
+
},
|
|
43
|
+
getLedger() {
|
|
44
|
+
return memory.getLedger();
|
|
45
|
+
},
|
|
46
|
+
appendLedger(entry) {
|
|
47
|
+
memory.appendLedger(entry);
|
|
48
|
+
enqueueFlush();
|
|
49
|
+
},
|
|
50
|
+
clone() {
|
|
51
|
+
return memory.clone();
|
|
52
|
+
},
|
|
53
|
+
commitFrom(other) {
|
|
54
|
+
memory.commitFrom(other);
|
|
55
|
+
enqueueFlush();
|
|
56
|
+
},
|
|
57
|
+
async hydrate() {
|
|
58
|
+
const agentDocs = await db.collection(AGENTS).find({}).toArray();
|
|
59
|
+
const ledgerDocs = await db
|
|
60
|
+
.collection(LEDGER)
|
|
61
|
+
.find({})
|
|
62
|
+
.sort({ installedAt: 1 })
|
|
63
|
+
.toArray();
|
|
64
|
+
const scratch = createInMemoryMetadataStore();
|
|
65
|
+
for (const doc of agentDocs) {
|
|
66
|
+
scratch.replaceAgentPack(doc._id, doc.checksum, doc.definitions, new Date(0).toISOString());
|
|
67
|
+
}
|
|
68
|
+
for (const entry of ledgerDocs) {
|
|
69
|
+
const { _id: _omit, ...rest } = entry;
|
|
70
|
+
scratch.appendLedger(rest);
|
|
71
|
+
}
|
|
72
|
+
// commit without enqueue — hydrate is loading truth
|
|
73
|
+
memory.commitFrom(scratch);
|
|
74
|
+
},
|
|
75
|
+
async drain() {
|
|
76
|
+
await pendingFlush;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
return api;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=mongo-metadata-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-metadata-store.js","sourceRoot":"","sources":["../src/mongo-metadata-store.ts"],"names":[],"mappings":"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"}
|