@unisource/sdk 0.1.2 → 0.3.0
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 +55 -23
- package/dist/index.d.mts +879 -36
- package/dist/index.mjs +664 -48
- package/package.json +9 -5
- package/src/client.ts +472 -0
- package/src/fileRecords.ts +99 -0
- package/src/folders.ts +97 -0
- package/src/index.ts +198 -125
- package/src/mainStorage.ts +40 -0
- package/src/primitives.ts +30 -0
- package/src/releases.ts +132 -0
- package/src/services.ts +135 -0
- package/src/shareLinks.ts +93 -0
- package/src/uploads.ts +99 -0
- package/dist/index.d.ts +0 -174
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/primitives.ts
|
|
3
|
+
const nonEmptyString = z.string().trim().min(1);
|
|
4
|
+
const positiveInt = z.number().int().positive();
|
|
5
|
+
const unixTimestamp = z.number().int().nonnegative();
|
|
3
6
|
const FILES_DEFAULT_LIMIT = 25;
|
|
4
7
|
const FILES_MAX_LIMIT = 100;
|
|
5
|
-
const nonEmptyStringSchema = z.string().trim().min(1);
|
|
6
|
-
const positiveIntegerSchema = z.number().int().positive();
|
|
7
8
|
const uploadDestinationSchema = z.enum(["r2", "appwrite"]);
|
|
8
9
|
const uploadStatusSchema = z.enum([
|
|
9
10
|
"pending",
|
|
@@ -11,84 +12,699 @@ const uploadStatusSchema = z.enum([
|
|
|
11
12
|
"failed"
|
|
12
13
|
]);
|
|
13
14
|
const apiErrorSchema = z.object({
|
|
14
|
-
error:
|
|
15
|
-
message:
|
|
15
|
+
error: nonEmptyString,
|
|
16
|
+
message: nonEmptyString
|
|
16
17
|
});
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/uploads.ts
|
|
17
20
|
const uploadR2InitRequestSchema = z.object({
|
|
18
|
-
filename:
|
|
19
|
-
size:
|
|
20
|
-
mime_type:
|
|
21
|
-
|
|
21
|
+
filename: nonEmptyString,
|
|
22
|
+
size: positiveInt,
|
|
23
|
+
mime_type: nonEmptyString,
|
|
24
|
+
folder_id: nonEmptyString.optional(),
|
|
25
|
+
is_main_storage: z.boolean().optional().default(false)
|
|
22
26
|
});
|
|
23
27
|
const uploadR2InitResponseSchema = z.object({
|
|
24
|
-
upload_id:
|
|
28
|
+
upload_id: nonEmptyString,
|
|
25
29
|
destination: z.literal("r2"),
|
|
26
30
|
presigned_url: z.string().url(),
|
|
27
|
-
storage_key:
|
|
28
|
-
bucket:
|
|
29
|
-
expires_at:
|
|
31
|
+
storage_key: nonEmptyString,
|
|
32
|
+
bucket: nonEmptyString,
|
|
33
|
+
expires_at: positiveInt
|
|
30
34
|
});
|
|
31
35
|
const uploadAppwriteInitRequestSchema = z.object({
|
|
32
|
-
filename:
|
|
33
|
-
size:
|
|
34
|
-
mime_type:
|
|
36
|
+
filename: nonEmptyString,
|
|
37
|
+
size: positiveInt,
|
|
38
|
+
mime_type: nonEmptyString,
|
|
39
|
+
folder_id: nonEmptyString.optional(),
|
|
40
|
+
is_main_storage: z.boolean().optional().default(false)
|
|
35
41
|
});
|
|
36
42
|
const uploadAppwriteInitResponseSchema = z.object({
|
|
37
|
-
upload_id:
|
|
43
|
+
upload_id: nonEmptyString,
|
|
38
44
|
destination: z.literal("appwrite"),
|
|
39
45
|
appwrite_endpoint: z.string().url(),
|
|
40
|
-
appwrite_project_id:
|
|
41
|
-
appwrite_bucket_id:
|
|
42
|
-
file_id:
|
|
43
|
-
expires_at:
|
|
46
|
+
appwrite_project_id: nonEmptyString,
|
|
47
|
+
appwrite_bucket_id: nonEmptyString,
|
|
48
|
+
file_id: nonEmptyString,
|
|
49
|
+
expires_at: positiveInt
|
|
50
|
+
});
|
|
51
|
+
const uploadLifecycleRequestSchema = z.object({
|
|
52
|
+
upload_id: nonEmptyString,
|
|
53
|
+
is_main_storage: z.boolean().optional().default(false)
|
|
44
54
|
});
|
|
45
|
-
const uploadLifecycleRequestSchema = z.object({ upload_id: nonEmptyStringSchema });
|
|
46
55
|
const uploadCompleteResponseSchema = z.object({
|
|
47
56
|
success: z.literal(true),
|
|
48
|
-
upload_id:
|
|
57
|
+
upload_id: nonEmptyString,
|
|
49
58
|
status: z.literal("completed")
|
|
50
59
|
});
|
|
51
60
|
const uploadFailResponseSchema = z.object({
|
|
52
61
|
success: z.literal(true),
|
|
53
|
-
upload_id:
|
|
62
|
+
upload_id: nonEmptyString,
|
|
54
63
|
status: z.literal("failed")
|
|
55
64
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
/** Raw upload record — returned by admin `/files` endpoints. */
|
|
66
|
+
const uploadRecordSchema = z.object({
|
|
67
|
+
id: nonEmptyString,
|
|
68
|
+
service_id: nonEmptyString,
|
|
69
|
+
user_id: nonEmptyString.nullable(),
|
|
70
|
+
filename: nonEmptyString,
|
|
71
|
+
size: positiveInt,
|
|
72
|
+
mime_type: nonEmptyString,
|
|
61
73
|
destination: uploadDestinationSchema,
|
|
62
|
-
storage_key: nonEmptyStringSchema,
|
|
63
|
-
bucket: nonEmptyStringSchema,
|
|
64
74
|
status: uploadStatusSchema,
|
|
65
|
-
expires_at:
|
|
66
|
-
created_at:
|
|
67
|
-
updated_at:
|
|
75
|
+
expires_at: positiveInt,
|
|
76
|
+
created_at: positiveInt,
|
|
77
|
+
updated_at: positiveInt
|
|
68
78
|
});
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
status: uploadStatusSchema.optional()
|
|
79
|
+
const uploadsListResponseSchema = z.object({
|
|
80
|
+
items: z.array(uploadRecordSchema),
|
|
81
|
+
next_cursor: z.string().nullable(),
|
|
82
|
+
limit: positiveInt
|
|
74
83
|
});
|
|
75
|
-
const
|
|
84
|
+
const uploadRecordDetailResponseSchema = z.object({ upload: uploadRecordSchema });
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/fileRecords.ts
|
|
87
|
+
/**
|
|
88
|
+
* A confirmed file record owned by a user.
|
|
89
|
+
* Internal fields (storage_key, bucket) are intentionally excluded from the public API.
|
|
90
|
+
*/
|
|
91
|
+
const fileRecordSchema = z.object({
|
|
92
|
+
id: nonEmptyString,
|
|
93
|
+
service_id: nonEmptyString,
|
|
94
|
+
user_id: nonEmptyString,
|
|
95
|
+
folder_id: nonEmptyString.nullable(),
|
|
96
|
+
upload_id: nonEmptyString.nullable(),
|
|
97
|
+
filename: nonEmptyString,
|
|
98
|
+
size: positiveInt,
|
|
99
|
+
mime_type: nonEmptyString,
|
|
100
|
+
storage_destination: uploadDestinationSchema,
|
|
101
|
+
is_trashed: z.boolean(),
|
|
102
|
+
trashed_at: positiveInt.nullable(),
|
|
103
|
+
created_at: positiveInt,
|
|
104
|
+
updated_at: positiveInt
|
|
105
|
+
});
|
|
106
|
+
const fileRecordsListQuerySchema = z.object({
|
|
107
|
+
folder_id: nonEmptyString.nullable().optional(),
|
|
108
|
+
is_trashed: z.boolean().optional(),
|
|
109
|
+
cursor: nonEmptyString.optional(),
|
|
110
|
+
limit: z.number().int().min(1).max(100).optional()
|
|
111
|
+
});
|
|
112
|
+
const fileRecordsListResponseSchema = z.object({
|
|
76
113
|
items: z.array(fileRecordSchema),
|
|
77
114
|
next_cursor: z.string().nullable(),
|
|
78
|
-
limit:
|
|
115
|
+
limit: positiveInt
|
|
79
116
|
});
|
|
80
|
-
const
|
|
117
|
+
const fileRecordDetailResponseSchema = z.object({ file: fileRecordSchema });
|
|
118
|
+
const fileMoveRequestSchema = z.object({ folder_id: nonEmptyString.nullable().optional() });
|
|
81
119
|
const fileDownloadUrlResponseSchema = z.object({
|
|
82
|
-
upload_id:
|
|
120
|
+
upload_id: nonEmptyString,
|
|
83
121
|
destination: uploadDestinationSchema,
|
|
84
122
|
download_url: z.string().url(),
|
|
85
|
-
expires_at:
|
|
123
|
+
expires_at: positiveInt
|
|
86
124
|
});
|
|
87
125
|
const fileDeleteResponseSchema = z.object({
|
|
88
126
|
success: z.literal(true),
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
127
|
+
id: nonEmptyString,
|
|
128
|
+
permanent: z.boolean()
|
|
129
|
+
});
|
|
130
|
+
const fileRestoreResponseSchema = z.object({
|
|
131
|
+
success: z.literal(true),
|
|
132
|
+
id: nonEmptyString
|
|
133
|
+
});
|
|
134
|
+
const fileUpdateRequestSchema = z.object({ filename: nonEmptyString });
|
|
135
|
+
const fileUpdateResponseSchema = z.object({ file: fileRecordSchema });
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/folders.ts
|
|
138
|
+
const folderSchema = z.object({
|
|
139
|
+
id: nonEmptyString,
|
|
140
|
+
service_id: nonEmptyString,
|
|
141
|
+
user_id: nonEmptyString,
|
|
142
|
+
parent_id: nonEmptyString.nullable(),
|
|
143
|
+
name: nonEmptyString,
|
|
144
|
+
color_tag: z.string().nullable(),
|
|
145
|
+
is_trashed: z.boolean(),
|
|
146
|
+
trashed_at: positiveInt.nullable(),
|
|
147
|
+
created_at: positiveInt,
|
|
148
|
+
updated_at: positiveInt
|
|
149
|
+
});
|
|
150
|
+
const folderListQuerySchema = z.object({
|
|
151
|
+
parent_id: nonEmptyString.nullable().optional(),
|
|
152
|
+
trashed: z.boolean().optional(),
|
|
153
|
+
is_trashed: z.boolean().optional(),
|
|
154
|
+
cursor: nonEmptyString.optional(),
|
|
155
|
+
limit: z.number().int().min(1).max(100).optional()
|
|
156
|
+
}).refine((v) => !(v.trashed !== void 0 && v.is_trashed !== void 0), { message: "Use either trashed or is_trashed, not both" });
|
|
157
|
+
const folderListResponseSchema = z.object({
|
|
158
|
+
items: z.array(folderSchema),
|
|
159
|
+
next_cursor: z.string().nullable(),
|
|
160
|
+
limit: positiveInt
|
|
161
|
+
});
|
|
162
|
+
const folderCreateRequestSchema = z.object({
|
|
163
|
+
name: nonEmptyString,
|
|
164
|
+
parent_id: nonEmptyString.optional(),
|
|
165
|
+
color_tag: z.string().optional()
|
|
166
|
+
});
|
|
167
|
+
const folderCreateResponseSchema = z.object({ folder: folderSchema });
|
|
168
|
+
const folderUpdateRequestSchema = z.object({
|
|
169
|
+
name: nonEmptyString.optional(),
|
|
170
|
+
color_tag: z.string().nullable().optional()
|
|
171
|
+
}).refine((v) => v.name !== void 0 || v.color_tag !== void 0, { message: "At least one of name or color_tag must be provided" });
|
|
172
|
+
const folderUpdateResponseSchema = z.object({ folder: folderSchema });
|
|
173
|
+
const folderDeleteResponseSchema = z.object({
|
|
174
|
+
success: z.literal(true),
|
|
175
|
+
id: nonEmptyString,
|
|
176
|
+
permanent: z.boolean(),
|
|
177
|
+
folders_deleted: z.number().int().nonnegative().optional()
|
|
178
|
+
});
|
|
179
|
+
const folderDetailResponseSchema = z.object({ folder: folderSchema });
|
|
180
|
+
const folderRestoreResponseSchema = z.object({
|
|
181
|
+
success: z.literal(true),
|
|
182
|
+
id: nonEmptyString
|
|
183
|
+
});
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/services.ts
|
|
186
|
+
/** Public service info returned to admins. Never exposes secrets. */
|
|
187
|
+
const serviceSchema = z.object({
|
|
188
|
+
id: nonEmptyString,
|
|
189
|
+
name: nonEmptyString,
|
|
190
|
+
max_storage_bytes: positiveInt,
|
|
191
|
+
current_used_bytes: z.number().int().nonnegative(),
|
|
192
|
+
max_file_size_bytes: positiveInt,
|
|
193
|
+
created_at: unixTimestamp
|
|
194
|
+
});
|
|
195
|
+
const serviceDetailResponseSchema = z.object({ service: serviceSchema });
|
|
196
|
+
const adminServiceUpdateRequestSchema = z.object({
|
|
197
|
+
max_storage_bytes: positiveInt.optional(),
|
|
198
|
+
max_file_size_bytes: positiveInt.optional()
|
|
199
|
+
}).refine((v) => v.max_storage_bytes !== void 0 || v.max_file_size_bytes !== void 0, { message: "At least one of max_storage_bytes or max_file_size_bytes must be provided" });
|
|
200
|
+
const adminServiceUpdateResponseSchema = serviceDetailResponseSchema;
|
|
201
|
+
const serviceUsageResponseSchema = z.object({
|
|
202
|
+
service_id: nonEmptyString,
|
|
203
|
+
max_storage_bytes: positiveInt,
|
|
204
|
+
current_used_bytes: z.number().int().nonnegative(),
|
|
205
|
+
used_percent: z.number().min(0).max(100)
|
|
206
|
+
});
|
|
207
|
+
const auditEventActionSchema = z.enum([
|
|
208
|
+
"upload_completed",
|
|
209
|
+
"file_deleted",
|
|
210
|
+
"folder_deleted",
|
|
211
|
+
"quota_exceeded",
|
|
212
|
+
"share_link_accessed",
|
|
213
|
+
"quota_reconciled"
|
|
214
|
+
]);
|
|
215
|
+
const auditEventSchema = z.object({
|
|
216
|
+
id: nonEmptyString,
|
|
217
|
+
service_id: nonEmptyString,
|
|
218
|
+
user_id: nonEmptyString,
|
|
219
|
+
action: auditEventActionSchema,
|
|
220
|
+
resource_type: z.enum([
|
|
221
|
+
"file",
|
|
222
|
+
"folder",
|
|
223
|
+
"service"
|
|
224
|
+
]),
|
|
225
|
+
resource_id: nonEmptyString,
|
|
226
|
+
metadata: z.record(z.string(), z.unknown()).nullable(),
|
|
227
|
+
ip_address: z.string().nullable(),
|
|
228
|
+
created_at: unixTimestamp
|
|
229
|
+
});
|
|
230
|
+
const auditLogListQuerySchema = z.object({
|
|
231
|
+
user_id: nonEmptyString.optional(),
|
|
232
|
+
action: auditEventActionSchema.optional(),
|
|
233
|
+
resource_type: z.enum([
|
|
234
|
+
"file",
|
|
235
|
+
"folder",
|
|
236
|
+
"service"
|
|
237
|
+
]).optional(),
|
|
238
|
+
cursor: nonEmptyString.optional(),
|
|
239
|
+
limit: z.number().int().min(1).max(200).optional()
|
|
92
240
|
});
|
|
241
|
+
const auditLogListResponseSchema = z.object({
|
|
242
|
+
items: z.array(auditEventSchema),
|
|
243
|
+
next_cursor: z.string().nullable(),
|
|
244
|
+
limit: positiveInt
|
|
245
|
+
});
|
|
246
|
+
const adminUserSchema = z.object({
|
|
247
|
+
id: nonEmptyString,
|
|
248
|
+
name: z.string(),
|
|
249
|
+
email: z.string().email(),
|
|
250
|
+
status: z.boolean(),
|
|
251
|
+
labels: z.array(z.string()),
|
|
252
|
+
role: nonEmptyString,
|
|
253
|
+
has_service_access: z.boolean(),
|
|
254
|
+
max_storage_bytes: positiveInt.nullable(),
|
|
255
|
+
effective_max_storage_bytes: positiveInt,
|
|
256
|
+
current_used_bytes: z.number().int().nonnegative(),
|
|
257
|
+
registration: unixTimestamp,
|
|
258
|
+
email_verification: z.boolean()
|
|
259
|
+
});
|
|
260
|
+
const adminUserListResponseSchema = z.object({
|
|
261
|
+
items: z.array(adminUserSchema),
|
|
262
|
+
total: z.number().int().nonnegative(),
|
|
263
|
+
offset: z.number().int().nonnegative(),
|
|
264
|
+
limit: positiveInt
|
|
265
|
+
});
|
|
266
|
+
const adminUserUpdateRequestSchema = z.object({
|
|
267
|
+
name: z.string().trim().min(1).max(128).optional(),
|
|
268
|
+
email: z.string().trim().email().optional(),
|
|
269
|
+
status: z.boolean().optional(),
|
|
270
|
+
labels: z.array(z.string().trim().min(1)).max(32).optional(),
|
|
271
|
+
role: z.enum([
|
|
272
|
+
"user",
|
|
273
|
+
"plus",
|
|
274
|
+
"admin"
|
|
275
|
+
]).optional(),
|
|
276
|
+
max_storage_bytes: positiveInt.nullable().optional()
|
|
277
|
+
});
|
|
278
|
+
const adminUserUpdateResponseSchema = z.object({ user: adminUserSchema });
|
|
279
|
+
const adminUserPasswordResetRequestSchema = z.object({ password: z.string().min(8).max(256) });
|
|
280
|
+
const adminUserPasswordResetResponseSchema = z.object({
|
|
281
|
+
success: z.literal(true),
|
|
282
|
+
user_id: nonEmptyString
|
|
283
|
+
});
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/mainStorage.ts
|
|
286
|
+
const mainStorageListQuerySchema = z.object({
|
|
287
|
+
limit: z.number().int().positive().optional(),
|
|
288
|
+
cursor: nonEmptyString.optional()
|
|
289
|
+
});
|
|
290
|
+
const mainStorageListResponseSchema = z.object({
|
|
291
|
+
items: z.array(fileRecordSchema),
|
|
292
|
+
next_cursor: z.string().nullable()
|
|
293
|
+
});
|
|
294
|
+
const mainStorageRenameRequestSchema = z.object({ filename: nonEmptyString });
|
|
295
|
+
const mainStorageDeleteResponseSchema = z.object({
|
|
296
|
+
success: z.boolean(),
|
|
297
|
+
file_id: nonEmptyString
|
|
298
|
+
});
|
|
299
|
+
const mainStorageRestoreResponseSchema = z.object({
|
|
300
|
+
success: z.boolean(),
|
|
301
|
+
file_id: nonEmptyString
|
|
302
|
+
});
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region src/releases.ts
|
|
305
|
+
const releaseIdSchema = z.string().trim().min(1).max(128);
|
|
306
|
+
const releaseNameSchema = z.string().trim().min(1).max(256);
|
|
307
|
+
const releaseFilenameSchema = z.string().trim().min(1).max(255);
|
|
308
|
+
const releaseTagsSchema = z.array(z.string().trim().min(1).max(64)).max(32);
|
|
309
|
+
const releaseNotesSchema = z.string().trim().max(1e4).nullable().optional();
|
|
310
|
+
const releaseR2KeySchema = z.string().trim().min(1).max(1024);
|
|
311
|
+
const releaseDTOSchema = z.object({
|
|
312
|
+
id: nonEmptyString,
|
|
313
|
+
service_id: nonEmptyString,
|
|
314
|
+
name: nonEmptyString,
|
|
315
|
+
size: z.number().int().nonnegative(),
|
|
316
|
+
r2_key: nonEmptyString,
|
|
317
|
+
tags: z.array(nonEmptyString),
|
|
318
|
+
notes: z.string().nullable(),
|
|
319
|
+
force_update: z.boolean(),
|
|
320
|
+
uploaded_by: nonEmptyString,
|
|
321
|
+
upload_status: uploadStatusSchema,
|
|
322
|
+
created_at: nonEmptyString
|
|
323
|
+
});
|
|
324
|
+
const releaseUploadInitRequestSchema = z.object({
|
|
325
|
+
name: releaseNameSchema,
|
|
326
|
+
filename: releaseFilenameSchema,
|
|
327
|
+
tags: releaseTagsSchema.optional().default([]),
|
|
328
|
+
notes: releaseNotesSchema,
|
|
329
|
+
force_update: z.boolean().optional().default(false)
|
|
330
|
+
});
|
|
331
|
+
const releaseUploadInitResponseSchema = z.object({
|
|
332
|
+
release_id: nonEmptyString,
|
|
333
|
+
presigned_url: z.string().url(),
|
|
334
|
+
r2_key: nonEmptyString,
|
|
335
|
+
expires_at: positiveInt
|
|
336
|
+
});
|
|
337
|
+
const releaseUploadCompleteRequestSchema = z.object({
|
|
338
|
+
release_id: releaseIdSchema,
|
|
339
|
+
size: z.number().int().nonnegative()
|
|
340
|
+
});
|
|
341
|
+
const releaseUploadCompleteResponseSchema = z.object({
|
|
342
|
+
success: z.literal(true),
|
|
343
|
+
release_id: nonEmptyString,
|
|
344
|
+
status: z.literal("completed")
|
|
345
|
+
});
|
|
346
|
+
const releaseUploadFailResponseSchema = z.object({
|
|
347
|
+
success: z.literal(true),
|
|
348
|
+
release_id: nonEmptyString,
|
|
349
|
+
status: z.literal("failed")
|
|
350
|
+
});
|
|
351
|
+
const releasesListQuerySchema = z.object({
|
|
352
|
+
limit: z.number().int().positive().max(100).optional(),
|
|
353
|
+
cursor: nonEmptyString.optional()
|
|
354
|
+
});
|
|
355
|
+
const releasesListResponseSchema = z.object({
|
|
356
|
+
items: z.array(releaseDTOSchema),
|
|
357
|
+
next_cursor: z.string().nullable()
|
|
358
|
+
});
|
|
359
|
+
const releaseUpdateRequestSchema = z.object({
|
|
360
|
+
name: releaseNameSchema.optional(),
|
|
361
|
+
tags: releaseTagsSchema.optional(),
|
|
362
|
+
notes: releaseNotesSchema,
|
|
363
|
+
force_update: z.boolean().optional()
|
|
364
|
+
}).refine((body) => Object.values(body).some((value) => value !== void 0), { message: "At least one field must be provided" });
|
|
365
|
+
const releaseDeleteResponseSchema = z.object({
|
|
366
|
+
success: z.literal(true),
|
|
367
|
+
release_id: nonEmptyString
|
|
368
|
+
});
|
|
369
|
+
const releaseSyncManifestSchema = z.object({
|
|
370
|
+
id: releaseIdSchema.optional(),
|
|
371
|
+
name: releaseNameSchema,
|
|
372
|
+
r2_key: releaseR2KeySchema,
|
|
373
|
+
size: z.number().int().nonnegative(),
|
|
374
|
+
tags: releaseTagsSchema.optional().default([]),
|
|
375
|
+
notes: releaseNotesSchema,
|
|
376
|
+
force_update: z.boolean().optional().default(false)
|
|
377
|
+
});
|
|
378
|
+
const releaseSyncRequestSchema = z.object({ releases: z.array(releaseSyncManifestSchema).min(1).max(100) });
|
|
379
|
+
const releaseSyncResultSchema = z.object({
|
|
380
|
+
release_id: nonEmptyString,
|
|
381
|
+
success: z.boolean(),
|
|
382
|
+
status: uploadStatusSchema
|
|
383
|
+
});
|
|
384
|
+
const releaseSyncResponseSchema = z.object({
|
|
385
|
+
synced: z.number().int().nonnegative(),
|
|
386
|
+
results: z.array(releaseSyncResultSchema)
|
|
387
|
+
});
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/shareLinks.ts
|
|
390
|
+
const shareLinkSchema = z.object({
|
|
391
|
+
id: nonEmptyString,
|
|
392
|
+
service_id: nonEmptyString,
|
|
393
|
+
file_id: nonEmptyString,
|
|
394
|
+
user_id: nonEmptyString,
|
|
395
|
+
slug: nonEmptyString,
|
|
396
|
+
name: z.string().nullable(),
|
|
397
|
+
has_password: z.boolean(),
|
|
398
|
+
expires_at: unixTimestamp.nullable(),
|
|
399
|
+
download_count: z.number().int().nonnegative(),
|
|
400
|
+
max_downloads: positiveInt.nullable(),
|
|
401
|
+
is_active: z.boolean(),
|
|
402
|
+
created_at: unixTimestamp,
|
|
403
|
+
updated_at: unixTimestamp
|
|
404
|
+
});
|
|
405
|
+
const shareLinkCreateRequestSchema = z.object({
|
|
406
|
+
slug: z.string().trim().min(3).max(64).optional(),
|
|
407
|
+
name: z.string().trim().max(128).optional(),
|
|
408
|
+
password: z.string().min(1).optional(),
|
|
409
|
+
expires_at: unixTimestamp.optional(),
|
|
410
|
+
max_downloads: positiveInt.optional()
|
|
411
|
+
});
|
|
412
|
+
const shareLinkUpdateRequestSchema = z.object({
|
|
413
|
+
name: z.string().trim().max(128).nullable().optional(),
|
|
414
|
+
is_active: z.boolean().optional(),
|
|
415
|
+
password: z.string().min(1).nullable().optional(),
|
|
416
|
+
expires_at: unixTimestamp.nullable().optional(),
|
|
417
|
+
max_downloads: positiveInt.nullable().optional()
|
|
418
|
+
}).refine((v) => v.name !== void 0 || v.is_active !== void 0 || v.password !== void 0 || v.expires_at !== void 0 || v.max_downloads !== void 0, { message: "At least one field must be provided" });
|
|
419
|
+
const shareLinkListResponseSchema = z.object({ items: z.array(shareLinkSchema) });
|
|
420
|
+
const shareLinkCreateResponseSchema = z.object({ link: shareLinkSchema });
|
|
421
|
+
const shareLinkUpdateResponseSchema = z.object({ link: shareLinkSchema });
|
|
422
|
+
const publicFileAccessResponseSchema = z.object({
|
|
423
|
+
file_id: nonEmptyString,
|
|
424
|
+
filename: nonEmptyString,
|
|
425
|
+
size: positiveInt,
|
|
426
|
+
mime_type: nonEmptyString,
|
|
427
|
+
requires_password: z.literal(false),
|
|
428
|
+
download_url: z.string().url(),
|
|
429
|
+
url_expires_at: unixTimestamp,
|
|
430
|
+
link_name: z.string().nullable(),
|
|
431
|
+
link_expires_at: unixTimestamp.nullable()
|
|
432
|
+
});
|
|
433
|
+
const publicFileLockedResponseSchema = z.object({
|
|
434
|
+
filename: nonEmptyString,
|
|
435
|
+
size: positiveInt,
|
|
436
|
+
mime_type: nonEmptyString,
|
|
437
|
+
requires_password: z.literal(true),
|
|
438
|
+
link_name: z.string().nullable()
|
|
439
|
+
});
|
|
440
|
+
const shareLinkDeleteResponseSchema = z.object({
|
|
441
|
+
success: z.literal(true),
|
|
442
|
+
id: nonEmptyString
|
|
443
|
+
});
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region src/client.ts
|
|
446
|
+
var UnisourceError = class extends Error {
|
|
447
|
+
constructor(message, status, body) {
|
|
448
|
+
super(message);
|
|
449
|
+
this.status = status;
|
|
450
|
+
this.body = body;
|
|
451
|
+
this.name = "UnisourceError";
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
var UnisourceNetworkError = class extends Error {
|
|
455
|
+
constructor(message, cause) {
|
|
456
|
+
super(message);
|
|
457
|
+
this.cause = cause;
|
|
458
|
+
this.name = "UnisourceNetworkError";
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
async function fetchApi(baseUrl, method, path, options = {}) {
|
|
462
|
+
const url = new URL(path, baseUrl);
|
|
463
|
+
if (options.query) {
|
|
464
|
+
for (const [key, value] of Object.entries(options.query)) if (value !== void 0 && value !== null) url.searchParams.set(key, String(value));
|
|
465
|
+
}
|
|
466
|
+
const headers = { ...options.authHeaders };
|
|
467
|
+
if (options.body !== void 0) headers["Content-Type"] = "application/json";
|
|
468
|
+
let response;
|
|
469
|
+
try {
|
|
470
|
+
response = await fetch(url.toString(), {
|
|
471
|
+
method,
|
|
472
|
+
headers,
|
|
473
|
+
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
474
|
+
signal: options.signal
|
|
475
|
+
});
|
|
476
|
+
} catch (err) {
|
|
477
|
+
throw new UnisourceNetworkError("Network request failed", err);
|
|
478
|
+
}
|
|
479
|
+
if (!response.ok) {
|
|
480
|
+
let body;
|
|
481
|
+
try {
|
|
482
|
+
body = await response.json();
|
|
483
|
+
} catch {
|
|
484
|
+
body = {
|
|
485
|
+
error: "Unknown",
|
|
486
|
+
message: response.statusText
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
throw new UnisourceError(body.message, response.status, body);
|
|
490
|
+
}
|
|
491
|
+
return response.json();
|
|
492
|
+
}
|
|
493
|
+
async function apiRequest(config, method, path, options = {}) {
|
|
494
|
+
const token = await config.getToken();
|
|
495
|
+
const authHeaders = {
|
|
496
|
+
...options.extraHeaders ?? {},
|
|
497
|
+
"X-Service-ID": config.serviceId
|
|
498
|
+
};
|
|
499
|
+
if (token) authHeaders["Authorization"] = `Bearer ${token}`;
|
|
500
|
+
return fetchApi(config.baseUrl, method, path, {
|
|
501
|
+
...options,
|
|
502
|
+
authHeaders
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
async function getPublicFileInfo(baseUrl, slug, signal) {
|
|
506
|
+
return fetchApi(baseUrl, "GET", `/public/${encodeURIComponent(slug)}`, { signal });
|
|
507
|
+
}
|
|
508
|
+
async function unlockPublicFile(baseUrl, slug, password, signal) {
|
|
509
|
+
return fetchApi(baseUrl, "POST", `/public/${encodeURIComponent(slug)}/unlock`, {
|
|
510
|
+
body: { password },
|
|
511
|
+
signal
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
var UnisourceClient = class {
|
|
515
|
+
config;
|
|
516
|
+
constructor(config) {
|
|
517
|
+
this.config = config;
|
|
518
|
+
}
|
|
519
|
+
request(method, path, options = {}) {
|
|
520
|
+
return apiRequest(this.config, method, path, options);
|
|
521
|
+
}
|
|
522
|
+
withAsUser(options) {
|
|
523
|
+
return options?.asUser ? { "X-Target-User-ID": options.asUser } : {};
|
|
524
|
+
}
|
|
525
|
+
upload = {
|
|
526
|
+
r2Init: (body, signal) => apiRequest(this.config, "POST", "/upload/r2/init", {
|
|
527
|
+
body,
|
|
528
|
+
signal
|
|
529
|
+
}),
|
|
530
|
+
appwriteInit: (body, signal) => apiRequest(this.config, "POST", "/upload/appwrite/init", {
|
|
531
|
+
body,
|
|
532
|
+
signal
|
|
533
|
+
}),
|
|
534
|
+
complete: (body, signal) => apiRequest(this.config, "POST", "/upload/complete", {
|
|
535
|
+
body,
|
|
536
|
+
signal
|
|
537
|
+
}),
|
|
538
|
+
fail: (body, signal) => apiRequest(this.config, "POST", "/upload/fail", {
|
|
539
|
+
body,
|
|
540
|
+
signal
|
|
541
|
+
})
|
|
542
|
+
};
|
|
543
|
+
myFiles = {
|
|
544
|
+
list: (query, signal, options) => apiRequest(this.config, "GET", "/my-files", {
|
|
545
|
+
query,
|
|
546
|
+
signal,
|
|
547
|
+
extraHeaders: this.withAsUser(options)
|
|
548
|
+
}),
|
|
549
|
+
trash: (query, signal, options) => apiRequest(this.config, "GET", "/my-files/trash", {
|
|
550
|
+
query,
|
|
551
|
+
signal,
|
|
552
|
+
extraHeaders: this.withAsUser(options)
|
|
553
|
+
}),
|
|
554
|
+
get: (id, signal, options) => apiRequest(this.config, "GET", `/my-files/${id}`, {
|
|
555
|
+
signal,
|
|
556
|
+
extraHeaders: this.withAsUser(options)
|
|
557
|
+
}),
|
|
558
|
+
downloadUrl: (id, signal, options) => apiRequest(this.config, "GET", `/my-files/${id}/download-url`, {
|
|
559
|
+
signal,
|
|
560
|
+
extraHeaders: this.withAsUser(options)
|
|
561
|
+
}),
|
|
562
|
+
move: (id, body, signal, options) => apiRequest(this.config, "PATCH", `/my-files/${id}/move`, {
|
|
563
|
+
body,
|
|
564
|
+
signal,
|
|
565
|
+
extraHeaders: this.withAsUser(options)
|
|
566
|
+
}),
|
|
567
|
+
delete: (id, query, signal, options) => apiRequest(this.config, "DELETE", `/my-files/${id}`, {
|
|
568
|
+
query,
|
|
569
|
+
signal,
|
|
570
|
+
extraHeaders: this.withAsUser(options)
|
|
571
|
+
}),
|
|
572
|
+
restore: (id, signal, options) => apiRequest(this.config, "POST", `/my-files/${id}/restore`, {
|
|
573
|
+
signal,
|
|
574
|
+
extraHeaders: this.withAsUser(options)
|
|
575
|
+
}),
|
|
576
|
+
update: (id, body, signal, options) => apiRequest(this.config, "PATCH", `/my-files/${id}`, {
|
|
577
|
+
body,
|
|
578
|
+
signal,
|
|
579
|
+
extraHeaders: this.withAsUser(options)
|
|
580
|
+
})
|
|
581
|
+
};
|
|
582
|
+
folders = {
|
|
583
|
+
list: (query, signal, options) => apiRequest(this.config, "GET", "/folders", {
|
|
584
|
+
query,
|
|
585
|
+
signal,
|
|
586
|
+
extraHeaders: this.withAsUser(options)
|
|
587
|
+
}),
|
|
588
|
+
get: (id, signal, options) => apiRequest(this.config, "GET", `/folders/${id}`, {
|
|
589
|
+
signal,
|
|
590
|
+
extraHeaders: this.withAsUser(options)
|
|
591
|
+
}),
|
|
592
|
+
create: (body, signal, options) => apiRequest(this.config, "POST", "/folders", {
|
|
593
|
+
body,
|
|
594
|
+
signal,
|
|
595
|
+
extraHeaders: this.withAsUser(options)
|
|
596
|
+
}),
|
|
597
|
+
update: (id, body, signal, options) => apiRequest(this.config, "PATCH", `/folders/${id}`, {
|
|
598
|
+
body,
|
|
599
|
+
signal,
|
|
600
|
+
extraHeaders: this.withAsUser(options)
|
|
601
|
+
}),
|
|
602
|
+
delete: (id, query, signal, options) => apiRequest(this.config, "DELETE", `/folders/${id}`, {
|
|
603
|
+
query,
|
|
604
|
+
signal,
|
|
605
|
+
extraHeaders: this.withAsUser(options)
|
|
606
|
+
}),
|
|
607
|
+
restore: (id, signal, options) => apiRequest(this.config, "POST", `/folders/${id}/restore`, {
|
|
608
|
+
signal,
|
|
609
|
+
extraHeaders: this.withAsUser(options)
|
|
610
|
+
})
|
|
611
|
+
};
|
|
612
|
+
mainStorage = {
|
|
613
|
+
list: (query) => this.request("GET", "/main", { query }),
|
|
614
|
+
get: (fileId) => this.request("GET", `/main/${fileId}`),
|
|
615
|
+
rename: (fileId, filename) => this.request("PATCH", `/main/${fileId}`, { body: { filename } }),
|
|
616
|
+
delete: (fileId, permanent = false) => this.request("DELETE", `/main/${fileId}${permanent ? "?permanent=true" : ""}`),
|
|
617
|
+
restore: (fileId) => this.request("POST", `/main/${fileId}/restore`),
|
|
618
|
+
upload: {
|
|
619
|
+
r2Init: (input) => this.request("POST", "/upload/r2/init", { body: {
|
|
620
|
+
...input,
|
|
621
|
+
is_main_storage: true
|
|
622
|
+
} }),
|
|
623
|
+
appwriteInit: (input) => this.request("POST", "/upload/appwrite/init", { body: {
|
|
624
|
+
...input,
|
|
625
|
+
is_main_storage: true
|
|
626
|
+
} }),
|
|
627
|
+
complete: (uploadId) => this.request("POST", "/upload/complete", { body: {
|
|
628
|
+
upload_id: uploadId,
|
|
629
|
+
is_main_storage: true
|
|
630
|
+
} }),
|
|
631
|
+
fail: (uploadId) => this.request("POST", "/upload/fail", { body: { upload_id: uploadId } })
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
releases = {
|
|
635
|
+
upload: {
|
|
636
|
+
init: (body, signal) => apiRequest(this.config, "POST", "/releases/upload/init", {
|
|
637
|
+
body,
|
|
638
|
+
signal
|
|
639
|
+
}),
|
|
640
|
+
complete: (body, signal) => apiRequest(this.config, "POST", "/releases/upload/complete", {
|
|
641
|
+
body,
|
|
642
|
+
signal
|
|
643
|
+
}),
|
|
644
|
+
fail: (releaseId, signal) => apiRequest(this.config, "POST", "/releases/upload/fail", {
|
|
645
|
+
body: { release_id: releaseId },
|
|
646
|
+
signal
|
|
647
|
+
})
|
|
648
|
+
},
|
|
649
|
+
list: (query, signal) => apiRequest(this.config, "GET", "/releases", {
|
|
650
|
+
query,
|
|
651
|
+
signal
|
|
652
|
+
}),
|
|
653
|
+
get: (releaseId, signal) => apiRequest(this.config, "GET", `/releases/${releaseId}`, { signal }),
|
|
654
|
+
latest: (signal) => apiRequest(this.config, "GET", "/releases/latest", { signal }),
|
|
655
|
+
update: (releaseId, body, signal) => apiRequest(this.config, "PATCH", `/releases/${releaseId}`, {
|
|
656
|
+
body,
|
|
657
|
+
signal
|
|
658
|
+
}),
|
|
659
|
+
delete: (releaseId, signal) => apiRequest(this.config, "DELETE", `/releases/${releaseId}`, { signal }),
|
|
660
|
+
sync: (body, signal) => apiRequest(this.config, "POST", "/releases/sync", {
|
|
661
|
+
body,
|
|
662
|
+
signal
|
|
663
|
+
})
|
|
664
|
+
};
|
|
665
|
+
admin = {
|
|
666
|
+
serviceDetail: (signal) => apiRequest(this.config, "GET", "/admin/service", { signal }),
|
|
667
|
+
updateService: (body, signal) => apiRequest(this.config, "PATCH", "/admin/service", {
|
|
668
|
+
body,
|
|
669
|
+
signal
|
|
670
|
+
}),
|
|
671
|
+
usage: (signal) => apiRequest(this.config, "GET", "/admin/service/usage", { signal }),
|
|
672
|
+
listUploads: (query, signal) => apiRequest(this.config, "GET", "/files", {
|
|
673
|
+
query,
|
|
674
|
+
signal
|
|
675
|
+
}),
|
|
676
|
+
getUpload: (id, signal) => apiRequest(this.config, "GET", `/files/${id}`, { signal }),
|
|
677
|
+
downloadUploadUrl: (id, signal) => apiRequest(this.config, "GET", `/files/${id}/download-url`, { signal }),
|
|
678
|
+
deleteUpload: (id, signal) => apiRequest(this.config, "DELETE", `/files/${id}`, { signal }),
|
|
679
|
+
auditLog: (query, signal) => apiRequest(this.config, "GET", "/admin/audit-log", {
|
|
680
|
+
query,
|
|
681
|
+
signal
|
|
682
|
+
}),
|
|
683
|
+
listUsers: (query, signal) => apiRequest(this.config, "GET", "/admin/users", {
|
|
684
|
+
query,
|
|
685
|
+
signal
|
|
686
|
+
}),
|
|
687
|
+
updateUser: (userId, body, signal) => apiRequest(this.config, "PATCH", `/admin/users/${userId}`, {
|
|
688
|
+
body,
|
|
689
|
+
signal
|
|
690
|
+
}),
|
|
691
|
+
resetUserPassword: (userId, body, signal) => apiRequest(this.config, "POST", `/admin/users/${userId}/password`, {
|
|
692
|
+
body,
|
|
693
|
+
signal
|
|
694
|
+
})
|
|
695
|
+
};
|
|
696
|
+
shareLinks = {
|
|
697
|
+
create: (fileId, body, signal) => apiRequest(this.config, "POST", `/my-files/${fileId}/share-links`, {
|
|
698
|
+
body,
|
|
699
|
+
signal
|
|
700
|
+
}),
|
|
701
|
+
list: (fileId, signal) => apiRequest(this.config, "GET", `/my-files/${fileId}/share-links`, { signal }),
|
|
702
|
+
update: (linkId, body, signal) => apiRequest(this.config, "PATCH", `/share-links/${linkId}`, {
|
|
703
|
+
body,
|
|
704
|
+
signal
|
|
705
|
+
}),
|
|
706
|
+
delete: (linkId, signal) => apiRequest(this.config, "DELETE", `/share-links/${linkId}`, { signal })
|
|
707
|
+
};
|
|
708
|
+
};
|
|
93
709
|
//#endregion
|
|
94
|
-
export { FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, apiErrorSchema,
|
|
710
|
+
export { FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, UnisourceClient, UnisourceError, UnisourceNetworkError, adminServiceUpdateRequestSchema, adminServiceUpdateResponseSchema, adminUserListResponseSchema, adminUserPasswordResetRequestSchema, adminUserPasswordResetResponseSchema, adminUserSchema, adminUserUpdateRequestSchema, adminUserUpdateResponseSchema, apiErrorSchema, auditEventActionSchema, auditEventSchema, auditLogListQuerySchema, auditLogListResponseSchema, fileDeleteResponseSchema, fileDownloadUrlResponseSchema, fileMoveRequestSchema, fileRecordDetailResponseSchema, fileRecordSchema, fileRecordsListQuerySchema, fileRecordsListResponseSchema, fileRestoreResponseSchema, fileUpdateRequestSchema, fileUpdateResponseSchema, folderCreateRequestSchema, folderCreateResponseSchema, folderDeleteResponseSchema, folderDetailResponseSchema, folderListQuerySchema, folderListResponseSchema, folderRestoreResponseSchema, folderSchema, folderUpdateRequestSchema, folderUpdateResponseSchema, getPublicFileInfo, mainStorageDeleteResponseSchema, mainStorageListQuerySchema, mainStorageListResponseSchema, mainStorageRenameRequestSchema, mainStorageRestoreResponseSchema, nonEmptyString, positiveInt, publicFileAccessResponseSchema, publicFileLockedResponseSchema, releaseDTOSchema, releaseDeleteResponseSchema, releaseSyncManifestSchema, releaseSyncRequestSchema, releaseSyncResponseSchema, releaseSyncResultSchema, releaseUpdateRequestSchema, releaseUploadCompleteRequestSchema, releaseUploadCompleteResponseSchema, releaseUploadFailResponseSchema, releaseUploadInitRequestSchema, releaseUploadInitResponseSchema, releasesListQuerySchema, releasesListResponseSchema, serviceDetailResponseSchema, serviceSchema, serviceUsageResponseSchema, shareLinkCreateRequestSchema, shareLinkCreateResponseSchema, shareLinkDeleteResponseSchema, shareLinkListResponseSchema, shareLinkSchema, shareLinkUpdateRequestSchema, shareLinkUpdateResponseSchema, unixTimestamp, unlockPublicFile, uploadAppwriteInitRequestSchema, uploadAppwriteInitResponseSchema, uploadCompleteResponseSchema, uploadDestinationSchema, uploadFailResponseSchema, uploadLifecycleRequestSchema, uploadR2InitRequestSchema, uploadR2InitResponseSchema, uploadRecordDetailResponseSchema, uploadRecordSchema, uploadStatusSchema, uploadsListResponseSchema };
|