@x12i/catalox 2.2.2 → 2.4.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 +42 -7
- package/dist/src/catalox/backup-data.d.ts +40 -0
- package/dist/src/catalox/backup-data.d.ts.map +1 -0
- package/dist/src/catalox/backup-data.js +522 -0
- package/dist/src/catalox/backup-data.js.map +1 -0
- package/dist/src/catalox/catalox.d.ts +25 -0
- package/dist/src/catalox/catalox.d.ts.map +1 -1
- package/dist/src/catalox/catalox.js +63 -1
- package/dist/src/catalox/catalox.js.map +1 -1
- package/dist/src/catalox/index.d.ts +3 -0
- package/dist/src/catalox/index.d.ts.map +1 -1
- package/dist/src/catalox/index.js +3 -0
- package/dist/src/catalox/index.js.map +1 -1
- package/dist/src/catalox/native-catalog-layout-diagnostics.d.ts +29 -0
- package/dist/src/catalox/native-catalog-layout-diagnostics.d.ts.map +1 -0
- package/dist/src/catalox/native-catalog-layout-diagnostics.js +55 -0
- package/dist/src/catalox/native-catalog-layout-diagnostics.js.map +1 -0
- package/dist/src/catalox/restore-firestore-backup.d.ts +13 -0
- package/dist/src/catalox/restore-firestore-backup.d.ts.map +1 -0
- package/dist/src/catalox/restore-firestore-backup.js +326 -0
- package/dist/src/catalox/restore-firestore-backup.js.map +1 -0
- package/dist/src/cli/index.js +156 -5
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/contracts/backup.d.ts +36 -0
- package/dist/src/contracts/backup.d.ts.map +1 -0
- package/dist/src/contracts/backup.js +2 -0
- package/dist/src/contracts/backup.js.map +1 -0
- package/dist/src/contracts/catalog-data-index.d.ts +13 -0
- package/dist/src/contracts/catalog-data-index.d.ts.map +1 -0
- package/dist/src/contracts/catalog-data-index.js +2 -0
- package/dist/src/contracts/catalog-data-index.js.map +1 -0
- package/dist/src/contracts/catalogs.d.ts +2 -1
- package/dist/src/contracts/catalogs.d.ts.map +1 -1
- package/dist/src/contracts/index.d.ts +3 -0
- package/dist/src/contracts/index.d.ts.map +1 -1
- package/dist/src/contracts/index.js.map +1 -1
- package/dist/src/contracts/restore.d.ts +44 -0
- package/dist/src/contracts/restore.d.ts.map +1 -0
- package/dist/src/contracts/restore.js +2 -0
- package/dist/src/contracts/restore.js.map +1 -0
- package/dist/src/firebase/catalog-data-index-store.d.ts +14 -0
- package/dist/src/firebase/catalog-data-index-store.d.ts.map +1 -0
- package/dist/src/firebase/catalog-data-index-store.js +33 -0
- package/dist/src/firebase/catalog-data-index-store.js.map +1 -0
- package/dist/src/firebase/catalog-data-paths.d.ts +14 -0
- package/dist/src/firebase/catalog-data-paths.d.ts.map +1 -0
- package/dist/src/firebase/catalog-data-paths.js +31 -0
- package/dist/src/firebase/catalog-data-paths.js.map +1 -0
- package/dist/src/firebase/index.d.ts +2 -0
- package/dist/src/firebase/index.d.ts.map +1 -1
- package/dist/src/firebase/index.js +2 -0
- package/dist/src/firebase/index.js.map +1 -1
- package/dist/src/firebase/native-item-store.d.ts +5 -1
- package/dist/src/firebase/native-item-store.d.ts.map +1 -1
- package/dist/src/firebase/native-item-store.js +33 -15
- package/dist/src/firebase/native-item-store.js.map +1 -1
- package/dist/src/migrations/index.d.ts +1 -0
- package/dist/src/migrations/index.d.ts.map +1 -1
- package/dist/src/migrations/index.js +1 -0
- package/dist/src/migrations/index.js.map +1 -1
- package/dist/src/migrations/migrate-native-catalog-layout.d.ts +51 -0
- package/dist/src/migrations/migrate-native-catalog-layout.d.ts.map +1 -0
- package/dist/src/migrations/migrate-native-catalog-layout.js +224 -0
- package/dist/src/migrations/migrate-native-catalog-layout.js.map +1 -0
- package/dist/test/integration/firestore.emulator.test.js +10 -2
- package/dist/test/integration/firestore.emulator.test.js.map +1 -1
- package/dist/test/unit/backup-timestamp.test.d.ts +2 -0
- package/dist/test/unit/backup-timestamp.test.d.ts.map +1 -0
- package/dist/test/unit/backup-timestamp.test.js +11 -0
- package/dist/test/unit/backup-timestamp.test.js.map +1 -0
- package/dist/test/unit/resolve-native-items-layout.test.d.ts +2 -0
- package/dist/test/unit/resolve-native-items-layout.test.d.ts.map +1 -0
- package/dist/test/unit/resolve-native-items-layout.test.js +50 -0
- package/dist/test/unit/resolve-native-items-layout.test.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ This repo is currently set up as a workspace package.
|
|
|
22
22
|
|
|
23
23
|
## Configuration (real connections)
|
|
24
24
|
|
|
25
|
-
Catalox is a library: you provide initialized clients + runtime env.
|
|
25
|
+
Catalox is a library: you provide initialized clients + runtime env. For a **full list of environment variables**, CLI vs library behavior, and integration-test requirements, see [`docs/environment.md`](docs/environment.md).
|
|
26
26
|
|
|
27
27
|
### Firestore (Firebase Admin SDK)
|
|
28
28
|
|
|
@@ -66,15 +66,39 @@ GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
|
|
|
66
66
|
FIREBASE_SERVICE_ACCOUNT_PATH=/path/to/service-account.json
|
|
67
67
|
FIREBASE_PROJECT_ID=your-project-id
|
|
68
68
|
FIRESTORE_LIVE_TESTS=1
|
|
69
|
+
# Optional defaults for the packaged `catalox` CLI (Catalox app/store context, not GCP):
|
|
70
|
+
# CATALOX_APP_ID=myAppId
|
|
71
|
+
# CATALOX_STORE_ID=myStoreId
|
|
72
|
+
# CATALOX_USER_ID=user-123
|
|
73
|
+
# CATALOX_MONGO_URI=mongodb://127.0.0.1:27017
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `catalox` CLI environment
|
|
77
|
+
|
|
78
|
+
The `catalox` binary loads `.env` via `dotenv`. Use **`CATALOX_*`** for **Catalox runtime context** (catalog `appId`, optional `storeId`, actor, Mongo URI for the bundled adapter). Use **`FIREBASE_*` / `FIRESTORE_*`** for **Firebase Admin / Firestore connection** (service account path, GCP `projectId`, database id, live-test flags).
|
|
79
|
+
|
|
80
|
+
- **`CATALOX_APP_ID`** — Default `appId` in CLI context when a command does not pass `--app` (when present, `--app` overrides).
|
|
81
|
+
- **`CATALOX_STORE_ID`** — Default `storeId` for **`report`** and **`export`** when `--store` is omitted (`--store` overrides).
|
|
82
|
+
- **`CATALOX_USER_ID`** — Optional user id / actor for authz-sensitive CLI paths.
|
|
83
|
+
- **`CATALOX_MONGO_URI`** — If set, enables the Mongo catalog adapter in the CLI (see `createCatalox()` in `src/cli/index.ts`).
|
|
84
|
+
|
|
85
|
+
**Running commands from this repository:** the shell command `catalox` is only on your `PATH` if the package is installed globally (`npm i -g @x12i/catalox`) or linked (`npm link` from this repo). Otherwise, after `npm run build`, use:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm run cli -- firestore report-native-layout --app "narrix"
|
|
89
|
+
# same as: node dist/src/cli/index.js firestore report-native-layout --app "narrix"
|
|
69
90
|
```
|
|
70
91
|
|
|
71
92
|
## Firestore data model (logical collections)
|
|
72
93
|
|
|
94
|
+
For a **full layout** (subcollections, document id conventions, snapshot runs, and query notes), see [`docs/firestore-data-model.md`](docs/firestore-data-model.md).
|
|
95
|
+
|
|
73
96
|
Metadata:
|
|
74
97
|
|
|
75
98
|
- `apps/{appId}`
|
|
76
99
|
- `catalogs/{catalogId}`
|
|
77
100
|
- `catalogBindings/{bindingId}` (many-to-many app↔catalog)
|
|
101
|
+
- `storeAppBindings/{bindingId}` (store↔app, multi-app export/report)
|
|
78
102
|
- `catalogDefinitions/{catalogId}` (native vs mapped specifics)
|
|
79
103
|
- `catalogAdapters/{adapterId}` (mongo/api adapter definitions)
|
|
80
104
|
- `catalogMappings/{mappingId}` (field mapping specs)
|
|
@@ -84,16 +108,24 @@ Metadata:
|
|
|
84
108
|
|
|
85
109
|
Data:
|
|
86
110
|
|
|
87
|
-
- `catalogData
|
|
111
|
+
- `catalogData-{catalogId}-items/{itemId}` (native item rows; top-level collection per catalog)
|
|
112
|
+
- `catalogData/{catalogId}` (index and metadata for that catalog’s native storage; not item payloads)
|
|
88
113
|
- `catalogSnapshots/{catalogId}/items/{itemId}` (mapped snapshot mode)
|
|
89
114
|
|
|
115
|
+
Backups (optional operator feature):
|
|
116
|
+
|
|
117
|
+
- `backup-*` and `{timestamp}__backup-*` (Firebase mode, same database)
|
|
118
|
+
- Mongo database `catalox-backups` (Mongo mode)
|
|
119
|
+
|
|
120
|
+
See [`docs/backup.md`](docs/backup.md) for `backupData` / CLI backup, [`docs/restore-firestore-backup.md`](docs/restore-firestore-backup.md) for restoring Firebase mirrors to live data with undo, [`docs/migration-native-catalog-data.md`](docs/migration-native-catalog-data.md) for moving legacy native rows into `catalogData-{catalogId}-items`, and [`docs/firestore-native-layout-vs-backup.md`](docs/firestore-native-layout-vs-backup.md) for how live paths differ from `backup-*` mirrors and what `backupData` reports in `nativeItemSourceLayoutByCatalogId`. If the console still shows **`catalogData/{catalogId}/items`**, run **`catalox firestore report-native-layout`** then **`catalox firestore migrate-native-catalog-data`** (backup + copy to flat; optional `--delete-legacy` after you trust backups).
|
|
121
|
+
|
|
90
122
|
## Core usage (generic from `appId`)
|
|
91
123
|
|
|
92
124
|
### Create stores and `Catalox`
|
|
93
125
|
|
|
94
126
|
```ts
|
|
95
127
|
import { FirestoreStore } from "@x12i/catalox";
|
|
96
|
-
import { AppStore, CatalogStore, BindingStore, DefinitionStore, MappingStore, DescriptorStore, ReferenceStore, NativeItemStore, SnapshotStore, AdapterStore } from "@x12i/catalox";
|
|
128
|
+
import { AppStore, CatalogStore, BindingStore, DefinitionStore, MappingStore, DescriptorStore, ReferenceStore, NativeItemStore, CatalogDataIndexStore, SnapshotStore, AdapterStore } from "@x12i/catalox";
|
|
97
129
|
import { AuthorizationService, Catalox } from "@x12i/catalox";
|
|
98
130
|
|
|
99
131
|
// firebase-admin initialization is up to the consumer
|
|
@@ -102,18 +134,21 @@ import { getFirestore } from "firebase-admin/firestore";
|
|
|
102
134
|
const firestore = getFirestore();
|
|
103
135
|
const store = new FirestoreStore({ firestore });
|
|
104
136
|
|
|
137
|
+
const bindings = new BindingStore(store);
|
|
105
138
|
const deps = {
|
|
106
139
|
apps: new AppStore(store),
|
|
107
140
|
catalogs: new CatalogStore(store),
|
|
108
|
-
bindings
|
|
141
|
+
bindings,
|
|
109
142
|
definitions: new DefinitionStore(store),
|
|
110
143
|
mappings: new MappingStore(store),
|
|
111
144
|
descriptors: new DescriptorStore(store),
|
|
112
145
|
references: new ReferenceStore(store),
|
|
113
146
|
nativeItems: new NativeItemStore(store),
|
|
147
|
+
catalogDataIndex: new CatalogDataIndexStore(store),
|
|
114
148
|
snapshots: new SnapshotStore(store),
|
|
115
149
|
adapters: new AdapterStore(store),
|
|
116
|
-
|
|
150
|
+
firestoreStore: store,
|
|
151
|
+
authz: new AuthorizationService(bindings),
|
|
117
152
|
};
|
|
118
153
|
|
|
119
154
|
const catalox = new Catalox(deps);
|
|
@@ -306,7 +341,7 @@ await catalox.createCatalog(ctx, {
|
|
|
306
341
|
catalogId: "signals",
|
|
307
342
|
name: "Signals",
|
|
308
343
|
sourceMode: "native",
|
|
309
|
-
native: { type: "native"
|
|
344
|
+
native: { type: "native" },
|
|
310
345
|
});
|
|
311
346
|
```
|
|
312
347
|
|
|
@@ -450,7 +485,7 @@ Integration tests are **live-only** (no mocks, no emulators). They require:
|
|
|
450
485
|
### Live test safety (read before running)
|
|
451
486
|
|
|
452
487
|
- **Never run against production credentials/projects.** Use a dedicated Firebase project for tests.
|
|
453
|
-
- **Touched collections**: `apps`, `catalogs`, `catalogBindings`, `catalogDefinitions`, `catalogDescriptors`, and `catalogData
|
|
488
|
+
- **Touched collections**: `apps`, `catalogs`, `catalogBindings`, `catalogDefinitions`, `catalogDescriptors`, `catalogData/{catalogId}`, and `catalogData-{catalogId}-items/...`. The **`catalox firestore restore-backup`** / **`undo-restore-backup`** commands additionally write `backup-restoreSessions` and `{restoreSessionId}__preRestore-*` sidecar collections (see [`docs/restore-firestore-backup.md`](docs/restore-firestore-backup.md)).
|
|
454
489
|
- **Cleanup**: tests do best-effort deletes of the docs they created, but do not guarantee full teardown.
|
|
455
490
|
|
|
456
491
|
## Boundaries (important)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type Firestore } from "firebase-admin/firestore";
|
|
2
|
+
import { type Db } from "mongodb";
|
|
3
|
+
import type { CatalogId } from "../contracts/ids.js";
|
|
4
|
+
import type { BackupDataInput, BackupDataResult } from "../contracts/backup.js";
|
|
5
|
+
import type { CatalogRecord } from "../contracts/catalogs.js";
|
|
6
|
+
import { CatalogStore } from "../firebase/catalog-store.js";
|
|
7
|
+
import { BindingStore } from "../firebase/binding-store.js";
|
|
8
|
+
import { FirestoreStore } from "../firebase/firestore-store.js";
|
|
9
|
+
export declare const BACKUP_METADATA_SOURCE_NAMES: readonly ["apps", "catalogs", "catalogBindings", "storeAppBindings", "catalogDefinitions", "catalogDescriptors", "catalogMappings", "catalogAdapters", "catalogReferences", "catalogData"];
|
|
10
|
+
export type BackupDataDeps = {
|
|
11
|
+
firestoreStore: FirestoreStore;
|
|
12
|
+
catalogs: CatalogStore;
|
|
13
|
+
bindings: BindingStore;
|
|
14
|
+
};
|
|
15
|
+
export declare function formatBackupTimestamp(versionOverride?: string, d?: Date): string;
|
|
16
|
+
/** Latest Firebase backup mirror collection id for a logical source (e.g. `apps`, `catalogData--{id}`). */
|
|
17
|
+
export declare function firebaseLatestName(logical: string): string;
|
|
18
|
+
/** Versioned Firebase backup collection id. */
|
|
19
|
+
export declare function firebaseVersionedName(ts: string, logical: string): string;
|
|
20
|
+
export declare function firebaseNativeLogical(catalogId: string): string;
|
|
21
|
+
export declare function firebaseSnapshotLogical(catalogId: string): string;
|
|
22
|
+
export declare function firebaseSnapshotRunLogical(catalogId: string, runId: string): string;
|
|
23
|
+
export declare function paginatedCopyFirestoreToFirestore(fs: Firestore, sourceCollectionPath: string, destCollectionPath: string, counts: Record<string, number>, countKey: string): Promise<void>;
|
|
24
|
+
export declare function deleteAllDocsInFirestoreCollection(fs: Firestore, collectionPath: string): Promise<void>;
|
|
25
|
+
export declare function discoverNativeCatalogIds(fs: Firestore, catalogs: CatalogRecord[], opts: {
|
|
26
|
+
bindings: BindingStore;
|
|
27
|
+
catalogIds?: CatalogId[];
|
|
28
|
+
appId?: string;
|
|
29
|
+
}): Promise<CatalogId[]>;
|
|
30
|
+
/** Delete Mongo `backupRuns` documents with createdAt older than cutoff ISO string. */
|
|
31
|
+
export declare function pruneMongoBackupRuns(db: Db, createdBeforeIso: string): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* Delete documents in oldest Firestore versioned backup collections matching `{ts}__backup-*`
|
|
34
|
+
* until at most `keepLast` such collections remain.
|
|
35
|
+
*/
|
|
36
|
+
export declare function pruneFirebaseVersionedBackups(firestore: Firestore, keepLast: number): Promise<{
|
|
37
|
+
deleted: string[];
|
|
38
|
+
}>;
|
|
39
|
+
export declare function runBackupData(deps: BackupDataDeps, input: BackupDataInput): Promise<BackupDataResult>;
|
|
40
|
+
//# sourceMappingURL=backup-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-data.d.ts","sourceRoot":"","sources":["../../../src/catalox/backup-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAe,KAAK,EAAE,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAmB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAWhE,eAAO,MAAM,4BAA4B,4LAY/B,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,OAAa,GAAG,MAAM,CAMtF;AAMD,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzE;AA0BD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,SAAS,EACb,oBAAoB,EAAE,MAAM,EAC5B,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,kCAAkC,CAAC,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7G;AAED,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,aAAa,EAAE,EACzB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,OAAO,CAAC,SAAS,EAAE,CAAC,CAwBtB;AA0PD,uFAAuF;AACvF,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK5F;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAchC;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA+K3B"}
|