@unisource/sdk 0.3.1 → 0.4.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/dist/index.d.mts CHANGED
@@ -31,7 +31,7 @@ declare const uploadR2InitRequestSchema: z.ZodObject<{
31
31
  folder_id: z.ZodOptional<z.ZodString>;
32
32
  is_main_storage: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
33
33
  }, z.core.$strip>;
34
- type UploadR2InitRequest = z.infer<typeof uploadR2InitRequestSchema>;
34
+ type UploadR2InitRequest = z.input<typeof uploadR2InitRequestSchema>;
35
35
  declare const uploadR2InitResponseSchema: z.ZodObject<{
36
36
  upload_id: z.ZodString;
37
37
  destination: z.ZodLiteral<"r2">;
@@ -48,7 +48,7 @@ declare const uploadAppwriteInitRequestSchema: z.ZodObject<{
48
48
  folder_id: z.ZodOptional<z.ZodString>;
49
49
  is_main_storage: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
50
50
  }, z.core.$strip>;
51
- type UploadAppwriteInitRequest = z.infer<typeof uploadAppwriteInitRequestSchema>;
51
+ type UploadAppwriteInitRequest = z.input<typeof uploadAppwriteInitRequestSchema>;
52
52
  declare const uploadAppwriteInitResponseSchema: z.ZodObject<{
53
53
  upload_id: z.ZodString;
54
54
  destination: z.ZodLiteral<"appwrite">;
@@ -57,13 +57,14 @@ declare const uploadAppwriteInitResponseSchema: z.ZodObject<{
57
57
  appwrite_bucket_id: z.ZodString;
58
58
  file_id: z.ZodString;
59
59
  expires_at: z.ZodNumber;
60
+ jwt: z.ZodOptional<z.ZodString>;
60
61
  }, z.core.$strip>;
61
62
  type UploadAppwriteInitResponse = z.infer<typeof uploadAppwriteInitResponseSchema>;
62
63
  declare const uploadLifecycleRequestSchema: z.ZodObject<{
63
64
  upload_id: z.ZodString;
64
65
  is_main_storage: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
65
66
  }, z.core.$strip>;
66
- type UploadLifecycleRequest = z.infer<typeof uploadLifecycleRequestSchema>;
67
+ type UploadLifecycleRequest = z.input<typeof uploadLifecycleRequestSchema>;
67
68
  declare const uploadCompleteResponseSchema: z.ZodObject<{
68
69
  success: z.ZodLiteral<true>;
69
70
  upload_id: z.ZodString;
@@ -76,6 +77,79 @@ declare const uploadFailResponseSchema: z.ZodObject<{
76
77
  status: z.ZodLiteral<"failed">;
77
78
  }, z.core.$strip>;
78
79
  type UploadFailResponse = z.infer<typeof uploadFailResponseSchema>;
80
+ declare const multipartCreateRequestSchema: z.ZodObject<{
81
+ filename: z.ZodString;
82
+ size: z.ZodNumber;
83
+ mime_type: z.ZodString;
84
+ folder_id: z.ZodOptional<z.ZodString>;
85
+ is_main_storage: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
86
+ }, z.core.$strip>;
87
+ type MultipartCreateRequest = z.input<typeof multipartCreateRequestSchema>;
88
+ declare const multipartCreateResponseSchema: z.ZodObject<{
89
+ upload_id: z.ZodString;
90
+ r2_upload_id: z.ZodString;
91
+ key: z.ZodString;
92
+ bucket: z.ZodString;
93
+ expires_at: z.ZodNumber;
94
+ }, z.core.$strip>;
95
+ type MultipartCreateResponse = z.infer<typeof multipartCreateResponseSchema>;
96
+ declare const multipartSignPartQuerySchema: z.ZodObject<{
97
+ upload_id: z.ZodString;
98
+ part_number: z.ZodCoercedNumber<unknown>;
99
+ }, z.core.$strip>;
100
+ type MultipartSignPartQuery = z.input<typeof multipartSignPartQuerySchema>;
101
+ declare const multipartSignPartResponseSchema: z.ZodObject<{
102
+ url: z.ZodString;
103
+ expires_at: z.ZodNumber;
104
+ }, z.core.$strip>;
105
+ type MultipartSignPartResponse = z.infer<typeof multipartSignPartResponseSchema>;
106
+ declare const multipartListPartsQuerySchema: z.ZodObject<{
107
+ upload_id: z.ZodString;
108
+ }, z.core.$strip>;
109
+ type MultipartListPartsQuery = z.input<typeof multipartListPartsQuerySchema>;
110
+ declare const multipartPartSchema: z.ZodObject<{
111
+ PartNumber: z.ZodNumber;
112
+ ETag: z.ZodString;
113
+ Size: z.ZodNumber;
114
+ }, z.core.$strip>;
115
+ type MultipartPart = z.infer<typeof multipartPartSchema>;
116
+ declare const multipartListPartsResponseSchema: z.ZodObject<{
117
+ parts: z.ZodArray<z.ZodObject<{
118
+ PartNumber: z.ZodNumber;
119
+ ETag: z.ZodString;
120
+ Size: z.ZodNumber;
121
+ }, z.core.$strip>>;
122
+ }, z.core.$strip>;
123
+ type MultipartListPartsResponse = z.infer<typeof multipartListPartsResponseSchema>;
124
+ declare const multipartCompleteRequestSchema: z.ZodObject<{
125
+ upload_id: z.ZodString;
126
+ parts: z.ZodArray<z.ZodObject<{
127
+ PartNumber: z.ZodNumber;
128
+ ETag: z.ZodString;
129
+ }, z.core.$strip>>;
130
+ }, z.core.$strip>;
131
+ type MultipartCompleteRequest = z.input<typeof multipartCompleteRequestSchema>;
132
+ declare const multipartCompleteResponseSchema: z.ZodObject<{
133
+ success: z.ZodLiteral<true>;
134
+ upload_id: z.ZodString;
135
+ status: z.ZodLiteral<"completed">;
136
+ }, z.core.$strip>;
137
+ type MultipartCompleteResponse = z.infer<typeof multipartCompleteResponseSchema>;
138
+ declare const multipartAbortRequestSchema: z.ZodObject<{
139
+ upload_id: z.ZodString;
140
+ }, z.core.$strip>;
141
+ type MultipartAbortRequest = z.input<typeof multipartAbortRequestSchema>;
142
+ declare const multipartAbortResponseSchema: z.ZodObject<{
143
+ success: z.ZodLiteral<true>;
144
+ upload_id: z.ZodString;
145
+ status: z.ZodLiteral<"failed">;
146
+ }, z.core.$strip>;
147
+ type MultipartAbortResponse = z.infer<typeof multipartAbortResponseSchema>;
148
+ declare const uploadTypeSchema: z.ZodEnum<{
149
+ multipart: "multipart";
150
+ single: "single";
151
+ }>;
152
+ type UploadType = z.infer<typeof uploadTypeSchema>;
79
153
  /** Raw upload record — returned by admin `/files` endpoints. */
80
154
  declare const uploadRecordSchema: z.ZodObject<{
81
155
  id: z.ZodString;
@@ -93,6 +167,10 @@ declare const uploadRecordSchema: z.ZodObject<{
93
167
  failed: "failed";
94
168
  pending: "pending";
95
169
  }>;
170
+ upload_type: z.ZodOptional<z.ZodEnum<{
171
+ multipart: "multipart";
172
+ single: "single";
173
+ }>>;
96
174
  expires_at: z.ZodNumber;
97
175
  created_at: z.ZodNumber;
98
176
  updated_at: z.ZodNumber;
@@ -115,6 +193,10 @@ declare const uploadsListResponseSchema: z.ZodObject<{
115
193
  failed: "failed";
116
194
  pending: "pending";
117
195
  }>;
196
+ upload_type: z.ZodOptional<z.ZodEnum<{
197
+ multipart: "multipart";
198
+ single: "single";
199
+ }>>;
118
200
  expires_at: z.ZodNumber;
119
201
  created_at: z.ZodNumber;
120
202
  updated_at: z.ZodNumber;
@@ -140,6 +222,10 @@ declare const uploadRecordDetailResponseSchema: z.ZodObject<{
140
222
  failed: "failed";
141
223
  pending: "pending";
142
224
  }>;
225
+ upload_type: z.ZodOptional<z.ZodEnum<{
226
+ multipart: "multipart";
227
+ single: "single";
228
+ }>>;
143
229
  expires_at: z.ZodNumber;
144
230
  created_at: z.ZodNumber;
145
231
  updated_at: z.ZodNumber;
@@ -389,6 +475,10 @@ declare const serviceSchema: z.ZodObject<{
389
475
  max_storage_bytes: z.ZodNumber;
390
476
  current_used_bytes: z.ZodNumber;
391
477
  max_file_size_bytes: z.ZodNumber;
478
+ recommended_upload_destination: z.ZodOptional<z.ZodEnum<{
479
+ appwrite: "appwrite";
480
+ r2: "r2";
481
+ }>>;
392
482
  created_at: z.ZodNumber;
393
483
  }, z.core.$strip>;
394
484
  type Service = z.infer<typeof serviceSchema>;
@@ -399,6 +489,10 @@ declare const serviceDetailResponseSchema: z.ZodObject<{
399
489
  max_storage_bytes: z.ZodNumber;
400
490
  current_used_bytes: z.ZodNumber;
401
491
  max_file_size_bytes: z.ZodNumber;
492
+ recommended_upload_destination: z.ZodOptional<z.ZodEnum<{
493
+ appwrite: "appwrite";
494
+ r2: "r2";
495
+ }>>;
402
496
  created_at: z.ZodNumber;
403
497
  }, z.core.$strip>;
404
498
  }, z.core.$strip>;
@@ -415,10 +509,41 @@ declare const adminServiceUpdateResponseSchema: z.ZodObject<{
415
509
  max_storage_bytes: z.ZodNumber;
416
510
  current_used_bytes: z.ZodNumber;
417
511
  max_file_size_bytes: z.ZodNumber;
512
+ recommended_upload_destination: z.ZodOptional<z.ZodEnum<{
513
+ appwrite: "appwrite";
514
+ r2: "r2";
515
+ }>>;
418
516
  created_at: z.ZodNumber;
419
517
  }, z.core.$strip>;
420
518
  }, z.core.$strip>;
421
519
  type AdminServiceUpdateResponse = z.infer<typeof adminServiceUpdateResponseSchema>;
520
+ /**
521
+ * Separate settings endpoint driven by the Split-Button upload UI. Clients
522
+ * can flip the recommended default upload destination per service without
523
+ * disturbing quota-related fields.
524
+ */
525
+ declare const adminServiceSettingsRequestSchema: z.ZodObject<{
526
+ recommended_upload_destination: z.ZodOptional<z.ZodEnum<{
527
+ appwrite: "appwrite";
528
+ r2: "r2";
529
+ }>>;
530
+ }, z.core.$strip>;
531
+ type AdminServiceSettingsRequest = z.infer<typeof adminServiceSettingsRequestSchema>;
532
+ declare const adminServiceSettingsResponseSchema: z.ZodObject<{
533
+ service: z.ZodObject<{
534
+ id: z.ZodString;
535
+ name: z.ZodString;
536
+ max_storage_bytes: z.ZodNumber;
537
+ current_used_bytes: z.ZodNumber;
538
+ max_file_size_bytes: z.ZodNumber;
539
+ recommended_upload_destination: z.ZodOptional<z.ZodEnum<{
540
+ appwrite: "appwrite";
541
+ r2: "r2";
542
+ }>>;
543
+ created_at: z.ZodNumber;
544
+ }, z.core.$strip>;
545
+ }, z.core.$strip>;
546
+ type AdminServiceSettingsResponse = z.infer<typeof adminServiceSettingsResponseSchema>;
422
547
  declare const serviceUsageResponseSchema: z.ZodObject<{
423
548
  service_id: z.ZodString;
424
549
  max_storage_bytes: z.ZodNumber;
@@ -582,6 +707,18 @@ declare const adminUserPasswordResetResponseSchema: z.ZodObject<{
582
707
  user_id: z.ZodString;
583
708
  }, z.core.$strip>;
584
709
  type AdminUserPasswordResetResponse = z.infer<typeof adminUserPasswordResetResponseSchema>;
710
+ declare const adminUserRoleUpdateRequestSchema: z.ZodObject<{
711
+ role: z.ZodEnum<{
712
+ admin: "admin";
713
+ plus: "plus";
714
+ user: "user";
715
+ }>;
716
+ }, z.core.$strip>;
717
+ type AdminUserRoleUpdateRequest = z.infer<typeof adminUserRoleUpdateRequestSchema>;
718
+ declare const adminUserStorageLimitUpdateRequestSchema: z.ZodObject<{
719
+ limit_bytes: z.ZodNullable<z.ZodNumber>;
720
+ }, z.core.$strip>;
721
+ type AdminUserStorageLimitUpdateRequest = z.infer<typeof adminUserStorageLimitUpdateRequestSchema>;
585
722
  //#endregion
586
723
  //#region src/mainStorage.d.ts
587
724
  declare const mainStorageListQuerySchema: z.ZodObject<{
@@ -932,6 +1069,32 @@ declare const shareLinkDeleteResponseSchema: z.ZodObject<{
932
1069
  id: z.ZodString;
933
1070
  }, z.core.$strip>;
934
1071
  type ShareLinkDeleteResponse = z.infer<typeof shareLinkDeleteResponseSchema>;
1072
+ declare const shareLinkDetailResponseSchema: z.ZodObject<{
1073
+ link: z.ZodObject<{
1074
+ id: z.ZodString;
1075
+ service_id: z.ZodString;
1076
+ file_id: z.ZodString;
1077
+ user_id: z.ZodString;
1078
+ slug: z.ZodString;
1079
+ name: z.ZodNullable<z.ZodString>;
1080
+ has_password: z.ZodBoolean;
1081
+ expires_at: z.ZodNullable<z.ZodNumber>;
1082
+ download_count: z.ZodNumber;
1083
+ max_downloads: z.ZodNullable<z.ZodNumber>;
1084
+ is_active: z.ZodBoolean;
1085
+ created_at: z.ZodNumber;
1086
+ updated_at: z.ZodNumber;
1087
+ }, z.core.$strip>;
1088
+ }, z.core.$strip>;
1089
+ type ShareLinkDetailResponse = z.infer<typeof shareLinkDetailResponseSchema>;
1090
+ declare const sharesCreateRequestSchema: z.ZodObject<{
1091
+ file_id: z.ZodString;
1092
+ name: z.ZodOptional<z.ZodString>;
1093
+ expires_at: z.ZodOptional<z.ZodNumber>;
1094
+ max_downloads: z.ZodOptional<z.ZodNumber>;
1095
+ password: z.ZodOptional<z.ZodString>;
1096
+ }, z.core.$strip>;
1097
+ type SharesCreateRequest = z.infer<typeof sharesCreateRequestSchema>;
935
1098
  //#endregion
936
1099
  //#region src/client.d.ts
937
1100
  declare class UnisourceError extends Error {
@@ -965,7 +1128,14 @@ declare class UnisourceClient {
965
1128
  /** Initiate an R2 upload — returns a presigned PUT URL */r2Init: (body: UploadR2InitRequest, signal?: AbortSignal) => Promise<UploadR2InitResponse>; /** Initiate an Appwrite upload — returns credentials for direct SDK upload */
966
1129
  appwriteInit: (body: UploadAppwriteInitRequest, signal?: AbortSignal) => Promise<UploadAppwriteInitResponse>; /** Confirm that the file was successfully uploaded to storage */
967
1130
  complete: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadCompleteResponse>; /** Mark an upload as failed and release reserved quota */
968
- fail: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadFailResponse>;
1131
+ fail: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadFailResponse>; /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
1132
+ multipart: {
1133
+ /** Create a multipart upload — returns UploadId + storage key */create: (body: MultipartCreateRequest, signal?: AbortSignal) => Promise<MultipartCreateResponse>; /** Short-lived presigned PUT URL for a single part */
1134
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal) => Promise<MultipartSignPartResponse>; /** List parts already uploaded — feeds Golden Retriever's resume logic */
1135
+ listParts: (uploadId: string, signal?: AbortSignal) => Promise<MultipartListPartsResponse>; /** Finalize the multipart upload. Parts must include PartNumber + ETag. */
1136
+ complete: (body: MultipartCompleteRequest, signal?: AbortSignal) => Promise<MultipartCompleteResponse>; /** Abort the multipart upload and release reserved quota */
1137
+ abort: (uploadId: string, signal?: AbortSignal) => Promise<MultipartAbortResponse>;
1138
+ };
969
1139
  };
970
1140
  readonly myFiles: {
971
1141
  /** List files owned by the authenticated user */list: (query?: FileRecordsListQuery, signal?: AbortSignal, options?: {
@@ -1050,7 +1220,8 @@ declare class UnisourceClient {
1050
1220
  };
1051
1221
  readonly admin: {
1052
1222
  /** Get service info and quota limits */serviceDetail: (signal?: AbortSignal) => Promise<ServiceDetailResponse>; /** Update custom service-wide limits */
1053
- updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal) => Promise<AdminServiceUpdateResponse>; /** Get real-time storage usage for the service */
1223
+ updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal) => Promise<AdminServiceUpdateResponse>; /** Update service-wide settings (e.g. recommended upload destination) */
1224
+ updateServiceSettings: (body: AdminServiceSettingsRequest, signal?: AbortSignal) => Promise<AdminServiceSettingsResponse>; /** Get real-time storage usage for the service */
1054
1225
  usage: (signal?: AbortSignal) => Promise<ServiceUsageResponse>; /** List all uploads (pending/completed/failed) for this service */
1055
1226
  listUploads: (query?: {
1056
1227
  status?: UploadStatus;
@@ -1067,7 +1238,9 @@ declare class UnisourceClient {
1067
1238
  limit?: number;
1068
1239
  }, signal?: AbortSignal) => Promise<AdminUserListResponse>; /** Update Appwrite user properties and service-specific quota/role */
1069
1240
  updateUser: (userId: string, body: AdminUserUpdateRequest, signal?: AbortSignal) => Promise<AdminUserUpdateResponse>; /** Overwrite a user's password and revoke active sessions */
1070
- resetUserPassword: (userId: string, body: AdminUserPasswordResetRequest, signal?: AbortSignal) => Promise<AdminUserPasswordResetResponse>;
1241
+ resetUserPassword: (userId: string, body: AdminUserPasswordResetRequest, signal?: AbortSignal) => Promise<AdminUserPasswordResetResponse>; /** Update a user's role */
1242
+ updateUserRole: (userId: string, body: AdminUserRoleUpdateRequest, signal?: AbortSignal) => Promise<AdminUserUpdateResponse>; /** Update a user's storage limit */
1243
+ updateUserStorageLimit: (userId: string, body: AdminUserStorageLimitUpdateRequest, signal?: AbortSignal) => Promise<AdminUserUpdateResponse>;
1071
1244
  };
1072
1245
  readonly shareLinks: {
1073
1246
  /** Create a public share link for a file */create: (fileId: string, body: ShareLinkCreateRequest, signal?: AbortSignal) => Promise<ShareLinkCreateResponse>; /** List all share links for a file */
@@ -1075,6 +1248,31 @@ declare class UnisourceClient {
1075
1248
  update: (linkId: string, body: ShareLinkUpdateRequest, signal?: AbortSignal) => Promise<ShareLinkUpdateResponse>; /** Permanently delete a share link */
1076
1249
  delete: (linkId: string, signal?: AbortSignal) => Promise<ShareLinkDeleteResponse>;
1077
1250
  };
1251
+ readonly files: {
1252
+ /** Get a single file record */get: (id: string, signal?: AbortSignal, options?: {
1253
+ asUser?: string;
1254
+ }) => Promise<FileRecordDetailResponse>; /** Rename or update a file */
1255
+ update: (id: string, body: FileUpdateRequest, signal?: AbortSignal, options?: {
1256
+ asUser?: string;
1257
+ }) => Promise<FileUpdateResponse>; /** Soft-delete or permanently delete a file */
1258
+ delete: (id: string, query?: {
1259
+ permanent?: boolean;
1260
+ }, signal?: AbortSignal, options?: {
1261
+ asUser?: string;
1262
+ }) => Promise<FileDeleteResponse>; /** Restore a file from trash */
1263
+ restore: (id: string, signal?: AbortSignal, options?: {
1264
+ asUser?: string;
1265
+ }) => Promise<FileRestoreResponse>; /** Get a time-limited download URL */
1266
+ downloadUrl: (id: string, signal?: AbortSignal, options?: {
1267
+ asUser?: string;
1268
+ }) => Promise<FileDownloadUrlResponse>;
1269
+ };
1270
+ readonly shares: {
1271
+ /** List all share links for the authenticated user */list: (signal?: AbortSignal) => Promise<ShareLinkListResponse>; /** Create a share link (file_id in body) */
1272
+ create: (body: SharesCreateRequest, signal?: AbortSignal) => Promise<ShareLinkCreateResponse>; /** Get a single share link by ID */
1273
+ get: (id: string, signal?: AbortSignal) => Promise<ShareLinkDetailResponse>; /** Delete a share link */
1274
+ delete: (id: string, signal?: AbortSignal) => Promise<ShareLinkDeleteResponse>;
1275
+ };
1078
1276
  }
1079
1277
  //#endregion
1080
- export { type AdminServiceUpdateRequest, type AdminServiceUpdateResponse, type AdminUser, type AdminUserListResponse, type AdminUserPasswordResetRequest, type AdminUserPasswordResetResponse, type AdminUserUpdateRequest, type AdminUserUpdateResponse, type ApiError, type AuditEvent, type AuditEventAction, type AuditLogListQuery, type AuditLogListResponse, FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, type FileDeleteResponse, type FileDownloadUrlResponse, type FileMoveRequest, type FileRecord, type FileRecordDetailResponse, type FileRecordsListQuery, type FileRecordsListResponse, type FileRestoreResponse, type FileUpdateRequest, type FileUpdateResponse, type Folder, type FolderCreateRequest, type FolderCreateResponse, type FolderDeleteResponse, type FolderDetailResponse, type FolderListQuery, type FolderListResponse, type FolderRestoreResponse, type FolderUpdateRequest, type FolderUpdateResponse, MainStorageDeleteResponse, MainStorageDetailResponse, MainStorageFile, MainStorageListQuery, MainStorageListResponse, MainStorageRenameRequest, MainStorageRenameResponse, MainStorageRestoreResponse, type PublicFileAccessResponse, type PublicFileLockedResponse, type ReleaseDTO, type ReleaseDeleteResponse, type ReleaseSyncManifest, type ReleaseSyncRequest, type ReleaseSyncResponse, type ReleaseSyncResult, type ReleaseUpdateRequest, type ReleaseUploadCompleteRequest, type ReleaseUploadCompleteResponse, type ReleaseUploadFailResponse, type ReleaseUploadInitRequest, type ReleaseUploadInitResponse, type ReleasesListQuery, type ReleasesListResponse, type Service, type ServiceDetailResponse, type ServiceUsageResponse, type ShareLink, type ShareLinkCreateRequest, type ShareLinkCreateResponse, type ShareLinkDeleteResponse, type ShareLinkListResponse, type ShareLinkUpdateRequest, type ShareLinkUpdateResponse, UnisourceClient, type UnisourceClientConfig, UnisourceError, UnisourceNetworkError, type UploadAppwriteInitRequest, type UploadAppwriteInitResponse, type UploadCompleteResponse, type UploadDestination, type UploadFailResponse, type UploadLifecycleRequest, type UploadR2InitRequest, type UploadR2InitResponse, type UploadRecord, type UploadRecordDetailResponse, type UploadStatus, type UploadsListResponse, 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, mainStorageDetailResponseSchema, mainStorageFileSchema, mainStorageListQuerySchema, mainStorageListResponseSchema, mainStorageRenameRequestSchema, mainStorageRenameResponseSchema, 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 };
1278
+ export { type AdminServiceSettingsRequest, type AdminServiceSettingsResponse, type AdminServiceUpdateRequest, type AdminServiceUpdateResponse, type AdminUser, type AdminUserListResponse, type AdminUserPasswordResetRequest, type AdminUserPasswordResetResponse, type AdminUserRoleUpdateRequest, type AdminUserStorageLimitUpdateRequest, type AdminUserUpdateRequest, type AdminUserUpdateResponse, type ApiError, type AuditEvent, type AuditEventAction, type AuditLogListQuery, type AuditLogListResponse, FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, type FileDeleteResponse, type FileDownloadUrlResponse, type FileMoveRequest, type FileRecord, type FileRecordDetailResponse, type FileRecordsListQuery, type FileRecordsListResponse, type FileRestoreResponse, type FileUpdateRequest, type FileUpdateResponse, type Folder, type FolderCreateRequest, type FolderCreateResponse, type FolderDeleteResponse, type FolderDetailResponse, type FolderListQuery, type FolderListResponse, type FolderRestoreResponse, type FolderUpdateRequest, type FolderUpdateResponse, MainStorageDeleteResponse, MainStorageDetailResponse, MainStorageFile, MainStorageListQuery, MainStorageListResponse, MainStorageRenameRequest, MainStorageRenameResponse, MainStorageRestoreResponse, type MultipartAbortRequest, type MultipartAbortResponse, type MultipartCompleteRequest, type MultipartCompleteResponse, type MultipartCreateRequest, type MultipartCreateResponse, type MultipartListPartsQuery, type MultipartListPartsResponse, type MultipartPart, type MultipartSignPartQuery, type MultipartSignPartResponse, type PublicFileAccessResponse, type PublicFileLockedResponse, type ReleaseDTO, type ReleaseDeleteResponse, type ReleaseSyncManifest, type ReleaseSyncRequest, type ReleaseSyncResponse, type ReleaseSyncResult, type ReleaseUpdateRequest, type ReleaseUploadCompleteRequest, type ReleaseUploadCompleteResponse, type ReleaseUploadFailResponse, type ReleaseUploadInitRequest, type ReleaseUploadInitResponse, type ReleasesListQuery, type ReleasesListResponse, type Service, type ServiceDetailResponse, type ServiceUsageResponse, type ShareLink, type ShareLinkCreateRequest, type ShareLinkCreateResponse, type ShareLinkDeleteResponse, type ShareLinkDetailResponse, type ShareLinkListResponse, type ShareLinkUpdateRequest, type ShareLinkUpdateResponse, type SharesCreateRequest, UnisourceClient, type UnisourceClientConfig, UnisourceError, UnisourceNetworkError, type UploadAppwriteInitRequest, type UploadAppwriteInitResponse, type UploadCompleteResponse, type UploadDestination, type UploadFailResponse, type UploadLifecycleRequest, type UploadR2InitRequest, type UploadR2InitResponse, type UploadRecord, type UploadRecordDetailResponse, type UploadStatus, type UploadType, type UploadsListResponse, adminServiceSettingsRequestSchema, adminServiceSettingsResponseSchema, adminServiceUpdateRequestSchema, adminServiceUpdateResponseSchema, adminUserListResponseSchema, adminUserPasswordResetRequestSchema, adminUserPasswordResetResponseSchema, adminUserRoleUpdateRequestSchema, adminUserSchema, adminUserStorageLimitUpdateRequestSchema, 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, mainStorageDetailResponseSchema, mainStorageFileSchema, mainStorageListQuerySchema, mainStorageListResponseSchema, mainStorageRenameRequestSchema, mainStorageRenameResponseSchema, mainStorageRestoreResponseSchema, multipartAbortRequestSchema, multipartAbortResponseSchema, multipartCompleteRequestSchema, multipartCompleteResponseSchema, multipartCreateRequestSchema, multipartCreateResponseSchema, multipartListPartsQuerySchema, multipartListPartsResponseSchema, multipartPartSchema, multipartSignPartQuerySchema, multipartSignPartResponseSchema, nonEmptyString, positiveInt, publicFileAccessResponseSchema, publicFileLockedResponseSchema, releaseDTOSchema, releaseDeleteResponseSchema, releaseSyncManifestSchema, releaseSyncRequestSchema, releaseSyncResponseSchema, releaseSyncResultSchema, releaseUpdateRequestSchema, releaseUploadCompleteRequestSchema, releaseUploadCompleteResponseSchema, releaseUploadFailResponseSchema, releaseUploadInitRequestSchema, releaseUploadInitResponseSchema, releasesListQuerySchema, releasesListResponseSchema, serviceDetailResponseSchema, serviceSchema, serviceUsageResponseSchema, shareLinkCreateRequestSchema, shareLinkCreateResponseSchema, shareLinkDeleteResponseSchema, shareLinkDetailResponseSchema, shareLinkListResponseSchema, shareLinkSchema, shareLinkUpdateRequestSchema, shareLinkUpdateResponseSchema, sharesCreateRequestSchema, unixTimestamp, unlockPublicFile, uploadAppwriteInitRequestSchema, uploadAppwriteInitResponseSchema, uploadCompleteResponseSchema, uploadDestinationSchema, uploadFailResponseSchema, uploadLifecycleRequestSchema, uploadR2InitRequestSchema, uploadR2InitResponseSchema, uploadRecordDetailResponseSchema, uploadRecordSchema, uploadStatusSchema, uploadTypeSchema, uploadsListResponseSchema };
package/dist/index.mjs CHANGED
@@ -46,7 +46,8 @@ const uploadAppwriteInitResponseSchema = z.object({
46
46
  appwrite_project_id: nonEmptyString,
47
47
  appwrite_bucket_id: nonEmptyString,
48
48
  file_id: nonEmptyString,
49
- expires_at: positiveInt
49
+ expires_at: positiveInt,
50
+ jwt: nonEmptyString.optional()
50
51
  });
51
52
  const uploadLifecycleRequestSchema = z.object({
52
53
  upload_id: nonEmptyString,
@@ -62,6 +63,46 @@ const uploadFailResponseSchema = z.object({
62
63
  upload_id: nonEmptyString,
63
64
  status: z.literal("failed")
64
65
  });
66
+ const multipartCreateRequestSchema = z.object({
67
+ filename: nonEmptyString,
68
+ size: positiveInt,
69
+ mime_type: nonEmptyString,
70
+ folder_id: nonEmptyString.optional(),
71
+ is_main_storage: z.boolean().optional().default(false)
72
+ });
73
+ const multipartCreateResponseSchema = z.object({
74
+ upload_id: nonEmptyString,
75
+ r2_upload_id: nonEmptyString,
76
+ key: nonEmptyString,
77
+ bucket: nonEmptyString,
78
+ expires_at: positiveInt
79
+ });
80
+ const multipartSignPartQuerySchema = z.object({
81
+ upload_id: nonEmptyString,
82
+ part_number: z.coerce.number().int().min(1).max(1e4)
83
+ });
84
+ const multipartSignPartResponseSchema = z.object({
85
+ url: z.string().url(),
86
+ expires_at: positiveInt
87
+ });
88
+ const multipartListPartsQuerySchema = z.object({ upload_id: nonEmptyString });
89
+ const multipartPartSchema = z.object({
90
+ PartNumber: z.number().int().min(1).max(1e4),
91
+ ETag: nonEmptyString,
92
+ Size: z.number().int().nonnegative()
93
+ });
94
+ const multipartListPartsResponseSchema = z.object({ parts: z.array(multipartPartSchema) });
95
+ const multipartCompleteRequestSchema = z.object({
96
+ upload_id: nonEmptyString,
97
+ parts: z.array(z.object({
98
+ PartNumber: z.number().int().min(1).max(1e4),
99
+ ETag: nonEmptyString
100
+ })).min(1)
101
+ });
102
+ const multipartCompleteResponseSchema = uploadCompleteResponseSchema;
103
+ const multipartAbortRequestSchema = z.object({ upload_id: nonEmptyString });
104
+ const multipartAbortResponseSchema = uploadFailResponseSchema;
105
+ const uploadTypeSchema = z.enum(["single", "multipart"]);
65
106
  /** Raw upload record — returned by admin `/files` endpoints. */
66
107
  const uploadRecordSchema = z.object({
67
108
  id: nonEmptyString,
@@ -72,6 +113,7 @@ const uploadRecordSchema = z.object({
72
113
  mime_type: nonEmptyString,
73
114
  destination: uploadDestinationSchema,
74
115
  status: uploadStatusSchema,
116
+ upload_type: uploadTypeSchema.optional(),
75
117
  expires_at: positiveInt,
76
118
  created_at: positiveInt,
77
119
  updated_at: positiveInt
@@ -190,6 +232,7 @@ const serviceSchema = z.object({
190
232
  max_storage_bytes: positiveInt,
191
233
  current_used_bytes: z.number().int().nonnegative(),
192
234
  max_file_size_bytes: positiveInt,
235
+ recommended_upload_destination: uploadDestinationSchema.optional(),
193
236
  created_at: unixTimestamp
194
237
  });
195
238
  const serviceDetailResponseSchema = z.object({ service: serviceSchema });
@@ -198,6 +241,13 @@ const adminServiceUpdateRequestSchema = z.object({
198
241
  max_file_size_bytes: positiveInt.optional()
199
242
  }).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
243
  const adminServiceUpdateResponseSchema = serviceDetailResponseSchema;
244
+ /**
245
+ * Separate settings endpoint driven by the Split-Button upload UI. Clients
246
+ * can flip the recommended default upload destination per service without
247
+ * disturbing quota-related fields.
248
+ */
249
+ const adminServiceSettingsRequestSchema = z.object({ recommended_upload_destination: uploadDestinationSchema.optional() }).refine((v) => v.recommended_upload_destination !== void 0, { message: "At least one setting must be provided" });
250
+ const adminServiceSettingsResponseSchema = serviceDetailResponseSchema;
201
251
  const serviceUsageResponseSchema = z.object({
202
252
  service_id: nonEmptyString,
203
253
  max_storage_bytes: positiveInt,
@@ -283,6 +333,12 @@ const adminUserPasswordResetResponseSchema = z.object({
283
333
  success: z.literal(true),
284
334
  user_id: nonEmptyString
285
335
  });
336
+ const adminUserRoleUpdateRequestSchema = z.object({ role: z.enum([
337
+ "user",
338
+ "plus",
339
+ "admin"
340
+ ]) });
341
+ const adminUserStorageLimitUpdateRequestSchema = z.object({ limit_bytes: positiveInt.nullable() });
286
342
  //#endregion
287
343
  //#region src/mainStorage.ts
288
344
  const mainStorageListQuerySchema = z.object({
@@ -446,6 +502,14 @@ const shareLinkDeleteResponseSchema = z.object({
446
502
  success: z.literal(true),
447
503
  id: nonEmptyString
448
504
  });
505
+ const shareLinkDetailResponseSchema = z.object({ link: shareLinkSchema });
506
+ const sharesCreateRequestSchema = z.object({
507
+ file_id: nonEmptyString,
508
+ name: z.string().trim().max(128).optional(),
509
+ expires_at: positiveInt.optional(),
510
+ max_downloads: positiveInt.optional(),
511
+ password: z.string().min(1).optional()
512
+ });
449
513
  //#endregion
450
514
  //#region src/client.ts
451
515
  var UnisourceError = class extends Error {
@@ -543,7 +607,32 @@ var UnisourceClient = class {
543
607
  fail: (body, signal) => apiRequest(this.config, "POST", "/upload/fail", {
544
608
  body,
545
609
  signal
546
- })
610
+ }),
611
+ multipart: {
612
+ create: (body, signal) => apiRequest(this.config, "POST", "/upload/r2/multipart/create", {
613
+ body,
614
+ signal
615
+ }),
616
+ signPart: (uploadId, partNumber, signal) => apiRequest(this.config, "GET", "/upload/r2/multipart/sign-part", {
617
+ query: {
618
+ upload_id: uploadId,
619
+ part_number: partNumber
620
+ },
621
+ signal
622
+ }),
623
+ listParts: (uploadId, signal) => apiRequest(this.config, "GET", "/upload/r2/multipart/list-parts", {
624
+ query: { upload_id: uploadId },
625
+ signal
626
+ }),
627
+ complete: (body, signal) => apiRequest(this.config, "POST", "/upload/r2/multipart/complete", {
628
+ body,
629
+ signal
630
+ }),
631
+ abort: (uploadId, signal) => apiRequest(this.config, "DELETE", "/upload/r2/multipart/abort", {
632
+ body: { upload_id: uploadId },
633
+ signal
634
+ })
635
+ }
547
636
  };
548
637
  myFiles = {
549
638
  list: (query, signal, options) => apiRequest(this.config, "GET", "/my-files", {
@@ -673,14 +762,18 @@ var UnisourceClient = class {
673
762
  body,
674
763
  signal
675
764
  }),
765
+ updateServiceSettings: (body, signal) => apiRequest(this.config, "PATCH", "/admin/service/settings", {
766
+ body,
767
+ signal
768
+ }),
676
769
  usage: (signal) => apiRequest(this.config, "GET", "/admin/service/usage", { signal }),
677
- listUploads: (query, signal) => apiRequest(this.config, "GET", "/files", {
770
+ listUploads: (query, signal) => apiRequest(this.config, "GET", "/admin/files", {
678
771
  query,
679
772
  signal
680
773
  }),
681
- getUpload: (id, signal) => apiRequest(this.config, "GET", `/files/${id}`, { signal }),
682
- downloadUploadUrl: (id, signal) => apiRequest(this.config, "GET", `/files/${id}/download-url`, { signal }),
683
- deleteUpload: (id, signal) => apiRequest(this.config, "DELETE", `/files/${id}`, { signal }),
774
+ getUpload: (id, signal) => apiRequest(this.config, "GET", `/admin/files/${id}`, { signal }),
775
+ downloadUploadUrl: (id, signal) => apiRequest(this.config, "GET", `/admin/files/${id}/download-url`, { signal }),
776
+ deleteUpload: (id, signal) => apiRequest(this.config, "DELETE", `/admin/files/${id}`, { signal }),
684
777
  auditLog: (query, signal) => apiRequest(this.config, "GET", "/admin/audit-log", {
685
778
  query,
686
779
  signal
@@ -696,6 +789,14 @@ var UnisourceClient = class {
696
789
  resetUserPassword: (userId, body, signal) => apiRequest(this.config, "POST", `/admin/users/${userId}/password`, {
697
790
  body,
698
791
  signal
792
+ }),
793
+ updateUserRole: (userId, body, signal) => apiRequest(this.config, "PATCH", `/admin/users/${userId}/role`, {
794
+ body,
795
+ signal
796
+ }),
797
+ updateUserStorageLimit: (userId, body, signal) => apiRequest(this.config, "PATCH", `/admin/users/${userId}/storage-limit`, {
798
+ body,
799
+ signal
699
800
  })
700
801
  };
701
802
  shareLinks = {
@@ -710,6 +811,39 @@ var UnisourceClient = class {
710
811
  }),
711
812
  delete: (linkId, signal) => apiRequest(this.config, "DELETE", `/share-links/${linkId}`, { signal })
712
813
  };
814
+ files = {
815
+ get: (id, signal, options) => apiRequest(this.config, "GET", `/files/${id}`, {
816
+ signal,
817
+ extraHeaders: this.withAsUser(options)
818
+ }),
819
+ update: (id, body, signal, options) => apiRequest(this.config, "PATCH", `/files/${id}`, {
820
+ body,
821
+ signal,
822
+ extraHeaders: this.withAsUser(options)
823
+ }),
824
+ delete: (id, query, signal, options) => apiRequest(this.config, "DELETE", `/files/${id}`, {
825
+ query,
826
+ signal,
827
+ extraHeaders: this.withAsUser(options)
828
+ }),
829
+ restore: (id, signal, options) => apiRequest(this.config, "POST", `/files/${id}/restore`, {
830
+ signal,
831
+ extraHeaders: this.withAsUser(options)
832
+ }),
833
+ downloadUrl: (id, signal, options) => apiRequest(this.config, "GET", `/files/${id}/download-url`, {
834
+ signal,
835
+ extraHeaders: this.withAsUser(options)
836
+ })
837
+ };
838
+ shares = {
839
+ list: (signal) => apiRequest(this.config, "GET", "/shares", { signal }),
840
+ create: (body, signal) => apiRequest(this.config, "POST", "/shares", {
841
+ body,
842
+ signal
843
+ }),
844
+ get: (id, signal) => apiRequest(this.config, "GET", `/shares/${id}`, { signal }),
845
+ delete: (id, signal) => apiRequest(this.config, "DELETE", `/shares/${id}`, { signal })
846
+ };
713
847
  };
714
848
  //#endregion
715
- 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, mainStorageDetailResponseSchema, mainStorageFileSchema, mainStorageListQuerySchema, mainStorageListResponseSchema, mainStorageRenameRequestSchema, mainStorageRenameResponseSchema, 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 };
849
+ export { FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, UnisourceClient, UnisourceError, UnisourceNetworkError, adminServiceSettingsRequestSchema, adminServiceSettingsResponseSchema, adminServiceUpdateRequestSchema, adminServiceUpdateResponseSchema, adminUserListResponseSchema, adminUserPasswordResetRequestSchema, adminUserPasswordResetResponseSchema, adminUserRoleUpdateRequestSchema, adminUserSchema, adminUserStorageLimitUpdateRequestSchema, 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, mainStorageDetailResponseSchema, mainStorageFileSchema, mainStorageListQuerySchema, mainStorageListResponseSchema, mainStorageRenameRequestSchema, mainStorageRenameResponseSchema, mainStorageRestoreResponseSchema, multipartAbortRequestSchema, multipartAbortResponseSchema, multipartCompleteRequestSchema, multipartCompleteResponseSchema, multipartCreateRequestSchema, multipartCreateResponseSchema, multipartListPartsQuerySchema, multipartListPartsResponseSchema, multipartPartSchema, multipartSignPartQuerySchema, multipartSignPartResponseSchema, nonEmptyString, positiveInt, publicFileAccessResponseSchema, publicFileLockedResponseSchema, releaseDTOSchema, releaseDeleteResponseSchema, releaseSyncManifestSchema, releaseSyncRequestSchema, releaseSyncResponseSchema, releaseSyncResultSchema, releaseUpdateRequestSchema, releaseUploadCompleteRequestSchema, releaseUploadCompleteResponseSchema, releaseUploadFailResponseSchema, releaseUploadInitRequestSchema, releaseUploadInitResponseSchema, releasesListQuerySchema, releasesListResponseSchema, serviceDetailResponseSchema, serviceSchema, serviceUsageResponseSchema, shareLinkCreateRequestSchema, shareLinkCreateResponseSchema, shareLinkDeleteResponseSchema, shareLinkDetailResponseSchema, shareLinkListResponseSchema, shareLinkSchema, shareLinkUpdateRequestSchema, shareLinkUpdateResponseSchema, sharesCreateRequestSchema, unixTimestamp, unlockPublicFile, uploadAppwriteInitRequestSchema, uploadAppwriteInitResponseSchema, uploadCompleteResponseSchema, uploadDestinationSchema, uploadFailResponseSchema, uploadLifecycleRequestSchema, uploadR2InitRequestSchema, uploadR2InitResponseSchema, uploadRecordDetailResponseSchema, uploadRecordSchema, uploadStatusSchema, uploadTypeSchema, uploadsListResponseSchema };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@unisource/sdk",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.3.1",
5
+ "version": "0.4.0",
6
6
  "description": "Wspolne kontrakty danych dla backendu i frontendu UniSource.",
7
7
  "license": "MIT",
8
8
  "publishConfig": {
package/src/client.ts CHANGED
@@ -9,6 +9,13 @@ import type {
9
9
  UploadFailResponse,
10
10
  UploadsListResponse,
11
11
  UploadRecordDetailResponse,
12
+ MultipartCreateRequest,
13
+ MultipartCreateResponse,
14
+ MultipartSignPartResponse,
15
+ MultipartListPartsResponse,
16
+ MultipartCompleteRequest,
17
+ MultipartCompleteResponse,
18
+ MultipartAbortResponse,
12
19
  } from './uploads';
13
20
  import type {
14
21
  FileRecord,
@@ -38,6 +45,8 @@ import type {
38
45
  ServiceUsageResponse,
39
46
  AdminServiceUpdateRequest,
40
47
  AdminServiceUpdateResponse,
48
+ AdminServiceSettingsRequest,
49
+ AdminServiceSettingsResponse,
41
50
  AuditLogListQuery,
42
51
  AuditLogListResponse,
43
52
  AdminUserListResponse,
@@ -45,11 +54,15 @@ import type {
45
54
  AdminUserUpdateResponse,
46
55
  AdminUserPasswordResetRequest,
47
56
  AdminUserPasswordResetResponse,
57
+ AdminUserRoleUpdateRequest,
58
+ AdminUserStorageLimitUpdateRequest,
48
59
  } from './services';
49
60
  import type {
50
61
  ShareLinkCreateRequest,
51
62
  ShareLinkCreateResponse,
52
63
  ShareLinkListResponse,
64
+ ShareLinkDetailResponse,
65
+ SharesCreateRequest,
53
66
  PublicFileAccessResponse,
54
67
  PublicFileLockedResponse,
55
68
  ShareLinkUpdateRequest,
@@ -244,6 +257,38 @@ export class UnisourceClient {
244
257
  /** Mark an upload as failed and release reserved quota */
245
258
  fail: (body: UploadLifecycleRequest, signal?: AbortSignal): Promise<UploadFailResponse> =>
246
259
  apiRequest(this.config, 'POST', '/upload/fail', { body, signal }),
260
+
261
+ /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
262
+ multipart: {
263
+ /** Create a multipart upload — returns UploadId + storage key */
264
+ create: (body: MultipartCreateRequest, signal?: AbortSignal): Promise<MultipartCreateResponse> =>
265
+ apiRequest(this.config, 'POST', '/upload/r2/multipart/create', { body, signal }),
266
+
267
+ /** Short-lived presigned PUT URL for a single part */
268
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal): Promise<MultipartSignPartResponse> =>
269
+ apiRequest(this.config, 'GET', '/upload/r2/multipart/sign-part', {
270
+ query: { upload_id: uploadId, part_number: partNumber },
271
+ signal,
272
+ }),
273
+
274
+ /** List parts already uploaded — feeds Golden Retriever's resume logic */
275
+ listParts: (uploadId: string, signal?: AbortSignal): Promise<MultipartListPartsResponse> =>
276
+ apiRequest(this.config, 'GET', '/upload/r2/multipart/list-parts', {
277
+ query: { upload_id: uploadId },
278
+ signal,
279
+ }),
280
+
281
+ /** Finalize the multipart upload. Parts must include PartNumber + ETag. */
282
+ complete: (body: MultipartCompleteRequest, signal?: AbortSignal): Promise<MultipartCompleteResponse> =>
283
+ apiRequest(this.config, 'POST', '/upload/r2/multipart/complete', { body, signal }),
284
+
285
+ /** Abort the multipart upload and release reserved quota */
286
+ abort: (uploadId: string, signal?: AbortSignal): Promise<MultipartAbortResponse> =>
287
+ apiRequest(this.config, 'DELETE', '/upload/r2/multipart/abort', {
288
+ body: { upload_id: uploadId },
289
+ signal,
290
+ }),
291
+ },
247
292
  };
248
293
 
249
294
  // ─── My Files ─────────────────────────────────────────────────────────────
@@ -405,25 +450,32 @@ export class UnisourceClient {
405
450
  updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal): Promise<AdminServiceUpdateResponse> =>
406
451
  apiRequest(this.config, 'PATCH', '/admin/service', { body, signal }),
407
452
 
453
+ /** Update service-wide settings (e.g. recommended upload destination) */
454
+ updateServiceSettings: (
455
+ body: AdminServiceSettingsRequest,
456
+ signal?: AbortSignal
457
+ ): Promise<AdminServiceSettingsResponse> =>
458
+ apiRequest(this.config, 'PATCH', '/admin/service/settings', { body, signal }),
459
+
408
460
  /** Get real-time storage usage for the service */
409
461
  usage: (signal?: AbortSignal): Promise<ServiceUsageResponse> =>
410
462
  apiRequest(this.config, 'GET', '/admin/service/usage', { signal }),
411
463
 
412
464
  /** List all uploads (pending/completed/failed) for this service */
413
465
  listUploads: (query?: { status?: UploadStatus; cursor?: string; limit?: number }, signal?: AbortSignal): Promise<UploadsListResponse> =>
414
- apiRequest(this.config, 'GET', '/files', { query, signal }),
466
+ apiRequest(this.config, 'GET', '/admin/files', { query, signal }),
415
467
 
416
468
  /** Get a single upload for this service */
417
469
  getUpload: (id: string, signal?: AbortSignal): Promise<UploadRecordDetailResponse> =>
418
- apiRequest(this.config, 'GET', `/files/${id}`, { signal }),
470
+ apiRequest(this.config, 'GET', `/admin/files/${id}`, { signal }),
419
471
 
420
472
  /** Get a time-limited download URL for an upload owned by this service */
421
473
  downloadUploadUrl: (id: string, signal?: AbortSignal): Promise<FileDownloadUrlResponse> =>
422
- apiRequest(this.config, 'GET', `/files/${id}/download-url`, { signal }),
474
+ apiRequest(this.config, 'GET', `/admin/files/${id}/download-url`, { signal }),
423
475
 
424
476
  /** Permanently delete an upload owned by this service */
425
477
  deleteUpload: (id: string, signal?: AbortSignal): Promise<FileDeleteResponse> =>
426
- apiRequest(this.config, 'DELETE', `/files/${id}`, { signal }),
478
+ apiRequest(this.config, 'DELETE', `/admin/files/${id}`, { signal }),
427
479
 
428
480
  /** List audit log events for this service */
429
481
  auditLog: (query?: AuditLogListQuery, signal?: AbortSignal): Promise<AuditLogListResponse> =>
@@ -450,9 +502,25 @@ export class UnisourceClient {
450
502
  signal?: AbortSignal
451
503
  ): Promise<AdminUserPasswordResetResponse> =>
452
504
  apiRequest(this.config, 'POST', `/admin/users/${userId}/password`, { body, signal }),
505
+
506
+ /** Update a user's role */
507
+ updateUserRole: (
508
+ userId: string,
509
+ body: AdminUserRoleUpdateRequest,
510
+ signal?: AbortSignal
511
+ ): Promise<AdminUserUpdateResponse> =>
512
+ apiRequest(this.config, 'PATCH', `/admin/users/${userId}/role`, { body, signal }),
513
+
514
+ /** Update a user's storage limit */
515
+ updateUserStorageLimit: (
516
+ userId: string,
517
+ body: AdminUserStorageLimitUpdateRequest,
518
+ signal?: AbortSignal
519
+ ): Promise<AdminUserUpdateResponse> =>
520
+ apiRequest(this.config, 'PATCH', `/admin/users/${userId}/storage-limit`, { body, signal }),
453
521
  };
454
522
 
455
- // ─── Share Links ──────────────────────────────────────────────────────────────
523
+ // ─── Share Links (legacy — per-file endpoints) ────────────────────────────────
456
524
 
457
525
  readonly shareLinks = {
458
526
  /** Create a public share link for a file */
@@ -471,4 +539,48 @@ export class UnisourceClient {
471
539
  delete: (linkId: string, signal?: AbortSignal): Promise<ShareLinkDeleteResponse> =>
472
540
  apiRequest(this.config, 'DELETE', `/share-links/${linkId}`, { signal }),
473
541
  };
542
+
543
+ // ─── Files (Plan 2 contract — /files/:id) ────────────────────────────────────
544
+
545
+ readonly files = {
546
+ /** Get a single file record */
547
+ get: (id: string, signal?: AbortSignal, options?: { asUser?: string }): Promise<FileRecordDetailResponse> =>
548
+ apiRequest(this.config, 'GET', `/files/${id}`, { signal, extraHeaders: this.withAsUser(options) }),
549
+
550
+ /** Rename or update a file */
551
+ update: (id: string, body: FileUpdateRequest, signal?: AbortSignal, options?: { asUser?: string }): Promise<FileUpdateResponse> =>
552
+ apiRequest(this.config, 'PATCH', `/files/${id}`, { body, signal, extraHeaders: this.withAsUser(options) }),
553
+
554
+ /** Soft-delete or permanently delete a file */
555
+ delete: (id: string, query?: { permanent?: boolean }, signal?: AbortSignal, options?: { asUser?: string }): Promise<FileDeleteResponse> =>
556
+ apiRequest(this.config, 'DELETE', `/files/${id}`, { query, signal, extraHeaders: this.withAsUser(options) }),
557
+
558
+ /** Restore a file from trash */
559
+ restore: (id: string, signal?: AbortSignal, options?: { asUser?: string }): Promise<FileRestoreResponse> =>
560
+ apiRequest(this.config, 'POST', `/files/${id}/restore`, { signal, extraHeaders: this.withAsUser(options) }),
561
+
562
+ /** Get a time-limited download URL */
563
+ downloadUrl: (id: string, signal?: AbortSignal, options?: { asUser?: string }): Promise<FileDownloadUrlResponse> =>
564
+ apiRequest(this.config, 'GET', `/files/${id}/download-url`, { signal, extraHeaders: this.withAsUser(options) }),
565
+ };
566
+
567
+ // ─── Shares (Plan 2 contract — /shares) ──────────────────────────────────────
568
+
569
+ readonly shares = {
570
+ /** List all share links for the authenticated user */
571
+ list: (signal?: AbortSignal): Promise<ShareLinkListResponse> =>
572
+ apiRequest(this.config, 'GET', '/shares', { signal }),
573
+
574
+ /** Create a share link (file_id in body) */
575
+ create: (body: SharesCreateRequest, signal?: AbortSignal): Promise<ShareLinkCreateResponse> =>
576
+ apiRequest(this.config, 'POST', '/shares', { body, signal }),
577
+
578
+ /** Get a single share link by ID */
579
+ get: (id: string, signal?: AbortSignal): Promise<ShareLinkDetailResponse> =>
580
+ apiRequest(this.config, 'GET', `/shares/${id}`, { signal }),
581
+
582
+ /** Delete a share link */
583
+ delete: (id: string, signal?: AbortSignal): Promise<ShareLinkDeleteResponse> =>
584
+ apiRequest(this.config, 'DELETE', `/shares/${id}`, { signal }),
585
+ };
474
586
  }
package/src/index.ts CHANGED
@@ -24,6 +24,18 @@ export {
24
24
  uploadRecordSchema,
25
25
  uploadsListResponseSchema,
26
26
  uploadRecordDetailResponseSchema,
27
+ uploadTypeSchema,
28
+ multipartCreateRequestSchema,
29
+ multipartCreateResponseSchema,
30
+ multipartSignPartQuerySchema,
31
+ multipartSignPartResponseSchema,
32
+ multipartListPartsQuerySchema,
33
+ multipartListPartsResponseSchema,
34
+ multipartPartSchema,
35
+ multipartCompleteRequestSchema,
36
+ multipartCompleteResponseSchema,
37
+ multipartAbortRequestSchema,
38
+ multipartAbortResponseSchema,
27
39
  } from './uploads';
28
40
  export type {
29
41
  UploadR2InitRequest,
@@ -36,6 +48,18 @@ export type {
36
48
  UploadRecord,
37
49
  UploadsListResponse,
38
50
  UploadRecordDetailResponse,
51
+ UploadType,
52
+ MultipartCreateRequest,
53
+ MultipartCreateResponse,
54
+ MultipartSignPartQuery,
55
+ MultipartSignPartResponse,
56
+ MultipartListPartsQuery,
57
+ MultipartListPartsResponse,
58
+ MultipartPart,
59
+ MultipartCompleteRequest,
60
+ MultipartCompleteResponse,
61
+ MultipartAbortRequest,
62
+ MultipartAbortResponse,
39
63
  } from './uploads';
40
64
 
41
65
  // ─── File Records ─────────────────────────────────────────────────────────────
@@ -96,6 +120,8 @@ export {
96
120
  serviceDetailResponseSchema,
97
121
  adminServiceUpdateRequestSchema,
98
122
  adminServiceUpdateResponseSchema,
123
+ adminServiceSettingsRequestSchema,
124
+ adminServiceSettingsResponseSchema,
99
125
  serviceUsageResponseSchema,
100
126
  auditEventActionSchema,
101
127
  auditEventSchema,
@@ -107,12 +133,16 @@ export {
107
133
  adminUserUpdateResponseSchema,
108
134
  adminUserPasswordResetRequestSchema,
109
135
  adminUserPasswordResetResponseSchema,
136
+ adminUserRoleUpdateRequestSchema,
137
+ adminUserStorageLimitUpdateRequestSchema,
110
138
  } from './services';
111
139
  export type {
112
140
  Service,
113
141
  ServiceDetailResponse,
114
142
  AdminServiceUpdateRequest,
115
143
  AdminServiceUpdateResponse,
144
+ AdminServiceSettingsRequest,
145
+ AdminServiceSettingsResponse,
116
146
  ServiceUsageResponse,
117
147
  AuditEventAction,
118
148
  AuditEvent,
@@ -124,6 +154,8 @@ export type {
124
154
  AdminUserUpdateResponse,
125
155
  AdminUserPasswordResetRequest,
126
156
  AdminUserPasswordResetResponse,
157
+ AdminUserRoleUpdateRequest,
158
+ AdminUserStorageLimitUpdateRequest,
127
159
  } from './services';
128
160
 
129
161
  // ─── Main Storage ─────────────────────────────────────────────────────────────
@@ -172,6 +204,8 @@ export {
172
204
  shareLinkCreateResponseSchema,
173
205
  shareLinkUpdateResponseSchema,
174
206
  shareLinkDeleteResponseSchema,
207
+ shareLinkDetailResponseSchema,
208
+ sharesCreateRequestSchema,
175
209
  publicFileAccessResponseSchema,
176
210
  publicFileLockedResponseSchema,
177
211
  } from './shareLinks';
@@ -183,6 +217,8 @@ export type {
183
217
  ShareLinkCreateResponse,
184
218
  ShareLinkUpdateResponse,
185
219
  ShareLinkDeleteResponse,
220
+ ShareLinkDetailResponse,
221
+ SharesCreateRequest,
186
222
  PublicFileAccessResponse,
187
223
  PublicFileLockedResponse,
188
224
  } from './shareLinks';
package/src/services.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { nonEmptyString, positiveInt, unixTimestamp } from './primitives';
2
+ import { nonEmptyString, positiveInt, unixTimestamp, uploadDestinationSchema } from './primitives';
3
3
 
4
4
  // ─── Service record ───────────────────────────────────────────────────────────
5
5
 
@@ -10,6 +10,7 @@ export const serviceSchema = z.object({
10
10
  max_storage_bytes: positiveInt,
11
11
  current_used_bytes: z.number().int().nonnegative(),
12
12
  max_file_size_bytes: positiveInt,
13
+ recommended_upload_destination: uploadDestinationSchema.optional(),
13
14
  created_at: unixTimestamp,
14
15
  });
15
16
  export type Service = z.infer<typeof serviceSchema>;
@@ -33,6 +34,25 @@ export type AdminServiceUpdateRequest = z.infer<typeof adminServiceUpdateRequest
33
34
  export const adminServiceUpdateResponseSchema = serviceDetailResponseSchema;
34
35
  export type AdminServiceUpdateResponse = z.infer<typeof adminServiceUpdateResponseSchema>;
35
36
 
37
+ // ─── Admin: Service Settings (split from limits) ──────────────────────────────
38
+
39
+ /**
40
+ * Separate settings endpoint driven by the Split-Button upload UI. Clients
41
+ * can flip the recommended default upload destination per service without
42
+ * disturbing quota-related fields.
43
+ */
44
+ export const adminServiceSettingsRequestSchema = z
45
+ .object({
46
+ recommended_upload_destination: uploadDestinationSchema.optional(),
47
+ })
48
+ .refine((v) => v.recommended_upload_destination !== undefined, {
49
+ message: 'At least one setting must be provided',
50
+ });
51
+ export type AdminServiceSettingsRequest = z.infer<typeof adminServiceSettingsRequestSchema>;
52
+
53
+ export const adminServiceSettingsResponseSchema = serviceDetailResponseSchema;
54
+ export type AdminServiceSettingsResponse = z.infer<typeof adminServiceSettingsResponseSchema>;
55
+
36
56
  // ─── Service usage summary ────────────────────────────────────────────────────
37
57
 
38
58
  export const serviceUsageResponseSchema = z.object({
@@ -135,3 +155,15 @@ export const adminUserPasswordResetResponseSchema = z.object({
135
155
  user_id: nonEmptyString,
136
156
  });
137
157
  export type AdminUserPasswordResetResponse = z.infer<typeof adminUserPasswordResetResponseSchema>;
158
+
159
+ // ─── Separate role/storage-limit update endpoints ─────────────────────────────
160
+
161
+ export const adminUserRoleUpdateRequestSchema = z.object({
162
+ role: z.enum(['user', 'plus', 'admin']),
163
+ });
164
+ export type AdminUserRoleUpdateRequest = z.infer<typeof adminUserRoleUpdateRequestSchema>;
165
+
166
+ export const adminUserStorageLimitUpdateRequestSchema = z.object({
167
+ limit_bytes: positiveInt.nullable(),
168
+ });
169
+ export type AdminUserStorageLimitUpdateRequest = z.infer<typeof adminUserStorageLimitUpdateRequestSchema>;
package/src/shareLinks.ts CHANGED
@@ -91,3 +91,19 @@ export const shareLinkDeleteResponseSchema = z.object({
91
91
  id: nonEmptyString,
92
92
  });
93
93
  export type ShareLinkDeleteResponse = z.infer<typeof shareLinkDeleteResponseSchema>;
94
+
95
+ // ─── Get single share link ────────────────────────────────────────────────────
96
+ export const shareLinkDetailResponseSchema = z.object({
97
+ link: shareLinkSchema,
98
+ });
99
+ export type ShareLinkDetailResponse = z.infer<typeof shareLinkDetailResponseSchema>;
100
+
101
+ // ─── Create via /shares (file_id in body) ────────────────────────────────────
102
+ export const sharesCreateRequestSchema = z.object({
103
+ file_id: nonEmptyString,
104
+ name: z.string().trim().max(128).optional(),
105
+ expires_at: positiveInt.optional(),
106
+ max_downloads: positiveInt.optional(),
107
+ password: z.string().min(1).optional(),
108
+ });
109
+ export type SharesCreateRequest = z.infer<typeof sharesCreateRequestSchema>;
package/src/uploads.ts CHANGED
@@ -10,7 +10,7 @@ export const uploadR2InitRequestSchema = z.object({
10
10
  folder_id: nonEmptyString.optional(),
11
11
  is_main_storage: z.boolean().optional().default(false),
12
12
  });
13
- export type UploadR2InitRequest = z.infer<typeof uploadR2InitRequestSchema>;
13
+ export type UploadR2InitRequest = z.input<typeof uploadR2InitRequestSchema>;
14
14
 
15
15
  export const uploadR2InitResponseSchema = z.object({
16
16
  upload_id: nonEmptyString,
@@ -31,7 +31,7 @@ export const uploadAppwriteInitRequestSchema = z.object({
31
31
  folder_id: nonEmptyString.optional(),
32
32
  is_main_storage: z.boolean().optional().default(false),
33
33
  });
34
- export type UploadAppwriteInitRequest = z.infer<typeof uploadAppwriteInitRequestSchema>;
34
+ export type UploadAppwriteInitRequest = z.input<typeof uploadAppwriteInitRequestSchema>;
35
35
 
36
36
  export const uploadAppwriteInitResponseSchema = z.object({
37
37
  upload_id: nonEmptyString,
@@ -41,6 +41,8 @@ export const uploadAppwriteInitResponseSchema = z.object({
41
41
  appwrite_bucket_id: nonEmptyString,
42
42
  file_id: nonEmptyString,
43
43
  expires_at: positiveInt,
44
+ /** Appwrite JWT to authenticate the client-side SDK upload. Only present for JWT-authenticated requests. */
45
+ jwt: nonEmptyString.optional(),
44
46
  });
45
47
  export type UploadAppwriteInitResponse = z.infer<typeof uploadAppwriteInitResponseSchema>;
46
48
 
@@ -50,7 +52,7 @@ export const uploadLifecycleRequestSchema = z.object({
50
52
  upload_id: nonEmptyString,
51
53
  is_main_storage: z.boolean().optional().default(false),
52
54
  });
53
- export type UploadLifecycleRequest = z.infer<typeof uploadLifecycleRequestSchema>;
55
+ export type UploadLifecycleRequest = z.input<typeof uploadLifecycleRequestSchema>;
54
56
 
55
57
  export const uploadCompleteResponseSchema = z.object({
56
58
  success: z.literal(true),
@@ -66,10 +68,97 @@ export const uploadFailResponseSchema = z.object({
66
68
  });
67
69
  export type UploadFailResponse = z.infer<typeof uploadFailResponseSchema>;
68
70
 
71
+ // ─── Multipart: Create ────────────────────────────────────────────────────────
72
+
73
+ export const multipartCreateRequestSchema = z.object({
74
+ filename: nonEmptyString,
75
+ size: positiveInt,
76
+ mime_type: nonEmptyString,
77
+ folder_id: nonEmptyString.optional(),
78
+ is_main_storage: z.boolean().optional().default(false),
79
+ });
80
+ export type MultipartCreateRequest = z.input<typeof multipartCreateRequestSchema>;
81
+
82
+ export const multipartCreateResponseSchema = z.object({
83
+ /** Internal UniSource upload record id. */
84
+ upload_id: nonEmptyString,
85
+ /** S3 (R2) multipart UploadId — required for every sign/complete/abort call. */
86
+ r2_upload_id: nonEmptyString,
87
+ /** R2 object key that the parts are being uploaded to. */
88
+ key: nonEmptyString,
89
+ bucket: nonEmptyString,
90
+ expires_at: positiveInt,
91
+ });
92
+ export type MultipartCreateResponse = z.infer<typeof multipartCreateResponseSchema>;
93
+
94
+ // ─── Multipart: Sign Part ─────────────────────────────────────────────────────
95
+
96
+ export const multipartSignPartQuerySchema = z.object({
97
+ upload_id: nonEmptyString,
98
+ part_number: z.coerce.number().int().min(1).max(10_000),
99
+ });
100
+ export type MultipartSignPartQuery = z.input<typeof multipartSignPartQuerySchema>;
101
+
102
+ export const multipartSignPartResponseSchema = z.object({
103
+ url: z.string().url(),
104
+ expires_at: positiveInt,
105
+ });
106
+ export type MultipartSignPartResponse = z.infer<typeof multipartSignPartResponseSchema>;
107
+
108
+ // ─── Multipart: List Parts ────────────────────────────────────────────────────
109
+
110
+ export const multipartListPartsQuerySchema = z.object({
111
+ upload_id: nonEmptyString,
112
+ });
113
+ export type MultipartListPartsQuery = z.input<typeof multipartListPartsQuerySchema>;
114
+
115
+ export const multipartPartSchema = z.object({
116
+ PartNumber: z.number().int().min(1).max(10_000),
117
+ ETag: nonEmptyString,
118
+ Size: z.number().int().nonnegative(),
119
+ });
120
+ export type MultipartPart = z.infer<typeof multipartPartSchema>;
121
+
122
+ export const multipartListPartsResponseSchema = z.object({
123
+ parts: z.array(multipartPartSchema),
124
+ });
125
+ export type MultipartListPartsResponse = z.infer<typeof multipartListPartsResponseSchema>;
126
+
127
+ // ─── Multipart: Complete ──────────────────────────────────────────────────────
128
+
129
+ export const multipartCompleteRequestSchema = z.object({
130
+ upload_id: nonEmptyString,
131
+ parts: z
132
+ .array(
133
+ z.object({
134
+ PartNumber: z.number().int().min(1).max(10_000),
135
+ ETag: nonEmptyString,
136
+ })
137
+ )
138
+ .min(1),
139
+ });
140
+ export type MultipartCompleteRequest = z.input<typeof multipartCompleteRequestSchema>;
141
+
142
+ export const multipartCompleteResponseSchema = uploadCompleteResponseSchema;
143
+ export type MultipartCompleteResponse = z.infer<typeof multipartCompleteResponseSchema>;
144
+
145
+ // ─── Multipart: Abort ─────────────────────────────────────────────────────────
146
+
147
+ export const multipartAbortRequestSchema = z.object({
148
+ upload_id: nonEmptyString,
149
+ });
150
+ export type MultipartAbortRequest = z.input<typeof multipartAbortRequestSchema>;
151
+
152
+ export const multipartAbortResponseSchema = uploadFailResponseSchema;
153
+ export type MultipartAbortResponse = z.infer<typeof multipartAbortResponseSchema>;
154
+
69
155
  // ─── Admin: list uploads ──────────────────────────────────────────────────────
70
156
 
71
157
  export { FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT };
72
158
 
159
+ export const uploadTypeSchema = z.enum(['single', 'multipart']);
160
+ export type UploadType = z.infer<typeof uploadTypeSchema>;
161
+
73
162
  /** Raw upload record — returned by admin `/files` endpoints. */
74
163
  export const uploadRecordSchema = z.object({
75
164
  id: nonEmptyString,
@@ -80,6 +169,7 @@ export const uploadRecordSchema = z.object({
80
169
  mime_type: nonEmptyString,
81
170
  destination: uploadDestinationSchema,
82
171
  status: uploadStatusSchema,
172
+ upload_type: uploadTypeSchema.optional(),
83
173
  expires_at: positiveInt,
84
174
  created_at: positiveInt,
85
175
  updated_at: positiveInt,