@wirecat/zoom-cli 0.55.0 → 0.57.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 +4 -4
- package/dist/bin/zm.js +35 -5
- package/dist/bundle/all-profiles-EKHWTGOY.js +25 -0
- package/dist/bundle/answer-policy-KH2IFXPN.js +96 -0
- package/dist/bundle/anthropic-VL54IUGF.js +70 -0
- package/dist/bundle/bun-ADJVI4HY.js +169 -0
- package/dist/bundle/bun-sqlite-2SDA3YOT.js +69 -0
- package/dist/bundle/chunk-2IKY7VBH.js +9 -0
- package/dist/bundle/chunk-2WOGZDZG.js +431 -0
- package/dist/bundle/chunk-4R7HYNZS.js +73 -0
- package/dist/bundle/chunk-4VCA7QU3.js +538 -0
- package/dist/bundle/chunk-4YLS4YLS.js +29 -0
- package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
- package/dist/bundle/chunk-5F7IOESV.js +281 -0
- package/dist/bundle/chunk-5QESMCQK.js +122 -0
- package/dist/bundle/chunk-6M6FJV5D.js +138 -0
- package/dist/bundle/chunk-6MX5T6AQ.js +17 -0
- package/dist/bundle/chunk-6P3YHT54.js +385 -0
- package/dist/bundle/chunk-7A6PZUDR.js +938 -0
- package/dist/bundle/chunk-7GUG6UZS.js +884 -0
- package/dist/bundle/chunk-7JZJMHQY.js +487 -0
- package/dist/bundle/chunk-A4ETXPMZ.js +98 -0
- package/dist/bundle/chunk-ADLS6FVG.js +24600 -0
- package/dist/bundle/chunk-AE4BOXH7.js +5292 -0
- package/dist/bundle/chunk-AN3GVZTU.js +76 -0
- package/dist/bundle/chunk-BAYNCCNM.js +215 -0
- package/dist/bundle/chunk-BW2WPOXP.js +166 -0
- package/dist/bundle/chunk-BW52AJ4R.js +3387 -0
- package/dist/bundle/chunk-CB5UTASG.js +18 -0
- package/dist/bundle/chunk-CLMXBW53.js +1028 -0
- package/dist/bundle/chunk-DCTXOMOR.js +35 -0
- package/dist/bundle/chunk-DFDN6AUB.js +21 -0
- package/dist/bundle/chunk-EOQFWJJD.js +1095 -0
- package/dist/bundle/chunk-G4R4ZIGD.js +3569 -0
- package/dist/bundle/chunk-G4VZDINN.js +161 -0
- package/dist/bundle/chunk-GARCOIB6.js +409 -0
- package/dist/bundle/chunk-GKMGS7G5.js +1938 -0
- package/dist/bundle/chunk-HCNMFFG3.js +82 -0
- package/dist/bundle/chunk-HG5KRV55.js +1970 -0
- package/dist/bundle/chunk-HKYLSIZ2.js +82 -0
- package/dist/bundle/chunk-HTQTIKWP.js +928 -0
- package/dist/bundle/chunk-I4VQDXFR.js +100 -0
- package/dist/bundle/chunk-ICSKEDPI.js +36139 -0
- package/dist/bundle/chunk-IP4OK7RQ.js +24 -0
- package/dist/bundle/chunk-IVQ6342B.js +2 -0
- package/dist/bundle/chunk-K72SEMYI.js +160 -0
- package/dist/bundle/chunk-LHRCJYFC.js +19 -0
- package/dist/bundle/chunk-LPTIQLDW.js +192 -0
- package/dist/bundle/chunk-LQ3T2ZIX.js +124 -0
- package/dist/bundle/chunk-LSVI3A5X.js +836 -0
- package/dist/bundle/chunk-LW2G4U6W.js +570 -0
- package/dist/bundle/chunk-LXB6ONWC.js +3517 -0
- package/dist/bundle/chunk-LY26NW3I.js +6848 -0
- package/dist/bundle/chunk-MAEFLDHG.js +6092 -0
- package/dist/bundle/chunk-MZH4GDR4.js +45 -0
- package/dist/bundle/chunk-NN5B24KP.js +1109 -0
- package/dist/bundle/chunk-NO7CJEYV.js +22 -0
- package/dist/bundle/chunk-NTDWAAGL.js +18435 -0
- package/dist/bundle/chunk-NW3X3G5X.js +264 -0
- package/dist/bundle/chunk-O66V2WHK.js +48 -0
- package/dist/bundle/chunk-OCGPZHXW.js +25 -0
- package/dist/bundle/chunk-OIHDCGV4.js +151 -0
- package/dist/bundle/chunk-OVSWVPXL.js +8190 -0
- package/dist/bundle/chunk-PIN5RZ3D.js +63 -0
- package/dist/bundle/chunk-QLIB3PEC.js +1146 -0
- package/dist/bundle/chunk-QTR6D5HT.js +58 -0
- package/dist/bundle/chunk-QUJPQMHJ.js +2315 -0
- package/dist/bundle/chunk-R3HPOCZD.js +188 -0
- package/dist/bundle/chunk-RMV4C2YL.js +482 -0
- package/dist/bundle/chunk-RRRBMQ2E.js +844 -0
- package/dist/bundle/chunk-S4S7E54J.js +60 -0
- package/dist/bundle/chunk-SB6WOSHG.js +1109 -0
- package/dist/bundle/chunk-SE75DPBY.js +31 -0
- package/dist/bundle/chunk-SQJ7EH2D.js +97 -0
- package/dist/bundle/chunk-TKCHUT2H.js +422 -0
- package/dist/bundle/chunk-TLQUKHEM.js +193 -0
- package/dist/bundle/chunk-TZ2MKETI.js +100 -0
- package/dist/bundle/chunk-UC44ZMQV.js +78 -0
- package/dist/bundle/chunk-UI5UTMSZ.js +275 -0
- package/dist/bundle/chunk-VPPYYWOH.js +630 -0
- package/dist/bundle/chunk-WJHK5D7Z.js +35612 -0
- package/dist/bundle/chunk-WQ24UC44.js +239 -0
- package/dist/bundle/chunk-X5DFDGWS.js +2 -0
- package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
- package/dist/bundle/chunk-YB4DMKYX.js +119 -0
- package/dist/bundle/chunk-Z4TZ6TAF.js +288 -0
- package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
- package/dist/bundle/cli-72EQATJF.js +825 -0
- package/dist/bundle/command-contract-4MHSZUN3.js +38 -0
- package/dist/bundle/config-GFIJK6G2.js +79 -0
- package/dist/bundle/dist-IBNHCQXT.js +136 -0
- package/dist/bundle/dist-XUFQCJXW.js +7577 -0
- package/dist/bundle/echarts-RFTK737T.js +42501 -0
- package/dist/bundle/embed-7QYA2ZZE.js +35 -0
- package/dist/bundle/embedder-YNN6PCHG.js +108 -0
- package/dist/bundle/first-run-EVSRQKZJ.js +23 -0
- package/dist/bundle/first-screen-RG4GUKW7.js +36 -0
- package/dist/bundle/folders-JEPOMYM4.js +13 -0
- package/dist/bundle/instructions-FHNL7CMW.js +9 -0
- package/dist/bundle/main-NYGJXPH7.js +130 -0
- package/dist/bundle/mcp-IXFC2VVR.js +165 -0
- package/dist/bundle/mcp-VGSZDCKK.js +189 -0
- package/dist/bundle/mcp-XKP2PXLS.js +92 -0
- package/dist/bundle/meetings-IBPI4MM4.js +215 -0
- package/dist/bundle/node-P4E63KXA.js +2340 -0
- package/dist/bundle/node-TLZSIHIJ.js +21 -0
- package/dist/bundle/node-ZMCACJVS.js +176 -0
- package/dist/bundle/node-sqlite-ZNGOBA5Q.js +45 -0
- package/dist/bundle/oauth-Q6LKF7DB.js +17 -0
- package/dist/bundle/open-LJ332Y5O.js +19 -0
- package/dist/bundle/output-file-RYQZ3RTE.js +63 -0
- package/dist/bundle/process-ZPTLNVQS.js +91 -0
- package/dist/bundle/program-IBRQBQ6W.js +5845 -0
- package/dist/bundle/prompt-RT7GUUXH.js +12 -0
- package/dist/bundle/recognize-QXGE7YJH.js +190 -0
- package/dist/bundle/remote-FD4MZQV3.js +26 -0
- package/dist/bundle/rerank-V6AVV755.js +49 -0
- package/dist/bundle/run-log-RE2EI3UU.js +111 -0
- package/dist/bundle/serve-HIJTFAW7.js +19 -0
- package/dist/bundle/server-3QOXOYYL.js +53 -0
- package/dist/bundle/server-WLJCU7KK.js +812 -0
- package/dist/bundle/services-KC5KQFBS.js +330 -0
- package/dist/bundle/speech-5JOXLYDA.js +44 -0
- package/dist/bundle/state-PPGRB3T6.js +33 -0
- package/dist/bundle/store-LODVDPK3.js +141 -0
- package/dist/bundle/store-WB5BICTG.js +124 -0
- package/dist/bundle/store-connection-EG6Z5ITP.js +76 -0
- package/dist/bundle/store-maintenance-command-Q5WMFUZ2.js +54 -0
- package/dist/bundle/streaming-UGFFNOXL.js +15 -0
- package/dist/bundle/tokens-AF5CPY2F.js +17 -0
- package/dist/bundle/zm.js +8 -0
- package/dist/commands.js +2 -2
- package/dist/commands.js.map +1 -1
- package/dist/config-issues.d.ts.map +1 -1
- package/dist/config-issues.js +3 -0
- package/dist/config-issues.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -1
- package/dist/contract-overrides.d.ts.map +1 -1
- package/dist/contract-overrides.js +34 -45
- package/dist/contract-overrides.js.map +1 -1
- package/dist/first-screen.js +1 -1
- package/dist/first-screen.js.map +1 -1
- package/dist/mcp-command.d.ts +5 -3
- package/dist/mcp-command.d.ts.map +1 -1
- package/dist/mcp-command.js +73 -15
- package/dist/mcp-command.js.map +1 -1
- package/dist/program-bindings.d.ts.map +1 -1
- package/dist/program-bindings.js +1 -0
- package/dist/program-bindings.js.map +1 -1
- package/dist/recording-archive.d.ts.map +1 -1
- package/dist/recording-archive.js +9 -4
- package/dist/recording-archive.js.map +1 -1
- package/dist/remote-http.d.ts +2 -0
- package/dist/remote-http.d.ts.map +1 -1
- package/dist/remote-http.js +21 -11
- package/dist/remote-http.js.map +1 -1
- package/dist/request-events.d.ts +12 -0
- package/dist/request-events.d.ts.map +1 -1
- package/dist/request-events.js +56 -4
- package/dist/request-events.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +4 -1
- package/dist/run.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -5
- package/skills/zoom-cli/SKILL.md +3 -1
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
import { createRequire as __bundleRequire } from "node:module";
|
|
2
|
+
const require = __bundleRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
organization,
|
|
5
|
+
project,
|
|
6
|
+
reminder
|
|
7
|
+
} from "./chunk-YB4DMKYX.js";
|
|
8
|
+
import {
|
|
9
|
+
MIGRATIONS,
|
|
10
|
+
SnapshotBudget,
|
|
11
|
+
assertReadCompatible,
|
|
12
|
+
botNamed,
|
|
13
|
+
canonicalTagNamed,
|
|
14
|
+
decodeProjectAnnotationSnapshot,
|
|
15
|
+
migrate,
|
|
16
|
+
openSqlite,
|
|
17
|
+
openStoreContext,
|
|
18
|
+
ownerPerson,
|
|
19
|
+
previewAnnotationSnapshot,
|
|
20
|
+
projectAnnotationBindingSources,
|
|
21
|
+
projectAnnotationSnapshot,
|
|
22
|
+
projectAnnotationSnapshotFingerprint,
|
|
23
|
+
read,
|
|
24
|
+
referenceOfThing,
|
|
25
|
+
stateOfThing,
|
|
26
|
+
storedThing,
|
|
27
|
+
syncFile,
|
|
28
|
+
tagMemberIds,
|
|
29
|
+
thingOf,
|
|
30
|
+
write
|
|
31
|
+
} from "./chunk-WJHK5D7Z.js";
|
|
32
|
+
import {
|
|
33
|
+
filesAccountSql,
|
|
34
|
+
folderProviderOf,
|
|
35
|
+
folderProviderSql,
|
|
36
|
+
isDocumentAccountProvider
|
|
37
|
+
} from "./chunk-GARCOIB6.js";
|
|
38
|
+
import {
|
|
39
|
+
queryFieldsOf
|
|
40
|
+
} from "./chunk-LSVI3A5X.js";
|
|
41
|
+
import {
|
|
42
|
+
CliError
|
|
43
|
+
} from "./chunk-AE4BOXH7.js";
|
|
44
|
+
import {
|
|
45
|
+
__name
|
|
46
|
+
} from "./chunk-ZVVMGPBJ.js";
|
|
47
|
+
|
|
48
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/document-transfer/index.js
|
|
49
|
+
import { realpathSync, statSync } from "node:fs";
|
|
50
|
+
import { resolve } from "node:path";
|
|
51
|
+
|
|
52
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/sqlite/document-transfer/people.js
|
|
53
|
+
var planPeople = /* @__PURE__ */ __name((database, snapshot, mappings, bindings, conflicts) => {
|
|
54
|
+
const creatable = /* @__PURE__ */ new Set();
|
|
55
|
+
let people = 0, identities = 0;
|
|
56
|
+
for (const external of snapshot.external) {
|
|
57
|
+
if (!external.person)
|
|
58
|
+
continue;
|
|
59
|
+
const matched = external.person.identities.flatMap((identity) => {
|
|
60
|
+
const row = database.prepare("SELECT i.id,l.person_id FROM identities i LEFT JOIN identity_links l ON l.identity_id=i.id WHERE i.provider=? AND i.external_id=?").get(String(identity.provider), String(identity.external_id));
|
|
61
|
+
if (row && row.person_id == null)
|
|
62
|
+
conflicts.add(`a destination identity has no person for ${external.reference}`);
|
|
63
|
+
if (!row) {
|
|
64
|
+
identities++;
|
|
65
|
+
creatable.add(`identity:${String(identity.id)}`);
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
mappings.set(`identity:${String(identity.id)}`, { type: "identity", id: Number(row.id) });
|
|
69
|
+
return row.person_id == null ? [] : [Number(row.person_id)];
|
|
70
|
+
});
|
|
71
|
+
let selected = mappings.get(external.key);
|
|
72
|
+
const binding = bindings[external.reference];
|
|
73
|
+
if (binding !== void 0)
|
|
74
|
+
selected = thingOf(database, binding);
|
|
75
|
+
else if (external.owner)
|
|
76
|
+
selected = ownerPerson(database);
|
|
77
|
+
else if (new Set(matched).size === 1)
|
|
78
|
+
selected = { type: "person", id: matched[0] };
|
|
79
|
+
if (selected && (selected.type !== "person" || stateOfThing(database, selected) !== "available"))
|
|
80
|
+
selected = void 0;
|
|
81
|
+
if (new Set(matched).size > 1 || selected && matched.some((id) => id !== selected.id))
|
|
82
|
+
conflicts.add(`source identities disagree with the destination person for ${external.reference}`);
|
|
83
|
+
if (selected)
|
|
84
|
+
mappings.set(external.key, selected);
|
|
85
|
+
else if (binding === void 0) {
|
|
86
|
+
creatable.add(external.key);
|
|
87
|
+
people++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { creatable, people, identities };
|
|
91
|
+
}, "planPeople");
|
|
92
|
+
var copyPeople = /* @__PURE__ */ __name((database, snapshot, mappings, now) => {
|
|
93
|
+
for (const external of snapshot.external) {
|
|
94
|
+
if (!external.person)
|
|
95
|
+
continue;
|
|
96
|
+
let person = mappings.get(external.key);
|
|
97
|
+
if (!person) {
|
|
98
|
+
const row = database.prepare("INSERT INTO persons (name,owner,created_at,updated_at) VALUES (?,0,?,?) RETURNING id").get(external.person.name, now(), now());
|
|
99
|
+
person = { type: "person", id: Number(row?.id) };
|
|
100
|
+
mappings.set(external.key, person);
|
|
101
|
+
}
|
|
102
|
+
for (const identity of external.person.identities) {
|
|
103
|
+
let row = database.prepare("SELECT i.id,l.person_id FROM identities i LEFT JOIN identity_links l ON l.identity_id=i.id WHERE i.provider=? AND i.external_id=?").get(String(identity.provider), String(identity.external_id));
|
|
104
|
+
if (row && Number(row.person_id) !== person.id)
|
|
105
|
+
throw new CliError("configuration_error", "an identity belongs to another destination person; the transfer was rolled back");
|
|
106
|
+
if (!row)
|
|
107
|
+
row = database.prepare("INSERT INTO identities (provider,external_id,name,username,bot,created_at,updated_at) VALUES (?,?,?,?,?,?,?) RETURNING id").get(String(identity.provider), String(identity.external_id), identity.name ?? null, identity.username ?? null, identity.bot ?? null, identity.created_at ?? now(), identity.updated_at ?? now());
|
|
108
|
+
if (!database.prepare("SELECT identity_id FROM identity_links WHERE identity_id=?").get(Number(row?.id)))
|
|
109
|
+
database.prepare("INSERT INTO identity_links (identity_id,person_id,method,confidence,author,source,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)").run(Number(row?.id), person.id, identity.link_method ?? "transfer", identity.link_confidence ?? 1, identity.link_author ?? "owner", identity.link_source ?? null, identity.link_created_at ?? now(), identity.link_updated_at ?? now());
|
|
110
|
+
mappings.set(`identity:${String(identity.id)}`, { type: "identity", id: Number(row?.id) });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, "copyPeople");
|
|
114
|
+
|
|
115
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/document-transfer/digest.js
|
|
116
|
+
import { createHash } from "node:crypto";
|
|
117
|
+
var digest = /* @__PURE__ */ __name((value) => createHash("sha256").update(JSON.stringify(value)).digest("hex"), "digest");
|
|
118
|
+
|
|
119
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/sqlite/document-transfer/collection.js
|
|
120
|
+
var documentsKeyOf = /* @__PURE__ */ __name((collection) => {
|
|
121
|
+
const colon = collection.indexOf(":");
|
|
122
|
+
const provider = collection.slice(0, colon);
|
|
123
|
+
return colon > 0 && isDocumentAccountProvider(provider) ? { provider, account: collection.slice(colon + 1) } : void 0;
|
|
124
|
+
}, "documentsKeyOf");
|
|
125
|
+
var collectionNameOf = /* @__PURE__ */ __name((row) => isDocumentAccountProvider(String(row.provider)) ? `${String(row.provider)}:${String(row.external_id)}` : String(row.name), "collectionNameOf");
|
|
126
|
+
var collectionAccounts = /* @__PURE__ */ __name((database, collection) => {
|
|
127
|
+
const key = documentsKeyOf(collection);
|
|
128
|
+
return key ? database.prepare(`SELECT * FROM accounts WHERE (provider=? AND external_id=?) OR (${folderProviderSql()} AND name=?) ORDER BY id LIMIT 2`).all(key.provider, key.account, collection) : database.prepare(`SELECT * FROM accounts WHERE ${folderProviderSql()} AND name=? ORDER BY id LIMIT 2`).all(collection);
|
|
129
|
+
}, "collectionAccounts");
|
|
130
|
+
var movedFromOf = /* @__PURE__ */ __name((row) => {
|
|
131
|
+
if (typeof row?.settings !== "string")
|
|
132
|
+
return void 0;
|
|
133
|
+
try {
|
|
134
|
+
const moved = JSON.parse(row.settings).movedFrom;
|
|
135
|
+
return typeof moved === "object" && moved !== null ? moved : void 0;
|
|
136
|
+
} catch {
|
|
137
|
+
return void 0;
|
|
138
|
+
}
|
|
139
|
+
}, "movedFromOf");
|
|
140
|
+
var currentCollection = /* @__PURE__ */ __name((row) => {
|
|
141
|
+
const key = isDocumentAccountProvider(String(row.provider)) ? void 0 : documentsKeyOf(String(row.name));
|
|
142
|
+
if (!key)
|
|
143
|
+
return row;
|
|
144
|
+
const settings = (() => {
|
|
145
|
+
try {
|
|
146
|
+
return typeof row.settings === "string" ? JSON.parse(row.settings) : {};
|
|
147
|
+
} catch {
|
|
148
|
+
return {};
|
|
149
|
+
}
|
|
150
|
+
})();
|
|
151
|
+
return {
|
|
152
|
+
...row,
|
|
153
|
+
provider: key.provider,
|
|
154
|
+
external_id: key.account,
|
|
155
|
+
name: "Google Drive",
|
|
156
|
+
settings: JSON.stringify({
|
|
157
|
+
...settings,
|
|
158
|
+
movedFrom: { id: row.id, external_id: row.external_id, name: row.name }
|
|
159
|
+
})
|
|
160
|
+
};
|
|
161
|
+
}, "currentCollection");
|
|
162
|
+
|
|
163
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/sqlite/document-transfer/plan.js
|
|
164
|
+
var planTransfer = /* @__PURE__ */ __name((database, snapshot, sourceKey, bindings) => {
|
|
165
|
+
const mappings = /* @__PURE__ */ new Map();
|
|
166
|
+
const missing = /* @__PURE__ */ new Set(), conflicts = /* @__PURE__ */ new Set();
|
|
167
|
+
const snapshotHash = digest(snapshot);
|
|
168
|
+
const bindingsHash = digest(Object.entries(bindings).sort(([a], [b]) => a.localeCompare(b)));
|
|
169
|
+
const collection = String(snapshot.collection.external_id);
|
|
170
|
+
const targets = collectionAccounts(database, collectionNameOf(snapshot.collection));
|
|
171
|
+
if (targets.length > 1)
|
|
172
|
+
conflicts.add("the destination has duplicate document collection identities");
|
|
173
|
+
const target = targets[0];
|
|
174
|
+
if (!target && database.prepare(`SELECT id FROM accounts WHERE ${folderProviderSql()} AND external_id=?`).get(collection))
|
|
175
|
+
conflicts.add("source collection identity is held by another destination collection");
|
|
176
|
+
const hasReceipts = database.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='document_annotation_transfers'").get();
|
|
177
|
+
const receipt = hasReceipts && database.prepare("SELECT * FROM document_annotation_transfers WHERE source_key=? AND collection IN (?,?,?) LIMIT 1").get(sourceKey, collection, String(movedFromOf(snapshot.collection)?.external_id ?? collection), String(movedFromOf(target)?.external_id ?? collection));
|
|
178
|
+
if (receipt && (receipt.snapshot_hash !== snapshotHash || receipt.bindings_hash !== bindingsHash))
|
|
179
|
+
conflicts.add("the source or binding decisions changed after a completed transfer; keep the original store selected");
|
|
180
|
+
if (target && target.scope !== snapshot.collection.scope)
|
|
181
|
+
conflicts.add("the destination collection has a different scope or an organization binding");
|
|
182
|
+
for (const entity of snapshot.entities) {
|
|
183
|
+
if (entity.kind !== "document" || !target)
|
|
184
|
+
continue;
|
|
185
|
+
const existing = database.prepare("SELECT * FROM documents WHERE account_id=? AND external_id=?").get(Number(target.id), String(entity.values.external_id));
|
|
186
|
+
if (!existing)
|
|
187
|
+
continue;
|
|
188
|
+
mappings.set(entity.key, { type: "document", id: Number(existing.id) });
|
|
189
|
+
for (const field of ["body", "content_hash", "deleted_at", "revision"])
|
|
190
|
+
if (existing[field] !== entity.values[field])
|
|
191
|
+
conflicts.add(`destination content differs for ${entity.key}`);
|
|
192
|
+
for (const revision of entity.revisions) {
|
|
193
|
+
const row = database.prepare("SELECT body FROM document_revisions WHERE document_id=? AND revision=?").get(Number(existing.id), Number(revision.revision));
|
|
194
|
+
if (row && row.body !== revision.body)
|
|
195
|
+
conflicts.add(`destination revision differs for ${entity.key}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (receipt && receipt.snapshot_hash === snapshotHash && receipt.bindings_hash === bindingsHash)
|
|
199
|
+
for (const [key, value] of Object.entries(JSON.parse(String(receipt.reference_map))))
|
|
200
|
+
mappings.set(key, value);
|
|
201
|
+
const personPlan = planPeople(database, snapshot, mappings, bindings, conflicts);
|
|
202
|
+
const knownBindings = new Set(snapshot.external.map((item) => item.reference));
|
|
203
|
+
for (const key of Object.keys(bindings))
|
|
204
|
+
if (!knownBindings.has(key))
|
|
205
|
+
throw new CliError("validation_error", "a transfer binding names a reference outside the source annotation graph");
|
|
206
|
+
for (const external of snapshot.external) {
|
|
207
|
+
let found = mappings.get(external.key);
|
|
208
|
+
if (personPlan.creatable.has(external.key) && bindings[external.reference] === void 0)
|
|
209
|
+
continue;
|
|
210
|
+
if (external.key === `account:${String(snapshot.collection.id)}` && bindings[external.reference] === void 0) {
|
|
211
|
+
if (target)
|
|
212
|
+
mappings.set(external.key, { type: "account", id: Number(target.id) });
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const binding = bindings[external.reference];
|
|
216
|
+
if (binding !== void 0)
|
|
217
|
+
found = thingOf(database, binding);
|
|
218
|
+
else if (external.owner)
|
|
219
|
+
found = ownerPerson(database);
|
|
220
|
+
else if (external.bot) {
|
|
221
|
+
const bot = database.prepare("SELECT id,kind FROM bots WHERE name=?").get(external.bot.name);
|
|
222
|
+
if (bot && bot.kind !== external.bot.kind)
|
|
223
|
+
conflicts.add(`destination bot kind differs for ${external.reference}`);
|
|
224
|
+
if (bot)
|
|
225
|
+
found = { type: "bot", id: Number(bot.id) };
|
|
226
|
+
else
|
|
227
|
+
continue;
|
|
228
|
+
} else if (external.collection && external.external_id) {
|
|
229
|
+
const holders = JSON.stringify(collectionAccounts(database, external.collection).map(({ id }) => Number(id)));
|
|
230
|
+
const row = database.prepare("SELECT id FROM documents WHERE account_id IN (SELECT value FROM json_each(?)) AND external_id=? AND deleted_at IS NULL ORDER BY id LIMIT 1").get(holders, external.external_id);
|
|
231
|
+
if (row)
|
|
232
|
+
found = { type: "document", id: Number(row.id) };
|
|
233
|
+
} else if (["message", "chat", "identity", "email", "email_thread"].includes(external.kind))
|
|
234
|
+
found = thingOf(database, external.reference);
|
|
235
|
+
if (found?.type === "document" && external.document_fingerprint) {
|
|
236
|
+
const content = database.prepare("SELECT body,content_hash,deleted_at FROM documents WHERE id=?").get(found.id);
|
|
237
|
+
if (!content || digest(content) !== external.document_fingerprint)
|
|
238
|
+
conflicts.add(`destination evidence content differs for ${external.reference}`);
|
|
239
|
+
}
|
|
240
|
+
if (found && found.type === external.kind && stateOfThing(database, found) === "available")
|
|
241
|
+
mappings.set(external.key, found);
|
|
242
|
+
else
|
|
243
|
+
missing.add(external.reference);
|
|
244
|
+
}
|
|
245
|
+
const organization2 = snapshot.collection.organization_id == null ? null : mappings.get(`organization:${String(snapshot.collection.organization_id)}`)?.id;
|
|
246
|
+
if (target && target.organization_id !== organization2)
|
|
247
|
+
conflicts.add("the destination collection has a different organization binding");
|
|
248
|
+
for (const tagging of snapshot.taggings) {
|
|
249
|
+
if (Number(tagging.tag_group_size ?? 1) > 1)
|
|
250
|
+
conflicts.add(`source tag ${String(tagging.tag_id)} belongs to a consolidated group; annotation transfer cannot preserve that group yet`);
|
|
251
|
+
const tag = canonicalTagNamed(database, String(tagging.tag_name));
|
|
252
|
+
if (tag && tagMemberIds(database, tag.id).length > 1)
|
|
253
|
+
conflicts.add(`destination tag ${String(tag.id)} belongs to a consolidated group; annotation transfer cannot preserve independent contributions yet`);
|
|
254
|
+
if (tag && tag.name !== tagging.tag_name)
|
|
255
|
+
conflicts.add(`destination vocabulary resolves source tag ${String(tagging.tag_id)} to another canonical label`);
|
|
256
|
+
if (tag && tag.kind !== tagging.tag_kind)
|
|
257
|
+
conflicts.add(`destination tag kind differs for source tag ${String(tagging.tag_id)}`);
|
|
258
|
+
const subject = mappings.get(`${String(tagging.taggable_type)}:${String(tagging.taggable_id)}`);
|
|
259
|
+
if (!subject)
|
|
260
|
+
continue;
|
|
261
|
+
const existing = tag && database.prepare("SELECT source,main FROM taggings WHERE tag_id=? AND taggable_type=? AND taggable_id=?").get(Number(tag.id), subject.type, subject.id);
|
|
262
|
+
if (existing && (existing.source !== tagging.source || existing.main !== tagging.main))
|
|
263
|
+
conflicts.add(`destination tag assignment differs for ${subject.type}:${subject.id}`);
|
|
264
|
+
if (tagging.main === 1) {
|
|
265
|
+
const main = database.prepare("SELECT tag_id FROM taggings WHERE taggable_type=? AND taggable_id=? AND main=1").get(subject.type, subject.id);
|
|
266
|
+
if (main && Number(main.tag_id) !== Number(tag?.id))
|
|
267
|
+
conflicts.add(`destination primary topic differs for ${subject.type}:${subject.id}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
for (const alias of snapshot.aliases) {
|
|
271
|
+
const sourceTag = snapshot.taggings.find((tagging) => tagging.tag_id === alias.aliasable_id);
|
|
272
|
+
const named = canonicalTagNamed(database, String(alias.name));
|
|
273
|
+
const targetTag = sourceTag && canonicalTagNamed(database, String(sourceTag.tag_name));
|
|
274
|
+
if (named && named.id !== targetTag?.id)
|
|
275
|
+
conflicts.add(`destination alias conflicts with source tag ${String(alias.aliasable_id)}`);
|
|
276
|
+
if (targetTag && alias.display === 1) {
|
|
277
|
+
const displayed = database.prepare("SELECT name_folded FROM aliases WHERE aliasable_type='tag' AND aliasable_id=? AND account_id IS NULL AND display=1").get(targetTag.id);
|
|
278
|
+
if (displayed && displayed.name_folded !== alias.name_folded)
|
|
279
|
+
conflicts.add(`destination display alias conflicts with source tag ${String(alias.aliasable_id)}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const counts = {
|
|
283
|
+
documents: snapshot.entities.filter((item) => item.kind === "document").length,
|
|
284
|
+
notes: snapshot.entities.filter((item) => item.kind === "note").length,
|
|
285
|
+
memories: snapshot.entities.filter((item) => item.kind === "memory").length,
|
|
286
|
+
facts: snapshot.entities.filter((item) => item.kind === "fact").length,
|
|
287
|
+
tags: snapshot.taggings.length,
|
|
288
|
+
links: snapshot.links.length,
|
|
289
|
+
people: personPlan.people,
|
|
290
|
+
identities: personPlan.identities,
|
|
291
|
+
authors: snapshot.external.filter((item) => item.bot && !mappings.has(item.key)).length,
|
|
292
|
+
aliases: snapshot.aliases.length
|
|
293
|
+
};
|
|
294
|
+
if (receipt && conflicts.size === 0) {
|
|
295
|
+
for (const [key, value] of Object.entries(JSON.parse(String(receipt.reference_map)))) {
|
|
296
|
+
if (stateOfThing(database, value) === "unavailable")
|
|
297
|
+
conflicts.add("a transferred destination record is missing");
|
|
298
|
+
mappings.set(key, value);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const fingerprint = digest({
|
|
302
|
+
sourceKey,
|
|
303
|
+
snapshotHash,
|
|
304
|
+
bindingsHash,
|
|
305
|
+
collection: target?.id ?? null,
|
|
306
|
+
mappings: [...mappings.entries()].sort(([a], [b]) => a.localeCompare(b)),
|
|
307
|
+
conflicts: [...conflicts],
|
|
308
|
+
missing: [...missing]
|
|
309
|
+
});
|
|
310
|
+
return {
|
|
311
|
+
preview: {
|
|
312
|
+
fingerprint,
|
|
313
|
+
source_documents: snapshot.entities.filter((entity) => entity.kind === "document").map((entity) => ({
|
|
314
|
+
external_id: String(entity.values.external_id),
|
|
315
|
+
content_hash: entity.values.content_hash == null ? null : String(entity.values.content_hash)
|
|
316
|
+
})).sort((a, b) => a.external_id.localeCompare(b.external_id)),
|
|
317
|
+
counts,
|
|
318
|
+
missing_bindings: [...missing].sort(),
|
|
319
|
+
conflicts: [...conflicts].sort(),
|
|
320
|
+
already_transferred: Boolean(receipt) && conflicts.size === 0 && missing.size === 0,
|
|
321
|
+
ready: conflicts.size === 0 && missing.size === 0
|
|
322
|
+
},
|
|
323
|
+
mappings,
|
|
324
|
+
snapshotHash,
|
|
325
|
+
bindingsHash,
|
|
326
|
+
...target ? { collectionId: Number(target.id) } : {}
|
|
327
|
+
};
|
|
328
|
+
}, "planTransfer");
|
|
329
|
+
|
|
330
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/sqlite/document-transfer/snapshot.js
|
|
331
|
+
var TRANSFER_TABLES = { document: "documents", note: "notes", memory: "memories", fact: "facts" };
|
|
332
|
+
var MAX_ENTITIES = 1e3;
|
|
333
|
+
var MAX_AUXILIARY = 1e4;
|
|
334
|
+
var MAX_BYTES = 16 * 1024 * 1024;
|
|
335
|
+
var keyOf = /* @__PURE__ */ __name((type, id) => `${String(type)}:${String(id)}`, "keyOf");
|
|
336
|
+
var isAnnotation = /* @__PURE__ */ __name((type) => type === "note" || type === "memory" || type === "fact", "isAnnotation");
|
|
337
|
+
var valuesOf = /* @__PURE__ */ __name((row) => Object.fromEntries(Object.entries(row).map(([key, value]) => {
|
|
338
|
+
if (value !== null && typeof value !== "string" && typeof value !== "number")
|
|
339
|
+
throw new CliError("configuration_error", "the source contains an unsupported annotation value");
|
|
340
|
+
return [key, value];
|
|
341
|
+
})), "valuesOf");
|
|
342
|
+
var transferSnapshot = /* @__PURE__ */ __name((database, collection) => read(database, () => {
|
|
343
|
+
const accounts = collectionAccounts(database, collection);
|
|
344
|
+
if (accounts.length > 1)
|
|
345
|
+
throw new CliError("configuration_error", "the source has duplicate document collection identities; select a repaired copy before transferring");
|
|
346
|
+
const account = accounts[0];
|
|
347
|
+
if (!account)
|
|
348
|
+
throw new CliError("not_found", "the source store does not hold the requested document collection");
|
|
349
|
+
if (!database.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='facts'").get())
|
|
350
|
+
throw new CliError("configuration_error", "the source store needs schema 2 or newer; upgrade a separate copy before transferring");
|
|
351
|
+
let bytes = 0;
|
|
352
|
+
const bounded = /* @__PURE__ */ __name((row) => {
|
|
353
|
+
const values = valuesOf(row);
|
|
354
|
+
bytes += Buffer.byteLength(JSON.stringify(values));
|
|
355
|
+
if (bytes > MAX_BYTES)
|
|
356
|
+
throw new CliError("validation_error", "annotation transfer exceeds its 16 MiB snapshot limit");
|
|
357
|
+
return values;
|
|
358
|
+
}, "bounded");
|
|
359
|
+
const entities = /* @__PURE__ */ new Map();
|
|
360
|
+
const links = /* @__PURE__ */ new Map();
|
|
361
|
+
const taggings = /* @__PURE__ */ new Map();
|
|
362
|
+
const canonicalTags = Boolean(database.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='canonical_tags'").get());
|
|
363
|
+
const tagTable = canonicalTags ? "canonical_tags" : "tags";
|
|
364
|
+
const resolution = canonicalTags ? "r.canonical_id AS tag_canonical_id,(SELECT count(*) FROM resolved_tags members WHERE members.canonical_id=r.canonical_id) AS tag_group_size" : "t.id AS tag_canonical_id,1 AS tag_group_size";
|
|
365
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
366
|
+
const depend = /* @__PURE__ */ __name((type, id) => {
|
|
367
|
+
if (type != null && id != null)
|
|
368
|
+
dependencies.set(keyOf(type, id), { type: String(type), id: Number(id) });
|
|
369
|
+
}, "depend");
|
|
370
|
+
const add = /* @__PURE__ */ __name((kind, row) => {
|
|
371
|
+
const key = keyOf(kind, row.id);
|
|
372
|
+
if (entities.has(key))
|
|
373
|
+
return;
|
|
374
|
+
if (entities.size >= MAX_ENTITIES)
|
|
375
|
+
throw new CliError("validation_error", "annotation transfer exceeds 1000 document and annotation records");
|
|
376
|
+
const values = bounded(row);
|
|
377
|
+
entities.set(key, { key, kind, values, revisions: [] });
|
|
378
|
+
}, "add");
|
|
379
|
+
for (const row of database.prepare("SELECT * FROM documents WHERE account_id=? ORDER BY id LIMIT 1001").all(Number(account.id)))
|
|
380
|
+
add("document", row);
|
|
381
|
+
for (const entity of entities.values()) {
|
|
382
|
+
const { kind, values } = entity;
|
|
383
|
+
for (const [child, subject] of [
|
|
384
|
+
["note", "notable"],
|
|
385
|
+
["memory", "subject"],
|
|
386
|
+
["fact", "subject"]
|
|
387
|
+
]) {
|
|
388
|
+
for (const row of database.prepare(`SELECT * FROM ${TRANSFER_TABLES[child]} WHERE ${subject}_type=? AND ${subject}_id=? ORDER BY id LIMIT 1001`).all(kind, Number(values.id)))
|
|
389
|
+
add(child, row);
|
|
390
|
+
}
|
|
391
|
+
for (const row of database.prepare("SELECT * FROM links WHERE (from_type=? AND from_id=?) OR (to_type=? AND to_id=?) ORDER BY id LIMIT 10001").all(kind, Number(values.id), kind, Number(values.id))) {
|
|
392
|
+
if (links.has(String(row.id)))
|
|
393
|
+
continue;
|
|
394
|
+
if (links.size >= MAX_AUXILIARY)
|
|
395
|
+
throw new CliError("validation_error", "annotation transfer exceeds 10000 relationships");
|
|
396
|
+
links.set(String(row.id), bounded(row));
|
|
397
|
+
for (const side of ["from", "to"]) {
|
|
398
|
+
const type = row[`${side}_type`], id = row[`${side}_id`];
|
|
399
|
+
depend(type, id);
|
|
400
|
+
if (isAnnotation(type)) {
|
|
401
|
+
const related = database.prepare(`SELECT * FROM ${TRANSFER_TABLES[type]} WHERE id=?`).get(Number(id));
|
|
402
|
+
if (related)
|
|
403
|
+
add(type, related);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
for (const row of database.prepare(`SELECT g.*,t.name AS tag_name,t.kind AS tag_kind,${resolution} FROM taggings g JOIN ${tagTable} t ON t.id=g.tag_id ${canonicalTags ? "JOIN resolved_tags r ON r.id=t.id" : ""} WHERE g.taggable_type=? AND g.taggable_id=? ORDER BY g.id LIMIT 10001`).all(kind, Number(values.id))) {
|
|
408
|
+
if (taggings.size >= MAX_AUXILIARY)
|
|
409
|
+
throw new CliError("validation_error", "annotation transfer exceeds 10000 tag assignments");
|
|
410
|
+
taggings.set(String(row.id), bounded(row));
|
|
411
|
+
depend(row.author_type, row.author_id);
|
|
412
|
+
}
|
|
413
|
+
for (const prefix of ["notable", "subject", "author", "confirmed_by"])
|
|
414
|
+
depend(values[`${prefix}_type`], values[`${prefix}_id`]);
|
|
415
|
+
if (values.project_id != null)
|
|
416
|
+
depend("project", values.project_id);
|
|
417
|
+
if (kind === "memory" || kind === "fact")
|
|
418
|
+
for (const next of database.prepare(`SELECT * FROM ${TRANSFER_TABLES[kind]} WHERE supersedes_id=? ORDER BY id LIMIT 1001`).all(Number(values.id)))
|
|
419
|
+
add(kind, next);
|
|
420
|
+
if (values.supersedes_id != null) {
|
|
421
|
+
depend(kind, values.supersedes_id);
|
|
422
|
+
const previous = database.prepare(`SELECT * FROM ${TRANSFER_TABLES[kind]} WHERE id=?`).get(values.supersedes_id);
|
|
423
|
+
if (previous)
|
|
424
|
+
add(kind, previous);
|
|
425
|
+
}
|
|
426
|
+
if (kind === "document" || kind === "note") {
|
|
427
|
+
const table = kind === "document" ? "document_revisions" : "note_revisions";
|
|
428
|
+
const rows = database.prepare(`SELECT * FROM ${table} WHERE ${kind}_id=? ORDER BY id LIMIT 10001`).all(Number(values.id));
|
|
429
|
+
if (rows.length > MAX_AUXILIARY)
|
|
430
|
+
throw new CliError("validation_error", "annotation transfer exceeds 10000 revisions on one record");
|
|
431
|
+
entity.revisions = rows.map(bounded);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (account.organization_id != null)
|
|
435
|
+
depend("organization", account.organization_id);
|
|
436
|
+
const external = [];
|
|
437
|
+
const aliases = [];
|
|
438
|
+
for (const tag of new Set([...taggings.values()].map((item) => Number(item.tag_id))))
|
|
439
|
+
for (const alias of database.prepare("SELECT * FROM aliases WHERE aliasable_type='tag' AND aliasable_id=? AND account_id IS NULL ORDER BY id LIMIT 10001").all(tag)) {
|
|
440
|
+
if (aliases.length >= MAX_AUXILIARY)
|
|
441
|
+
throw new CliError("validation_error", "annotation transfer exceeds 10000 label aliases");
|
|
442
|
+
aliases.push(bounded(alias));
|
|
443
|
+
}
|
|
444
|
+
for (const [key, thing] of dependencies) {
|
|
445
|
+
if (entities.has(key))
|
|
446
|
+
continue;
|
|
447
|
+
const reference = referenceOfThing(database, storedThing(thing.type, thing.id)) ?? key;
|
|
448
|
+
const item = { key, reference, kind: thing.type };
|
|
449
|
+
if (thing.type === "person") {
|
|
450
|
+
const person = database.prepare("SELECT name,owner FROM persons WHERE id=?").get(thing.id);
|
|
451
|
+
if (person) {
|
|
452
|
+
item.owner = person.owner === 1;
|
|
453
|
+
item.person = {
|
|
454
|
+
name: person.name == null ? null : String(person.name),
|
|
455
|
+
identities: database.prepare("SELECT i.id,i.provider,i.external_id,i.name,i.username,i.bot,i.created_at,i.updated_at,l.method AS link_method,l.confidence AS link_confidence,l.author AS link_author,l.source AS link_source,l.created_at AS link_created_at,l.updated_at AS link_updated_at FROM identities i JOIN identity_links l ON l.identity_id=i.id WHERE l.person_id=? ORDER BY i.id LIMIT 10001").all(thing.id).map(bounded)
|
|
456
|
+
};
|
|
457
|
+
if (item.person.identities.length > MAX_AUXILIARY)
|
|
458
|
+
throw new CliError("validation_error", "annotation transfer exceeds 10000 identities for one person");
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (thing.type === "identity") {
|
|
462
|
+
const identity = database.prepare("SELECT person_id FROM identity_links WHERE identity_id=?").get(thing.id);
|
|
463
|
+
if (identity?.person_id != null)
|
|
464
|
+
depend("person", identity.person_id);
|
|
465
|
+
}
|
|
466
|
+
if (thing.type === "bot") {
|
|
467
|
+
const bot = database.prepare("SELECT name,kind FROM bots WHERE id=?").get(thing.id);
|
|
468
|
+
if (bot)
|
|
469
|
+
item.bot = { name: String(bot.name), kind: String(bot.kind) };
|
|
470
|
+
}
|
|
471
|
+
if (thing.type === "document") {
|
|
472
|
+
const doc = database.prepare(`SELECT a.provider,a.external_id AS account,a.name,d.external_id,d.body,d.content_hash,d.deleted_at FROM documents d JOIN accounts a ON a.id=d.account_id WHERE d.id=? AND ${filesAccountSql("a.provider")}`).get(thing.id);
|
|
473
|
+
if (doc) {
|
|
474
|
+
item.collection = collectionNameOf({ provider: doc.provider, external_id: doc.account, name: doc.name });
|
|
475
|
+
item.external_id = String(doc.external_id);
|
|
476
|
+
const content = bounded({ body: doc.body, content_hash: doc.content_hash, deleted_at: doc.deleted_at });
|
|
477
|
+
item.document_fingerprint = digest(content);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
external.push(item);
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
collection: bounded(currentCollection(account)),
|
|
484
|
+
entities: [...entities.values()].sort((a, b) => a.key.localeCompare(b.key)),
|
|
485
|
+
links: [...links.values()].sort((a, b) => Number(a.id) - Number(b.id)),
|
|
486
|
+
taggings: [...taggings.values()].sort((a, b) => Number(a.id) - Number(b.id)),
|
|
487
|
+
external: external.sort((a, b) => a.key.localeCompare(b.key)),
|
|
488
|
+
aliases
|
|
489
|
+
};
|
|
490
|
+
}), "transferSnapshot");
|
|
491
|
+
|
|
492
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/sqlite/document-transfer/apply.js
|
|
493
|
+
var providerHere = /* @__PURE__ */ __name(({ provider, name, settings }) => {
|
|
494
|
+
if (provider !== "folder" || String(name ?? "").startsWith("google-drive:"))
|
|
495
|
+
return provider ?? null;
|
|
496
|
+
return folderProviderOf(formatOf(settings) === "markdown" ? "markdown" : "obsidian");
|
|
497
|
+
}, "providerHere");
|
|
498
|
+
var formatOf = /* @__PURE__ */ __name((settings) => {
|
|
499
|
+
try {
|
|
500
|
+
return JSON.parse(String(settings))?.format;
|
|
501
|
+
} catch {
|
|
502
|
+
return void 0;
|
|
503
|
+
}
|
|
504
|
+
}, "formatOf");
|
|
505
|
+
var COLUMNS = {
|
|
506
|
+
document: "account_id external_id kind title location file_name extension url storage local_path mime size content_hash front_matter body normalized_text extraction extraction_error language revision export_path external_created_at external_updated_at metadata created_at updated_at deleted_at",
|
|
507
|
+
note: "notable_type notable_id title body author_type author_id revision created_at updated_at deleted_at",
|
|
508
|
+
memory: "kind body subject_type subject_id author_type author_id model confidence status last_verified_at supersedes_id scope created_at updated_at deleted_at",
|
|
509
|
+
fact: "type statement status project_id subject_type subject_id occurred_at supersedes_id author_type author_id model confirmed_by_type confirmed_by_id scope source metadata created_at updated_at deleted_at"
|
|
510
|
+
};
|
|
511
|
+
var LINK_COLUMNS = "from_type from_id to_type to_id kind anchor source target_text target_folded role evidence metadata confirmed created_at author updated_at";
|
|
512
|
+
var TAGGING_COLUMNS = "tag_id taggable_type taggable_id main source author_type author_id created_at updated_at";
|
|
513
|
+
var insert = /* @__PURE__ */ __name((database, table, columns, values) => {
|
|
514
|
+
const fields = columns.split(" ");
|
|
515
|
+
const row = database.prepare(`INSERT INTO ${table} (${fields.join(",")}) VALUES (${fields.map(() => "?").join(",")}) RETURNING id`).get(...fields.map((field) => values[field] ?? null));
|
|
516
|
+
return Number(row?.id);
|
|
517
|
+
}, "insert");
|
|
518
|
+
var mapped = /* @__PURE__ */ __name((mappings, type, id) => {
|
|
519
|
+
if (type == null && id == null)
|
|
520
|
+
return void 0;
|
|
521
|
+
const result = mappings.get(`${String(type)}:${String(id)}`);
|
|
522
|
+
if (!result)
|
|
523
|
+
throw new CliError("configuration_error", "an annotation reference was not resolved; the transfer was rolled back");
|
|
524
|
+
return result;
|
|
525
|
+
}, "mapped");
|
|
526
|
+
var applyTransfer = /* @__PURE__ */ __name((database, snapshot, sourceKey, bindings, expectedFingerprint, now) => write(database, () => {
|
|
527
|
+
const plan = planTransfer(database, snapshot, sourceKey, bindings);
|
|
528
|
+
if (plan.preview.fingerprint !== expectedFingerprint)
|
|
529
|
+
throw new CliError("validation_error", "the transfer preview changed; preview it again before applying");
|
|
530
|
+
if (!plan.preview.ready)
|
|
531
|
+
throw new CliError("configuration_error", "the transfer has unresolved references or conflicts; preview it before applying");
|
|
532
|
+
const mappings = plan.mappings;
|
|
533
|
+
const references = /* @__PURE__ */ __name(() => Object.fromEntries([...mappings].map(([key, value]) => [key, referenceOfThing(database, value) ?? `${value.type}:${value.id}`])), "references");
|
|
534
|
+
const documents = /* @__PURE__ */ __name((refs2) => Object.fromEntries(snapshot.entities.filter((entity) => entity.kind === "document").map((entity) => [String(entity.values.external_id), refs2[entity.key]])), "documents");
|
|
535
|
+
if (plan.preview.already_transferred) {
|
|
536
|
+
const refs2 = references();
|
|
537
|
+
return { ...plan.preview, references: refs2, documents: documents(refs2) };
|
|
538
|
+
}
|
|
539
|
+
copyPeople(database, snapshot, mappings, now);
|
|
540
|
+
const owner = ownerPerson(database);
|
|
541
|
+
for (const external of snapshot.external)
|
|
542
|
+
if (external.bot && !mappings.has(external.key))
|
|
543
|
+
mappings.set(external.key, botNamed(database, external.bot.name, now(), external.bot.kind));
|
|
544
|
+
let collectionId = plan.collectionId;
|
|
545
|
+
if (collectionId === void 0) {
|
|
546
|
+
const organization2 = snapshot.collection.organization_id == null ? void 0 : mapped(mappings, "organization", snapshot.collection.organization_id);
|
|
547
|
+
collectionId = insert(database, "accounts", "provider external_id name created_at settings updated_at scope organization_id", {
|
|
548
|
+
...snapshot.collection,
|
|
549
|
+
provider: providerHere(snapshot.collection),
|
|
550
|
+
organization_id: organization2?.id ?? null
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
mappings.set(`account:${String(snapshot.collection.id)}`, { type: "account", id: collectionId });
|
|
554
|
+
const inserted = /* @__PURE__ */ new Set();
|
|
555
|
+
const ordered = [...snapshot.entities].sort((a, b) => Number(a.kind !== "document") - Number(b.kind !== "document"));
|
|
556
|
+
for (const entity of ordered) {
|
|
557
|
+
if (mappings.has(entity.key))
|
|
558
|
+
continue;
|
|
559
|
+
const values = { ...entity.values };
|
|
560
|
+
if (entity.kind === "document")
|
|
561
|
+
values.account_id = collectionId;
|
|
562
|
+
else {
|
|
563
|
+
for (const prefix of ["notable", "subject", "author", "confirmed_by"]) {
|
|
564
|
+
if (!Object.hasOwn(values, `${prefix}_type`))
|
|
565
|
+
continue;
|
|
566
|
+
const required = prefix === "notable" || prefix === "author" && entity.kind !== "note";
|
|
567
|
+
values[`${prefix}_type`] = required ? owner.type : null;
|
|
568
|
+
values[`${prefix}_id`] = required ? owner.id : null;
|
|
569
|
+
}
|
|
570
|
+
if (Object.hasOwn(values, "supersedes_id"))
|
|
571
|
+
values.supersedes_id = null;
|
|
572
|
+
if (Object.hasOwn(values, "project_id"))
|
|
573
|
+
values.project_id = null;
|
|
574
|
+
}
|
|
575
|
+
const id = insert(database, TRANSFER_TABLES[entity.kind], COLUMNS[entity.kind], values);
|
|
576
|
+
if (entity.kind === "document")
|
|
577
|
+
syncFile(database, now(), id, { seen: false });
|
|
578
|
+
mappings.set(entity.key, { type: entity.kind, id });
|
|
579
|
+
inserted.add(entity.key);
|
|
580
|
+
}
|
|
581
|
+
for (const entity of ordered) {
|
|
582
|
+
const destination = mappings.get(entity.key);
|
|
583
|
+
if (inserted.has(entity.key))
|
|
584
|
+
remapEntity(database, entity, destination.id, mappings);
|
|
585
|
+
if (entity.kind === "document" || entity.kind === "note") {
|
|
586
|
+
const table = entity.kind === "document" ? "document_revisions" : "note_revisions";
|
|
587
|
+
for (const revision of entity.revisions) {
|
|
588
|
+
const existing = database.prepare(`SELECT body FROM ${table} WHERE ${entity.kind}_id=? AND revision=?`).get(destination.id, Number(revision.revision));
|
|
589
|
+
if (existing)
|
|
590
|
+
continue;
|
|
591
|
+
insert(database, table, `${entity.kind}_id body revision created_at`, {
|
|
592
|
+
...revision,
|
|
593
|
+
[`${entity.kind}_id`]: destination.id
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
for (const tagging of snapshot.taggings) {
|
|
599
|
+
const tag = canonicalTagNamed(database, String(tagging.tag_name));
|
|
600
|
+
const tagId = tag ? Number(tag.id) : insert(database, "canonical_tags", "name kind created_at updated_at", {
|
|
601
|
+
name: tagging.tag_name ?? null,
|
|
602
|
+
kind: tagging.tag_kind ?? null,
|
|
603
|
+
created_at: tagging.created_at ?? null,
|
|
604
|
+
updated_at: tagging.updated_at ?? null
|
|
605
|
+
});
|
|
606
|
+
const subject = mapped(mappings, tagging.taggable_type, tagging.taggable_id);
|
|
607
|
+
const author = mapped(mappings, tagging.author_type, tagging.author_id);
|
|
608
|
+
if (database.prepare("SELECT id FROM taggings WHERE tag_id=? AND taggable_type=? AND taggable_id=?").get(tagId, subject.type, subject.id))
|
|
609
|
+
continue;
|
|
610
|
+
insert(database, "taggings", TAGGING_COLUMNS, {
|
|
611
|
+
...tagging,
|
|
612
|
+
tag_id: tagId,
|
|
613
|
+
taggable_type: subject.type,
|
|
614
|
+
taggable_id: subject.id,
|
|
615
|
+
author_type: author?.type ?? null,
|
|
616
|
+
author_id: author?.id ?? null
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
for (const alias of snapshot.aliases) {
|
|
620
|
+
const sourceTag = snapshot.taggings.find((tagging) => tagging.tag_id === alias.aliasable_id);
|
|
621
|
+
const targetTag = canonicalTagNamed(database, String(sourceTag?.tag_name));
|
|
622
|
+
if (!targetTag)
|
|
623
|
+
throw new CliError("configuration_error", "an imported label alias has no canonical tag; the transfer was rolled back");
|
|
624
|
+
const existing = database.prepare("SELECT id FROM aliases WHERE aliasable_type='tag' AND aliasable_id=? AND account_id IS NULL AND name_folded=?").get(targetTag.id, String(alias.name_folded));
|
|
625
|
+
if (!existing)
|
|
626
|
+
insert(database, "aliases", "aliasable_type aliasable_id account_id name name_folded display source created_at updated_at", { ...alias, aliasable_id: targetTag.id });
|
|
627
|
+
}
|
|
628
|
+
for (const link of snapshot.links) {
|
|
629
|
+
const from = mapped(mappings, link.from_type, link.from_id);
|
|
630
|
+
const to = mapped(mappings, link.to_type, link.to_id);
|
|
631
|
+
insert(database, "links", LINK_COLUMNS, {
|
|
632
|
+
...link,
|
|
633
|
+
from_type: from.type,
|
|
634
|
+
from_id: from.id,
|
|
635
|
+
to_type: to?.type ?? null,
|
|
636
|
+
to_id: to?.id ?? null
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
database.prepare("INSERT INTO document_annotation_transfers (source_key,collection,snapshot_hash,bindings_hash,reference_map,created_at) VALUES (?,?,?,?,?,?)").run(sourceKey, String(snapshot.collection.external_id), plan.snapshotHash, plan.bindingsHash, JSON.stringify(Object.fromEntries(mappings)), now());
|
|
640
|
+
const refs = references();
|
|
641
|
+
return { ...plan.preview, references: refs, documents: documents(refs) };
|
|
642
|
+
}), "applyTransfer");
|
|
643
|
+
var remapEntity = /* @__PURE__ */ __name((database, entity, id, mappings) => {
|
|
644
|
+
const columns = [], values = [];
|
|
645
|
+
for (const prefix of ["notable", "subject", "author", "confirmed_by"]) {
|
|
646
|
+
if (!Object.hasOwn(entity.values, `${prefix}_type`))
|
|
647
|
+
continue;
|
|
648
|
+
const target = mapped(mappings, entity.values[`${prefix}_type`], entity.values[`${prefix}_id`]);
|
|
649
|
+
columns.push(`${prefix}_type=?`, `${prefix}_id=?`);
|
|
650
|
+
values.push(target?.type ?? null, target?.id ?? null);
|
|
651
|
+
}
|
|
652
|
+
if (Object.hasOwn(entity.values, "supersedes_id")) {
|
|
653
|
+
columns.push("supersedes_id=?");
|
|
654
|
+
values.push(entity.values.supersedes_id == null ? null : mapped(mappings, entity.kind, entity.values.supersedes_id).id);
|
|
655
|
+
}
|
|
656
|
+
if (Object.hasOwn(entity.values, "project_id")) {
|
|
657
|
+
columns.push("project_id=?");
|
|
658
|
+
values.push(entity.values.project_id == null ? null : mapped(mappings, "project", entity.values.project_id).id);
|
|
659
|
+
}
|
|
660
|
+
if (columns.length)
|
|
661
|
+
database.prepare(`UPDATE ${TRANSFER_TABLES[entity.kind]} SET ${columns.join(",")} WHERE id=?`).run(...values, id);
|
|
662
|
+
}, "remapEntity");
|
|
663
|
+
|
|
664
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/document-transfer/index.js
|
|
665
|
+
var locations = /* @__PURE__ */ __name((options) => {
|
|
666
|
+
for (const value of [options.source, options.destination, options.collection])
|
|
667
|
+
if (typeof value !== "string" || !value.trim())
|
|
668
|
+
throw new CliError("validation_error", "transfer source, destination and collection are required");
|
|
669
|
+
if (!statSync(options.source, { throwIfNoEntry: false })?.isFile())
|
|
670
|
+
throw new CliError("not_found", "the source store does not exist as a file");
|
|
671
|
+
const source = realpathSync(options.source), destination = resolve(options.destination);
|
|
672
|
+
const left = statSync(source), right = statSync(destination, { throwIfNoEntry: false });
|
|
673
|
+
if (right && (!right.isFile() || left.dev === right.dev && left.ino === right.ino))
|
|
674
|
+
throw new CliError("validation_error", "the source and destination must be different ordinary store files");
|
|
675
|
+
const bindings = options.bindings ?? {};
|
|
676
|
+
if (!bindings || typeof bindings !== "object" || Array.isArray(bindings) || Object.values(bindings).some((value) => typeof value !== "string" || !value.trim()))
|
|
677
|
+
throw new CliError("validation_error", "transfer bindings must map source references to destination references");
|
|
678
|
+
return { source, destination, sourceKey: digest([left.dev, left.ino, left.birthtimeMs]), bindings };
|
|
679
|
+
}, "locations");
|
|
680
|
+
var openSource = /* @__PURE__ */ __name(async (path) => {
|
|
681
|
+
const opened = await openSqlite(path, { readOnly: true });
|
|
682
|
+
try {
|
|
683
|
+
const row = opened.database.prepare("SELECT version,min_compatible FROM schema_migrations ORDER BY version DESC LIMIT 1").get();
|
|
684
|
+
const version = Number(row?.version), minimum = Number(row?.min_compatible);
|
|
685
|
+
if (!Number.isSafeInteger(version) || version < 2 || version > (MIGRATIONS.at(-1)?.version ?? 0) || !Number.isSafeInteger(minimum) || minimum < 1 || minimum > version || minimum > (MIGRATIONS.at(-1)?.version ?? 0))
|
|
686
|
+
throw new CliError("configuration_error", "the store schema is not compatible with document annotation transfer; upgrade a separate copy first");
|
|
687
|
+
return opened;
|
|
688
|
+
} catch (error) {
|
|
689
|
+
opened.database.close();
|
|
690
|
+
if (error instanceof CliError)
|
|
691
|
+
throw error;
|
|
692
|
+
throw new CliError("configuration_error", "the store has no readable annotation schema; it was not changed");
|
|
693
|
+
}
|
|
694
|
+
}, "openSource");
|
|
695
|
+
var openPreviewTarget = /* @__PURE__ */ __name(async (path) => {
|
|
696
|
+
if (statSync(path, { throwIfNoEntry: false })) {
|
|
697
|
+
const opened = await openSource(path);
|
|
698
|
+
try {
|
|
699
|
+
assertReadCompatible(opened.database);
|
|
700
|
+
return opened;
|
|
701
|
+
} catch (error) {
|
|
702
|
+
opened.database.close();
|
|
703
|
+
throw error;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
const target = await openSqlite(":memory:");
|
|
707
|
+
try {
|
|
708
|
+
migrate(target.database);
|
|
709
|
+
return target;
|
|
710
|
+
} catch (error) {
|
|
711
|
+
target.database.close();
|
|
712
|
+
throw error;
|
|
713
|
+
}
|
|
714
|
+
}, "openPreviewTarget");
|
|
715
|
+
var previewDocumentTransfer = /* @__PURE__ */ __name(async (options) => {
|
|
716
|
+
const location = locations(options);
|
|
717
|
+
const source = await openSource(location.source);
|
|
718
|
+
try {
|
|
719
|
+
const target = await openPreviewTarget(location.destination);
|
|
720
|
+
try {
|
|
721
|
+
return planTransfer(target.database, transferSnapshot(source.database, options.collection), location.sourceKey, location.bindings).preview;
|
|
722
|
+
} finally {
|
|
723
|
+
target.database.close();
|
|
724
|
+
}
|
|
725
|
+
} finally {
|
|
726
|
+
source.database.close();
|
|
727
|
+
}
|
|
728
|
+
}, "previewDocumentTransfer");
|
|
729
|
+
var applyDocumentTransfer = /* @__PURE__ */ __name(async (options) => {
|
|
730
|
+
if (!/^[a-f0-9]{64}$/.test(options.expected_fingerprint))
|
|
731
|
+
throw new CliError("validation_error", "apply requires the fingerprint returned by a transfer preview");
|
|
732
|
+
const location = locations(options);
|
|
733
|
+
const source = await openSource(location.source);
|
|
734
|
+
try {
|
|
735
|
+
const snapshot = transferSnapshot(source.database, options.collection);
|
|
736
|
+
const check = await openPreviewTarget(location.destination);
|
|
737
|
+
try {
|
|
738
|
+
const preview = planTransfer(check.database, snapshot, location.sourceKey, location.bindings).preview;
|
|
739
|
+
if (preview.fingerprint !== options.expected_fingerprint)
|
|
740
|
+
throw new CliError("validation_error", "the transfer preview changed; preview it again before applying");
|
|
741
|
+
if (!preview.ready)
|
|
742
|
+
throw new CliError("configuration_error", "the transfer has unresolved references or conflicts; preview it before applying");
|
|
743
|
+
} finally {
|
|
744
|
+
check.database.close();
|
|
745
|
+
}
|
|
746
|
+
const target = await openStoreContext({ path: location.destination, env: options.env });
|
|
747
|
+
try {
|
|
748
|
+
const receipt = applyTransfer(target.database, snapshot, location.sourceKey, location.bindings, options.expected_fingerprint, target.now);
|
|
749
|
+
if (digest(transferSnapshot(source.database, options.collection)) !== digest(snapshot))
|
|
750
|
+
throw new CliError("configuration_error", "source annotations changed during the transfer; the source and copied snapshot were retained, keep the original store selected");
|
|
751
|
+
return receipt;
|
|
752
|
+
} finally {
|
|
753
|
+
target.database.close();
|
|
754
|
+
}
|
|
755
|
+
} finally {
|
|
756
|
+
source.database.close();
|
|
757
|
+
}
|
|
758
|
+
}, "applyDocumentTransfer");
|
|
759
|
+
|
|
760
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/knowledge-query.js
|
|
761
|
+
var ORGANIZATIONS_QUERY = {
|
|
762
|
+
entity: "organization",
|
|
763
|
+
backend: "sql",
|
|
764
|
+
fields: queryFieldsOf(organization, {
|
|
765
|
+
native: ["id", "kind", "scope", "created_at"],
|
|
766
|
+
examples: { id: "id:1", kind: "kind:company", scope: "scope:work", created_at: "created_at>=2026-01-01" }
|
|
767
|
+
})
|
|
768
|
+
};
|
|
769
|
+
var PROJECTS_QUERY = {
|
|
770
|
+
entity: "project",
|
|
771
|
+
backend: "sql",
|
|
772
|
+
fields: queryFieldsOf(project, {
|
|
773
|
+
native: ["id", "key", "type", "organization_id", "scope", "created_at"],
|
|
774
|
+
examples: {
|
|
775
|
+
id: "id:1",
|
|
776
|
+
key: "key:SMP",
|
|
777
|
+
type: "type:work",
|
|
778
|
+
organization_id: "organization_id:1",
|
|
779
|
+
scope: "scope:work",
|
|
780
|
+
created_at: "created_at>=2026-01-01"
|
|
781
|
+
}
|
|
782
|
+
})
|
|
783
|
+
};
|
|
784
|
+
var REMINDERS_QUERY = {
|
|
785
|
+
entity: "reminder",
|
|
786
|
+
backend: "sql",
|
|
787
|
+
fields: queryFieldsOf(reminder, {
|
|
788
|
+
native: ["id", "state", "due_at", "revision"],
|
|
789
|
+
examples: { id: "id:1", state: "state:pending", due_at: "due_at>=2026-01-01", revision: "revision>1" }
|
|
790
|
+
})
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/project-transfer/preview.js
|
|
794
|
+
var previewProjectAnnotationSnapshot = /* @__PURE__ */ __name(async (options) => {
|
|
795
|
+
if (!options || typeof options !== "object" || Array.isArray(options))
|
|
796
|
+
throw new CliError("validation_error", "project preview options are required");
|
|
797
|
+
for (const field of Object.keys(options))
|
|
798
|
+
if (!["snapshot", "target", "project", "bindings", "maxReadBytes", "env"].includes(field))
|
|
799
|
+
throw new CliError("validation_error", `unknown project preview field ${field}`);
|
|
800
|
+
const snapshot = decodeProjectAnnotationSnapshot(options.snapshot);
|
|
801
|
+
projectAnnotationBindingSources(snapshot, options.bindings);
|
|
802
|
+
if (typeof options.target !== "string" || !options.target.trim() || options.target.length > 4096)
|
|
803
|
+
throw new CliError("validation_error", "project preview target is an explicit existing store path");
|
|
804
|
+
if (typeof options.project !== "string" || !/^project:[1-9]\d*$/.test(options.project) || !Number.isSafeInteger(Number(options.project.slice(8))))
|
|
805
|
+
throw new CliError("validation_error", "project preview project is a project:<safe integer id> reference");
|
|
806
|
+
const budget = new SnapshotBudget(options.maxReadBytes ?? 4 * 1024 * 1024);
|
|
807
|
+
const context = await openStoreContext({ path: options.target, env: options.env, readOnly: true });
|
|
808
|
+
try {
|
|
809
|
+
return previewAnnotationSnapshot(context.database, Number(options.project.slice(8)), snapshot, options.bindings, budget);
|
|
810
|
+
} finally {
|
|
811
|
+
context.database.close();
|
|
812
|
+
}
|
|
813
|
+
}, "previewProjectAnnotationSnapshot");
|
|
814
|
+
|
|
815
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.469.0_@wirecat+cli-base@0.65.0_commander@15.0.0_typescript@7.0.2_vi_80b586dbc8b099637a6e461856c2ee6b/node_modules/@wirecat/cli-core/dist/store/project-transfer/snapshot.js
|
|
816
|
+
var snapshotProjectAnnotations = /* @__PURE__ */ __name(async (options) => {
|
|
817
|
+
if (!options || typeof options !== "object" || Array.isArray(options))
|
|
818
|
+
throw new CliError("validation_error", "snapshot options are required");
|
|
819
|
+
for (const field of Object.keys(options))
|
|
820
|
+
if (!["source", "project", "env", "maxReadBytes"].includes(field))
|
|
821
|
+
throw new CliError("validation_error", `unknown snapshot field ${field}`);
|
|
822
|
+
if (typeof options.source !== "string" || !options.source.trim() || options.source.length > 4096)
|
|
823
|
+
throw new CliError("validation_error", "snapshot source is an explicit existing store path");
|
|
824
|
+
if (typeof options.project !== "string" || !/^project:[1-9]\d*$/.test(options.project) || !Number.isSafeInteger(Number(options.project.slice(8))))
|
|
825
|
+
throw new CliError("validation_error", "snapshot project is a project:<safe integer id> reference");
|
|
826
|
+
const budget = new SnapshotBudget(options.maxReadBytes ?? 4 * 1024 * 1024);
|
|
827
|
+
const context = await openStoreContext({ path: options.source, env: options.env, readOnly: true });
|
|
828
|
+
try {
|
|
829
|
+
const result = projectAnnotationSnapshot(context.database, Number(options.project.slice(8)), budget);
|
|
830
|
+
return { ...result, fingerprint: projectAnnotationSnapshotFingerprint(JSON.stringify(result.snapshot)) };
|
|
831
|
+
} finally {
|
|
832
|
+
context.database.close();
|
|
833
|
+
}
|
|
834
|
+
}, "snapshotProjectAnnotations");
|
|
835
|
+
|
|
836
|
+
export {
|
|
837
|
+
previewDocumentTransfer,
|
|
838
|
+
applyDocumentTransfer,
|
|
839
|
+
ORGANIZATIONS_QUERY,
|
|
840
|
+
PROJECTS_QUERY,
|
|
841
|
+
REMINDERS_QUERY,
|
|
842
|
+
previewProjectAnnotationSnapshot,
|
|
843
|
+
snapshotProjectAnnotations
|
|
844
|
+
};
|