document-drive 1.28.1 → 1.28.3
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/dist/prisma/schema.prisma +19 -19
- package/dist/src/storage/browser.d.ts +4 -3
- package/dist/src/storage/browser.d.ts.map +1 -1
- package/dist/src/storage/browser.js +23 -11
- package/dist/src/storage/filesystem.d.ts +7 -6
- package/dist/src/storage/filesystem.d.ts.map +1 -1
- package/dist/src/storage/filesystem.js +41 -26
- package/dist/src/storage/ipfs.d.ts +38 -0
- package/dist/src/storage/ipfs.d.ts.map +1 -0
- package/dist/src/storage/ipfs.js +274 -0
- package/dist/src/storage/memory.d.ts +5 -1
- package/dist/src/storage/memory.d.ts.map +1 -1
- package/dist/src/storage/memory.js +78 -35
- package/dist/src/storage/prisma/index.d.ts +4 -2
- package/dist/src/storage/prisma/index.d.ts.map +1 -1
- package/dist/src/storage/prisma/index.js +134 -48
- package/dist/src/storage/sequelize.d.ts +1 -32
- package/dist/src/storage/sequelize.d.ts.map +1 -1
- package/dist/src/storage/sequelize.js +491 -349
- package/dist/src/storage/types.d.ts +1 -0
- package/dist/src/storage/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -5
|
@@ -3,58 +3,59 @@ import { mergeOperations } from "#utils/misc";
|
|
|
3
3
|
export class MemoryStorage {
|
|
4
4
|
documents;
|
|
5
5
|
drives;
|
|
6
|
+
driveManifests;
|
|
6
7
|
slugToDriveId = {};
|
|
7
8
|
constructor() {
|
|
8
9
|
this.documents = {};
|
|
9
10
|
this.drives = {};
|
|
11
|
+
this.driveManifests = {};
|
|
10
12
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
////////////////////////////////
|
|
14
|
+
// IDocumentStorage
|
|
15
|
+
////////////////////////////////
|
|
16
|
+
exists(documentId) {
|
|
17
|
+
return Promise.resolve(!!this.documents[documentId]);
|
|
18
|
+
}
|
|
19
|
+
create(documentId, document) {
|
|
20
|
+
this.documents[documentId] = document;
|
|
21
|
+
return Promise.resolve();
|
|
18
22
|
}
|
|
23
|
+
////////////////////////////////
|
|
24
|
+
// IDriveStorage
|
|
25
|
+
////////////////////////////////
|
|
19
26
|
checkDocumentExists(drive, id) {
|
|
20
27
|
return this.exists(id);
|
|
21
28
|
}
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
getDocuments(drive) {
|
|
30
|
+
const manifest = this.getDriveManifest(drive);
|
|
31
|
+
return Promise.resolve([...manifest.documentIds]);
|
|
24
32
|
}
|
|
25
33
|
async getDocument(driveId, id) {
|
|
26
|
-
const
|
|
27
|
-
if (!drive) {
|
|
28
|
-
throw new DriveNotFoundError(driveId);
|
|
29
|
-
}
|
|
30
|
-
const document = drive[id];
|
|
34
|
+
const document = this.documents[id];
|
|
31
35
|
if (!document) {
|
|
32
36
|
throw new Error(`Document with id ${id} not found`);
|
|
33
37
|
}
|
|
34
38
|
return document;
|
|
35
39
|
}
|
|
36
40
|
async saveDocument(drive, id, document) {
|
|
37
|
-
this.documents[
|
|
38
|
-
|
|
41
|
+
this.documents[id] = document;
|
|
42
|
+
// Update the drive manifest
|
|
43
|
+
const manifest = this.getDriveManifest(drive);
|
|
44
|
+
manifest.documentIds.add(id);
|
|
45
|
+
this.updateDriveManifest(drive, manifest);
|
|
39
46
|
}
|
|
40
47
|
async clearStorage() {
|
|
41
48
|
this.documents = {};
|
|
42
49
|
this.drives = {};
|
|
50
|
+
this.driveManifests = {};
|
|
51
|
+
this.slugToDriveId = {};
|
|
43
52
|
}
|
|
44
53
|
async createDocument(drive, id, document) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
name,
|
|
51
|
-
revision,
|
|
52
|
-
documentType,
|
|
53
|
-
created,
|
|
54
|
-
lastModified,
|
|
55
|
-
clipboard,
|
|
56
|
-
state,
|
|
57
|
-
};
|
|
54
|
+
await this.create(id, document);
|
|
55
|
+
// Update the drive manifest
|
|
56
|
+
const manifest = this.getDriveManifest(drive);
|
|
57
|
+
manifest.documentIds.add(id);
|
|
58
|
+
this.updateDriveManifest(drive, manifest);
|
|
58
59
|
}
|
|
59
60
|
async addDocumentOperations(drive, id, operations, header) {
|
|
60
61
|
const document = await this.getDocument(drive, id);
|
|
@@ -62,17 +63,23 @@ export class MemoryStorage {
|
|
|
62
63
|
throw new Error(`Document with id ${id} not found`);
|
|
63
64
|
}
|
|
64
65
|
const mergedOperations = mergeOperations(document.operations, operations);
|
|
65
|
-
this.documents[
|
|
66
|
+
this.documents[id] = {
|
|
66
67
|
...document,
|
|
67
68
|
...header,
|
|
68
69
|
operations: mergedOperations,
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
async deleteDocument(drive, id) {
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
// delete the document from all drive manifests
|
|
74
|
+
const drives = await this.getDrives();
|
|
75
|
+
for (const driveId of drives) {
|
|
76
|
+
const manifest = this.getDriveManifest(driveId);
|
|
77
|
+
if (manifest.documentIds.has(id)) {
|
|
78
|
+
manifest.documentIds.delete(id);
|
|
79
|
+
this.updateDriveManifest(driveId, manifest);
|
|
80
|
+
}
|
|
74
81
|
}
|
|
75
|
-
delete this.documents[
|
|
82
|
+
delete this.documents[id];
|
|
76
83
|
}
|
|
77
84
|
async getDrives() {
|
|
78
85
|
return Object.keys(this.drives);
|
|
@@ -93,7 +100,8 @@ export class MemoryStorage {
|
|
|
93
100
|
}
|
|
94
101
|
async createDrive(id, drive) {
|
|
95
102
|
this.drives[id] = drive;
|
|
96
|
-
|
|
103
|
+
// Initialize an empty manifest for the new drive
|
|
104
|
+
this.updateDriveManifest(id, { documentIds: new Set() });
|
|
97
105
|
const { slug } = drive.initialState.state.global;
|
|
98
106
|
if (slug) {
|
|
99
107
|
this.slugToDriveId[slug] = id;
|
|
@@ -109,8 +117,31 @@ export class MemoryStorage {
|
|
|
109
117
|
};
|
|
110
118
|
}
|
|
111
119
|
async deleteDrive(id) {
|
|
112
|
-
|
|
120
|
+
// Get all documents in this drive
|
|
121
|
+
const manifest = this.getDriveManifest(id);
|
|
122
|
+
// delete each document that belongs only to this drive
|
|
123
|
+
const drives = await this.getDrives();
|
|
124
|
+
await Promise.all([...manifest.documentIds].map((docId) => {
|
|
125
|
+
for (const driveId of drives) {
|
|
126
|
+
if (driveId === id) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const manifest = this.getDriveManifest(driveId);
|
|
130
|
+
if (manifest.documentIds.has(docId)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
delete this.documents[docId];
|
|
135
|
+
}));
|
|
136
|
+
// Delete the drive manifest and the drive itself
|
|
137
|
+
delete this.driveManifests[id];
|
|
113
138
|
delete this.drives[id];
|
|
139
|
+
// Clean up slug mapping if needed
|
|
140
|
+
for (const [slug, driveId] of Object.entries(this.slugToDriveId)) {
|
|
141
|
+
if (driveId === id) {
|
|
142
|
+
delete this.slugToDriveId[slug];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
114
145
|
}
|
|
115
146
|
async getSynchronizationUnitsRevision(units) {
|
|
116
147
|
const results = await Promise.allSettled(units.map(async (unit) => {
|
|
@@ -144,4 +175,16 @@ export class MemoryStorage {
|
|
|
144
175
|
return acc;
|
|
145
176
|
}, []);
|
|
146
177
|
}
|
|
178
|
+
////////////////////////////////
|
|
179
|
+
// Private
|
|
180
|
+
////////////////////////////////
|
|
181
|
+
getDriveManifest(driveId) {
|
|
182
|
+
if (!this.driveManifests[driveId]) {
|
|
183
|
+
this.driveManifests[driveId] = { documentIds: new Set() };
|
|
184
|
+
}
|
|
185
|
+
return this.driveManifests[driveId];
|
|
186
|
+
}
|
|
187
|
+
updateDriveManifest(driveId, manifest) {
|
|
188
|
+
this.driveManifests[driveId] = manifest;
|
|
189
|
+
}
|
|
147
190
|
}
|
|
@@ -3,7 +3,7 @@ import type { BaseStateFromDocument, DocumentHeader, Operation, OperationFromDoc
|
|
|
3
3
|
import { type IBackOffOptions } from "exponential-backoff";
|
|
4
4
|
import { type DocumentDriveAction, type DocumentDriveDocument } from "../../drive-document-model/gen/types.js";
|
|
5
5
|
import { type SynchronizationUnitQuery } from "../../server/types.js";
|
|
6
|
-
import {
|
|
6
|
+
import type { IDocumentStorage, IDriveStorage, IStorageDelegate } from "../types.js";
|
|
7
7
|
export * from "./factory.js";
|
|
8
8
|
type Transaction = Omit<PrismaClient<Prisma.PrismaClientOptions, never>, "$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends"> | ExtendedPrismaClient;
|
|
9
9
|
export type PrismaStorageOptions = {
|
|
@@ -25,10 +25,12 @@ declare function getRetryTransactionsClient<T extends PrismaClient>(prisma: T, b
|
|
|
25
25
|
};
|
|
26
26
|
}, {}>;
|
|
27
27
|
type ExtendedPrismaClient = ReturnType<typeof getRetryTransactionsClient<PrismaClient>>;
|
|
28
|
-
export declare class PrismaStorage implements IDriveStorage {
|
|
28
|
+
export declare class PrismaStorage implements IDriveStorage, IDocumentStorage {
|
|
29
29
|
private db;
|
|
30
30
|
private delegate;
|
|
31
31
|
constructor(db: PrismaClient, options?: PrismaStorageOptions);
|
|
32
|
+
exists(documentId: string): Promise<boolean>;
|
|
33
|
+
create(documentId: string, document: PHDocument): Promise<void>;
|
|
32
34
|
setStorageDelegate(delegate: IStorageDelegate): void;
|
|
33
35
|
createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
|
|
34
36
|
addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,KAAK,EAEV,qBAAqB,EACrB,cAAc,EAGd,SAAS,EACT,qBAAqB,EAGrB,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAW,MAAM,qBAAqB,CAAC;AACpE,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
|
2
2
|
import { backOff } from "exponential-backoff";
|
|
3
|
-
import { ConflictOperationError
|
|
3
|
+
import { ConflictOperationError } from "../../server/error.js";
|
|
4
4
|
import { logger } from "../../utils/logger.js";
|
|
5
5
|
export * from "./factory.js";
|
|
6
6
|
function storageToOperation(op) {
|
|
@@ -54,22 +54,88 @@ export class PrismaStorage {
|
|
|
54
54
|
jitter: backOffOptions?.jitter ?? "full",
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
////////////////////////////////
|
|
58
|
+
// IDocumentStorage
|
|
59
|
+
////////////////////////////////
|
|
60
|
+
async exists(documentId) {
|
|
61
|
+
const count = await this.db.document.count({
|
|
62
|
+
where: {
|
|
63
|
+
id: documentId,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
return count > 0;
|
|
67
|
+
}
|
|
68
|
+
async create(documentId, document) {
|
|
69
|
+
await this.db.document.upsert({
|
|
70
|
+
where: {
|
|
71
|
+
id: documentId,
|
|
72
|
+
},
|
|
73
|
+
update: {},
|
|
74
|
+
create: {
|
|
75
|
+
name: document.name,
|
|
76
|
+
documentType: document.documentType,
|
|
77
|
+
isDrive: false,
|
|
78
|
+
initialState: JSON.stringify(document.initialState),
|
|
79
|
+
lastModified: document.lastModified,
|
|
80
|
+
revision: JSON.stringify(document.revision),
|
|
81
|
+
meta: document.meta ? JSON.stringify(document.meta) : undefined,
|
|
82
|
+
id: documentId,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
////////////////////////////////
|
|
87
|
+
// IDriveStorage
|
|
88
|
+
////////////////////////////////
|
|
57
89
|
setStorageDelegate(delegate) {
|
|
58
90
|
this.delegate = delegate;
|
|
59
91
|
}
|
|
60
92
|
async createDrive(id, drive) {
|
|
61
|
-
|
|
62
|
-
|
|
93
|
+
const doc = {
|
|
94
|
+
name: drive.name,
|
|
95
|
+
documentType: drive.documentType,
|
|
96
|
+
isDrive: true,
|
|
97
|
+
initialState: JSON.stringify(drive.initialState),
|
|
98
|
+
lastModified: drive.lastModified,
|
|
99
|
+
revision: JSON.stringify(drive.revision),
|
|
100
|
+
meta: drive.meta ? JSON.stringify(drive.meta) : undefined,
|
|
101
|
+
id,
|
|
102
|
+
};
|
|
103
|
+
await this.db.document.upsert({
|
|
104
|
+
where: {
|
|
105
|
+
id,
|
|
106
|
+
},
|
|
107
|
+
update: doc,
|
|
108
|
+
create: doc,
|
|
109
|
+
});
|
|
110
|
+
// backwards compatibility -- if the drive has a slug, check if it already exists
|
|
111
|
+
if (drive.initialState.state.global.slug) {
|
|
112
|
+
const existingDrive = await this.db.drive.findFirst({
|
|
113
|
+
where: {
|
|
114
|
+
slug: drive.initialState.state.global.slug,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
if (existingDrive) {
|
|
118
|
+
await this.db.drive.update({
|
|
119
|
+
where: { id: existingDrive.id },
|
|
120
|
+
data: {
|
|
121
|
+
id,
|
|
122
|
+
slug: drive.initialState.state.global.slug,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
63
128
|
await this.db.drive.upsert({
|
|
64
129
|
where: {
|
|
65
|
-
|
|
130
|
+
id,
|
|
66
131
|
},
|
|
67
132
|
create: {
|
|
68
|
-
id
|
|
133
|
+
id,
|
|
69
134
|
slug: drive.initialState.state.global.slug ?? id,
|
|
70
135
|
},
|
|
71
136
|
update: {
|
|
72
137
|
id,
|
|
138
|
+
slug: drive.initialState.state.global.slug ?? id,
|
|
73
139
|
},
|
|
74
140
|
});
|
|
75
141
|
}
|
|
@@ -80,24 +146,15 @@ export class PrismaStorage {
|
|
|
80
146
|
return this.addDocumentOperationsWithTransaction("drives", drive, (document) => callback(document));
|
|
81
147
|
}
|
|
82
148
|
async createDocument(drive, id, document) {
|
|
83
|
-
await this.
|
|
149
|
+
await this.create(id, document);
|
|
150
|
+
// create the many-to-many relation
|
|
151
|
+
await this.db.document.update({
|
|
84
152
|
where: {
|
|
85
|
-
id_driveId: {
|
|
86
|
-
id,
|
|
87
|
-
driveId: drive,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
update: {},
|
|
91
|
-
create: {
|
|
92
|
-
name: document.name,
|
|
93
|
-
documentType: document.documentType,
|
|
94
|
-
driveId: drive,
|
|
95
|
-
initialState: JSON.stringify(document.initialState),
|
|
96
|
-
lastModified: document.lastModified,
|
|
97
|
-
revision: JSON.stringify(document.revision),
|
|
98
|
-
meta: document.meta ? JSON.stringify(document.meta) : undefined,
|
|
99
153
|
id,
|
|
100
154
|
},
|
|
155
|
+
data: {
|
|
156
|
+
driveDocuments: { create: { driveId: drive } },
|
|
157
|
+
},
|
|
101
158
|
});
|
|
102
159
|
}
|
|
103
160
|
async _addDocumentOperations(tx, drive, id, operations, header) {
|
|
@@ -124,7 +181,6 @@ export class PrismaStorage {
|
|
|
124
181
|
await tx.document.updateMany({
|
|
125
182
|
where: {
|
|
126
183
|
id,
|
|
127
|
-
driveId: drive,
|
|
128
184
|
},
|
|
129
185
|
data: {
|
|
130
186
|
lastModified: header.lastModified,
|
|
@@ -210,10 +266,9 @@ export class PrismaStorage {
|
|
|
210
266
|
id: true,
|
|
211
267
|
},
|
|
212
268
|
where: {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
id: "drives",
|
|
269
|
+
driveDocuments: {
|
|
270
|
+
some: {
|
|
271
|
+
driveId: drive,
|
|
217
272
|
},
|
|
218
273
|
},
|
|
219
274
|
},
|
|
@@ -224,21 +279,31 @@ export class PrismaStorage {
|
|
|
224
279
|
const count = await this.db.document.count({
|
|
225
280
|
where: {
|
|
226
281
|
id: id,
|
|
227
|
-
|
|
282
|
+
driveDocuments: {
|
|
283
|
+
some: {
|
|
284
|
+
driveId: driveId,
|
|
285
|
+
},
|
|
286
|
+
},
|
|
228
287
|
},
|
|
229
288
|
});
|
|
230
289
|
return count > 0;
|
|
231
290
|
}
|
|
232
291
|
async getDocument(driveId, id, tx) {
|
|
233
292
|
const prisma = tx ?? this.db;
|
|
234
|
-
const
|
|
293
|
+
const query = {
|
|
235
294
|
where: {
|
|
236
|
-
|
|
295
|
+
id,
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
if (driveId !== "drives") {
|
|
299
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
300
|
+
query.where.driveDocuments = {
|
|
301
|
+
some: {
|
|
237
302
|
driveId,
|
|
238
|
-
id,
|
|
239
303
|
},
|
|
240
|
-
}
|
|
241
|
-
}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const result = await prisma.document.findUnique(query);
|
|
242
307
|
if (result === null) {
|
|
243
308
|
throw new Error(`Document with id ${id} not found`);
|
|
244
309
|
}
|
|
@@ -327,10 +392,25 @@ export class PrismaStorage {
|
|
|
327
392
|
}
|
|
328
393
|
async deleteDocument(drive, id) {
|
|
329
394
|
try {
|
|
395
|
+
// delete out of drives
|
|
396
|
+
await this.db.drive.deleteMany({
|
|
397
|
+
where: {
|
|
398
|
+
driveDocuments: {
|
|
399
|
+
none: {
|
|
400
|
+
documentId: id,
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
// delete document
|
|
330
406
|
await this.db.document.deleteMany({
|
|
331
407
|
where: {
|
|
332
|
-
|
|
333
|
-
|
|
408
|
+
driveDocuments: {
|
|
409
|
+
some: {
|
|
410
|
+
driveId: drive,
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
id,
|
|
334
414
|
},
|
|
335
415
|
});
|
|
336
416
|
}
|
|
@@ -345,17 +425,15 @@ export class PrismaStorage {
|
|
|
345
425
|
}
|
|
346
426
|
}
|
|
347
427
|
async getDrives() {
|
|
348
|
-
|
|
428
|
+
const drives = await this.db.drive.findMany({
|
|
429
|
+
select: {
|
|
430
|
+
id: true,
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
return drives.map((d) => d.id);
|
|
349
434
|
}
|
|
350
435
|
async getDrive(id) {
|
|
351
|
-
|
|
352
|
-
const doc = await this.getDocument("drives", id);
|
|
353
|
-
return doc;
|
|
354
|
-
}
|
|
355
|
-
catch (e) {
|
|
356
|
-
logger.error(e);
|
|
357
|
-
throw new DriveNotFoundError(id);
|
|
358
|
-
}
|
|
436
|
+
return this.getDocument("drives", id);
|
|
359
437
|
}
|
|
360
438
|
async getDriveBySlug(slug) {
|
|
361
439
|
const driveEntity = await this.db.drive.findFirst({
|
|
@@ -369,18 +447,26 @@ export class PrismaStorage {
|
|
|
369
447
|
return this.getDrive(driveEntity.id);
|
|
370
448
|
}
|
|
371
449
|
async deleteDrive(id) {
|
|
372
|
-
// delete drive
|
|
373
|
-
await this.db.drive.
|
|
450
|
+
// delete drive
|
|
451
|
+
await this.db.drive.delete({
|
|
374
452
|
where: {
|
|
375
453
|
id,
|
|
376
454
|
},
|
|
377
455
|
});
|
|
378
|
-
// delete drive document
|
|
379
|
-
await this.
|
|
380
|
-
|
|
456
|
+
// delete drive document (will cascade)
|
|
457
|
+
await this.db.document.delete({
|
|
458
|
+
where: {
|
|
459
|
+
id,
|
|
460
|
+
},
|
|
461
|
+
});
|
|
462
|
+
// deletes all documents that only belong to this drive
|
|
381
463
|
await this.db.document.deleteMany({
|
|
382
464
|
where: {
|
|
383
|
-
|
|
465
|
+
driveDocuments: {
|
|
466
|
+
none: {
|
|
467
|
+
driveId: id,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
384
470
|
},
|
|
385
471
|
});
|
|
386
472
|
}
|
|
@@ -1,33 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { type SynchronizationUnitQuery } from "#server/types";
|
|
3
|
-
import { type AttachmentInput, type DocumentHeader, type Operation, type PHDocument } from "document-model";
|
|
4
|
-
import { type Options, Sequelize } from "sequelize";
|
|
5
|
-
import { type IDocumentStorage, type IDriveStorage } from "./types.js";
|
|
6
|
-
export declare class SequelizeStorage implements IDriveStorage, IDocumentStorage {
|
|
7
|
-
private db;
|
|
8
|
-
constructor(options: Options);
|
|
9
|
-
syncModels(): Promise<Sequelize>;
|
|
10
|
-
createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
|
|
11
|
-
addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
|
|
12
|
-
createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
|
|
13
|
-
addDocumentOperations(drive: string, id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
|
|
14
|
-
_addDocumentOperationAttachments(driveId: string, documentId: string, operation: Operation, attachments: AttachmentInput[]): Promise<import("sequelize").Model<any, any>[]>;
|
|
15
|
-
getDocuments(drive: string): Promise<string[]>;
|
|
16
|
-
exists(id: string): Promise<boolean>;
|
|
17
|
-
checkDocumentExists(drive: string, id: string): Promise<boolean>;
|
|
18
|
-
getDocument<TDocument extends PHDocument>(driveId: string, id: string): Promise<TDocument>;
|
|
19
|
-
deleteDocument(drive: string, id: string): Promise<void>;
|
|
20
|
-
getDrives(): Promise<string[]>;
|
|
21
|
-
getDrive(id: string): Promise<DocumentDriveDocument>;
|
|
22
|
-
getDriveBySlug(slug: string): Promise<DocumentDriveDocument>;
|
|
23
|
-
deleteDrive(id: string): Promise<void>;
|
|
24
|
-
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
|
|
25
|
-
driveId: string;
|
|
26
|
-
documentId: string;
|
|
27
|
-
scope: string;
|
|
28
|
-
branch: string;
|
|
29
|
-
lastUpdated: string;
|
|
30
|
-
revision: number;
|
|
31
|
-
}[]>;
|
|
32
|
-
}
|
|
1
|
+
export {};
|
|
33
2
|
//# sourceMappingURL=sequelize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequelize.d.ts","sourceRoot":"","sources":["../../../src/storage/sequelize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sequelize.d.ts","sourceRoot":"","sources":["../../../src/storage/sequelize.ts"],"names":[],"mappings":""}
|