@edgebasejs/client-core 0.1.7 → 0.1.9
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 +15 -0
- package/dist/client-core/src/index.d.ts +4 -0
- package/dist/client-core/src/index.d.ts.map +1 -1
- package/dist/client-core/src/index.js +4 -0
- package/dist/client-core/src/index.js.map +1 -1
- package/dist/client-core/src/mutations/batch-processor-client.d.ts +67 -0
- package/dist/client-core/src/mutations/batch-processor-client.d.ts.map +1 -0
- package/dist/client-core/src/mutations/batch-processor-client.js +64 -0
- package/dist/client-core/src/mutations/batch-processor-client.js.map +1 -0
- package/dist/client-core/src/mutations/transaction-hook.d.ts +80 -0
- package/dist/client-core/src/mutations/transaction-hook.d.ts.map +1 -0
- package/dist/client-core/src/mutations/transaction-hook.js +204 -0
- package/dist/client-core/src/mutations/transaction-hook.js.map +1 -0
- package/dist/client-core/src/realtime/realtime-sync-manager.d.ts +55 -0
- package/dist/client-core/src/realtime/realtime-sync-manager.d.ts.map +1 -0
- package/dist/client-core/src/realtime/realtime-sync-manager.js +208 -0
- package/dist/client-core/src/realtime/realtime-sync-manager.js.map +1 -0
- package/dist/client-core/src/realtime/subscription-handler.d.ts +74 -0
- package/dist/client-core/src/realtime/subscription-handler.d.ts.map +1 -0
- package/dist/client-core/src/realtime/subscription-handler.js +224 -0
- package/dist/client-core/src/realtime/subscription-handler.js.map +1 -0
- package/dist/client-core/src/sync/sync-engine.d.ts +10 -0
- package/dist/client-core/src/sync/sync-engine.d.ts.map +1 -1
- package/dist/client-core/src/sync/sync-engine.js +37 -5
- package/dist/client-core/src/sync/sync-engine.js.map +1 -1
- package/dist/core/src/access-rules/column-security.d.ts +80 -0
- package/dist/core/src/access-rules/column-security.d.ts.map +1 -0
- package/dist/core/src/access-rules/column-security.js +191 -0
- package/dist/core/src/access-rules/column-security.js.map +1 -0
- package/dist/core/src/access-rules/engine.d.ts +26 -0
- package/dist/core/src/access-rules/engine.d.ts.map +1 -0
- package/dist/core/src/access-rules/engine.js +76 -0
- package/dist/core/src/access-rules/engine.js.map +1 -0
- package/dist/core/src/access-rules/index.d.ts +3 -0
- package/dist/core/src/access-rules/index.d.ts.map +1 -0
- package/dist/core/src/access-rules/index.js +3 -0
- package/dist/core/src/access-rules/index.js.map +1 -0
- package/dist/core/src/audit/audit-manager.d.ts +108 -0
- package/dist/core/src/audit/audit-manager.d.ts.map +1 -0
- package/dist/core/src/audit/audit-manager.js +265 -0
- package/dist/core/src/audit/audit-manager.js.map +1 -0
- package/dist/core/src/auth/auth-service.d.ts +71 -0
- package/dist/core/src/auth/auth-service.d.ts.map +1 -0
- package/dist/core/src/auth/auth-service.js +177 -0
- package/dist/core/src/auth/auth-service.js.map +1 -0
- package/dist/core/src/auth/index.d.ts +4 -0
- package/dist/core/src/auth/index.d.ts.map +1 -0
- package/dist/core/src/auth/index.js +4 -0
- package/dist/core/src/auth/index.js.map +1 -0
- package/dist/core/src/encryption/encryption-manager.d.ts +97 -0
- package/dist/core/src/encryption/encryption-manager.d.ts.map +1 -0
- package/dist/core/src/encryption/encryption-manager.js +224 -0
- package/dist/core/src/encryption/encryption-manager.js.map +1 -0
- package/dist/core/src/index.d.ts +16 -0
- package/dist/core/src/index.d.ts.map +1 -0
- package/dist/core/src/index.js +16 -0
- package/dist/core/src/index.js.map +1 -0
- package/dist/core/src/realtime/change-notifier.d.ts +50 -0
- package/dist/core/src/realtime/change-notifier.d.ts.map +1 -0
- package/dist/core/src/realtime/change-notifier.js +145 -0
- package/dist/core/src/realtime/change-notifier.js.map +1 -0
- package/dist/core/src/realtime/message-types.d.ts +39 -0
- package/dist/core/src/realtime/message-types.d.ts.map +1 -0
- package/dist/core/src/realtime/message-types.js +5 -0
- package/dist/core/src/realtime/message-types.js.map +1 -0
- package/dist/core/src/realtime/subscription-manager.d.ts +67 -0
- package/dist/core/src/realtime/subscription-manager.d.ts.map +1 -0
- package/dist/core/src/realtime/subscription-manager.js +229 -0
- package/dist/core/src/realtime/subscription-manager.js.map +1 -0
- package/dist/core/src/search/search-manager.d.ts +93 -0
- package/dist/core/src/search/search-manager.d.ts.map +1 -0
- package/dist/core/src/search/search-manager.js +258 -0
- package/dist/core/src/search/search-manager.js.map +1 -0
- package/dist/core/src/storage/file-manager.d.ts +138 -0
- package/dist/core/src/storage/file-manager.d.ts.map +1 -0
- package/dist/core/src/storage/file-manager.js +224 -0
- package/dist/core/src/storage/file-manager.js.map +1 -0
- package/dist/core/src/sync/batch-processor.d.ts +97 -0
- package/dist/core/src/sync/batch-processor.d.ts.map +1 -0
- package/dist/core/src/sync/batch-processor.js +313 -0
- package/dist/core/src/sync/batch-processor.js.map +1 -0
- package/dist/core/src/sync/csv-processor.d.ts +66 -0
- package/dist/core/src/sync/csv-processor.d.ts.map +1 -0
- package/dist/core/src/sync/csv-processor.js +223 -0
- package/dist/core/src/sync/csv-processor.js.map +1 -0
- package/dist/core/src/sync/index.d.ts +3 -0
- package/dist/core/src/sync/index.d.ts.map +1 -0
- package/dist/core/src/sync/index.js +3 -0
- package/dist/core/src/sync/index.js.map +1 -0
- package/dist/core/src/sync/sync-engine.d.ts +68 -0
- package/dist/core/src/sync/sync-engine.d.ts.map +1 -0
- package/dist/core/src/sync/sync-engine.js +317 -0
- package/dist/core/src/sync/sync-engine.js.map +1 -0
- package/dist/core/src/sync/transaction-manager.d.ts +83 -0
- package/dist/core/src/sync/transaction-manager.d.ts.map +1 -0
- package/dist/core/src/sync/transaction-manager.js +227 -0
- package/dist/core/src/sync/transaction-manager.js.map +1 -0
- package/dist/core/src/webhooks/webhook-manager.d.ts +137 -0
- package/dist/core/src/webhooks/webhook-manager.d.ts.map +1 -0
- package/dist/core/src/webhooks/webhook-manager.js +334 -0
- package/dist/core/src/webhooks/webhook-manager.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/package.json +2 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File storage manager for Cloudflare R2
|
|
3
|
+
* Handles upload, download, and file metadata management
|
|
4
|
+
*/
|
|
5
|
+
import type { User } from '@edgebasejs/types';
|
|
6
|
+
export interface R2Bucket {
|
|
7
|
+
put(key: string, value: ReadableStream | ArrayBuffer | string, options?: R2PutOptions): Promise<R2Object>;
|
|
8
|
+
get(key: string, options?: R2GetOptions): Promise<R2ObjectBody | null>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
head(key: string): Promise<R2Object | null>;
|
|
11
|
+
list(options?: R2ListOptions): Promise<R2Objects>;
|
|
12
|
+
}
|
|
13
|
+
export interface R2PutOptions {
|
|
14
|
+
httpMetadata?: R2HTTPMetadata;
|
|
15
|
+
customMetadata?: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export interface R2GetOptions {
|
|
18
|
+
range?: {
|
|
19
|
+
offset?: number;
|
|
20
|
+
length?: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface R2ListOptions {
|
|
24
|
+
prefix?: string;
|
|
25
|
+
limit?: number;
|
|
26
|
+
cursor?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface R2HTTPMetadata {
|
|
29
|
+
contentType?: string;
|
|
30
|
+
contentLanguage?: string;
|
|
31
|
+
contentDisposition?: string;
|
|
32
|
+
contentEncoding?: string;
|
|
33
|
+
cacheControl?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface R2Object {
|
|
36
|
+
key: string;
|
|
37
|
+
version: string;
|
|
38
|
+
size: number;
|
|
39
|
+
etag: string;
|
|
40
|
+
httpMetadata?: R2HTTPMetadata;
|
|
41
|
+
customMetadata?: Record<string, string>;
|
|
42
|
+
uploaded: Date;
|
|
43
|
+
}
|
|
44
|
+
export interface R2ObjectBody extends R2Object {
|
|
45
|
+
body: ReadableStream;
|
|
46
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
47
|
+
text(): Promise<string>;
|
|
48
|
+
json<T>(): Promise<T>;
|
|
49
|
+
blob(): Promise<Blob>;
|
|
50
|
+
}
|
|
51
|
+
export interface R2Objects {
|
|
52
|
+
objects: R2Object[];
|
|
53
|
+
truncated: boolean;
|
|
54
|
+
cursor?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface FileMetadata {
|
|
57
|
+
id: string;
|
|
58
|
+
key: string;
|
|
59
|
+
fileName: string;
|
|
60
|
+
mimeType: string;
|
|
61
|
+
size: number;
|
|
62
|
+
userId: string;
|
|
63
|
+
bucket: string;
|
|
64
|
+
entityType?: string;
|
|
65
|
+
entityId?: string;
|
|
66
|
+
isPublic: boolean;
|
|
67
|
+
uploadedAt: number;
|
|
68
|
+
expiresAt?: number;
|
|
69
|
+
checksum?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface UploadOptions {
|
|
72
|
+
fileName: string;
|
|
73
|
+
mimeType: string;
|
|
74
|
+
size: number;
|
|
75
|
+
entityType?: string;
|
|
76
|
+
entityId?: string;
|
|
77
|
+
isPublic?: boolean;
|
|
78
|
+
expiresIn?: number;
|
|
79
|
+
maxSize?: number;
|
|
80
|
+
}
|
|
81
|
+
export interface FileDatabase {
|
|
82
|
+
run(sql: string, params: any[]): Promise<any>;
|
|
83
|
+
getOne(sql: string, params: any[]): Promise<any>;
|
|
84
|
+
getAll(sql: string, params: any[]): Promise<any[]>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* File storage manager
|
|
88
|
+
*/
|
|
89
|
+
export declare class FileStorageManager {
|
|
90
|
+
private bucket;
|
|
91
|
+
private db;
|
|
92
|
+
private maxFileSize;
|
|
93
|
+
private allowedMimeTypes?;
|
|
94
|
+
constructor(bucket: R2Bucket, db: FileDatabase, options?: {
|
|
95
|
+
maxFileSize?: number;
|
|
96
|
+
allowedMimeTypes?: string[];
|
|
97
|
+
});
|
|
98
|
+
/**
|
|
99
|
+
* Upload a file to R2
|
|
100
|
+
*/
|
|
101
|
+
uploadFile(user: User, file: ReadableStream | ArrayBuffer | string, options: UploadOptions): Promise<FileMetadata>;
|
|
102
|
+
/**
|
|
103
|
+
* Download a file from R2
|
|
104
|
+
*/
|
|
105
|
+
downloadFile(fileId: string, user: User): Promise<R2ObjectBody | null>;
|
|
106
|
+
/**
|
|
107
|
+
* Delete a file
|
|
108
|
+
*/
|
|
109
|
+
deleteFile(fileId: string, user: User): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Get file metadata
|
|
112
|
+
*/
|
|
113
|
+
getFileMetadata(fileId: string): Promise<FileMetadata | null>;
|
|
114
|
+
/**
|
|
115
|
+
* List files for a user
|
|
116
|
+
*/
|
|
117
|
+
listFiles(user: User, options?: {
|
|
118
|
+
entityType?: string;
|
|
119
|
+
entityId?: string;
|
|
120
|
+
limit?: number;
|
|
121
|
+
offset?: number;
|
|
122
|
+
}): Promise<FileMetadata[]>;
|
|
123
|
+
/**
|
|
124
|
+
* Generate a signed URL for temporary access
|
|
125
|
+
* Note: R2 doesn't support presigned URLs natively yet, so this returns a direct URL
|
|
126
|
+
* In production, you'd implement token-based access or use Workers to proxy requests
|
|
127
|
+
*/
|
|
128
|
+
generateSignedUrl(fileId: string, user: User, expiresIn?: number): Promise<string>;
|
|
129
|
+
/**
|
|
130
|
+
* Verify a signed URL token
|
|
131
|
+
*/
|
|
132
|
+
verifyToken(fileId: string, token: string): Promise<boolean>;
|
|
133
|
+
/**
|
|
134
|
+
* Clean up expired files
|
|
135
|
+
*/
|
|
136
|
+
cleanupExpiredFiles(): Promise<number>;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=file-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-manager.d.ts","sourceRoot":"","sources":["../../../../../core/src/storage/file-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File storage manager for Cloudflare R2
|
|
3
|
+
* Handles upload, download, and file metadata management
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* File storage manager
|
|
7
|
+
*/
|
|
8
|
+
export class FileStorageManager {
|
|
9
|
+
constructor(bucket, db, options) {
|
|
10
|
+
this.bucket = bucket;
|
|
11
|
+
this.db = db;
|
|
12
|
+
this.maxFileSize = options?.maxFileSize || 100 * 1024 * 1024; // 100MB default
|
|
13
|
+
this.allowedMimeTypes = options?.allowedMimeTypes;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Upload a file to R2
|
|
17
|
+
*/
|
|
18
|
+
async uploadFile(user, file, options) {
|
|
19
|
+
// Validate file size
|
|
20
|
+
if (options.size > (options.maxSize || this.maxFileSize)) {
|
|
21
|
+
throw new Error(`File size (${options.size} bytes) exceeds maximum allowed size (${options.maxSize || this.maxFileSize} bytes)`);
|
|
22
|
+
}
|
|
23
|
+
// Validate MIME type
|
|
24
|
+
if (this.allowedMimeTypes && !this.allowedMimeTypes.includes(options.mimeType)) {
|
|
25
|
+
throw new Error(`File type ${options.mimeType} is not allowed`);
|
|
26
|
+
}
|
|
27
|
+
const fileId = `${user.id}_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
28
|
+
const key = `${user.id}/${fileId}/${options.fileName}`;
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
// Upload to R2
|
|
31
|
+
await this.bucket.put(key, file, {
|
|
32
|
+
httpMetadata: {
|
|
33
|
+
contentType: options.mimeType,
|
|
34
|
+
contentDisposition: `attachment; filename="${options.fileName}"`,
|
|
35
|
+
},
|
|
36
|
+
customMetadata: {
|
|
37
|
+
userId: user.id,
|
|
38
|
+
uploadedAt: now.toString(),
|
|
39
|
+
...(options.entityType ? { entityType: options.entityType } : {}),
|
|
40
|
+
...(options.entityId ? { entityId: options.entityId } : {}),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
// Save metadata to database
|
|
44
|
+
const metadata = {
|
|
45
|
+
id: fileId,
|
|
46
|
+
key,
|
|
47
|
+
fileName: options.fileName,
|
|
48
|
+
mimeType: options.mimeType,
|
|
49
|
+
size: options.size,
|
|
50
|
+
userId: user.id,
|
|
51
|
+
bucket: 'default',
|
|
52
|
+
entityType: options.entityType,
|
|
53
|
+
entityId: options.entityId,
|
|
54
|
+
isPublic: options.isPublic || false,
|
|
55
|
+
uploadedAt: now,
|
|
56
|
+
expiresAt: options.expiresIn ? now + options.expiresIn * 1000 : undefined,
|
|
57
|
+
};
|
|
58
|
+
await this.db.run(`INSERT INTO files (id, key, file_name, mime_type, size, user_id, bucket, entity_type, entity_id, is_public, uploaded_at, expires_at)
|
|
59
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
60
|
+
metadata.id,
|
|
61
|
+
metadata.key,
|
|
62
|
+
metadata.fileName,
|
|
63
|
+
metadata.mimeType,
|
|
64
|
+
metadata.size,
|
|
65
|
+
metadata.userId,
|
|
66
|
+
metadata.bucket,
|
|
67
|
+
metadata.entityType || null,
|
|
68
|
+
metadata.entityId || null,
|
|
69
|
+
metadata.isPublic ? 1 : 0,
|
|
70
|
+
metadata.uploadedAt,
|
|
71
|
+
metadata.expiresAt || null,
|
|
72
|
+
]);
|
|
73
|
+
return metadata;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Download a file from R2
|
|
77
|
+
*/
|
|
78
|
+
async downloadFile(fileId, user) {
|
|
79
|
+
// Get file metadata
|
|
80
|
+
const metadata = await this.getFileMetadata(fileId);
|
|
81
|
+
if (!metadata) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
// Check permissions
|
|
85
|
+
if (!metadata.isPublic && metadata.userId !== user.id) {
|
|
86
|
+
throw new Error('Access denied');
|
|
87
|
+
}
|
|
88
|
+
// Check if expired
|
|
89
|
+
if (metadata.expiresAt && metadata.expiresAt < Date.now()) {
|
|
90
|
+
throw new Error('File has expired');
|
|
91
|
+
}
|
|
92
|
+
// Download from R2
|
|
93
|
+
return await this.bucket.get(metadata.key);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Delete a file
|
|
97
|
+
*/
|
|
98
|
+
async deleteFile(fileId, user) {
|
|
99
|
+
// Get file metadata
|
|
100
|
+
const metadata = await this.getFileMetadata(fileId);
|
|
101
|
+
if (!metadata) {
|
|
102
|
+
throw new Error('File not found');
|
|
103
|
+
}
|
|
104
|
+
// Check permissions
|
|
105
|
+
if (metadata.userId !== user.id) {
|
|
106
|
+
throw new Error('Access denied');
|
|
107
|
+
}
|
|
108
|
+
// Delete from R2
|
|
109
|
+
await this.bucket.delete(metadata.key);
|
|
110
|
+
// Delete metadata from database
|
|
111
|
+
await this.db.run('DELETE FROM files WHERE id = ?', [fileId]);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get file metadata
|
|
115
|
+
*/
|
|
116
|
+
async getFileMetadata(fileId) {
|
|
117
|
+
const row = await this.db.getOne('SELECT * FROM files WHERE id = ?', [fileId]);
|
|
118
|
+
if (!row) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
id: row.id,
|
|
123
|
+
key: row.key,
|
|
124
|
+
fileName: row.file_name,
|
|
125
|
+
mimeType: row.mime_type,
|
|
126
|
+
size: row.size,
|
|
127
|
+
userId: row.user_id,
|
|
128
|
+
bucket: row.bucket,
|
|
129
|
+
entityType: row.entity_type,
|
|
130
|
+
entityId: row.entity_id,
|
|
131
|
+
isPublic: row.is_public === 1,
|
|
132
|
+
uploadedAt: row.uploaded_at,
|
|
133
|
+
expiresAt: row.expires_at,
|
|
134
|
+
checksum: row.checksum,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* List files for a user
|
|
139
|
+
*/
|
|
140
|
+
async listFiles(user, options) {
|
|
141
|
+
let query = 'SELECT * FROM files WHERE user_id = ?';
|
|
142
|
+
const params = [user.id];
|
|
143
|
+
if (options?.entityType) {
|
|
144
|
+
query += ' AND entity_type = ?';
|
|
145
|
+
params.push(options.entityType);
|
|
146
|
+
}
|
|
147
|
+
if (options?.entityId) {
|
|
148
|
+
query += ' AND entity_id = ?';
|
|
149
|
+
params.push(options.entityId);
|
|
150
|
+
}
|
|
151
|
+
query += ' ORDER BY uploaded_at DESC';
|
|
152
|
+
if (options?.limit) {
|
|
153
|
+
query += ' LIMIT ?';
|
|
154
|
+
params.push(options.limit);
|
|
155
|
+
}
|
|
156
|
+
if (options?.offset) {
|
|
157
|
+
query += ' OFFSET ?';
|
|
158
|
+
params.push(options.offset);
|
|
159
|
+
}
|
|
160
|
+
const rows = await this.db.getAll(query, params);
|
|
161
|
+
return rows.map((row) => ({
|
|
162
|
+
id: row.id,
|
|
163
|
+
key: row.key,
|
|
164
|
+
fileName: row.file_name,
|
|
165
|
+
mimeType: row.mime_type,
|
|
166
|
+
size: row.size,
|
|
167
|
+
userId: row.user_id,
|
|
168
|
+
bucket: row.bucket,
|
|
169
|
+
entityType: row.entity_type,
|
|
170
|
+
entityId: row.entity_id,
|
|
171
|
+
isPublic: row.is_public === 1,
|
|
172
|
+
uploadedAt: row.uploaded_at,
|
|
173
|
+
expiresAt: row.expires_at,
|
|
174
|
+
checksum: row.checksum,
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Generate a signed URL for temporary access
|
|
179
|
+
* Note: R2 doesn't support presigned URLs natively yet, so this returns a direct URL
|
|
180
|
+
* In production, you'd implement token-based access or use Workers to proxy requests
|
|
181
|
+
*/
|
|
182
|
+
async generateSignedUrl(fileId, user, expiresIn = 3600) {
|
|
183
|
+
const metadata = await this.getFileMetadata(fileId);
|
|
184
|
+
if (!metadata) {
|
|
185
|
+
throw new Error('File not found');
|
|
186
|
+
}
|
|
187
|
+
// Check permissions
|
|
188
|
+
if (!metadata.isPublic && metadata.userId !== user.id) {
|
|
189
|
+
throw new Error('Access denied');
|
|
190
|
+
}
|
|
191
|
+
// Generate a temporary access token (stored in database)
|
|
192
|
+
const token = `${fileId}_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
193
|
+
const expiresAt = Date.now() + expiresIn * 1000;
|
|
194
|
+
await this.db.run('INSERT INTO file_access_tokens (token, file_id, user_id, expires_at, created_at) VALUES (?, ?, ?, ?, ?)', [token, fileId, user.id, expiresAt, Date.now()]);
|
|
195
|
+
// Return URL with token
|
|
196
|
+
return `/files/download/${fileId}?token=${token}`;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Verify a signed URL token
|
|
200
|
+
*/
|
|
201
|
+
async verifyToken(fileId, token) {
|
|
202
|
+
const row = await this.db.getOne('SELECT * FROM file_access_tokens WHERE token = ? AND file_id = ? AND expires_at > ?', [token, fileId, Date.now()]);
|
|
203
|
+
return !!row;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Clean up expired files
|
|
207
|
+
*/
|
|
208
|
+
async cleanupExpiredFiles() {
|
|
209
|
+
const expiredFiles = await this.db.getAll('SELECT * FROM files WHERE expires_at IS NOT NULL AND expires_at < ?', [
|
|
210
|
+
Date.now(),
|
|
211
|
+
]);
|
|
212
|
+
for (const file of expiredFiles) {
|
|
213
|
+
try {
|
|
214
|
+
await this.bucket.delete(file.key);
|
|
215
|
+
await this.db.run('DELETE FROM files WHERE id = ?', [file.id]);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
console.error(`Failed to delete expired file ${file.id}:`, error);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return expiredFiles.length;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=file-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-manager.js","sourceRoot":"","sources":["../../../../../core/src/storage/file-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch processing for multiple CRUD operations
|
|
3
|
+
* Supports atomic transactions and individual operation processing
|
|
4
|
+
*/
|
|
5
|
+
import type { User } from '@edgebasejs/types';
|
|
6
|
+
import { EncryptionManager } from '../encryption/encryption-manager';
|
|
7
|
+
import type { SyncDatabase, EntitySchema } from './sync-engine';
|
|
8
|
+
export interface BatchOperation {
|
|
9
|
+
entity: string;
|
|
10
|
+
id: string;
|
|
11
|
+
operation: 'create' | 'update' | 'delete';
|
|
12
|
+
data?: Record<string, any>;
|
|
13
|
+
version?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface BatchRequest {
|
|
16
|
+
create?: BatchOperation[];
|
|
17
|
+
update?: BatchOperation[];
|
|
18
|
+
delete?: BatchOperation[];
|
|
19
|
+
atomic?: boolean;
|
|
20
|
+
isolationLevel?: 'READ_UNCOMMITTED' | 'READ_COMMITTED' | 'SERIALIZABLE';
|
|
21
|
+
}
|
|
22
|
+
export interface BatchResult {
|
|
23
|
+
applied: Array<BatchOperation & {
|
|
24
|
+
version: number;
|
|
25
|
+
serverTimestamp: number;
|
|
26
|
+
}>;
|
|
27
|
+
conflicts: Array<{
|
|
28
|
+
entity: string;
|
|
29
|
+
id: string;
|
|
30
|
+
operation: string;
|
|
31
|
+
clientVersion?: number;
|
|
32
|
+
serverVersion: number;
|
|
33
|
+
serverData: Record<string, any>;
|
|
34
|
+
}>;
|
|
35
|
+
errors: Array<{
|
|
36
|
+
entity: string;
|
|
37
|
+
id: string;
|
|
38
|
+
operation: string;
|
|
39
|
+
error: string;
|
|
40
|
+
code: string;
|
|
41
|
+
}>;
|
|
42
|
+
appliedCount: number;
|
|
43
|
+
conflictCount: number;
|
|
44
|
+
errorCount: number;
|
|
45
|
+
}
|
|
46
|
+
export interface BatchProcessorOptions {
|
|
47
|
+
schemas: Map<string, EntitySchema>;
|
|
48
|
+
db: SyncDatabase;
|
|
49
|
+
user: User;
|
|
50
|
+
maxBatchSize?: number;
|
|
51
|
+
encryption?: EncryptionManager;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Batch processor for handling multiple CRUD operations
|
|
55
|
+
*/
|
|
56
|
+
export declare class BatchProcessor {
|
|
57
|
+
private schemas;
|
|
58
|
+
private db;
|
|
59
|
+
private user;
|
|
60
|
+
private serverTimestamp;
|
|
61
|
+
private maxBatchSize;
|
|
62
|
+
private encryption?;
|
|
63
|
+
constructor(options: BatchProcessorOptions);
|
|
64
|
+
/**
|
|
65
|
+
* Process a batch of operations
|
|
66
|
+
*/
|
|
67
|
+
processBatch(request: BatchRequest): Promise<BatchResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Process batch atomically - all succeed or all fail
|
|
70
|
+
*/
|
|
71
|
+
private processBatchAtomic;
|
|
72
|
+
/**
|
|
73
|
+
* Process batch operations individually
|
|
74
|
+
*/
|
|
75
|
+
private processBatchIndividual;
|
|
76
|
+
/**
|
|
77
|
+
* Validate a single operation
|
|
78
|
+
*/
|
|
79
|
+
private validateOperation;
|
|
80
|
+
/**
|
|
81
|
+
* Check access rules for operation
|
|
82
|
+
*/
|
|
83
|
+
private checkAccess;
|
|
84
|
+
/**
|
|
85
|
+
* Check for conflicts (version mismatch)
|
|
86
|
+
*/
|
|
87
|
+
private checkConflict;
|
|
88
|
+
/**
|
|
89
|
+
* Get current version for an entity record
|
|
90
|
+
*/
|
|
91
|
+
private getVersion;
|
|
92
|
+
/**
|
|
93
|
+
* Prepare SQL statements for an operation
|
|
94
|
+
*/
|
|
95
|
+
private prepareStatements;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=batch-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../../../../core/src/sync/batch-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,cAAc,CAAC;CACzE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAC,cAAc,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9E,SAAS,EAAE,KAAK,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACnC,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAoB;gBAE3B,OAAO,EAAE,qBAAqB;IAS1C;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAwC/D;;OAEG;YACW,kBAAkB;IAwEhC;;OAEG;YACW,sBAAsB;IAgFpC;;OAEG;YACW,iBAAiB;IAqB/B;;OAEG;YACW,WAAW;IA6BzB;;OAEG;YACW,aAAa;IAyB3B;;OAEG;YACW,UAAU;IAQxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAyD1B"}
|