vintasend 0.4.17 → 0.5.0-alpha2
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/services/attachment-manager/base-attachment-manager.d.ts +5 -9
- package/dist/services/attachment-manager/local-file-attachment-manager.d.ts +7 -3
- package/dist/services/attachment-manager/local-file-attachment-manager.js +26 -8
- package/dist/services/notification-backends/base-notification-backend.d.ts +15 -1
- package/dist/services/notification-backends/base-notification-backend.js +2 -1
- package/dist/types/attachment.d.ts +36 -2
- package/package.json +2 -1
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import type { AttachmentFile, AttachmentFileRecord, FileAttachment } from '../../types/attachment';
|
|
1
|
+
import type { AttachmentFile, AttachmentFileRecord, FileAttachment, StorageIdentifiers } from '../../types/attachment';
|
|
2
2
|
export declare abstract class BaseAttachmentManager {
|
|
3
3
|
/**
|
|
4
4
|
* Upload a file and return file record (reusable across notifications)
|
|
5
5
|
*/
|
|
6
6
|
abstract uploadFile(file: FileAttachment, filename: string, contentType?: string): Promise<AttachmentFileRecord>;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Reconstruct AttachmentFile from storage identifiers
|
|
9
9
|
*/
|
|
10
|
-
abstract
|
|
10
|
+
abstract reconstructAttachmentFile(storageIdentifiers: StorageIdentifiers): AttachmentFile;
|
|
11
11
|
/**
|
|
12
|
-
* Delete a file
|
|
12
|
+
* Delete a file from storage using its identifiers
|
|
13
13
|
*/
|
|
14
|
-
abstract
|
|
15
|
-
/**
|
|
16
|
-
* Reconstruct AttachmentFile from storage metadata
|
|
17
|
-
*/
|
|
18
|
-
abstract reconstructAttachmentFile(storageMetadata: Record<string, unknown>): AttachmentFile;
|
|
14
|
+
abstract deleteFileByIdentifiers(storageIdentifiers: StorageIdentifiers): Promise<void>;
|
|
19
15
|
/**
|
|
20
16
|
* Detect content type from filename
|
|
21
17
|
* Public to allow backends and custom implementations to use it
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AttachmentFile, AttachmentFileRecord, FileAttachment } from '../../types/attachment';
|
|
1
|
+
import type { AttachmentFile, AttachmentFileRecord, FileAttachment, StorageIdentifiers } from '../../types/attachment';
|
|
2
2
|
import { BaseAttachmentManager } from './base-attachment-manager';
|
|
3
3
|
/**
|
|
4
4
|
* Configuration options for LocalFileAttachmentManager
|
|
@@ -56,7 +56,11 @@ export declare class LocalFileAttachmentManager extends BaseAttachmentManager {
|
|
|
56
56
|
*/
|
|
57
57
|
deleteFile(fileId: string): Promise<void>;
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* Delete a file from the local filesystem using storage identifiers
|
|
60
60
|
*/
|
|
61
|
-
|
|
61
|
+
deleteFileByIdentifiers(storageIdentifiers: StorageIdentifiers): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Reconstruct an AttachmentFile interface from stored identifiers
|
|
64
|
+
*/
|
|
65
|
+
reconstructAttachmentFile(storageIdentifiers: StorageIdentifiers): AttachmentFile;
|
|
62
66
|
}
|
|
@@ -119,7 +119,8 @@ class LocalFileAttachmentManager extends base_attachment_manager_1.BaseAttachmen
|
|
|
119
119
|
contentType: finalContentType,
|
|
120
120
|
size,
|
|
121
121
|
checksum,
|
|
122
|
-
|
|
122
|
+
storageIdentifiers: {
|
|
123
|
+
id: fileId,
|
|
123
124
|
path: filePath,
|
|
124
125
|
backend: 'local-filesystem',
|
|
125
126
|
},
|
|
@@ -147,7 +148,8 @@ class LocalFileAttachmentManager extends base_attachment_manager_1.BaseAttachmen
|
|
|
147
148
|
contentType: metadata.contentType,
|
|
148
149
|
size: metadata.size,
|
|
149
150
|
checksum: metadata.checksum,
|
|
150
|
-
|
|
151
|
+
storageIdentifiers: {
|
|
152
|
+
id: metadata.id,
|
|
151
153
|
path: filePath,
|
|
152
154
|
backend: 'local-filesystem',
|
|
153
155
|
},
|
|
@@ -169,7 +171,8 @@ class LocalFileAttachmentManager extends base_attachment_manager_1.BaseAttachmen
|
|
|
169
171
|
contentType: 'application/octet-stream', // Unknown
|
|
170
172
|
size: stats.size,
|
|
171
173
|
checksum,
|
|
172
|
-
|
|
174
|
+
storageIdentifiers: {
|
|
175
|
+
id: fileId,
|
|
173
176
|
path: filePath,
|
|
174
177
|
backend: 'local-filesystem',
|
|
175
178
|
},
|
|
@@ -210,13 +213,28 @@ class LocalFileAttachmentManager extends base_attachment_manager_1.BaseAttachmen
|
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
/**
|
|
213
|
-
*
|
|
216
|
+
* Delete a file from the local filesystem using storage identifiers
|
|
214
217
|
*/
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
+
async deleteFileByIdentifiers(storageIdentifiers) {
|
|
219
|
+
if (storageIdentifiers.id && typeof storageIdentifiers.id === 'string') {
|
|
220
|
+
await this.deleteFile(storageIdentifiers.id);
|
|
221
|
+
return;
|
|
218
222
|
}
|
|
219
|
-
|
|
223
|
+
if (storageIdentifiers.path && typeof storageIdentifiers.path === 'string') {
|
|
224
|
+
const fileId = path.basename(storageIdentifiers.path);
|
|
225
|
+
await this.deleteFile(fileId);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
throw new Error('Invalid storage identifiers: missing id or path');
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Reconstruct an AttachmentFile interface from stored identifiers
|
|
232
|
+
*/
|
|
233
|
+
reconstructAttachmentFile(storageIdentifiers) {
|
|
234
|
+
if (!storageIdentifiers.path || typeof storageIdentifiers.path !== 'string') {
|
|
235
|
+
throw new Error('Invalid storage identifiers: missing path');
|
|
236
|
+
}
|
|
237
|
+
const filePath = storageIdentifiers.path;
|
|
220
238
|
return new LocalAttachmentFile(filePath, this);
|
|
221
239
|
}
|
|
222
240
|
}
|
|
@@ -34,6 +34,19 @@ export interface BaseNotificationBackend<Config extends BaseNotificationTypeConf
|
|
|
34
34
|
*/
|
|
35
35
|
injectLogger?(logger: BaseLogger): void;
|
|
36
36
|
/**
|
|
37
|
+
* Store attachment file record in database.
|
|
38
|
+
* Called after AttachmentManager.uploadFile() returns storageIdentifiers.
|
|
39
|
+
* Backend persists file metadata and storage identifiers for later retrieval.
|
|
40
|
+
*/
|
|
41
|
+
storeAttachmentFileRecord?(record: AttachmentFileRecord): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Get attachment file record from database by ID.
|
|
44
|
+
* Returns the file metadata and storage identifiers needed to reconstruct file access.
|
|
45
|
+
* Used by AttachmentManager.reconstructAttachmentFile() to get file content.
|
|
46
|
+
*/
|
|
47
|
+
getAttachmentFileRecord?(fileId: string): Promise<AttachmentFileRecord | null>;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Use getAttachmentFileRecord instead.
|
|
37
50
|
* Get an attachment file record by ID
|
|
38
51
|
*/
|
|
39
52
|
getAttachmentFile?(fileId: string): Promise<AttachmentFileRecord | null>;
|
|
@@ -64,7 +77,8 @@ export interface BaseNotificationBackend<Config extends BaseNotificationTypeConf
|
|
|
64
77
|
* Type guard to check if backend supports attachment operations
|
|
65
78
|
*/
|
|
66
79
|
export declare function supportsAttachments<Config extends BaseNotificationTypeConfig>(backend: BaseNotificationBackend<Config>): backend is BaseNotificationBackend<Config> & {
|
|
67
|
-
|
|
80
|
+
storeAttachmentFileRecord(record: AttachmentFileRecord): Promise<void>;
|
|
81
|
+
getAttachmentFileRecord(fileId: string): Promise<AttachmentFileRecord | null>;
|
|
68
82
|
findAttachmentFileByChecksum(checksum: string): Promise<AttachmentFileRecord | null>;
|
|
69
83
|
deleteAttachmentFile(fileId: string): Promise<void>;
|
|
70
84
|
getOrphanedAttachmentFiles(): Promise<AttachmentFileRecord[]>;
|
|
@@ -5,7 +5,8 @@ exports.supportsAttachments = supportsAttachments;
|
|
|
5
5
|
* Type guard to check if backend supports attachment operations
|
|
6
6
|
*/
|
|
7
7
|
function supportsAttachments(backend) {
|
|
8
|
-
return (typeof backend.
|
|
8
|
+
return (typeof backend.storeAttachmentFileRecord === 'function' &&
|
|
9
|
+
typeof backend.getAttachmentFileRecord === 'function' &&
|
|
9
10
|
typeof backend.findAttachmentFileByChecksum === 'function' &&
|
|
10
11
|
typeof backend.deleteAttachmentFile === 'function' &&
|
|
11
12
|
typeof backend.getOrphanedAttachmentFiles === 'function' &&
|
|
@@ -18,15 +18,49 @@ export interface AttachmentFile {
|
|
|
18
18
|
url(expiresIn?: number): Promise<string>;
|
|
19
19
|
delete(): Promise<void>;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Generic storage identifiers returned by AttachmentManagers.
|
|
23
|
+
* Backends persist these as opaque data and pass them back for file reconstruction.
|
|
24
|
+
* Each AttachmentManager implementation defines its own specific structure.
|
|
25
|
+
*
|
|
26
|
+
* @example MedplumStorageIdentifiers
|
|
27
|
+
* ```typescript
|
|
28
|
+
* {
|
|
29
|
+
* id: "media-123",
|
|
30
|
+
* medplumBinaryId: "binary-456",
|
|
31
|
+
* medplumMediaId: "media-123",
|
|
32
|
+
* url: "Binary/binary-456"
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example S3StorageIdentifiers
|
|
37
|
+
* ```typescript
|
|
38
|
+
* {
|
|
39
|
+
* id: "file-123",
|
|
40
|
+
* awsS3Bucket: "my-bucket",
|
|
41
|
+
* awsS3Key: "uploads/file-123.pdf",
|
|
42
|
+
* awsS3Region: "us-east-1"
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export interface StorageIdentifiers {
|
|
47
|
+
id: string;
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Complete file record returned after upload.
|
|
52
|
+
* Contains both file metadata and storage identifiers.
|
|
53
|
+
* Storage identifiers are opaque to backends - used only for reconstruction.
|
|
54
|
+
*/
|
|
21
55
|
export interface AttachmentFileRecord {
|
|
22
56
|
id: string;
|
|
23
57
|
filename: string;
|
|
24
58
|
contentType: string;
|
|
25
59
|
size: number;
|
|
26
60
|
checksum: string;
|
|
27
|
-
storageMetadata: Record<string, unknown>;
|
|
28
61
|
createdAt: Date;
|
|
29
62
|
updatedAt: Date;
|
|
63
|
+
storageIdentifiers: StorageIdentifiers;
|
|
30
64
|
}
|
|
31
65
|
export interface StoredAttachment {
|
|
32
66
|
id: string;
|
|
@@ -38,5 +72,5 @@ export interface StoredAttachment {
|
|
|
38
72
|
createdAt: Date;
|
|
39
73
|
file: AttachmentFile;
|
|
40
74
|
description?: string;
|
|
41
|
-
storageMetadata:
|
|
75
|
+
storageMetadata: StorageIdentifiers;
|
|
42
76
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vintasend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-alpha2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"release:bump": "node scripts/release-bump.js",
|
|
20
20
|
"release:bump:patch": "node scripts/release-bump.js --bump=patch",
|
|
21
21
|
"release:bump:minor": "node scripts/release-bump.js --bump=minor",
|
|
22
|
+
"release:bump:alpha": "node scripts/release-bump.js --bump=alpha",
|
|
22
23
|
"release:publish": "node scripts/release-publish.js"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|