document-drive 1.19.1 → 1.20.1
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 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/src/cache/memory.d.ts +10 -0
- package/dist/src/cache/memory.d.ts.map +1 -0
- package/dist/src/cache/memory.js +26 -0
- package/dist/src/cache/redis.d.ts +14 -0
- package/dist/src/cache/redis.d.ts.map +1 -0
- package/dist/src/cache/redis.js +40 -0
- package/dist/src/cache/types.d.ts +7 -0
- package/dist/src/cache/types.d.ts.map +1 -0
- package/dist/src/cache/types.js +1 -0
- package/dist/src/drive-document-model/constants.d.ts +2 -0
- package/dist/src/drive-document-model/constants.d.ts.map +1 -0
- package/dist/src/drive-document-model/constants.js +1 -0
- package/dist/src/drive-document-model/gen/actions.d.ts +7 -0
- package/dist/src/drive-document-model/gen/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/actions.js +2 -0
- package/dist/src/drive-document-model/gen/constants.d.ts +7 -0
- package/dist/src/drive-document-model/gen/constants.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/constants.js +16 -0
- package/dist/src/drive-document-model/gen/creators.d.ts +3 -0
- package/dist/src/drive-document-model/gen/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/creators.js +2 -0
- package/dist/src/drive-document-model/gen/document-model.d.ts +3 -0
- package/dist/src/drive-document-model/gen/document-model.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/document-model.js +210 -0
- package/dist/src/drive-document-model/gen/drive/actions.d.ts +12 -0
- package/dist/src/drive-document-model/gen/drive/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/actions.js +1 -0
- package/dist/src/drive-document-model/gen/drive/creators.d.ts +11 -0
- package/dist/src/drive-document-model/gen/drive/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/creators.js +10 -0
- package/dist/src/drive-document-model/gen/drive/error.d.ts +2 -0
- package/dist/src/drive-document-model/gen/drive/error.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/error.js +1 -0
- package/dist/src/drive-document-model/gen/drive/object.d.ts +14 -0
- package/dist/src/drive-document-model/gen/drive/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/object.js +28 -0
- package/dist/src/drive-document-model/gen/drive/operations.d.ts +14 -0
- package/dist/src/drive-document-model/gen/drive/operations.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/operations.js +1 -0
- package/dist/src/drive-document-model/gen/node/actions.d.ts +11 -0
- package/dist/src/drive-document-model/gen/node/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/actions.js +1 -0
- package/dist/src/drive-document-model/gen/node/creators.d.ts +10 -0
- package/dist/src/drive-document-model/gen/node/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/creators.js +9 -0
- package/dist/src/drive-document-model/gen/node/error.d.ts +2 -0
- package/dist/src/drive-document-model/gen/node/error.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/error.js +1 -0
- package/dist/src/drive-document-model/gen/node/object.d.ts +13 -0
- package/dist/src/drive-document-model/gen/node/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/object.js +25 -0
- package/dist/src/drive-document-model/gen/node/operations.d.ts +13 -0
- package/dist/src/drive-document-model/gen/node/operations.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/operations.js +1 -0
- package/dist/src/drive-document-model/gen/object.d.ts +21 -0
- package/dist/src/drive-document-model/gen/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/object.js +28 -0
- package/dist/src/drive-document-model/gen/reducer.d.ts +4 -0
- package/dist/src/drive-document-model/gen/reducer.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/reducer.js +74 -0
- package/dist/src/drive-document-model/gen/schema/types.d.ts +176 -0
- package/dist/src/drive-document-model/gen/schema/types.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/schema/types.js +1 -0
- package/dist/src/drive-document-model/gen/schema/zod.d.ts +87 -0
- package/dist/src/drive-document-model/gen/schema/zod.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/schema/zod.js +203 -0
- package/dist/src/drive-document-model/gen/types.d.ts +9 -0
- package/dist/src/drive-document-model/gen/types.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/types.js +1 -0
- package/dist/src/drive-document-model/gen/utils.d.ts +10 -0
- package/dist/src/drive-document-model/gen/utils.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/utils.js +27 -0
- package/dist/src/drive-document-model/index.d.ts +2 -0
- package/dist/src/drive-document-model/index.d.ts.map +1 -0
- package/dist/src/drive-document-model/index.js +1 -0
- package/dist/src/drive-document-model/module.d.ts +3 -0
- package/dist/src/drive-document-model/module.d.ts.map +1 -0
- package/dist/src/drive-document-model/module.js +12 -0
- package/dist/src/drive-document-model/src/reducers/drive.d.ts +8 -0
- package/dist/src/drive-document-model/src/reducers/drive.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/reducers/drive.js +37 -0
- package/dist/src/drive-document-model/src/reducers/node.d.ts +8 -0
- package/dist/src/drive-document-model/src/reducers/node.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/reducers/node.js +185 -0
- package/dist/src/drive-document-model/src/utils.d.ts +34 -0
- package/dist/src/drive-document-model/src/utils.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/utils.js +146 -0
- package/dist/src/queue/base.d.ts +43 -0
- package/dist/src/queue/base.d.ts.map +1 -0
- package/dist/src/queue/base.js +241 -0
- package/dist/src/queue/redis.d.ts +28 -0
- package/dist/src/queue/redis.d.ts.map +1 -0
- package/dist/src/queue/redis.js +110 -0
- package/dist/src/queue/types.d.ts +55 -0
- package/dist/src/queue/types.d.ts.map +1 -0
- package/dist/src/queue/types.js +6 -0
- package/dist/src/read-mode/errors.d.ts +12 -0
- package/dist/src/read-mode/errors.d.ts.map +1 -0
- package/dist/src/read-mode/errors.js +17 -0
- package/dist/src/read-mode/server.d.ts +4 -0
- package/dist/src/read-mode/server.d.ts.map +1 -0
- package/dist/src/read-mode/server.js +78 -0
- package/dist/src/read-mode/service.d.ts +18 -0
- package/dist/src/read-mode/service.d.ts.map +1 -0
- package/dist/src/read-mode/service.js +112 -0
- package/dist/src/read-mode/types.d.ts +35 -0
- package/dist/src/read-mode/types.d.ts.map +1 -0
- package/dist/src/read-mode/types.js +1 -0
- package/dist/src/server/base-server.d.ts +112 -0
- package/dist/src/server/base-server.d.ts.map +1 -0
- package/dist/src/server/base-server.js +1280 -0
- package/dist/src/server/builder.d.ts +30 -0
- package/dist/src/server/builder.d.ts.map +1 -0
- package/dist/src/server/builder.js +89 -0
- package/dist/src/server/constants.d.ts +2 -0
- package/dist/src/server/constants.d.ts.map +1 -0
- package/dist/src/server/constants.js +1 -0
- package/dist/src/server/error.d.ts +30 -0
- package/dist/src/server/error.d.ts.map +1 -0
- package/dist/src/server/error.js +47 -0
- package/dist/src/server/event-emitter.d.ts +8 -0
- package/dist/src/server/event-emitter.d.ts.map +1 -0
- package/dist/src/server/event-emitter.js +10 -0
- package/dist/src/server/listener/index.d.ts +2 -0
- package/dist/src/server/listener/index.d.ts.map +1 -0
- package/dist/src/server/listener/index.js +1 -0
- package/dist/src/server/listener/listener-manager.d.ts +27 -0
- package/dist/src/server/listener/listener-manager.d.ts.map +1 -0
- package/dist/src/server/listener/listener-manager.js +401 -0
- package/dist/src/server/listener/transmitter/factory.d.ts +8 -0
- package/dist/src/server/listener/transmitter/factory.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/factory.js +25 -0
- package/dist/src/server/listener/transmitter/internal.d.ts +34 -0
- package/dist/src/server/listener/transmitter/internal.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/internal.js +87 -0
- package/dist/src/server/listener/transmitter/pull-responder.d.ts +38 -0
- package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/pull-responder.js +256 -0
- package/dist/src/server/listener/transmitter/switchboard-push.d.ts +9 -0
- package/dist/src/server/listener/transmitter/switchboard-push.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/switchboard-push.js +77 -0
- package/dist/src/server/listener/transmitter/types.d.ts +20 -0
- package/dist/src/server/listener/transmitter/types.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/types.js +1 -0
- package/dist/src/server/listener/util.d.ts +2 -0
- package/dist/src/server/listener/util.d.ts.map +1 -0
- package/dist/src/server/listener/util.js +22 -0
- package/dist/src/server/sync-manager.d.ts +30 -0
- package/dist/src/server/sync-manager.d.ts.map +1 -0
- package/dist/src/server/sync-manager.js +287 -0
- package/dist/src/server/types.d.ts +308 -0
- package/dist/src/server/types.d.ts.map +1 -0
- package/dist/src/server/types.js +12 -0
- package/dist/src/server/utils.d.ts +8 -0
- package/dist/src/server/utils.d.ts.map +1 -0
- package/dist/src/server/utils.js +47 -0
- package/dist/src/storage/base.d.ts +36 -0
- package/dist/src/storage/base.d.ts.map +1 -0
- package/dist/src/storage/base.js +4 -0
- package/dist/src/storage/browser.d.ts +36 -0
- package/dist/src/storage/browser.d.ts.map +1 -0
- package/dist/src/storage/browser.js +155 -0
- package/dist/src/storage/filesystem.d.ts +33 -0
- package/dist/src/storage/filesystem.d.ts.map +1 -0
- package/dist/src/storage/filesystem.js +197 -0
- package/dist/src/storage/memory.d.ts +33 -0
- package/dist/src/storage/memory.d.ts.map +1 -0
- package/dist/src/storage/memory.js +139 -0
- package/dist/src/storage/prisma.d.ts +67 -0
- package/dist/src/storage/prisma.d.ts.map +1 -0
- package/dist/src/storage/prisma.js +445 -0
- package/dist/src/storage/sequelize.d.ts +32 -0
- package/dist/src/storage/sequelize.d.ts.map +1 -0
- package/dist/src/storage/sequelize.js +373 -0
- package/dist/src/storage/types.d.ts +43 -0
- package/dist/src/storage/types.d.ts.map +1 -0
- package/dist/src/storage/types.js +1 -0
- package/dist/src/utils/default-drives-manager.d.ts +29 -0
- package/dist/src/utils/default-drives-manager.d.ts.map +1 -0
- package/dist/src/utils/default-drives-manager.js +208 -0
- package/dist/src/utils/graphql.d.ts +34 -0
- package/dist/src/utils/graphql.d.ts.map +1 -0
- package/dist/src/utils/graphql.js +183 -0
- package/dist/src/utils/logger.d.ts +27 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +105 -0
- package/dist/src/utils/migrations.d.ts +4 -0
- package/dist/src/utils/migrations.d.ts.map +1 -0
- package/dist/src/utils/migrations.js +41 -0
- package/dist/src/utils/misc.d.ts +11 -0
- package/dist/src/utils/misc.d.ts.map +1 -0
- package/dist/src/utils/misc.js +43 -0
- package/dist/src/utils/run-asap.d.ts +12 -0
- package/dist/src/utils/run-asap.d.ts.map +1 -0
- package/dist/src/utils/run-asap.js +131 -0
- package/dist/test/document-helpers/utils.d.ts +8 -0
- package/dist/test/document-helpers/utils.d.ts.map +1 -0
- package/dist/test/document-helpers/utils.js +21 -0
- package/dist/test/utils.d.ts +48 -0
- package/dist/test/utils.d.ts.map +1 -0
- package/dist/test/utils.js +132 -0
- package/dist/test/vitest-setup.d.ts +2 -0
- package/dist/test/vitest-setup.d.ts.map +1 -0
- package/dist/test/vitest-setup.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +20 -0
- package/package.json +20 -38
- package/src/cache/index.ts +0 -2
- package/src/cache/memory.ts +0 -33
- package/src/cache/redis.ts +0 -56
- package/src/cache/types.ts +0 -9
- package/src/index.ts +0 -4
- package/src/queue/base.ts +0 -320
- package/src/queue/index.ts +0 -2
- package/src/queue/redis.ts +0 -144
- package/src/queue/types.ts +0 -79
- package/src/read-mode/errors.ts +0 -19
- package/src/read-mode/index.ts +0 -125
- package/src/read-mode/service.ts +0 -207
- package/src/read-mode/types.ts +0 -108
- package/src/server/error.ts +0 -70
- package/src/server/index.ts +0 -2444
- package/src/server/listener/index.ts +0 -2
- package/src/server/listener/manager.ts +0 -652
- package/src/server/listener/transmitter/index.ts +0 -4
- package/src/server/listener/transmitter/internal.ts +0 -143
- package/src/server/listener/transmitter/pull-responder.ts +0 -462
- package/src/server/listener/transmitter/switchboard-push.ts +0 -125
- package/src/server/listener/transmitter/types.ts +0 -27
- package/src/server/types.ts +0 -596
- package/src/server/utils.ts +0 -82
- package/src/storage/base.ts +0 -81
- package/src/storage/browser.ts +0 -238
- package/src/storage/filesystem.ts +0 -297
- package/src/storage/index.ts +0 -2
- package/src/storage/memory.ts +0 -211
- package/src/storage/prisma.ts +0 -653
- package/src/storage/sequelize.ts +0 -498
- package/src/storage/types.ts +0 -97
- package/src/utils/default-drives-manager.ts +0 -341
- package/src/utils/document-helpers.ts +0 -21
- package/src/utils/graphql.ts +0 -301
- package/src/utils/index.ts +0 -90
- package/src/utils/logger.ts +0 -38
- package/src/utils/migrations.ts +0 -58
- package/src/utils/run-asap.ts +0 -156
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequelize.d.ts","sourceRoot":"","sources":["../../../src/storage/sequelize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAEL,eAAe,EACf,cAAc,EAEd,SAAS,EAET,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAa,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,EAAE,CAAY;gBAEV,OAAO,EAAE,OAAO;IAIrB,UAAU;IAuGX,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAGV,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,IAAI,CAAC;IAiBV,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAyEV,gCAAgC,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,eAAe,EAAE;IAuB1B,YAAY,CAAC,KAAK,EAAE,MAAM;IAoB1B,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAelE,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IA6Ef,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAcxC,SAAS;IAIT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAKnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAoB3B,WAAW,CAAC,EAAE,EAAE,MAAM;IAwBtB,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;CA2CF"}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { DataTypes, Sequelize } from "sequelize";
|
|
2
|
+
export class SequelizeStorage {
|
|
3
|
+
db;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.db = new Sequelize(options);
|
|
6
|
+
}
|
|
7
|
+
syncModels() {
|
|
8
|
+
const Drive = this.db.define("drive", {
|
|
9
|
+
slug: {
|
|
10
|
+
type: DataTypes.STRING,
|
|
11
|
+
primaryKey: true,
|
|
12
|
+
},
|
|
13
|
+
id: DataTypes.STRING,
|
|
14
|
+
});
|
|
15
|
+
const Document = this.db.define("document", {
|
|
16
|
+
id: {
|
|
17
|
+
type: DataTypes.STRING,
|
|
18
|
+
primaryKey: true,
|
|
19
|
+
},
|
|
20
|
+
driveId: {
|
|
21
|
+
type: DataTypes.STRING,
|
|
22
|
+
primaryKey: true,
|
|
23
|
+
},
|
|
24
|
+
name: DataTypes.STRING,
|
|
25
|
+
documentType: DataTypes.STRING,
|
|
26
|
+
initialState: DataTypes.JSON,
|
|
27
|
+
lastModified: DataTypes.DATE,
|
|
28
|
+
revision: DataTypes.JSON,
|
|
29
|
+
});
|
|
30
|
+
const Operation = this.db.define("operation", {
|
|
31
|
+
driveId: {
|
|
32
|
+
type: DataTypes.STRING,
|
|
33
|
+
primaryKey: true,
|
|
34
|
+
unique: "unique_operation",
|
|
35
|
+
},
|
|
36
|
+
documentId: {
|
|
37
|
+
type: DataTypes.STRING,
|
|
38
|
+
primaryKey: true,
|
|
39
|
+
unique: "unique_operation",
|
|
40
|
+
},
|
|
41
|
+
hash: DataTypes.STRING,
|
|
42
|
+
index: {
|
|
43
|
+
type: DataTypes.INTEGER,
|
|
44
|
+
primaryKey: true,
|
|
45
|
+
unique: "unique_operation",
|
|
46
|
+
},
|
|
47
|
+
input: DataTypes.JSON,
|
|
48
|
+
timestamp: DataTypes.DATE,
|
|
49
|
+
type: DataTypes.STRING,
|
|
50
|
+
scope: {
|
|
51
|
+
type: DataTypes.STRING,
|
|
52
|
+
primaryKey: true,
|
|
53
|
+
unique: "unique_operation",
|
|
54
|
+
},
|
|
55
|
+
branch: {
|
|
56
|
+
type: DataTypes.STRING,
|
|
57
|
+
primaryKey: true,
|
|
58
|
+
unique: "unique_operation",
|
|
59
|
+
},
|
|
60
|
+
skip: {
|
|
61
|
+
type: DataTypes.INTEGER,
|
|
62
|
+
defaultValue: 0,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
const Attachment = this.db.define("attachment", {
|
|
66
|
+
driveId: {
|
|
67
|
+
type: DataTypes.STRING,
|
|
68
|
+
primaryKey: true,
|
|
69
|
+
},
|
|
70
|
+
documentId: {
|
|
71
|
+
type: DataTypes.STRING,
|
|
72
|
+
primaryKey: true,
|
|
73
|
+
},
|
|
74
|
+
scope: {
|
|
75
|
+
type: DataTypes.STRING,
|
|
76
|
+
primaryKey: true,
|
|
77
|
+
},
|
|
78
|
+
branch: {
|
|
79
|
+
type: DataTypes.STRING,
|
|
80
|
+
primaryKey: true,
|
|
81
|
+
},
|
|
82
|
+
index: {
|
|
83
|
+
type: DataTypes.STRING,
|
|
84
|
+
primaryKey: true,
|
|
85
|
+
},
|
|
86
|
+
hash: {
|
|
87
|
+
type: DataTypes.STRING,
|
|
88
|
+
primaryKey: true,
|
|
89
|
+
},
|
|
90
|
+
mimeType: DataTypes.STRING,
|
|
91
|
+
fileName: DataTypes.STRING,
|
|
92
|
+
extension: DataTypes.STRING,
|
|
93
|
+
data: DataTypes.BLOB,
|
|
94
|
+
});
|
|
95
|
+
Operation.hasMany(Attachment, {
|
|
96
|
+
onDelete: "CASCADE",
|
|
97
|
+
});
|
|
98
|
+
Attachment.belongsTo(Operation);
|
|
99
|
+
Document.hasMany(Operation, {
|
|
100
|
+
onDelete: "CASCADE",
|
|
101
|
+
});
|
|
102
|
+
Operation.belongsTo(Document);
|
|
103
|
+
return this.db.sync({ force: true });
|
|
104
|
+
}
|
|
105
|
+
async createDrive(id, drive) {
|
|
106
|
+
await this.createDocument("drives", id, drive);
|
|
107
|
+
const Drive = this.db.models.drive;
|
|
108
|
+
await Drive.upsert({ id, slug: drive.initialState.state.global.slug });
|
|
109
|
+
}
|
|
110
|
+
async addDriveOperations(id, operations, header) {
|
|
111
|
+
await this.addDocumentOperations("drives", id, operations, header);
|
|
112
|
+
}
|
|
113
|
+
async createDocument(drive, id, document) {
|
|
114
|
+
const Document = this.db.models.document;
|
|
115
|
+
if (!Document) {
|
|
116
|
+
throw new Error("Document model not found");
|
|
117
|
+
}
|
|
118
|
+
await Document.create({
|
|
119
|
+
id: id,
|
|
120
|
+
driveId: drive,
|
|
121
|
+
name: document.name,
|
|
122
|
+
documentType: document.documentType,
|
|
123
|
+
initialState: document.initialState,
|
|
124
|
+
lastModified: document.lastModified,
|
|
125
|
+
revision: document.revision,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
async addDocumentOperations(drive, id, operations, header) {
|
|
129
|
+
const document = await this.getDocument(drive, id);
|
|
130
|
+
if (!document) {
|
|
131
|
+
throw new Error(`Document with id ${id} not found`);
|
|
132
|
+
}
|
|
133
|
+
const Operation = this.db.models.operation;
|
|
134
|
+
if (!Operation) {
|
|
135
|
+
throw new Error("Operation model not found");
|
|
136
|
+
}
|
|
137
|
+
await Operation.bulkCreate(operations.map((op) => ({
|
|
138
|
+
driveId: drive,
|
|
139
|
+
documentId: id,
|
|
140
|
+
hash: op.hash,
|
|
141
|
+
index: op.index,
|
|
142
|
+
input: op.input,
|
|
143
|
+
timestamp: op.timestamp,
|
|
144
|
+
type: op.type,
|
|
145
|
+
scope: op.scope,
|
|
146
|
+
branch: "main",
|
|
147
|
+
opId: op.id,
|
|
148
|
+
})));
|
|
149
|
+
const attachments = operations.reduce((acc, op) => {
|
|
150
|
+
if (op.attachments?.length) {
|
|
151
|
+
return acc.concat(op.attachments.map((attachment) => ({
|
|
152
|
+
driveId: drive,
|
|
153
|
+
documentId: id,
|
|
154
|
+
scope: op.scope,
|
|
155
|
+
branch: "main",
|
|
156
|
+
index: op.index,
|
|
157
|
+
mimeType: attachment.mimeType,
|
|
158
|
+
fileName: attachment.fileName,
|
|
159
|
+
extension: attachment.extension,
|
|
160
|
+
data: attachment.data,
|
|
161
|
+
hash: attachment.hash,
|
|
162
|
+
})));
|
|
163
|
+
}
|
|
164
|
+
return acc;
|
|
165
|
+
}, []);
|
|
166
|
+
if (attachments.length) {
|
|
167
|
+
const Attachment = this.db.models.attachment;
|
|
168
|
+
if (!Attachment) {
|
|
169
|
+
throw new Error("Attachment model not found");
|
|
170
|
+
}
|
|
171
|
+
await Attachment.bulkCreate(attachments);
|
|
172
|
+
}
|
|
173
|
+
const Document = this.db.models.document;
|
|
174
|
+
if (!Document) {
|
|
175
|
+
throw new Error("Document model not found");
|
|
176
|
+
}
|
|
177
|
+
await Document.update({
|
|
178
|
+
lastModified: header.lastModified,
|
|
179
|
+
revision: header.revision,
|
|
180
|
+
}, {
|
|
181
|
+
where: {
|
|
182
|
+
id: id,
|
|
183
|
+
driveId: drive,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async _addDocumentOperationAttachments(driveId, documentId, operation, attachments) {
|
|
188
|
+
const Attachment = this.db.models.attachment;
|
|
189
|
+
if (!Attachment) {
|
|
190
|
+
throw new Error("Attachment model not found");
|
|
191
|
+
}
|
|
192
|
+
return Attachment.bulkCreate(attachments.map((attachment) => ({
|
|
193
|
+
driveId: driveId,
|
|
194
|
+
documentId: documentId,
|
|
195
|
+
scope: operation.scope,
|
|
196
|
+
branch: "main",
|
|
197
|
+
index: operation.index,
|
|
198
|
+
mimeType: attachment.mimeType,
|
|
199
|
+
fileName: attachment.fileName,
|
|
200
|
+
extension: attachment.extension,
|
|
201
|
+
data: attachment.data,
|
|
202
|
+
hash: attachment.hash,
|
|
203
|
+
})));
|
|
204
|
+
}
|
|
205
|
+
async getDocuments(drive) {
|
|
206
|
+
const Document = this.db.models.document;
|
|
207
|
+
if (!Document) {
|
|
208
|
+
throw new Error("Document model not found");
|
|
209
|
+
}
|
|
210
|
+
const result = await Document.findAll({
|
|
211
|
+
attributes: ["id"],
|
|
212
|
+
where: {
|
|
213
|
+
driveId: drive,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
const ids = result.map((e) => {
|
|
217
|
+
const { id } = e.dataValues;
|
|
218
|
+
return id;
|
|
219
|
+
});
|
|
220
|
+
return ids;
|
|
221
|
+
}
|
|
222
|
+
async checkDocumentExists(driveId, id) {
|
|
223
|
+
const Document = this.db.models.document;
|
|
224
|
+
if (!Document) {
|
|
225
|
+
throw new Error("Document model not found");
|
|
226
|
+
}
|
|
227
|
+
const count = await Document.count({
|
|
228
|
+
where: {
|
|
229
|
+
id: id,
|
|
230
|
+
driveId: driveId,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
return count > 0;
|
|
234
|
+
}
|
|
235
|
+
async getDocument(driveId, id) {
|
|
236
|
+
const documentFromDb = this.db.models.document;
|
|
237
|
+
if (!documentFromDb) {
|
|
238
|
+
throw new Error("Document model not found");
|
|
239
|
+
}
|
|
240
|
+
const entry = await documentFromDb.findOne({
|
|
241
|
+
where: {
|
|
242
|
+
id: id,
|
|
243
|
+
driveId: driveId,
|
|
244
|
+
},
|
|
245
|
+
include: [
|
|
246
|
+
{
|
|
247
|
+
model: this.db.models.operation,
|
|
248
|
+
as: "operations",
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
});
|
|
252
|
+
if (entry === null) {
|
|
253
|
+
throw new Error(`Document with id ${id} not found`);
|
|
254
|
+
}
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
256
|
+
const document = entry.dataValues;
|
|
257
|
+
const operationFromDb = this.db.models.operation;
|
|
258
|
+
if (!operationFromDb) {
|
|
259
|
+
throw new Error("Operation model not found");
|
|
260
|
+
}
|
|
261
|
+
const operations = document.operations.map((op) => ({
|
|
262
|
+
hash: op.hash,
|
|
263
|
+
index: op.index,
|
|
264
|
+
timestamp: new Date(op.timestamp).toISOString(),
|
|
265
|
+
input: op.input,
|
|
266
|
+
type: op.type,
|
|
267
|
+
scope: op.scope,
|
|
268
|
+
id: op.opId,
|
|
269
|
+
skip: op.skip,
|
|
270
|
+
// attachments: fileRegistry
|
|
271
|
+
}));
|
|
272
|
+
const doc = {
|
|
273
|
+
created: document.createdAt.toISOString(),
|
|
274
|
+
name: document.name ? document.name : "",
|
|
275
|
+
documentType: document.documentType,
|
|
276
|
+
initialState: document.initialState,
|
|
277
|
+
lastModified: document.updatedAt.toISOString(),
|
|
278
|
+
operations: {
|
|
279
|
+
global: operations.filter((op) => op.scope === "global"),
|
|
280
|
+
local: operations.filter((op) => op.scope === "local"),
|
|
281
|
+
},
|
|
282
|
+
revision: document.revision,
|
|
283
|
+
};
|
|
284
|
+
return doc;
|
|
285
|
+
}
|
|
286
|
+
async deleteDocument(drive, id) {
|
|
287
|
+
const documentFromDb = this.db.models.document;
|
|
288
|
+
if (!documentFromDb) {
|
|
289
|
+
throw new Error("Document model not found");
|
|
290
|
+
}
|
|
291
|
+
await documentFromDb.destroy({
|
|
292
|
+
where: {
|
|
293
|
+
id: id,
|
|
294
|
+
driveId: drive,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async getDrives() {
|
|
299
|
+
return this.getDocuments("drives");
|
|
300
|
+
}
|
|
301
|
+
async getDrive(id) {
|
|
302
|
+
const doc = await this.getDocument("drives", id);
|
|
303
|
+
return doc;
|
|
304
|
+
}
|
|
305
|
+
async getDriveBySlug(slug) {
|
|
306
|
+
const driveFromDb = this.db.models.drive;
|
|
307
|
+
if (!driveFromDb) {
|
|
308
|
+
throw new Error("Drive model not found");
|
|
309
|
+
}
|
|
310
|
+
const driveEntity = await driveFromDb.findOne({
|
|
311
|
+
where: {
|
|
312
|
+
slug,
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
if (!driveEntity) {
|
|
316
|
+
throw new Error(`Drive with slug ${slug} not found`);
|
|
317
|
+
}
|
|
318
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
319
|
+
return this.getDrive(driveEntity.dataValues.id);
|
|
320
|
+
}
|
|
321
|
+
async deleteDrive(id) {
|
|
322
|
+
await this.deleteDocument("drives", id);
|
|
323
|
+
const documentFromDb = this.db.models.document;
|
|
324
|
+
if (!documentFromDb) {
|
|
325
|
+
throw new Error("Document model not found");
|
|
326
|
+
}
|
|
327
|
+
await documentFromDb.destroy({
|
|
328
|
+
where: {
|
|
329
|
+
driveId: id,
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
const driveFromDb = this.db.models.drive;
|
|
333
|
+
if (driveFromDb) {
|
|
334
|
+
await driveFromDb.destroy({
|
|
335
|
+
where: {
|
|
336
|
+
id: id,
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async getSynchronizationUnitsRevision(units) {
|
|
342
|
+
const results = await Promise.allSettled(units.map(async (unit) => {
|
|
343
|
+
try {
|
|
344
|
+
const document = await (unit.documentId
|
|
345
|
+
? this.getDocument(unit.driveId, unit.documentId)
|
|
346
|
+
: this.getDrive(unit.driveId));
|
|
347
|
+
if (!document) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
const operation = document.operations[unit.scope].at(-1);
|
|
351
|
+
if (operation) {
|
|
352
|
+
return {
|
|
353
|
+
driveId: unit.driveId,
|
|
354
|
+
documentId: unit.documentId,
|
|
355
|
+
scope: unit.scope,
|
|
356
|
+
branch: unit.branch,
|
|
357
|
+
lastUpdated: operation.timestamp,
|
|
358
|
+
revision: operation.index,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
}));
|
|
366
|
+
return results.reduce((acc, curr) => {
|
|
367
|
+
if (curr.status === "fulfilled" && curr.value !== undefined) {
|
|
368
|
+
acc.push(curr.value);
|
|
369
|
+
}
|
|
370
|
+
return acc;
|
|
371
|
+
}, []);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DocumentDriveDocument } from "#drive-document-model/gen/types";
|
|
2
|
+
import { SynchronizationUnitQuery } from "#server/types";
|
|
3
|
+
import type { DocumentHeader, Operation, OperationFromDocument, OperationsFromDocument, PHDocument } from "document-model";
|
|
4
|
+
export interface IStorageDelegate {
|
|
5
|
+
getCachedOperations<TDocument extends PHDocument = PHDocument>(drive: string, id: string): Promise<OperationsFromDocument<TDocument> | undefined>;
|
|
6
|
+
}
|
|
7
|
+
export interface IStorage {
|
|
8
|
+
checkDocumentExists(drive: string, id: string): Promise<boolean>;
|
|
9
|
+
getDocuments: (drive: string) => Promise<string[]>;
|
|
10
|
+
getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
|
|
11
|
+
createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
|
|
12
|
+
addDocumentOperations<TDocument extends PHDocument>(drive: string, id: string, operations: OperationFromDocument<TDocument>[], header: DocumentHeader): Promise<void>;
|
|
13
|
+
addDocumentOperationsWithTransaction?<TDocument extends PHDocument>(drive: string, id: string, callback: (document: TDocument) => Promise<{
|
|
14
|
+
operations: OperationFromDocument<TDocument>[];
|
|
15
|
+
header: DocumentHeader;
|
|
16
|
+
}>): Promise<void>;
|
|
17
|
+
deleteDocument(drive: string, id: string): Promise<void>;
|
|
18
|
+
getOperationResultingState?(drive: string, id: string, index: number, scope: string, branch: string): Promise<string | undefined>;
|
|
19
|
+
setStorageDelegate?(delegate: IStorageDelegate): void;
|
|
20
|
+
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
|
|
21
|
+
driveId: string;
|
|
22
|
+
documentId: string;
|
|
23
|
+
scope: string;
|
|
24
|
+
branch: string;
|
|
25
|
+
lastUpdated: string;
|
|
26
|
+
revision: number;
|
|
27
|
+
}[]>;
|
|
28
|
+
}
|
|
29
|
+
export interface IDriveStorage extends IStorage {
|
|
30
|
+
getDrives(): Promise<string[]>;
|
|
31
|
+
getDrive(id: string): Promise<DocumentDriveDocument>;
|
|
32
|
+
getDriveBySlug(slug: string): Promise<DocumentDriveDocument>;
|
|
33
|
+
createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
|
|
34
|
+
deleteDrive(id: string): Promise<void>;
|
|
35
|
+
clearStorage?(): Promise<void>;
|
|
36
|
+
addDriveOperations(id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
|
|
37
|
+
addDriveOperationsWithTransaction?(drive: string, callback: (document: DocumentDriveDocument) => Promise<{
|
|
38
|
+
operations: Operation[];
|
|
39
|
+
header: DocumentHeader;
|
|
40
|
+
}>): Promise<void>;
|
|
41
|
+
getDriveOperationResultingState?(drive: string, index: number, scope: string, branch: string): Promise<string | undefined>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IReadModeDriveServer } from "#read-mode/types";
|
|
2
|
+
import { DefaultRemoteDriveInfo, DocumentDriveServerOptions, DriveEvents, IBaseDocumentDriveServer, RemoteDriveAccessLevel } from "#server/types";
|
|
3
|
+
export interface IServerDelegateDrivesManager {
|
|
4
|
+
emit: (...args: Parameters<DriveEvents["defaultRemoteDrive"]>) => void;
|
|
5
|
+
detachDrive: (driveId: string) => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface IDefaultDrivesManager {
|
|
8
|
+
initializeDefaultRemoteDrives(): Promise<void>;
|
|
9
|
+
getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
|
|
10
|
+
setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
|
|
11
|
+
setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare class DefaultDrivesManager implements IDefaultDrivesManager {
|
|
14
|
+
private server;
|
|
15
|
+
private delegate;
|
|
16
|
+
private defaultRemoteDrives;
|
|
17
|
+
private removeOldRemoteDrivesConfig;
|
|
18
|
+
constructor(server: IBaseDocumentDriveServer | (IBaseDocumentDriveServer & IReadModeDriveServer), delegate: IServerDelegateDrivesManager, options?: Pick<DocumentDriveServerOptions, "defaultDrives">);
|
|
19
|
+
getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
|
|
20
|
+
private deleteDriveById;
|
|
21
|
+
private preserveDrivesById;
|
|
22
|
+
private removeDrivesById;
|
|
23
|
+
private detachDrivesById;
|
|
24
|
+
removeOldremoteDrives(): Promise<void>;
|
|
25
|
+
setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
|
|
26
|
+
setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
|
|
27
|
+
initializeDefaultRemoteDrives(defaultDrives?: DefaultRemoteDriveInfo[]): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=default-drives-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-drives-manager.d.ts","sourceRoot":"","sources":["../../../src/utils/default-drives-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,WAAW,EACX,wBAAwB,EACxB,sBAAsB,EAGvB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,KAAK,IAAI,CAAC;IACvE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAMD,MAAM,WAAW,qBAAqB;IACpC,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,sBAAsB,IAAI,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9D,0BAA0B,CACxB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED,qBAAa,oBAAqB,YAAW,qBAAqB;IAK9D,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,QAAQ;IAPlB,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,2BAA2B,CAA8B;gBAGvD,MAAM,EACV,wBAAwB,GACxB,CAAC,wBAAwB,GAAG,oBAAoB,CAAC,EAC7C,QAAQ,EAAE,4BAA4B,EAC9C,OAAO,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,eAAe,CAAC;IAiB7D,sBAAsB;YAQR,eAAe;YAUf,kBAAkB;YAwBlB,gBAAgB;YAMhB,gBAAgB;IAQxB,qBAAqB;IA0GrB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB;IAO5D,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB;IAYrE,6BAA6B,CACjC,aAAa,GAAE,sBAAsB,EAEpC;CAiGJ"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { DriveNotFoundError } from "#server/error";
|
|
2
|
+
import { requestPublicDrive } from "./graphql.js";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
function isReadModeDriveServer(obj) {
|
|
5
|
+
return typeof obj.getReadDrives === "function";
|
|
6
|
+
}
|
|
7
|
+
export class DefaultDrivesManager {
|
|
8
|
+
server;
|
|
9
|
+
delegate;
|
|
10
|
+
defaultRemoteDrives = new Map();
|
|
11
|
+
removeOldRemoteDrivesConfig;
|
|
12
|
+
constructor(server, delegate, options) {
|
|
13
|
+
this.server = server;
|
|
14
|
+
this.delegate = delegate;
|
|
15
|
+
if (options?.defaultDrives.remoteDrives) {
|
|
16
|
+
for (const defaultDrive of options.defaultDrives.remoteDrives) {
|
|
17
|
+
this.defaultRemoteDrives.set(defaultDrive.url, {
|
|
18
|
+
...defaultDrive,
|
|
19
|
+
status: "PENDING",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
this.removeOldRemoteDrivesConfig = options?.defaultDrives
|
|
24
|
+
.removeOldRemoteDrives || {
|
|
25
|
+
strategy: "preserve-all",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
getDefaultRemoteDrives() {
|
|
29
|
+
return new Map(JSON.parse(JSON.stringify(Array.from(this.defaultRemoteDrives))));
|
|
30
|
+
}
|
|
31
|
+
async deleteDriveById(driveId) {
|
|
32
|
+
try {
|
|
33
|
+
await this.server.deleteDrive(driveId);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (!(error instanceof DriveNotFoundError)) {
|
|
37
|
+
logger.error(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async preserveDrivesById(driveIdsToPreserve, drives, removeStrategy = "detach") {
|
|
42
|
+
const getAllDrives = drives.map((driveId) => this.server.getDrive(driveId));
|
|
43
|
+
const drivesToRemove = (await Promise.all(getAllDrives))
|
|
44
|
+
.filter((drive) => drive.state.local.listeners.length > 0 ||
|
|
45
|
+
drive.state.local.triggers.length > 0)
|
|
46
|
+
.filter((drive) => !driveIdsToPreserve.includes(drive.state.global.id));
|
|
47
|
+
const driveIds = drivesToRemove.map((drive) => drive.state.global.id);
|
|
48
|
+
if (removeStrategy === "detach") {
|
|
49
|
+
await this.detachDrivesById(driveIds);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
await this.removeDrivesById(driveIds);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async removeDrivesById(driveIds) {
|
|
56
|
+
for (const driveId of driveIds) {
|
|
57
|
+
await this.deleteDriveById(driveId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async detachDrivesById(driveIds) {
|
|
61
|
+
const detachDrivesPromises = driveIds.map((driveId) => this.delegate.detachDrive(driveId));
|
|
62
|
+
await Promise.all(detachDrivesPromises);
|
|
63
|
+
}
|
|
64
|
+
async removeOldremoteDrives() {
|
|
65
|
+
const driveids = await this.server.getDrives();
|
|
66
|
+
switch (this.removeOldRemoteDrivesConfig.strategy) {
|
|
67
|
+
case "preserve-by-id-and-detach":
|
|
68
|
+
case "preserve-by-id": {
|
|
69
|
+
const detach = this.removeOldRemoteDrivesConfig.strategy ===
|
|
70
|
+
"preserve-by-id-and-detach"
|
|
71
|
+
? "detach"
|
|
72
|
+
: "remove";
|
|
73
|
+
await this.preserveDrivesById(this.removeOldRemoteDrivesConfig.ids, driveids, detach);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case "preserve-by-url-and-detach":
|
|
77
|
+
case "preserve-by-url": {
|
|
78
|
+
const detach = this.removeOldRemoteDrivesConfig.strategy ===
|
|
79
|
+
"preserve-by-url-and-detach"
|
|
80
|
+
? "detach"
|
|
81
|
+
: "remove";
|
|
82
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((url) => requestPublicDrive(url));
|
|
83
|
+
const drivesIdsToPreserve = (await Promise.all(getDrivesInfo)).map((driveInfo) => driveInfo.id);
|
|
84
|
+
await this.preserveDrivesById(drivesIdsToPreserve, driveids, detach);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case "remove-by-id": {
|
|
88
|
+
const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter((driveId) => driveids.includes(driveId));
|
|
89
|
+
await this.removeDrivesById(drivesIdsToRemove);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "remove-by-url": {
|
|
93
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((driveUrl) => requestPublicDrive(driveUrl));
|
|
94
|
+
const drivesInfo = await Promise.all(getDrivesInfo);
|
|
95
|
+
const drivesIdsToRemove = drivesInfo
|
|
96
|
+
.map((driveInfo) => driveInfo.id)
|
|
97
|
+
.filter((driveId) => driveids.includes(driveId));
|
|
98
|
+
await this.removeDrivesById(drivesIdsToRemove);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "remove-all": {
|
|
102
|
+
const getDrives = driveids.map((driveId) => this.server.getDrive(driveId));
|
|
103
|
+
const drives = await Promise.all(getDrives);
|
|
104
|
+
const drivesToRemove = drives
|
|
105
|
+
.filter((drive) => drive.state.local.listeners.length > 0 ||
|
|
106
|
+
drive.state.local.triggers.length > 0)
|
|
107
|
+
.map((drive) => drive.state.global.id);
|
|
108
|
+
await this.removeDrivesById(drivesToRemove);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "detach-by-id": {
|
|
112
|
+
const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter((driveId) => driveids.includes(driveId));
|
|
113
|
+
const detachDrivesPromises = drivesIdsToRemove.map((driveId) => this.delegate.detachDrive(driveId));
|
|
114
|
+
await Promise.all(detachDrivesPromises);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case "detach-by-url": {
|
|
118
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((driveUrl) => requestPublicDrive(driveUrl));
|
|
119
|
+
const drivesInfo = await Promise.all(getDrivesInfo);
|
|
120
|
+
const drivesIdsToRemove = drivesInfo
|
|
121
|
+
.map((driveInfo) => driveInfo.id)
|
|
122
|
+
.filter((driveId) => driveids.includes(driveId));
|
|
123
|
+
const detachDrivesPromises = drivesIdsToRemove.map((driveId) => this.delegate.detachDrive(driveId));
|
|
124
|
+
await Promise.all(detachDrivesPromises);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async setAllDefaultDrivesAccessLevel(level) {
|
|
130
|
+
const drives = this.defaultRemoteDrives.values();
|
|
131
|
+
for (const drive of drives) {
|
|
132
|
+
await this.setDefaultDriveAccessLevel(drive.url, level);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async setDefaultDriveAccessLevel(url, level) {
|
|
136
|
+
const drive = this.defaultRemoteDrives.get(url);
|
|
137
|
+
if (drive && drive.options.accessLevel !== level) {
|
|
138
|
+
const newDriveValue = {
|
|
139
|
+
...drive,
|
|
140
|
+
options: { ...drive.options, accessLevel: level },
|
|
141
|
+
};
|
|
142
|
+
this.defaultRemoteDrives.set(url, newDriveValue);
|
|
143
|
+
await this.initializeDefaultRemoteDrives([newDriveValue]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async initializeDefaultRemoteDrives(defaultDrives = Array.from(this.defaultRemoteDrives.values())) {
|
|
147
|
+
const drives = await this.server.getDrives();
|
|
148
|
+
const readServer = isReadModeDriveServer(this.server)
|
|
149
|
+
? this.server
|
|
150
|
+
: undefined;
|
|
151
|
+
const readDrives = await readServer?.getReadDrives();
|
|
152
|
+
for (const remoteDrive of defaultDrives) {
|
|
153
|
+
let remoteDriveInfo = { ...remoteDrive };
|
|
154
|
+
try {
|
|
155
|
+
const driveInfo = remoteDrive.metadata ?? (await requestPublicDrive(remoteDrive.url));
|
|
156
|
+
remoteDriveInfo = { ...remoteDrive, metadata: driveInfo };
|
|
157
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
158
|
+
const driveIsAdded = drives.includes(driveInfo.id);
|
|
159
|
+
const readDriveIsAdded = readDrives?.includes(driveInfo.id);
|
|
160
|
+
const hasAccessLevel = remoteDrive.options.accessLevel !== undefined;
|
|
161
|
+
const readMode = readServer && remoteDrive.options.accessLevel === "READ";
|
|
162
|
+
const isAdded = readMode ? readDriveIsAdded : driveIsAdded;
|
|
163
|
+
// if the read mode has changed then existing drives
|
|
164
|
+
// in the previous mode should be deleted
|
|
165
|
+
const driveToDelete = hasAccessLevel && (readMode ? driveIsAdded : readDriveIsAdded);
|
|
166
|
+
if (driveToDelete) {
|
|
167
|
+
try {
|
|
168
|
+
await (readMode
|
|
169
|
+
? this.server.deleteDrive(driveInfo.id)
|
|
170
|
+
: readServer?.deleteReadDrive(driveInfo.id));
|
|
171
|
+
}
|
|
172
|
+
catch (e) {
|
|
173
|
+
logger.error(e);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (isAdded) {
|
|
177
|
+
remoteDriveInfo.status = "ALREADY_ADDED";
|
|
178
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
179
|
+
this.delegate.emit("ALREADY_ADDED", this.defaultRemoteDrives, remoteDriveInfo, driveInfo.id, driveInfo.name);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
remoteDriveInfo.status = "ADDING";
|
|
183
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
184
|
+
this.delegate.emit("ADDING", this.defaultRemoteDrives, remoteDriveInfo);
|
|
185
|
+
if ((!hasAccessLevel && readServer) || readMode) {
|
|
186
|
+
await readServer.addReadDrive(remoteDrive.url, {
|
|
187
|
+
...remoteDrive.options,
|
|
188
|
+
expectedDriveInfo: driveInfo,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
await this.server.addRemoteDrive(remoteDrive.url, {
|
|
193
|
+
...remoteDrive.options,
|
|
194
|
+
expectedDriveInfo: driveInfo,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
remoteDriveInfo.status = "SUCCESS";
|
|
198
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
199
|
+
this.delegate.emit("SUCCESS", this.defaultRemoteDrives, remoteDriveInfo, driveInfo.id, driveInfo.name);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
remoteDriveInfo.status = "ERROR";
|
|
203
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
204
|
+
this.delegate.emit("ERROR", this.defaultRemoteDrives, remoteDriveInfo, undefined, undefined, error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|