-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathtypes.ts
More file actions
163 lines (148 loc) · 4.97 KB
/
types.ts
File metadata and controls
163 lines (148 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import type { S3Client } from '@aws-sdk/client-s3';
/**
* Per-bucket configuration resolved from the storage_module tables.
*/
export interface BucketConfig {
id: string;
key: string;
type: 'public' | 'private' | 'temp';
is_public: boolean;
owner_id: string;
allowed_mime_types: string[] | null;
max_file_size: number | null;
}
/**
* Storage module configuration resolved from metaschema for a given database.
*/
export interface StorageModuleConfig {
/** The metaschema storage_module row ID */
id: string;
/** Resolved schema.table for buckets */
bucketsQualifiedName: string;
/** Resolved schema.table for files */
filesQualifiedName: string;
/** Resolved schema.table for upload_requests */
uploadRequestsQualifiedName: string;
/** Schema name (e.g., "app_public") */
schemaName: string;
/** Buckets table name */
bucketsTableName: string;
/** Files table name */
filesTableName: string;
/** Upload requests table name */
uploadRequestsTableName: string;
// --- S3 connection config (NULL in DB = use global env/plugin defaults) ---
/** S3-compatible API endpoint URL (per-database override) */
endpoint: string | null;
/** Public URL prefix for generating download URLs (per-database override) */
publicUrlPrefix: string | null;
/** Storage provider type: 'minio', 's3', 'gcs', etc. (per-database override) */
provider: string | null;
// --- Per-database configurable settings ---
/** Presigned PUT URL expiry in seconds (default: 900 = 15 min) */
uploadUrlExpirySeconds: number;
/** Presigned GET URL expiry in seconds (default: 3600 = 1 hour) */
downloadUrlExpirySeconds: number;
/** Default max file size in bytes (default: 200MB). Bucket-level max_file_size overrides this. */
defaultMaxFileSize: number;
/** Max filename length in characters (default: 1024) */
maxFilenameLength: number;
/** Cache TTL in seconds for this config entry (default: 300 dev / 3600 prod) */
cacheTtlSeconds: number;
}
/**
* Input for the requestUploadUrl mutation.
*/
export interface RequestUploadUrlInput {
/** Bucket key (e.g., "public", "private") */
bucketKey: string;
/** SHA-256 content hash computed by the client */
contentHash: string;
/** MIME type of the file */
contentType: string;
/** File size in bytes */
size: number;
/** Original filename (optional, for display/Content-Disposition) */
filename?: string;
}
/**
* Result of the requestUploadUrl mutation.
*/
export interface RequestUploadUrlPayload {
/** Presigned PUT URL (null if deduplicated) */
uploadUrl: string | null;
/** The file ID (existing if dedup, new if fresh upload) */
fileId: string;
/** The S3 key */
key: string;
/** Whether this file was deduplicated (already exists with same hash) */
deduplicated: boolean;
/** Presigned URL expiry time (null if deduplicated) */
expiresAt: string | null;
}
/**
* Input for the confirmUpload mutation.
*/
export interface ConfirmUploadInput {
/** The file ID returned by requestUploadUrl */
fileId: string;
}
/**
* Result of the confirmUpload mutation.
*/
export interface ConfirmUploadPayload {
/** The confirmed file ID */
fileId: string;
/** New file status (should be 'ready') */
status: string;
/** Whether confirmation succeeded */
success: boolean;
}
/**
* S3 configuration for the presigned URL plugin.
*/
export interface S3Config {
/** S3 client instance */
client: S3Client;
/** S3 bucket name (the actual S3 bucket, not the logical bucket key) */
bucket: string;
/** S3 endpoint URL (for MinIO/custom S3) */
endpoint?: string;
/** S3 region */
region?: string;
/** Whether to use path-style URLs (required for MinIO) */
forcePathStyle?: boolean;
/** Public URL prefix for generating download URLs */
publicUrlPrefix?: string;
}
/**
* S3 configuration or a lazy getter that returns it on first use.
* When a function is provided, it will only be called when the first
* mutation or resolver actually needs the S3 client — avoiding eager
* env-var reads and S3Client creation at module import time.
*/
export type S3ConfigOrGetter = S3Config | (() => S3Config);
/**
* Function to derive the actual S3 bucket name for a given database.
*
* When provided, the presigned URL plugin calls this on every request
* to determine which S3 bucket to use — enabling per-database bucket
* isolation. If not provided, falls back to `s3Config.bucket` (global).
*
* @param databaseId - The metaschema database UUID
* @returns The S3 bucket name for this database
*/
export type BucketNameResolver = (databaseId: string) => string;
/**
* Plugin options for the presigned URL plugin.
*/
export interface PresignedUrlPluginOptions {
/** S3 configuration (concrete or lazy getter) */
s3: S3ConfigOrGetter;
/**
* Optional function to resolve S3 bucket name per-database.
* When set, each database gets its own S3 bucket instead of sharing
* the global `s3Config.bucket`. The S3 credentials (client) remain shared.
*/
resolveBucketName?: BucketNameResolver;
}