@x12i/catalox 3.0.0 → 3.2.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 +43 -6
- package/dist/src/catalox/authorization.js +1 -1
- package/dist/src/catalox/authorization.js.map +1 -1
- package/dist/src/catalox/backup-data.d.ts +0 -6
- package/dist/src/catalox/backup-data.d.ts.map +1 -1
- package/dist/src/catalox/backup-data.js +2 -413
- package/dist/src/catalox/backup-data.js.map +1 -1
- package/dist/src/catalox/catalog-lifecycle.d.ts +29 -0
- package/dist/src/catalox/catalog-lifecycle.d.ts.map +1 -0
- package/dist/src/catalox/catalog-lifecycle.js +480 -0
- package/dist/src/catalox/catalog-lifecycle.js.map +1 -0
- package/dist/src/catalox/catalox-bound.d.ts +21 -6
- package/dist/src/catalox/catalox-bound.d.ts.map +1 -1
- package/dist/src/catalox/catalox-bound.js +30 -9
- package/dist/src/catalox/catalox-bound.js.map +1 -1
- package/dist/src/catalox/catalox.d.ts +31 -11
- package/dist/src/catalox/catalox.d.ts.map +1 -1
- package/dist/src/catalox/catalox.js +485 -82
- package/dist/src/catalox/catalox.js.map +1 -1
- package/dist/src/catalox/context.js +2 -2
- package/dist/src/catalox/context.js.map +1 -1
- package/dist/src/catalox/create-catalox.d.ts +6 -0
- package/dist/src/catalox/create-catalox.d.ts.map +1 -1
- package/dist/src/catalox/create-catalox.js +25 -0
- package/dist/src/catalox/create-catalox.js.map +1 -1
- package/dist/src/catalox/index.d.ts +4 -2
- package/dist/src/catalox/index.d.ts.map +1 -1
- package/dist/src/catalox/index.js +4 -2
- package/dist/src/catalox/index.js.map +1 -1
- package/dist/src/catalox/native-catalog-merge.d.ts +12 -0
- package/dist/src/catalox/native-catalog-merge.d.ts.map +1 -0
- package/dist/src/catalox/native-catalog-merge.js +102 -0
- package/dist/src/catalox/native-catalog-merge.js.map +1 -0
- package/dist/src/catalox/native-scope.d.ts +28 -0
- package/dist/src/catalox/native-scope.d.ts.map +1 -0
- package/dist/src/catalox/native-scope.js +184 -0
- package/dist/src/catalox/native-scope.js.map +1 -0
- package/dist/src/catalox/record-history.d.ts +53 -0
- package/dist/src/catalox/record-history.d.ts.map +1 -0
- package/dist/src/catalox/record-history.js +158 -0
- package/dist/src/catalox/record-history.js.map +1 -0
- package/dist/src/catalox/restore-firestore-backup.d.ts +6 -3
- package/dist/src/catalox/restore-firestore-backup.d.ts.map +1 -1
- package/dist/src/catalox/restore-firestore-backup.js +3 -224
- package/dist/src/catalox/restore-firestore-backup.js.map +1 -1
- package/dist/src/cli/index.js +159 -55
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/contracts/apps.d.ts +2 -0
- package/dist/src/contracts/apps.d.ts.map +1 -1
- package/dist/src/contracts/backup.d.ts +2 -2
- package/dist/src/contracts/backup.d.ts.map +1 -1
- package/dist/src/contracts/catalog-lifecycle.d.ts +70 -0
- package/dist/src/contracts/catalog-lifecycle.d.ts.map +1 -0
- package/dist/src/contracts/catalog-lifecycle.js +2 -0
- package/dist/src/contracts/catalog-lifecycle.js.map +1 -0
- package/dist/src/contracts/catalogs.d.ts +37 -0
- package/dist/src/contracts/catalogs.d.ts.map +1 -1
- package/dist/src/contracts/catalogs.js.map +1 -1
- package/dist/src/contracts/context.d.ts +5 -1
- package/dist/src/contracts/context.d.ts.map +1 -1
- package/dist/src/contracts/descriptors.d.ts +6 -0
- package/dist/src/contracts/descriptors.d.ts.map +1 -1
- package/dist/src/contracts/index.d.ts +6 -3
- package/dist/src/contracts/index.d.ts.map +1 -1
- package/dist/src/contracts/index.js.map +1 -1
- package/dist/src/contracts/items.d.ts +19 -0
- package/dist/src/contracts/items.d.ts.map +1 -1
- package/dist/src/contracts/record-history.d.ts +66 -0
- package/dist/src/contracts/record-history.d.ts.map +1 -0
- package/dist/src/contracts/record-history.js +2 -0
- package/dist/src/contracts/record-history.js.map +1 -0
- package/dist/src/contracts/restore.d.ts +0 -39
- package/dist/src/contracts/restore.d.ts.map +1 -1
- package/dist/src/firebase/adapter-store.d.ts +1 -0
- package/dist/src/firebase/adapter-store.d.ts.map +1 -1
- package/dist/src/firebase/adapter-store.js +3 -0
- package/dist/src/firebase/adapter-store.js.map +1 -1
- package/dist/src/firebase/binding-store.d.ts +2 -0
- package/dist/src/firebase/binding-store.d.ts.map +1 -1
- package/dist/src/firebase/binding-store.js +10 -0
- package/dist/src/firebase/binding-store.js.map +1 -1
- package/dist/src/firebase/catalog-data-index-store.d.ts +1 -0
- package/dist/src/firebase/catalog-data-index-store.d.ts.map +1 -1
- package/dist/src/firebase/catalog-data-index-store.js +3 -0
- package/dist/src/firebase/catalog-data-index-store.js.map +1 -1
- package/dist/src/firebase/catalog-item-history-store.d.ts +21 -0
- package/dist/src/firebase/catalog-item-history-store.d.ts.map +1 -0
- package/dist/src/firebase/catalog-item-history-store.js +61 -0
- package/dist/src/firebase/catalog-item-history-store.js.map +1 -0
- package/dist/src/firebase/catalog-store.d.ts +1 -0
- package/dist/src/firebase/catalog-store.d.ts.map +1 -1
- package/dist/src/firebase/catalog-store.js +3 -0
- package/dist/src/firebase/catalog-store.js.map +1 -1
- package/dist/src/firebase/index.d.ts +1 -0
- package/dist/src/firebase/index.d.ts.map +1 -1
- package/dist/src/firebase/index.js +1 -0
- package/dist/src/firebase/index.js.map +1 -1
- package/dist/src/firebase/mapping-store.d.ts +1 -0
- package/dist/src/firebase/mapping-store.d.ts.map +1 -1
- package/dist/src/firebase/mapping-store.js +3 -0
- package/dist/src/firebase/mapping-store.js.map +1 -1
- package/dist/src/firebase/native-item-store.d.ts +8 -2
- package/dist/src/firebase/native-item-store.d.ts.map +1 -1
- package/dist/src/firebase/native-item-store.js +22 -6
- package/dist/src/firebase/native-item-store.js.map +1 -1
- package/dist/src/firebase/reference-store.d.ts +3 -0
- package/dist/src/firebase/reference-store.d.ts.map +1 -1
- package/dist/src/firebase/reference-store.js +16 -0
- package/dist/src/firebase/reference-store.js.map +1 -1
- package/dist/src/firebase/renderer-snippet-store.d.ts +3 -0
- package/dist/src/firebase/renderer-snippet-store.d.ts.map +1 -1
- package/dist/src/firebase/renderer-snippet-store.js +17 -0
- package/dist/src/firebase/renderer-snippet-store.js.map +1 -1
- package/dist/src/firebase/snapshot-store.d.ts +1 -0
- package/dist/src/firebase/snapshot-store.d.ts.map +1 -1
- package/dist/src/firebase/snapshot-store.js +8 -0
- package/dist/src/firebase/snapshot-store.js.map +1 -1
- package/dist/test/integration/backup-data-gcs.live.test.d.ts +2 -0
- package/dist/test/integration/backup-data-gcs.live.test.d.ts.map +1 -0
- package/dist/test/integration/backup-data-gcs.live.test.js +98 -0
- package/dist/test/integration/backup-data-gcs.live.test.js.map +1 -0
- package/dist/test/integration/firestore.emulator.test.js +25 -4
- package/dist/test/integration/firestore.emulator.test.js.map +1 -1
- package/dist/test/integration/record-history.live.test.d.ts +2 -0
- package/dist/test/integration/record-history.live.test.d.ts.map +1 -0
- package/dist/test/integration/record-history.live.test.js +141 -0
- package/dist/test/integration/record-history.live.test.js.map +1 -0
- package/dist/test/unit/native-catalog-merge.test.d.ts +2 -0
- package/dist/test/unit/native-catalog-merge.test.d.ts.map +1 -0
- package/dist/test/unit/native-catalog-merge.test.js +33 -0
- package/dist/test/unit/native-catalog-merge.test.js.map +1 -0
- package/dist/test/unit/native-scope.test.d.ts +2 -0
- package/dist/test/unit/native-scope.test.d.ts.map +1 -0
- package/dist/test/unit/native-scope.test.js +29 -0
- package/dist/test/unit/native-scope.test.js.map +1 -0
- package/dist/test/unit/record-history-path.test.d.ts +2 -0
- package/dist/test/unit/record-history-path.test.d.ts.map +1 -0
- package/dist/test/unit/record-history-path.test.js +24 -0
- package/dist/test/unit/record-history-path.test.js.map +1 -0
- package/firestore.indexes.json +39 -0
- package/package.json +3 -2
|
@@ -1,66 +1,13 @@
|
|
|
1
|
-
import { BACKUP_METADATA_SOURCE_NAMES, deleteAllDocsInFirestoreCollection,
|
|
1
|
+
import { BACKUP_METADATA_SOURCE_NAMES, deleteAllDocsInFirestoreCollection, firebaseNativeLogical, firebaseSnapshotLogical, firebaseSnapshotRunLogical, paginatedCopyFirestoreToFirestore, } from "./backup-data.js";
|
|
2
2
|
import { NativeItemStore } from "../firebase/native-item-store.js";
|
|
3
3
|
import { DefinitionStore } from "../firebase/definition-store.js";
|
|
4
4
|
import { CatalogDataIndexStore } from "../firebase/catalog-data-index-store.js";
|
|
5
|
-
import { legacyNativeItemsCollectionRef,
|
|
6
|
-
import { fixNativeCatalogDataMetadata } from "../migrations/migrate-native-catalog-layout.js";
|
|
5
|
+
import { legacyNativeItemsCollectionRef, nativeItemsCollectionId, } from "../firebase/catalog-data-paths.js";
|
|
7
6
|
export const RESTORE_FIRESTORE_BACKUP_SESSION_COLLECTION = "backup-restoreSessions";
|
|
8
7
|
const RESTORE_MANIFEST_COLLECTION = RESTORE_FIRESTORE_BACKUP_SESSION_COLLECTION;
|
|
9
|
-
function sourceBackupCollectionId(source, logical) {
|
|
10
|
-
if (source.kind === "latest")
|
|
11
|
-
return firebaseLatestName(logical);
|
|
12
|
-
return firebaseVersionedName(source.versionTimestamp, logical);
|
|
13
|
-
}
|
|
14
8
|
function preRestoreCollectionId(restoreSessionId, logical) {
|
|
15
9
|
return `${restoreSessionId}__preRestore-${logical}`;
|
|
16
10
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Discover snapshot backup mirrors by scanning top-level collection ids.
|
|
19
|
-
* Parses `catalogSnapshotsRun--{catalogId}--{runId}` with the last `--` as delimiter (catalogId / runId must not contain `--`).
|
|
20
|
-
*/
|
|
21
|
-
async function listSnapshotRestoreWork(fs, source, includeSnapshots) {
|
|
22
|
-
if (!includeSnapshots)
|
|
23
|
-
return { snapshotCatalogIds: [], snapshotRuns: [] };
|
|
24
|
-
const cols = await fs.listCollections();
|
|
25
|
-
const itemPrefix = source.kind === "latest" ? "backup-catalogSnapshots--" : `${source.versionTimestamp}__backup-catalogSnapshots--`;
|
|
26
|
-
const runPrefix = source.kind === "latest"
|
|
27
|
-
? "backup-catalogSnapshotsRun--"
|
|
28
|
-
: `${source.versionTimestamp}__backup-catalogSnapshotsRun--`;
|
|
29
|
-
const snapshotCatalogIds = new Set();
|
|
30
|
-
const snapshotRuns = [];
|
|
31
|
-
for (const c of cols) {
|
|
32
|
-
const id = c.id;
|
|
33
|
-
if (!id.startsWith(itemPrefix) || id.includes("catalogSnapshotsRun"))
|
|
34
|
-
continue;
|
|
35
|
-
const catalogId = id.slice(itemPrefix.length);
|
|
36
|
-
if (!catalogId)
|
|
37
|
-
continue;
|
|
38
|
-
const probe = await fs.collection(id).limit(1).get();
|
|
39
|
-
if (!probe.empty)
|
|
40
|
-
snapshotCatalogIds.add(catalogId);
|
|
41
|
-
}
|
|
42
|
-
const runSeen = new Set();
|
|
43
|
-
for (const c of cols) {
|
|
44
|
-
const id = c.id;
|
|
45
|
-
if (!id.startsWith(runPrefix))
|
|
46
|
-
continue;
|
|
47
|
-
const rest = id.slice(runPrefix.length);
|
|
48
|
-
const delim = rest.lastIndexOf("--");
|
|
49
|
-
if (delim === -1)
|
|
50
|
-
continue;
|
|
51
|
-
const catalogId = rest.slice(0, delim);
|
|
52
|
-
const runId = rest.slice(delim + 2);
|
|
53
|
-
const probe = await fs.collection(id).limit(1).get();
|
|
54
|
-
if (probe.empty)
|
|
55
|
-
continue;
|
|
56
|
-
const rk = `${catalogId}\0${runId}`;
|
|
57
|
-
if (runSeen.has(rk))
|
|
58
|
-
continue;
|
|
59
|
-
runSeen.add(rk);
|
|
60
|
-
snapshotRuns.push({ catalogId, runId });
|
|
61
|
-
}
|
|
62
|
-
return { snapshotCatalogIds: [...snapshotCatalogIds], snapshotRuns };
|
|
63
|
-
}
|
|
64
11
|
async function writeManifest(fs, manifest) {
|
|
65
12
|
await fs.collection(RESTORE_MANIFEST_COLLECTION).doc(manifest.restoreSessionId).set(manifest, { merge: true });
|
|
66
13
|
}
|
|
@@ -70,175 +17,7 @@ async function readManifest(fs, restoreSessionId) {
|
|
|
70
17
|
return null;
|
|
71
18
|
return snap.data();
|
|
72
19
|
}
|
|
73
|
-
|
|
74
|
-
const issues = [];
|
|
75
|
-
const counts = {};
|
|
76
|
-
const nativeItemSourceLayoutByCatalogId = {};
|
|
77
|
-
if (input.source.kind === "versioned" && !input.source.versionTimestamp?.trim()) {
|
|
78
|
-
return {
|
|
79
|
-
ok: false,
|
|
80
|
-
restoreSessionId: "",
|
|
81
|
-
counts: {},
|
|
82
|
-
issues: [{ code: "missing_version_timestamp", message: "versioned restore requires versionTimestamp" }],
|
|
83
|
-
nativeItemSourceLayoutByCatalogId: {},
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const fs = deps.firestoreStore.firestore;
|
|
87
|
-
const restoreSessionId = (input.restoreSessionId?.trim() && input.restoreSessionId) || formatBackupTimestamp();
|
|
88
|
-
const includeSnapshots = Boolean(input.includeSnapshots);
|
|
89
|
-
const allCatalogs = await deps.catalogs.listAll();
|
|
90
|
-
const nativeCatalogIds = await discoverNativeCatalogIds(fs, allCatalogs, {
|
|
91
|
-
bindings: deps.bindings,
|
|
92
|
-
...(input.catalogIds != null && input.catalogIds.length ? { catalogIds: input.catalogIds } : {}),
|
|
93
|
-
...(input.appId != null && input.appId !== "" ? { appId: input.appId } : {}),
|
|
94
|
-
});
|
|
95
|
-
const probeLogical = BACKUP_METADATA_SOURCE_NAMES[0];
|
|
96
|
-
const probeId = sourceBackupCollectionId(input.source, probeLogical);
|
|
97
|
-
const probeSnap = await fs.collection(probeId).limit(1).get();
|
|
98
|
-
if (probeSnap.empty) {
|
|
99
|
-
return {
|
|
100
|
-
ok: false,
|
|
101
|
-
restoreSessionId,
|
|
102
|
-
counts,
|
|
103
|
-
issues: [
|
|
104
|
-
{
|
|
105
|
-
code: "backup_source_empty",
|
|
106
|
-
message: `No documents in backup collection ${probeId}; nothing to restore from this source`,
|
|
107
|
-
detail: { probeId },
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
nativeItemSourceLayoutByCatalogId: {},
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
const { snapshotCatalogIds, snapshotRuns } = await listSnapshotRestoreWork(fs, input.source, includeSnapshots);
|
|
114
|
-
try {
|
|
115
|
-
for (const name of BACKUP_METADATA_SOURCE_NAMES) {
|
|
116
|
-
const destPre = preRestoreCollectionId(restoreSessionId, name);
|
|
117
|
-
await deleteAllDocsInFirestoreCollection(fs, destPre);
|
|
118
|
-
await paginatedCopyFirestoreToFirestore(fs, name, destPre, counts, `pre:${destPre}`);
|
|
119
|
-
}
|
|
120
|
-
for (const catalogId of nativeCatalogIds) {
|
|
121
|
-
const layout = await resolveNativeItemsLayout(fs, catalogId);
|
|
122
|
-
nativeItemSourceLayoutByCatalogId[String(catalogId)] = layout;
|
|
123
|
-
const logical = firebaseNativeLogical(String(catalogId));
|
|
124
|
-
const destPre = preRestoreCollectionId(restoreSessionId, logical);
|
|
125
|
-
await deleteAllDocsInFirestoreCollection(fs, destPre);
|
|
126
|
-
const livePath = layout === "legacy"
|
|
127
|
-
? legacyNativeItemsCollectionRef(fs, catalogId).path
|
|
128
|
-
: fs.collection(nativeItemsCollectionId(String(catalogId))).path;
|
|
129
|
-
await paginatedCopyFirestoreToFirestore(fs, livePath, destPre, counts, `pre:${destPre}`);
|
|
130
|
-
}
|
|
131
|
-
if (includeSnapshots) {
|
|
132
|
-
for (const catalogId of snapshotCatalogIds) {
|
|
133
|
-
const logical = firebaseSnapshotLogical(catalogId);
|
|
134
|
-
const destPre = preRestoreCollectionId(restoreSessionId, logical);
|
|
135
|
-
await deleteAllDocsInFirestoreCollection(fs, destPre);
|
|
136
|
-
const liveItems = fs.collection("catalogSnapshots").doc(catalogId).collection("items").path;
|
|
137
|
-
await paginatedCopyFirestoreToFirestore(fs, liveItems, destPre, counts, `pre:${destPre}`);
|
|
138
|
-
}
|
|
139
|
-
for (const { catalogId, runId } of snapshotRuns) {
|
|
140
|
-
const logical = firebaseSnapshotRunLogical(catalogId, runId);
|
|
141
|
-
const destPre = preRestoreCollectionId(restoreSessionId, logical);
|
|
142
|
-
await deleteAllDocsInFirestoreCollection(fs, destPre);
|
|
143
|
-
const livePath = fs.collection("catalogSnapshots").doc(catalogId).collection("runs").doc(runId).collection("items")
|
|
144
|
-
.path;
|
|
145
|
-
await paginatedCopyFirestoreToFirestore(fs, livePath, destPre, counts, `pre:${destPre}`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const manifest = {
|
|
149
|
-
restoreSessionId,
|
|
150
|
-
createdAt: new Date().toISOString(),
|
|
151
|
-
source: input.source,
|
|
152
|
-
includeSnapshots,
|
|
153
|
-
phase: "preRestoreCaptured",
|
|
154
|
-
nativeCatalogIds: nativeCatalogIds.map(String),
|
|
155
|
-
nativeItemSourceLayoutByCatalogId: { ...nativeItemSourceLayoutByCatalogId },
|
|
156
|
-
metadataSourceNames: BACKUP_METADATA_SOURCE_NAMES,
|
|
157
|
-
snapshotCatalogIds,
|
|
158
|
-
snapshotRuns,
|
|
159
|
-
};
|
|
160
|
-
await writeManifest(fs, manifest);
|
|
161
|
-
for (const name of BACKUP_METADATA_SOURCE_NAMES) {
|
|
162
|
-
const src = sourceBackupCollectionId(input.source, name);
|
|
163
|
-
await deleteAllDocsInFirestoreCollection(fs, name);
|
|
164
|
-
await paginatedCopyFirestoreToFirestore(fs, src, name, counts, `restore:${name}`);
|
|
165
|
-
}
|
|
166
|
-
for (const catalogId of nativeCatalogIds) {
|
|
167
|
-
const cid = String(catalogId);
|
|
168
|
-
const flatPath = nativeItemsCollectionId(cid);
|
|
169
|
-
await deleteAllDocsInFirestoreCollection(fs, flatPath);
|
|
170
|
-
const src = sourceBackupCollectionId(input.source, firebaseNativeLogical(cid));
|
|
171
|
-
await paginatedCopyFirestoreToFirestore(fs, src, flatPath, counts, `restore:nativeFlat:${cid}`);
|
|
172
|
-
const legacyPath = legacyNativeItemsCollectionRef(fs, catalogId).path;
|
|
173
|
-
await deleteAllDocsInFirestoreCollection(fs, legacyPath);
|
|
174
|
-
}
|
|
175
|
-
const nowIso = new Date().toISOString();
|
|
176
|
-
if (nativeCatalogIds.length > 0) {
|
|
177
|
-
await fixNativeCatalogDataMetadata({
|
|
178
|
-
definitions: deps.definitions,
|
|
179
|
-
catalogDataIndex: deps.catalogDataIndex,
|
|
180
|
-
nativeItems: deps.nativeItems,
|
|
181
|
-
}, nativeCatalogIds, nowIso);
|
|
182
|
-
}
|
|
183
|
-
if (includeSnapshots) {
|
|
184
|
-
for (const catalogId of snapshotCatalogIds) {
|
|
185
|
-
const dest = fs.collection("catalogSnapshots").doc(catalogId).collection("items").path;
|
|
186
|
-
const src = sourceBackupCollectionId(input.source, firebaseSnapshotLogical(catalogId));
|
|
187
|
-
await deleteAllDocsInFirestoreCollection(fs, dest);
|
|
188
|
-
await paginatedCopyFirestoreToFirestore(fs, src, dest, counts, `restore:snap:${catalogId}`);
|
|
189
|
-
}
|
|
190
|
-
for (const { catalogId, runId } of snapshotRuns) {
|
|
191
|
-
const dest = fs
|
|
192
|
-
.collection("catalogSnapshots")
|
|
193
|
-
.doc(catalogId)
|
|
194
|
-
.collection("runs")
|
|
195
|
-
.doc(runId)
|
|
196
|
-
.collection("items").path;
|
|
197
|
-
const src = sourceBackupCollectionId(input.source, firebaseSnapshotRunLogical(catalogId, runId));
|
|
198
|
-
await deleteAllDocsInFirestoreCollection(fs, dest);
|
|
199
|
-
await paginatedCopyFirestoreToFirestore(fs, src, dest, counts, `restore:snaprun:${catalogId}:${runId}`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
await writeManifest(fs, { ...manifest, phase: "restored" });
|
|
203
|
-
deps.nativeItems.invalidateLayoutCache();
|
|
204
|
-
return {
|
|
205
|
-
ok: true,
|
|
206
|
-
restoreSessionId,
|
|
207
|
-
counts,
|
|
208
|
-
issues,
|
|
209
|
-
nativeItemSourceLayoutByCatalogId,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
catch (e) {
|
|
213
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
214
|
-
issues.push({ code: "restore_failed", message: msg });
|
|
215
|
-
try {
|
|
216
|
-
await writeManifest(fs, {
|
|
217
|
-
restoreSessionId,
|
|
218
|
-
createdAt: new Date().toISOString(),
|
|
219
|
-
source: input.source,
|
|
220
|
-
includeSnapshots,
|
|
221
|
-
phase: "failed",
|
|
222
|
-
nativeCatalogIds: nativeCatalogIds.map(String),
|
|
223
|
-
nativeItemSourceLayoutByCatalogId: { ...nativeItemSourceLayoutByCatalogId },
|
|
224
|
-
metadataSourceNames: BACKUP_METADATA_SOURCE_NAMES,
|
|
225
|
-
snapshotCatalogIds,
|
|
226
|
-
snapshotRuns,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
catch {
|
|
230
|
-
// ignore manifest write errors during failure handling
|
|
231
|
-
}
|
|
232
|
-
deps.nativeItems.invalidateLayoutCache();
|
|
233
|
-
return {
|
|
234
|
-
ok: false,
|
|
235
|
-
restoreSessionId,
|
|
236
|
-
counts,
|
|
237
|
-
issues,
|
|
238
|
-
nativeItemSourceLayoutByCatalogId,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
}
|
|
20
|
+
// Firestore mirror restore (backup-* / {ts}__backup-*) removed; backups are storage-only (GCS).
|
|
242
21
|
export async function runUndoFirestoreRestore(deps, input) {
|
|
243
22
|
const issues = [];
|
|
244
23
|
const counts = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore-firestore-backup.js","sourceRoot":"","sources":["../../../src/catalox/restore-firestore-backup.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"restore-firestore-backup.js","sourceRoot":"","sources":["../../../src/catalox/restore-firestore-backup.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli/index.js
CHANGED
|
@@ -49,7 +49,7 @@ function baseContext(opts) {
|
|
|
49
49
|
return {
|
|
50
50
|
appId,
|
|
51
51
|
...(storeId ? { storeId } : {}),
|
|
52
|
-
...(opts.god ? {
|
|
52
|
+
...(opts.god ? { superAdmin: true } : {}),
|
|
53
53
|
...(userId ? { userId, actor: { type: "user", id: userId } } : {}),
|
|
54
54
|
};
|
|
55
55
|
}
|
|
@@ -267,25 +267,21 @@ storeCmd
|
|
|
267
267
|
});
|
|
268
268
|
const firestoreCmd = program
|
|
269
269
|
.command("firestore")
|
|
270
|
-
.description("Firestore backup
|
|
270
|
+
.description("Firestore backup (GCS), restore-from-GCS, and native layout migration");
|
|
271
271
|
firestoreCmd
|
|
272
272
|
.command("backup")
|
|
273
|
-
.description("
|
|
273
|
+
.description("Catalox backup to GCS only (NDJSON + catalox-backup-manifest.json)")
|
|
274
274
|
.requiredOption("--app <appId>", "AppId for Catalox context")
|
|
275
|
-
.requiredOption("--
|
|
276
|
-
.option("--mongo-uri <uri>", "Mongo connection string (required when mode=mongo)")
|
|
277
|
-
.option("--bucket <name>", "GCS bucket name (required when mode=gcs)")
|
|
275
|
+
.requiredOption("--bucket <name>", "GCS bucket name")
|
|
278
276
|
.option("--gcs-prefix <path>", "Optional prefix before timestamp folder (default: catalox-firestore-backups/)", "")
|
|
279
277
|
.option("--label <text>", "Backup label stored on manifest")
|
|
280
278
|
.option("--snapshots", "Include catalogSnapshots data", false)
|
|
281
279
|
.option("--catalog <catalogId...>", "Restrict which native catalogs are copied")
|
|
282
280
|
.option("--god", "God mode", false)
|
|
283
281
|
.action(async (opts) => {
|
|
284
|
-
|
|
285
|
-
const mode = m === "mongo" ? "mongo" : m === "gcs" ? "gcs" : "firebase";
|
|
286
|
-
if (mode === "gcs" && !(opts.bucket != null && String(opts.bucket).trim())) {
|
|
282
|
+
if (!(opts.bucket != null && String(opts.bucket).trim())) {
|
|
287
283
|
// eslint-disable-next-line no-console
|
|
288
|
-
console.error("--bucket is required
|
|
284
|
+
console.error("--bucket is required");
|
|
289
285
|
process.exitCode = 1;
|
|
290
286
|
return;
|
|
291
287
|
}
|
|
@@ -293,14 +289,9 @@ firestoreCmd
|
|
|
293
289
|
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
294
290
|
const gcsPrefixOpt = opts.gcsPrefix != null && String(opts.gcsPrefix).trim() ? String(opts.gcsPrefix).trim() : undefined;
|
|
295
291
|
const res = await catalox.backupData(ctx, {
|
|
296
|
-
mode,
|
|
297
|
-
|
|
298
|
-
...(
|
|
299
|
-
? {
|
|
300
|
-
gcsBucket: String(opts.bucket).trim(),
|
|
301
|
-
...(gcsPrefixOpt !== undefined ? { gcsPrefix: gcsPrefixOpt } : {}),
|
|
302
|
-
}
|
|
303
|
-
: {}),
|
|
292
|
+
mode: "gcs",
|
|
293
|
+
gcsBucket: String(opts.bucket).trim(),
|
|
294
|
+
...(gcsPrefixOpt !== undefined ? { gcsPrefix: gcsPrefixOpt } : {}),
|
|
304
295
|
includeSnapshots: Boolean(opts.snapshots),
|
|
305
296
|
...(opts.catalog?.length ? { catalogIds: opts.catalog } : {}),
|
|
306
297
|
...(opts.label != null && String(opts.label) !== "" ? { backupLabel: String(opts.label) } : {}),
|
|
@@ -309,42 +300,11 @@ firestoreCmd
|
|
|
309
300
|
if (!res.ok)
|
|
310
301
|
process.exitCode = 1;
|
|
311
302
|
});
|
|
312
|
-
firestoreCmd
|
|
313
|
-
.command("restore-backup")
|
|
314
|
-
.description("Restore live Firestore from backup-* (same DB). Captures pre-restore copies to {session}__preRestore-* for undo.")
|
|
315
|
-
.requiredOption("--app <appId>", "AppId for Catalox context")
|
|
316
|
-
.option("--from <latest|versioned>", "Backup source", "latest")
|
|
317
|
-
.option("--version-ts <token>", "When --from versioned: timestamp token matching backup collection prefix")
|
|
318
|
-
.option("--snapshots", "Also restore catalogSnapshots from backup mirrors", false)
|
|
319
|
-
.option("--catalog <catalogId...>", "Restrict which native catalogs are restored")
|
|
320
|
-
.option("--god", "God mode", false)
|
|
321
|
-
.action(async (opts) => {
|
|
322
|
-
const catalox = createCatalox();
|
|
323
|
-
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
324
|
-
const from = String(opts.from).toLowerCase();
|
|
325
|
-
const source = from === "versioned"
|
|
326
|
-
? { kind: "versioned", versionTimestamp: String(opts.versionTs ?? "") }
|
|
327
|
-
: { kind: "latest" };
|
|
328
|
-
if (from === "versioned" && !String(opts.versionTs ?? "").trim()) {
|
|
329
|
-
// eslint-disable-next-line no-console
|
|
330
|
-
console.error("--version-ts is required when --from versioned");
|
|
331
|
-
process.exitCode = 1;
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const res = await catalox.restoreFirestoreBackup(ctx, {
|
|
335
|
-
source,
|
|
336
|
-
includeSnapshots: Boolean(opts.snapshots),
|
|
337
|
-
...(opts.catalog?.length ? { catalogIds: opts.catalog } : {}),
|
|
338
|
-
});
|
|
339
|
-
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
340
|
-
if (!res.ok)
|
|
341
|
-
process.exitCode = 1;
|
|
342
|
-
});
|
|
343
303
|
firestoreCmd
|
|
344
304
|
.command("undo-restore-backup")
|
|
345
|
-
.description("Revert a prior restore-backup
|
|
305
|
+
.description("Revert a prior restore-backup-from-gcs using backup-restoreSessions/{sessionId} and preRestore collections")
|
|
346
306
|
.requiredOption("--app <appId>", "AppId for Catalox context")
|
|
347
|
-
.requiredOption("--session <restoreSessionId>", "restoreSessionId returned by restore-backup")
|
|
307
|
+
.requiredOption("--session <restoreSessionId>", "restoreSessionId returned by restore-backup-from-gcs")
|
|
348
308
|
.option("--god", "God mode", false)
|
|
349
309
|
.action(async (opts) => {
|
|
350
310
|
const catalox = createCatalox();
|
|
@@ -358,7 +318,7 @@ firestoreCmd
|
|
|
358
318
|
});
|
|
359
319
|
firestoreCmd
|
|
360
320
|
.command("restore-backup-from-gcs")
|
|
361
|
-
.description("Restore live Firestore from one backupData GCS run (NDJSON under --run-folder).
|
|
321
|
+
.description("Restore live Firestore from one backupData GCS run (NDJSON under --run-folder). Uses pre-restore sidecars so undo works.")
|
|
362
322
|
.requiredOption("--app <appId>", "AppId for Catalox context")
|
|
363
323
|
.requiredOption("--bucket <name>", "GCS bucket name")
|
|
364
324
|
.requiredOption("--run-folder <path>", "Run folder within bucket (e.g. catalox-firestore-backups/2026_04_18T12_00_00Z)")
|
|
@@ -457,9 +417,11 @@ firestoreCmd
|
|
|
457
417
|
});
|
|
458
418
|
firestoreCmd
|
|
459
419
|
.command("migrate-native-catalog-data")
|
|
460
|
-
.description("
|
|
420
|
+
.description("Optional pre-migrate backup to GCS, then copy legacy catalogData/{catalogId}/items → flat catalogData-{catalogId}-items")
|
|
461
421
|
.requiredOption("--app <appId>", "AppId for Catalox context")
|
|
462
|
-
.option("--skip-backup", "Skip
|
|
422
|
+
.option("--skip-backup", "Skip pre-migrate GCS backup", false)
|
|
423
|
+
.option("--backup-bucket <name>", "GCS bucket for pre-migrate backup (required unless --skip-backup)")
|
|
424
|
+
.option("--backup-prefix <path>", "Optional gcsPrefix for pre-migrate backupData")
|
|
463
425
|
.option("--backup-label <text>", "Label for pre-migrate backup", "pre-native-layout-migration")
|
|
464
426
|
.option("--snapshots", "Include snapshots in pre-migrate backup", false)
|
|
465
427
|
.option("--dry-run", "Count/copy simulation only for migrate", false)
|
|
@@ -474,8 +436,18 @@ firestoreCmd
|
|
|
474
436
|
const catalox = createCatalox();
|
|
475
437
|
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
476
438
|
if (!opts.skipBackup) {
|
|
439
|
+
if (!(opts.backupBucket != null && String(opts.backupBucket).trim())) {
|
|
440
|
+
// eslint-disable-next-line no-console
|
|
441
|
+
console.error("--backup-bucket is required unless --skip-backup");
|
|
442
|
+
process.exitCode = 1;
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
477
445
|
const b = await catalox.backupData(ctx, {
|
|
478
|
-
mode: "
|
|
446
|
+
mode: "gcs",
|
|
447
|
+
gcsBucket: String(opts.backupBucket).trim(),
|
|
448
|
+
...(opts.backupPrefix != null && String(opts.backupPrefix).trim() !== ""
|
|
449
|
+
? { gcsPrefix: String(opts.backupPrefix).trim() }
|
|
450
|
+
: {}),
|
|
479
451
|
backupLabel: String(opts.backupLabel != null ? opts.backupLabel : "pre-native-layout-migration"),
|
|
480
452
|
includeSnapshots: Boolean(opts.snapshots),
|
|
481
453
|
});
|
|
@@ -669,6 +641,138 @@ firestoreCmd
|
|
|
669
641
|
if (!res.ok)
|
|
670
642
|
process.exitCode = 1;
|
|
671
643
|
});
|
|
644
|
+
const historyCmd = program.command("history").description("Native item history (Firestore index + GCS payloads)");
|
|
645
|
+
historyCmd
|
|
646
|
+
.command("list")
|
|
647
|
+
.description("List catalogItemHistory rows for a catalog (newest first)")
|
|
648
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
649
|
+
.requiredOption("--catalog <catalogId>", "Catalog id")
|
|
650
|
+
.option("--item <itemId>", "Filter by logical item id")
|
|
651
|
+
.option("--op <op>", "Filter by op (update|delete|restore|catalog_delete_bulk|catalog_rename)")
|
|
652
|
+
.option("--since <iso>", "Client-side filter: ts >= since")
|
|
653
|
+
.option("--until <iso>", "Client-side filter: ts <= until")
|
|
654
|
+
.option("--limit <n>", "Page size", "50")
|
|
655
|
+
.option("--cursor <eventId>", "startAfterEventId for pagination")
|
|
656
|
+
.option("--god", "God mode", false)
|
|
657
|
+
.action(async (opts) => {
|
|
658
|
+
const catalox = createCatalox();
|
|
659
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
660
|
+
const limit = Math.max(1, Math.min(500, parseInt(String(opts.limit ?? "50"), 10) || 50));
|
|
661
|
+
const res = await catalox.listCatalogItemHistory(ctx, String(opts.catalog), {
|
|
662
|
+
...(opts.item ? { itemId: String(opts.item) } : {}),
|
|
663
|
+
...(opts.op ? { op: String(opts.op) } : {}),
|
|
664
|
+
...(opts.since ? { since: String(opts.since) } : {}),
|
|
665
|
+
...(opts.until ? { until: String(opts.until) } : {}),
|
|
666
|
+
limit,
|
|
667
|
+
...(opts.cursor ? { startAfterEventId: String(opts.cursor) } : {}),
|
|
668
|
+
});
|
|
669
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
670
|
+
});
|
|
671
|
+
historyCmd
|
|
672
|
+
.command("show")
|
|
673
|
+
.description("Load index row + GCS payload for one eventId")
|
|
674
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
675
|
+
.argument("<eventId>", "catalogItemHistory document id")
|
|
676
|
+
.option("--god", "God mode", false)
|
|
677
|
+
.action(async (eventId, opts) => {
|
|
678
|
+
const catalox = createCatalox();
|
|
679
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
680
|
+
const res = await catalox.getCatalogItemHistoryEvent(ctx, String(eventId));
|
|
681
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
682
|
+
if (!res)
|
|
683
|
+
process.exitCode = 1;
|
|
684
|
+
});
|
|
685
|
+
historyCmd
|
|
686
|
+
.command("restore")
|
|
687
|
+
.description("Restore a native row from a history event (before or after snapshot)")
|
|
688
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
689
|
+
.argument("<eventId>", "catalogItemHistory document id")
|
|
690
|
+
.option("--mode <before|after>", "Which snapshot to apply", "before")
|
|
691
|
+
.option("--god", "God mode", false)
|
|
692
|
+
.action(async (eventId, opts) => {
|
|
693
|
+
const catalox = createCatalox();
|
|
694
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
695
|
+
const mode = String(opts.mode ?? "before").toLowerCase() === "after" ? "after" : "before";
|
|
696
|
+
const res = await catalox.restoreCatalogItemFromHistory(ctx, String(eventId), { mode });
|
|
697
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
698
|
+
});
|
|
699
|
+
historyCmd
|
|
700
|
+
.command("replay")
|
|
701
|
+
.description("Replay history up to --as-of and diff-apply to live native items")
|
|
702
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
703
|
+
.requiredOption("--catalog <catalogId>", "Catalog id")
|
|
704
|
+
.requiredOption("--as-of <iso>", "Inclusive upper bound on event ts")
|
|
705
|
+
.option("--god", "God mode", false)
|
|
706
|
+
.action(async (opts) => {
|
|
707
|
+
const catalox = createCatalox();
|
|
708
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
709
|
+
const res = await catalox.replayCatalogToPointInTime(ctx, String(opts.catalog), { asOf: String(opts.asOf) });
|
|
710
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
711
|
+
});
|
|
712
|
+
const catalogCmd = program.command("catalog").description("Catalog lifecycle (delete / restore / hard rename)");
|
|
713
|
+
catalogCmd
|
|
714
|
+
.command("delete")
|
|
715
|
+
.description("Snapshot catalog to GCS, write delete manifest, then hard-delete Firestore rows (requires record history bucket)")
|
|
716
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
717
|
+
.requiredOption("--catalog <catalogId>", "Catalog id")
|
|
718
|
+
.option("--confirm", "Must pass --confirm to run", false)
|
|
719
|
+
.option("--backup-bucket <name>", "Optional: run backupData mode=gcs to this bucket before delete")
|
|
720
|
+
.option("--backup-prefix <path>", "Optional gcsPrefix for pre-delete backupData")
|
|
721
|
+
.option("--god", "God mode", false)
|
|
722
|
+
.action(async (opts) => {
|
|
723
|
+
if (!opts.confirm) {
|
|
724
|
+
// eslint-disable-next-line no-console
|
|
725
|
+
console.error("Refusing to delete without --confirm");
|
|
726
|
+
process.exitCode = 1;
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
const catalox = createCatalox();
|
|
730
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
731
|
+
const res = await catalox.deleteCatalog(ctx, String(opts.catalog), {
|
|
732
|
+
confirm: true,
|
|
733
|
+
...(opts.backupBucket ? { gcsBackupBucket: String(opts.backupBucket).trim() } : {}),
|
|
734
|
+
...(opts.backupPrefix ? { gcsBackupPrefix: String(opts.backupPrefix).trim() } : {}),
|
|
735
|
+
});
|
|
736
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
737
|
+
if (!res.ok)
|
|
738
|
+
process.exitCode = 1;
|
|
739
|
+
});
|
|
740
|
+
catalogCmd
|
|
741
|
+
.command("restore")
|
|
742
|
+
.description("Restore a catalog from a delete manifest path (requires superAdmin context / --god)")
|
|
743
|
+
.requiredOption("--app <appId>", "AppId (superAdmin)")
|
|
744
|
+
.requiredOption("--manifest <relativePath>", "GCS object path relative to record-history prefix, ending in manifest.json")
|
|
745
|
+
.option("--god", "God mode (superAdmin)", true)
|
|
746
|
+
.action(async (opts) => {
|
|
747
|
+
const catalox = createCatalox();
|
|
748
|
+
const ctx = baseContext({ app: opts.app, god: true });
|
|
749
|
+
const res = await catalox.restoreDeletedCatalog(ctx, {
|
|
750
|
+
gcsManifestRelativePath: String(opts.manifest).trim(),
|
|
751
|
+
});
|
|
752
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
753
|
+
if (!res.ok)
|
|
754
|
+
process.exitCode = 1;
|
|
755
|
+
});
|
|
756
|
+
catalogCmd
|
|
757
|
+
.command("rename")
|
|
758
|
+
.description("Hard rename catalog id (copy + rewrite + delete source; requires record history bucket)")
|
|
759
|
+
.requiredOption("--app <appId>", "AppId for authz")
|
|
760
|
+
.requiredOption("--from <catalogId>", "Source catalog id")
|
|
761
|
+
.requiredOption("--to <catalogId>", "Target catalog id (must not exist)")
|
|
762
|
+
.option("--backup-bucket <name>", "Optional: backupData gcs bucket before rename")
|
|
763
|
+
.option("--backup-prefix <path>", "Optional gcsPrefix for pre-rename backup")
|
|
764
|
+
.option("--god", "God mode", false)
|
|
765
|
+
.action(async (opts) => {
|
|
766
|
+
const catalox = createCatalox();
|
|
767
|
+
const ctx = baseContext({ app: opts.app, god: opts.god });
|
|
768
|
+
const res = await catalox.renameCatalog(ctx, String(opts.from), String(opts.to), {
|
|
769
|
+
...(opts.backupBucket ? { gcsBackupBucket: String(opts.backupBucket).trim() } : {}),
|
|
770
|
+
...(opts.backupPrefix ? { gcsBackupPrefix: String(opts.backupPrefix).trim() } : {}),
|
|
771
|
+
});
|
|
772
|
+
await writeOrStdout(JSON.stringify(res, null, 2));
|
|
773
|
+
if (!res.ok)
|
|
774
|
+
process.exitCode = 1;
|
|
775
|
+
});
|
|
672
776
|
program.parseAsync(process.argv).catch((err) => {
|
|
673
777
|
// eslint-disable-next-line no-console
|
|
674
778
|
console.error(err instanceof Error ? err.message : err);
|