@credo-ts/askar-to-drizzle-storage-migration 0.6.0-alpha-20251127043254 → 0.6.0-alpha-20251127093557
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/package.json +7 -12
- package/build/AskarToDrizzleStorageMigrator.d.ts +0 -65
- package/build/AskarToDrizzleStorageMigrator.d.ts.map +0 -1
- package/build/AskarToDrizzleStorageMigrator.js +0 -202
- package/build/errors/AskarToDrizzleStorageMigrationError.js +0 -10
- package/build/index.d.ts +0 -2
- package/build/index.js +0 -3
package/package.json
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@credo-ts/askar-to-drizzle-storage-migration",
|
|
3
3
|
"exports": {
|
|
4
|
-
".":
|
|
5
|
-
"import": "./build/index.mjs",
|
|
6
|
-
"require": "./build/index.js",
|
|
7
|
-
"types": "./build/index.d.ts"
|
|
8
|
-
},
|
|
4
|
+
".": "./build/index.mjs",
|
|
9
5
|
"./package.json": "./package.json"
|
|
10
6
|
},
|
|
11
|
-
"version": "0.6.0-alpha-
|
|
7
|
+
"version": "0.6.0-alpha-20251127093557",
|
|
12
8
|
"files": [
|
|
13
9
|
"build"
|
|
14
10
|
],
|
|
@@ -23,10 +19,10 @@
|
|
|
23
19
|
"directory": "packages/askar-to-drizzle-storage-migration"
|
|
24
20
|
},
|
|
25
21
|
"dependencies": {
|
|
26
|
-
"@credo-ts/askar": "0.6.0-alpha-
|
|
27
|
-
"@credo-ts/tenants": "0.6.0-alpha-
|
|
28
|
-
"@credo-ts/drizzle-storage": "0.6.0-alpha-
|
|
29
|
-
"@credo-ts/core": "0.6.0-alpha-
|
|
22
|
+
"@credo-ts/askar": "0.6.0-alpha-20251127093557",
|
|
23
|
+
"@credo-ts/tenants": "0.6.0-alpha-20251127093557",
|
|
24
|
+
"@credo-ts/drizzle-storage": "0.6.0-alpha-20251127093557",
|
|
25
|
+
"@credo-ts/core": "0.6.0-alpha-20251127093557"
|
|
30
26
|
},
|
|
31
27
|
"peerDependencies": {
|
|
32
28
|
"@openwallet-foundation/askar-shared": "^0.4.3"
|
|
@@ -38,7 +34,6 @@
|
|
|
38
34
|
"scripts": {
|
|
39
35
|
"build": "tsdown --config-loader unconfig"
|
|
40
36
|
},
|
|
41
|
-
"
|
|
42
|
-
"types": "./build/index.d.ts",
|
|
37
|
+
"types": "./build/index.d.mts",
|
|
43
38
|
"module": "./build/index.mjs"
|
|
44
39
|
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import * as _credo_ts_core0 from "@credo-ts/core";
|
|
2
|
-
import { Agent, AgentDependencies, Logger } from "@credo-ts/core";
|
|
3
|
-
import { AskarModule } from "@credo-ts/askar";
|
|
4
|
-
import { DrizzleStorageModule } from "@credo-ts/drizzle-storage";
|
|
5
|
-
import { TenantsModule } from "@credo-ts/tenants";
|
|
6
|
-
|
|
7
|
-
//#region src/AskarToDrizzleStorageMigrator.d.ts
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Migration class to move storage from Askar to Drizzle. Note that this does not migrate
|
|
11
|
-
* the KMS part of Askar (the keys), and only the normal record storage.
|
|
12
|
-
*
|
|
13
|
-
* No backups are created during the process. The askar store is only used for reading, the
|
|
14
|
-
* drizzle store is also used for writing. Ensure the drizzle target is empty when starting the
|
|
15
|
-
* migration.
|
|
16
|
-
*
|
|
17
|
-
* Note that if you were previously using `AskarMultiWalletDatabaseScheme.DatabasePerWallet`, that all storage will be moved
|
|
18
|
-
* to a single database. You can still keep using multiiple databases for the Askar storage, but Drizzle only supports
|
|
19
|
-
* a single database per main agent instance (including sub agents for tenants).
|
|
20
|
-
*/
|
|
21
|
-
declare class AskarToDrizzleStorageMigrator {
|
|
22
|
-
private drizzleModule;
|
|
23
|
-
private askarModule;
|
|
24
|
-
private agentDependencies;
|
|
25
|
-
private logger;
|
|
26
|
-
private skipMigrationforMissingAdapter;
|
|
27
|
-
private tenantsModule?;
|
|
28
|
-
private drizzleAgent;
|
|
29
|
-
askarAgent: Agent<_credo_ts_core0.ModulesMap>;
|
|
30
|
-
private drizzleConfig;
|
|
31
|
-
private drizzleAdapters;
|
|
32
|
-
private constructor();
|
|
33
|
-
static initialize({
|
|
34
|
-
drizzleModule,
|
|
35
|
-
askarModule,
|
|
36
|
-
agentDependencies,
|
|
37
|
-
logger,
|
|
38
|
-
skipMigrationForMissingAdapter,
|
|
39
|
-
tenantsModule
|
|
40
|
-
}: {
|
|
41
|
-
drizzleModule: DrizzleStorageModule;
|
|
42
|
-
askarModule: AskarModule;
|
|
43
|
-
agentDependencies: AgentDependencies;
|
|
44
|
-
logger: Logger;
|
|
45
|
-
tenantsModule?: TenantsModule;
|
|
46
|
-
/**
|
|
47
|
-
* When set to `true`, the migration of any records in the Askar store that don't
|
|
48
|
-
* have an adapter registered will be skipped. Note that this can be dangerous and
|
|
49
|
-
* result in loss of data in the new store. Use this only if you have records with a
|
|
50
|
-
* category in your askar store, for which there is no adapter registered, and should
|
|
51
|
-
* not be migrated.
|
|
52
|
-
*
|
|
53
|
-
* @default false
|
|
54
|
-
*/
|
|
55
|
-
skipMigrationForMissingAdapter?: boolean;
|
|
56
|
-
}): Promise<AskarToDrizzleStorageMigrator>;
|
|
57
|
-
private getAdapterForRecordType;
|
|
58
|
-
migrate(): Promise<void>;
|
|
59
|
-
deleteStorageRecords(): Promise<void>;
|
|
60
|
-
private migrateForContext;
|
|
61
|
-
private deleteForContext;
|
|
62
|
-
}
|
|
63
|
-
//#endregion
|
|
64
|
-
export { AskarToDrizzleStorageMigrator };
|
|
65
|
-
//# sourceMappingURL=AskarToDrizzleStorageMigrator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AskarToDrizzleStorageMigrator.d.ts","names":[],"sources":["../src/AskarToDrizzleStorageMigrator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AA4BA;;;;;;;;;AAmDmB,cAnDN,6BAAA,CAmDM;EACF,QAAA,aAAA;EACM,QAAA,WAAA;EACX,QAAA,iBAAA;EACQ,QAAA,MAAA;EAYjB,QAAA,8BAAA;EAAA,QAAA,aAAA;EA6BmB,QAAA,YAAA;EAuDa,UAAA,EAvIhB,KAuIgB,CAvJO,eAAA,CAgBvB,UAAA,CAuIgB;EAAA,QAAA,aAAA;;;;;;;;;;;mBApGhB;iBACF;uBACM;YACX;oBACQ;;;;;;;;;;;MAYjB,QAAA;;aA6BmB;0BAuDa"}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
const require_AskarToDrizzleStorageMigrationError = require('./errors/AskarToDrizzleStorageMigrationError.js');
|
|
2
|
-
let __credo_ts_askar = require("@credo-ts/askar");
|
|
3
|
-
let __credo_ts_core = require("@credo-ts/core");
|
|
4
|
-
let __credo_ts_drizzle_storage = require("@credo-ts/drizzle-storage");
|
|
5
|
-
require("@credo-ts/tenants");
|
|
6
|
-
let __openwallet_foundation_askar_shared = require("@openwallet-foundation/askar-shared");
|
|
7
|
-
|
|
8
|
-
//#region src/AskarToDrizzleStorageMigrator.ts
|
|
9
|
-
/**
|
|
10
|
-
* Migration class to move storage from Askar to Drizzle. Note that this does not migrate
|
|
11
|
-
* the KMS part of Askar (the keys), and only the normal record storage.
|
|
12
|
-
*
|
|
13
|
-
* No backups are created during the process. The askar store is only used for reading, the
|
|
14
|
-
* drizzle store is also used for writing. Ensure the drizzle target is empty when starting the
|
|
15
|
-
* migration.
|
|
16
|
-
*
|
|
17
|
-
* Note that if you were previously using `AskarMultiWalletDatabaseScheme.DatabasePerWallet`, that all storage will be moved
|
|
18
|
-
* to a single database. You can still keep using multiiple databases for the Askar storage, but Drizzle only supports
|
|
19
|
-
* a single database per main agent instance (including sub agents for tenants).
|
|
20
|
-
*/
|
|
21
|
-
var AskarToDrizzleStorageMigrator = class AskarToDrizzleStorageMigrator {
|
|
22
|
-
constructor(drizzleModule, askarModule, agentDependencies, logger, skipMigrationforMissingAdapter, tenantsModule) {
|
|
23
|
-
this.drizzleModule = drizzleModule;
|
|
24
|
-
this.askarModule = askarModule;
|
|
25
|
-
this.agentDependencies = agentDependencies;
|
|
26
|
-
this.logger = logger;
|
|
27
|
-
this.skipMigrationforMissingAdapter = skipMigrationforMissingAdapter;
|
|
28
|
-
this.tenantsModule = tenantsModule;
|
|
29
|
-
this.drizzleAgent = new __credo_ts_core.Agent({
|
|
30
|
-
dependencies: this.agentDependencies,
|
|
31
|
-
config: { logger: this.logger },
|
|
32
|
-
modules: this.tenantsModule ? {
|
|
33
|
-
drizzle: this.drizzleModule,
|
|
34
|
-
tenants: this.tenantsModule
|
|
35
|
-
} : { drizzle: this.drizzleModule }
|
|
36
|
-
});
|
|
37
|
-
this.askarAgent = new __credo_ts_core.Agent({
|
|
38
|
-
modules: this.tenantsModule ? {
|
|
39
|
-
askar: this.askarModule,
|
|
40
|
-
tenants: this.tenantsModule
|
|
41
|
-
} : { askar: this.askarModule },
|
|
42
|
-
config: { logger: this.logger },
|
|
43
|
-
dependencies: this.agentDependencies
|
|
44
|
-
});
|
|
45
|
-
this.drizzleConfig = this.drizzleAgent.context.resolve(__credo_ts_drizzle_storage.DrizzleStorageModuleConfig);
|
|
46
|
-
this.drizzleAdapters = this.drizzleConfig.adapters;
|
|
47
|
-
}
|
|
48
|
-
static async initialize({ drizzleModule, askarModule, agentDependencies, logger = new __credo_ts_core.ConsoleLogger(__credo_ts_core.LogLevel.trace), skipMigrationForMissingAdapter = false, tenantsModule }) {
|
|
49
|
-
if (!askarModule.config.enableStorage) throw new require_AskarToDrizzleStorageMigrationError.AskarToDrizzleStorageMigrationError("Askar module has enableStorage set to false. Make sure the storage is enabled on the askar module");
|
|
50
|
-
return new AskarToDrizzleStorageMigrator(drizzleModule, askarModule, agentDependencies, logger, skipMigrationForMissingAdapter, tenantsModule);
|
|
51
|
-
}
|
|
52
|
-
getAdapterForRecordType(recordType) {
|
|
53
|
-
const adapter = this.drizzleAdapters.find((adapter$1) => adapter$1.recordClass.type === recordType);
|
|
54
|
-
if (!adapter) return null;
|
|
55
|
-
return adapter;
|
|
56
|
-
}
|
|
57
|
-
async migrate() {
|
|
58
|
-
try {
|
|
59
|
-
await this.drizzleAgent.initialize();
|
|
60
|
-
this.logger.info("Successfully initialized drizzle agent");
|
|
61
|
-
await this.askarAgent.initialize();
|
|
62
|
-
this.logger.info("Successfully initialized askar agent");
|
|
63
|
-
this.logger.info("Starting migration of default agent context");
|
|
64
|
-
await this.migrateForContext({
|
|
65
|
-
askarContext: this.askarAgent.context,
|
|
66
|
-
drizzleContext: this.drizzleAgent.context
|
|
67
|
-
});
|
|
68
|
-
this.logger.info("Succesfully migrated default agent context");
|
|
69
|
-
if (this.tenantsModule) {
|
|
70
|
-
const askarAgentWithTenants = this.askarAgent;
|
|
71
|
-
const drizzleAgentWithTenants = this.drizzleAgent;
|
|
72
|
-
this.logger.info("Detected tenants module, migrating tenants context");
|
|
73
|
-
const allTenants = await askarAgentWithTenants.modules.tenants.getAllTenants();
|
|
74
|
-
this.logger.debug(`Retrieved '${allTenants.length}' tenant records to migrate.`);
|
|
75
|
-
for (const tenant of allTenants) {
|
|
76
|
-
this.logger.info(`Starting migration of tenant '${tenant.id}'`);
|
|
77
|
-
await askarAgentWithTenants.modules.tenants.withTenantAgent({ tenantId: tenant.id }, async (askarTenantAgent) => {
|
|
78
|
-
await drizzleAgentWithTenants.modules.tenants.withTenantAgent({ tenantId: tenant.id }, (drizzleTenantAgent) => this.migrateForContext({
|
|
79
|
-
askarContext: askarTenantAgent.context,
|
|
80
|
-
drizzleContext: drizzleTenantAgent.context
|
|
81
|
-
}));
|
|
82
|
-
});
|
|
83
|
-
this.logger.info(`Succesfully migrated tenant '${tenant.id}'`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
} finally {
|
|
87
|
-
if (this.drizzleAgent.isInitialized) await this.drizzleAgent.shutdown();
|
|
88
|
-
if (this.askarAgent.isInitialized) await this.askarAgent.shutdown();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
async deleteStorageRecords() {
|
|
92
|
-
try {
|
|
93
|
-
await this.askarAgent.initialize();
|
|
94
|
-
this.logger.info("Successfully initialized askar agent");
|
|
95
|
-
if (this.tenantsModule) {
|
|
96
|
-
const askarAgentWithTenants = this.askarAgent;
|
|
97
|
-
this.logger.info("Detected tenants module, deleting tenant records");
|
|
98
|
-
const allTenants = await askarAgentWithTenants.modules.tenants.getAllTenants();
|
|
99
|
-
this.logger.debug(`Retrieved '${allTenants.length}' tenants to delete non-KMS storage for.`);
|
|
100
|
-
for (const tenant of allTenants) {
|
|
101
|
-
this.logger.info(`Starting deletion of non-KMS records for tenant '${tenant.id}'`);
|
|
102
|
-
await askarAgentWithTenants.modules.tenants.withTenantAgent({ tenantId: tenant.id }, async (askarTenantAgent) => this.deleteForContext({ askarContext: askarTenantAgent.context }));
|
|
103
|
-
this.logger.info(`Succesfully removed non-KMS records for tenant '${tenant.id}'`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
this.logger.info("Starting deletion of non-KMS records for default agent context");
|
|
107
|
-
await this.deleteForContext({ askarContext: this.askarAgent.context });
|
|
108
|
-
this.logger.info("Succesfully removed non-KMS records for default agent context");
|
|
109
|
-
} finally {
|
|
110
|
-
if (this.askarAgent.isInitialized) await this.askarAgent.shutdown();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async migrateForContext({ drizzleContext, askarContext }) {
|
|
114
|
-
try {
|
|
115
|
-
const storeManager = askarContext.resolve(__credo_ts_askar.AskarStoreManager);
|
|
116
|
-
const askar = askarContext.resolve(__credo_ts_askar.AskarModuleConfig).askar;
|
|
117
|
-
const { store, profile } = await storeManager.getInitializedStoreWithProfile(askarContext);
|
|
118
|
-
await this.drizzleModule.onProvisionContext(drizzleContext);
|
|
119
|
-
let scanHandle;
|
|
120
|
-
let entryListHandle = null;
|
|
121
|
-
let migratedRecordCount = 0;
|
|
122
|
-
let skippedRecordCount = 0;
|
|
123
|
-
const skippedRecordTypes = [];
|
|
124
|
-
try {
|
|
125
|
-
this.logger.debug(`Initializing retrieval of records from askar storage for context '${askarContext.contextCorrelationId}'`);
|
|
126
|
-
scanHandle = await askar.scanStart({
|
|
127
|
-
storeHandle: store.handle,
|
|
128
|
-
profile
|
|
129
|
-
});
|
|
130
|
-
while (true) {
|
|
131
|
-
this.logger.debug(`Fetching batch of records from askar storage for context '${askarContext.contextCorrelationId}'`);
|
|
132
|
-
entryListHandle = await askar.scanNext({ scanHandle });
|
|
133
|
-
if (!entryListHandle) {
|
|
134
|
-
this.logger.debug(`No records returned in batch from askar storage. No records left to migrate for context '${askarContext.contextCorrelationId}'`);
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
const list = new __openwallet_foundation_askar_shared.EntryList({ handle: entryListHandle });
|
|
138
|
-
this.logger.debug(`Retrieved batch of '${list.length}' records from askar storage for context '${askarContext.contextCorrelationId}'`);
|
|
139
|
-
for (let index = 0; index < list.length; index++) {
|
|
140
|
-
const entry = list.getEntryByIndex(index);
|
|
141
|
-
const entryObject = entry.toJson();
|
|
142
|
-
this.logger.trace(`Retrieved record with index '${index}', id '${entryObject.name}' and type '${entryObject.category}' from batch for context '${askarContext.contextCorrelationId}'`);
|
|
143
|
-
const adapter = this.getAdapterForRecordType(entryObject.category);
|
|
144
|
-
if (!adapter) {
|
|
145
|
-
if (this.skipMigrationforMissingAdapter) {
|
|
146
|
-
this.logger.info(`Skippping migration of record '${entry.name}' with type '${entry.category}' due to missing drizzle adapter for context '${askarContext.contextCorrelationId}'.`);
|
|
147
|
-
skippedRecordCount++;
|
|
148
|
-
skippedRecordTypes.push(entryObject.category);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
throw new require_AskarToDrizzleStorageMigrationError.AskarToDrizzleStorageMigrationError(`Could not find a registered drizzle adapter for record type '${entry.category}'. Make sure to register the record type in the DrizzleStorageModule.`);
|
|
152
|
-
}
|
|
153
|
-
const record = (0, __credo_ts_askar.recordToInstance)(entryObject, adapter.recordClass);
|
|
154
|
-
if (record instanceof __credo_ts_core.StorageVersionRecord && record.id === __credo_ts_core.StorageVersionRecord.storageVersionRecordId) {
|
|
155
|
-
this.logger.debug(`Updating record '${record.id}' with type '${record.type}' into drizzle storage for context '${askarContext.contextCorrelationId}'`);
|
|
156
|
-
await adapter.update(drizzleContext, record);
|
|
157
|
-
} else {
|
|
158
|
-
this.logger.debug(`Inserting record '${record.id}' with type '${record.type}' into drizzle storage for context '${askarContext.contextCorrelationId}'`);
|
|
159
|
-
await adapter.insert(drizzleContext, record);
|
|
160
|
-
}
|
|
161
|
-
migratedRecordCount++;
|
|
162
|
-
}
|
|
163
|
-
this.logger.debug(`Processed all records from batch for context '${askarContext.contextCorrelationId}'`);
|
|
164
|
-
entryListHandle.free();
|
|
165
|
-
entryListHandle = null;
|
|
166
|
-
}
|
|
167
|
-
this.logger.debug(`Succesfully migrated '${migratedRecordCount}' records from Askar to Drizzle for context '${askarContext.contextCorrelationId}'`, {
|
|
168
|
-
migratedRecordCount,
|
|
169
|
-
skippedRecordCount,
|
|
170
|
-
skippedRecordTypes
|
|
171
|
-
});
|
|
172
|
-
} finally {
|
|
173
|
-
entryListHandle?.free();
|
|
174
|
-
entryListHandle = null;
|
|
175
|
-
scanHandle?.free();
|
|
176
|
-
scanHandle = void 0;
|
|
177
|
-
}
|
|
178
|
-
} catch (error) {
|
|
179
|
-
this.logger.error(`Migration failed for context '${askarContext.contextCorrelationId}'. ${error.message}`);
|
|
180
|
-
throw new require_AskarToDrizzleStorageMigrationError.AskarToDrizzleStorageMigrationError(`Migration failed for context '${askarContext.contextCorrelationId}'. ${error.message}`, { cause: error });
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
async deleteForContext({ askarContext }) {
|
|
184
|
-
try {
|
|
185
|
-
const { store, profile } = await askarContext.resolve(__credo_ts_askar.AskarStoreManager).getInitializedStoreWithProfile(askarContext);
|
|
186
|
-
this.logger.debug(`Removing all non-KMS records from askar storage for context '${askarContext.contextCorrelationId}'`);
|
|
187
|
-
const session = await store.session(profile).open();
|
|
188
|
-
try {
|
|
189
|
-
await session.removeAll({});
|
|
190
|
-
this.logger.debug(`Succesfully removed all non-KMS records from Askar for context '${askarContext.contextCorrelationId}'`);
|
|
191
|
-
} finally {
|
|
192
|
-
await session.close();
|
|
193
|
-
}
|
|
194
|
-
} catch (error) {
|
|
195
|
-
this.logger.error(`Removing non-KMS records failed for context '${askarContext.contextCorrelationId}'. ${error.message}`);
|
|
196
|
-
throw new require_AskarToDrizzleStorageMigrationError.AskarToDrizzleStorageMigrationError(`Removing non-KMS record failed for context '${askarContext.contextCorrelationId}'. ${error.message}`, { cause: error });
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
//#endregion
|
|
202
|
-
exports.AskarToDrizzleStorageMigrator = AskarToDrizzleStorageMigrator;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
let __credo_ts_core = require("@credo-ts/core");
|
|
2
|
-
|
|
3
|
-
//#region src/errors/AskarToDrizzleStorageMigrationError.ts
|
|
4
|
-
/**
|
|
5
|
-
* @internal
|
|
6
|
-
*/
|
|
7
|
-
var AskarToDrizzleStorageMigrationError = class extends __credo_ts_core.CredoError {};
|
|
8
|
-
|
|
9
|
-
//#endregion
|
|
10
|
-
exports.AskarToDrizzleStorageMigrationError = AskarToDrizzleStorageMigrationError;
|
package/build/index.d.ts
DELETED
package/build/index.js
DELETED