@unisource/sdk 0.3.2 → 0.6.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
@@ -57,6 +57,7 @@ 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<{
@@ -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;
@@ -748,6 +873,75 @@ declare const releaseUploadFailResponseSchema: z.ZodObject<{
748
873
  status: z.ZodLiteral<"failed">;
749
874
  }, z.core.$strip>;
750
875
  type ReleaseUploadFailResponse = z.infer<typeof releaseUploadFailResponseSchema>;
876
+ declare const releaseMultipartCreateRequestSchema: z.ZodObject<{
877
+ name: z.ZodString;
878
+ filename: z.ZodString;
879
+ mime_type: z.ZodOptional<z.ZodString>;
880
+ tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
881
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
882
+ force_update: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
883
+ }, z.core.$strip>;
884
+ type ReleaseMultipartCreateRequest = z.input<typeof releaseMultipartCreateRequestSchema>;
885
+ declare const releaseMultipartCreateResponseSchema: z.ZodObject<{
886
+ upload_id: z.ZodString;
887
+ r2_upload_id: z.ZodString;
888
+ key: z.ZodString;
889
+ bucket: z.ZodString;
890
+ expires_at: z.ZodNumber;
891
+ }, z.core.$strip>;
892
+ type ReleaseMultipartCreateResponse = z.infer<typeof releaseMultipartCreateResponseSchema>;
893
+ declare const releaseMultipartSignPartQuerySchema: z.ZodObject<{
894
+ upload_id: z.ZodString;
895
+ part_number: z.ZodCoercedNumber<unknown>;
896
+ }, z.core.$strip>;
897
+ type ReleaseMultipartSignPartQuery = z.input<typeof releaseMultipartSignPartQuerySchema>;
898
+ declare const releaseMultipartSignPartResponseSchema: z.ZodObject<{
899
+ url: z.ZodString;
900
+ expires_at: z.ZodNumber;
901
+ }, z.core.$strip>;
902
+ type ReleaseMultipartSignPartResponse = z.infer<typeof releaseMultipartSignPartResponseSchema>;
903
+ declare const releaseMultipartListPartsQuerySchema: z.ZodObject<{
904
+ upload_id: z.ZodString;
905
+ }, z.core.$strip>;
906
+ type ReleaseMultipartListPartsQuery = z.input<typeof releaseMultipartListPartsQuerySchema>;
907
+ declare const releaseMultipartPartSchema: z.ZodObject<{
908
+ PartNumber: z.ZodNumber;
909
+ ETag: z.ZodString;
910
+ Size: z.ZodNumber;
911
+ }, z.core.$strip>;
912
+ type ReleaseMultipartPart = z.infer<typeof releaseMultipartPartSchema>;
913
+ declare const releaseMultipartListPartsResponseSchema: z.ZodObject<{
914
+ parts: z.ZodArray<z.ZodObject<{
915
+ PartNumber: z.ZodNumber;
916
+ ETag: z.ZodString;
917
+ Size: z.ZodNumber;
918
+ }, z.core.$strip>>;
919
+ }, z.core.$strip>;
920
+ type ReleaseMultipartListPartsResponse = z.infer<typeof releaseMultipartListPartsResponseSchema>;
921
+ declare const releaseMultipartCompleteRequestSchema: z.ZodObject<{
922
+ upload_id: z.ZodString;
923
+ parts: z.ZodArray<z.ZodObject<{
924
+ PartNumber: z.ZodNumber;
925
+ ETag: z.ZodString;
926
+ }, z.core.$strip>>;
927
+ }, z.core.$strip>;
928
+ type ReleaseMultipartCompleteRequest = z.input<typeof releaseMultipartCompleteRequestSchema>;
929
+ declare const releaseMultipartCompleteResponseSchema: z.ZodObject<{
930
+ success: z.ZodLiteral<true>;
931
+ release_id: z.ZodString;
932
+ status: z.ZodLiteral<"completed">;
933
+ }, z.core.$strip>;
934
+ type ReleaseMultipartCompleteResponse = z.infer<typeof releaseMultipartCompleteResponseSchema>;
935
+ declare const releaseMultipartAbortRequestSchema: z.ZodObject<{
936
+ upload_id: z.ZodString;
937
+ }, z.core.$strip>;
938
+ type ReleaseMultipartAbortRequest = z.input<typeof releaseMultipartAbortRequestSchema>;
939
+ declare const releaseMultipartAbortResponseSchema: z.ZodObject<{
940
+ success: z.ZodLiteral<true>;
941
+ release_id: z.ZodString;
942
+ status: z.ZodLiteral<"failed">;
943
+ }, z.core.$strip>;
944
+ type ReleaseMultipartAbortResponse = z.infer<typeof releaseMultipartAbortResponseSchema>;
751
945
  declare const releasesListQuerySchema: z.ZodObject<{
752
946
  limit: z.ZodOptional<z.ZodNumber>;
753
947
  cursor: z.ZodOptional<z.ZodString>;
@@ -1003,7 +1197,14 @@ declare class UnisourceClient {
1003
1197
  /** 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 */
1004
1198
  appwriteInit: (body: UploadAppwriteInitRequest, signal?: AbortSignal) => Promise<UploadAppwriteInitResponse>; /** Confirm that the file was successfully uploaded to storage */
1005
1199
  complete: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadCompleteResponse>; /** Mark an upload as failed and release reserved quota */
1006
- fail: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadFailResponse>;
1200
+ fail: (body: UploadLifecycleRequest, signal?: AbortSignal) => Promise<UploadFailResponse>; /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
1201
+ multipart: {
1202
+ /** Create a multipart upload — returns UploadId + storage key */create: (body: MultipartCreateRequest, signal?: AbortSignal) => Promise<MultipartCreateResponse>; /** Short-lived presigned PUT URL for a single part */
1203
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal) => Promise<MultipartSignPartResponse>; /** List parts already uploaded — feeds Golden Retriever's resume logic */
1204
+ listParts: (uploadId: string, signal?: AbortSignal) => Promise<MultipartListPartsResponse>; /** Finalize the multipart upload. Parts must include PartNumber + ETag. */
1205
+ complete: (body: MultipartCompleteRequest, signal?: AbortSignal) => Promise<MultipartCompleteResponse>; /** Abort the multipart upload and release reserved quota */
1206
+ abort: (uploadId: string, signal?: AbortSignal) => Promise<MultipartAbortResponse>;
1207
+ };
1007
1208
  };
1008
1209
  readonly myFiles: {
1009
1210
  /** List files owned by the authenticated user */list: (query?: FileRecordsListQuery, signal?: AbortSignal, options?: {
@@ -1077,7 +1278,14 @@ declare class UnisourceClient {
1077
1278
  upload: {
1078
1279
  /** Initiate a release upload — returns a presigned PUT URL */init: (body: ReleaseUploadInitRequest, signal?: AbortSignal) => Promise<ReleaseUploadInitResponse>; /** Confirm that a release object was successfully uploaded */
1079
1280
  complete: (body: ReleaseUploadCompleteRequest, signal?: AbortSignal) => Promise<ReleaseUploadCompleteResponse>; /** Mark a release upload as failed */
1080
- fail: (releaseId: string, signal?: AbortSignal) => Promise<ReleaseUploadFailResponse>;
1281
+ fail: (releaseId: string, signal?: AbortSignal) => Promise<ReleaseUploadFailResponse>; /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
1282
+ multipart: {
1283
+ /** Create a multipart release upload — returns the R2 UploadId + storage key */create: (body: ReleaseMultipartCreateRequest, signal?: AbortSignal) => Promise<ReleaseMultipartCreateResponse>; /** Short-lived presigned PUT URL for a single part */
1284
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal) => Promise<ReleaseMultipartSignPartResponse>; /** List parts already uploaded — feeds Golden Retriever's resume logic */
1285
+ listParts: (uploadId: string, signal?: AbortSignal) => Promise<ReleaseMultipartListPartsResponse>; /** Finalize the multipart upload — backend reads object size from R2 (no client size). */
1286
+ complete: (body: ReleaseMultipartCompleteRequest, signal?: AbortSignal) => Promise<ReleaseMultipartCompleteResponse>; /** Abort an in-flight multipart upload and mark the release as failed */
1287
+ abort: (uploadId: string, signal?: AbortSignal) => Promise<ReleaseMultipartAbortResponse>;
1288
+ };
1081
1289
  }; /** List releases for the configured service */
1082
1290
  list: (query?: ReleasesListQuery, signal?: AbortSignal) => Promise<ReleasesListResponse>; /** Get a single release */
1083
1291
  get: (releaseId: string, signal?: AbortSignal) => Promise<ReleaseDTO>; /** Get the latest completed release */
@@ -1088,7 +1296,8 @@ declare class UnisourceClient {
1088
1296
  };
1089
1297
  readonly admin: {
1090
1298
  /** Get service info and quota limits */serviceDetail: (signal?: AbortSignal) => Promise<ServiceDetailResponse>; /** Update custom service-wide limits */
1091
- updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal) => Promise<AdminServiceUpdateResponse>; /** Get real-time storage usage for the service */
1299
+ updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal) => Promise<AdminServiceUpdateResponse>; /** Update service-wide settings (e.g. recommended upload destination) */
1300
+ updateServiceSettings: (body: AdminServiceSettingsRequest, signal?: AbortSignal) => Promise<AdminServiceSettingsResponse>; /** Get real-time storage usage for the service */
1092
1301
  usage: (signal?: AbortSignal) => Promise<ServiceUsageResponse>; /** List all uploads (pending/completed/failed) for this service */
1093
1302
  listUploads: (query?: {
1094
1303
  status?: UploadStatus;
@@ -1142,4 +1351,4 @@ declare class UnisourceClient {
1142
1351
  };
1143
1352
  }
1144
1353
  //#endregion
1145
- export { 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 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 UploadsListResponse, 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, 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, uploadsListResponseSchema };
1354
+ 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 ReleaseMultipartAbortRequest, type ReleaseMultipartAbortResponse, type ReleaseMultipartCompleteRequest, type ReleaseMultipartCompleteResponse, type ReleaseMultipartCreateRequest, type ReleaseMultipartCreateResponse, type ReleaseMultipartListPartsQuery, type ReleaseMultipartListPartsResponse, type ReleaseMultipartPart, type ReleaseMultipartSignPartQuery, type ReleaseMultipartSignPartResponse, 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, releaseMultipartAbortRequestSchema, releaseMultipartAbortResponseSchema, releaseMultipartCompleteRequestSchema, releaseMultipartCompleteResponseSchema, releaseMultipartCreateRequestSchema, releaseMultipartCreateResponseSchema, releaseMultipartListPartsQuerySchema, releaseMultipartListPartsResponseSchema, releaseMultipartPartSchema, releaseMultipartSignPartQuerySchema, releaseMultipartSignPartResponseSchema, 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,
@@ -359,6 +409,46 @@ const releaseUploadFailResponseSchema = z.object({
359
409
  release_id: nonEmptyString,
360
410
  status: z.literal("failed")
361
411
  });
412
+ const releaseMultipartCreateRequestSchema = z.object({
413
+ name: releaseNameSchema,
414
+ filename: releaseFilenameSchema,
415
+ mime_type: nonEmptyString.optional(),
416
+ tags: releaseTagsSchema.optional().default([]),
417
+ notes: releaseNotesSchema,
418
+ force_update: z.boolean().optional().default(false)
419
+ });
420
+ const releaseMultipartCreateResponseSchema = z.object({
421
+ upload_id: nonEmptyString,
422
+ r2_upload_id: nonEmptyString,
423
+ key: nonEmptyString,
424
+ bucket: nonEmptyString,
425
+ expires_at: positiveInt
426
+ });
427
+ const releaseMultipartSignPartQuerySchema = z.object({
428
+ upload_id: releaseIdSchema,
429
+ part_number: z.coerce.number().int().min(1).max(1e4)
430
+ });
431
+ const releaseMultipartSignPartResponseSchema = z.object({
432
+ url: z.string().url(),
433
+ expires_at: positiveInt
434
+ });
435
+ const releaseMultipartListPartsQuerySchema = z.object({ upload_id: releaseIdSchema });
436
+ const releaseMultipartPartSchema = z.object({
437
+ PartNumber: z.number().int().min(1).max(1e4),
438
+ ETag: nonEmptyString,
439
+ Size: z.number().int().nonnegative()
440
+ });
441
+ const releaseMultipartListPartsResponseSchema = z.object({ parts: z.array(releaseMultipartPartSchema) });
442
+ const releaseMultipartCompleteRequestSchema = z.object({
443
+ upload_id: releaseIdSchema,
444
+ parts: z.array(z.object({
445
+ PartNumber: z.number().int().min(1).max(1e4),
446
+ ETag: nonEmptyString
447
+ })).min(1)
448
+ });
449
+ const releaseMultipartCompleteResponseSchema = releaseUploadCompleteResponseSchema;
450
+ const releaseMultipartAbortRequestSchema = z.object({ upload_id: releaseIdSchema });
451
+ const releaseMultipartAbortResponseSchema = releaseUploadFailResponseSchema;
362
452
  const releasesListQuerySchema = z.object({
363
453
  limit: z.number().int().positive().max(100).optional(),
364
454
  cursor: nonEmptyString.optional()
@@ -557,7 +647,32 @@ var UnisourceClient = class {
557
647
  fail: (body, signal) => apiRequest(this.config, "POST", "/upload/fail", {
558
648
  body,
559
649
  signal
560
- })
650
+ }),
651
+ multipart: {
652
+ create: (body, signal) => apiRequest(this.config, "POST", "/upload/r2/multipart/create", {
653
+ body,
654
+ signal
655
+ }),
656
+ signPart: (uploadId, partNumber, signal) => apiRequest(this.config, "GET", "/upload/r2/multipart/sign-part", {
657
+ query: {
658
+ upload_id: uploadId,
659
+ part_number: partNumber
660
+ },
661
+ signal
662
+ }),
663
+ listParts: (uploadId, signal) => apiRequest(this.config, "GET", "/upload/r2/multipart/list-parts", {
664
+ query: { upload_id: uploadId },
665
+ signal
666
+ }),
667
+ complete: (body, signal) => apiRequest(this.config, "POST", "/upload/r2/multipart/complete", {
668
+ body,
669
+ signal
670
+ }),
671
+ abort: (uploadId, signal) => apiRequest(this.config, "DELETE", "/upload/r2/multipart/abort", {
672
+ body: { upload_id: uploadId },
673
+ signal
674
+ })
675
+ }
561
676
  };
562
677
  myFiles = {
563
678
  list: (query, signal, options) => apiRequest(this.config, "GET", "/my-files", {
@@ -663,7 +778,32 @@ var UnisourceClient = class {
663
778
  fail: (releaseId, signal) => apiRequest(this.config, "POST", "/releases/upload/fail", {
664
779
  body: { release_id: releaseId },
665
780
  signal
666
- })
781
+ }),
782
+ multipart: {
783
+ create: (body, signal) => apiRequest(this.config, "POST", "/releases/upload/multipart/create", {
784
+ body,
785
+ signal
786
+ }),
787
+ signPart: (uploadId, partNumber, signal) => apiRequest(this.config, "GET", "/releases/upload/multipart/sign-part", {
788
+ query: {
789
+ upload_id: uploadId,
790
+ part_number: partNumber
791
+ },
792
+ signal
793
+ }),
794
+ listParts: (uploadId, signal) => apiRequest(this.config, "GET", "/releases/upload/multipart/list-parts", {
795
+ query: { upload_id: uploadId },
796
+ signal
797
+ }),
798
+ complete: (body, signal) => apiRequest(this.config, "POST", "/releases/upload/multipart/complete", {
799
+ body,
800
+ signal
801
+ }),
802
+ abort: (uploadId, signal) => apiRequest(this.config, "DELETE", "/releases/upload/multipart/abort", {
803
+ body: { upload_id: uploadId },
804
+ signal
805
+ })
806
+ }
667
807
  },
668
808
  list: (query, signal) => apiRequest(this.config, "GET", "/releases", {
669
809
  query,
@@ -687,6 +827,10 @@ var UnisourceClient = class {
687
827
  body,
688
828
  signal
689
829
  }),
830
+ updateServiceSettings: (body, signal) => apiRequest(this.config, "PATCH", "/admin/service/settings", {
831
+ body,
832
+ signal
833
+ }),
690
834
  usage: (signal) => apiRequest(this.config, "GET", "/admin/service/usage", { signal }),
691
835
  listUploads: (query, signal) => apiRequest(this.config, "GET", "/admin/files", {
692
836
  query,
@@ -767,4 +911,4 @@ var UnisourceClient = class {
767
911
  };
768
912
  };
769
913
  //#endregion
770
- export { FILES_DEFAULT_LIMIT, FILES_MAX_LIMIT, UnisourceClient, UnisourceError, UnisourceNetworkError, 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, 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, uploadsListResponseSchema };
914
+ 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, releaseMultipartAbortRequestSchema, releaseMultipartAbortResponseSchema, releaseMultipartCompleteRequestSchema, releaseMultipartCompleteResponseSchema, releaseMultipartCreateRequestSchema, releaseMultipartCreateResponseSchema, releaseMultipartListPartsQuerySchema, releaseMultipartListPartsResponseSchema, releaseMultipartPartSchema, releaseMultipartSignPartQuerySchema, releaseMultipartSignPartResponseSchema, 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.2",
5
+ "version": "0.6.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,
@@ -81,6 +90,13 @@ import type {
81
90
  ReleaseDeleteResponse,
82
91
  ReleaseSyncRequest,
83
92
  ReleaseSyncResponse,
93
+ ReleaseMultipartCreateRequest,
94
+ ReleaseMultipartCreateResponse,
95
+ ReleaseMultipartSignPartResponse,
96
+ ReleaseMultipartListPartsResponse,
97
+ ReleaseMultipartCompleteRequest,
98
+ ReleaseMultipartCompleteResponse,
99
+ ReleaseMultipartAbortResponse,
84
100
  } from './releases';
85
101
 
86
102
  // ─── SDK Error classes ────────────────────────────────────────────────────────
@@ -248,6 +264,38 @@ export class UnisourceClient {
248
264
  /** Mark an upload as failed and release reserved quota */
249
265
  fail: (body: UploadLifecycleRequest, signal?: AbortSignal): Promise<UploadFailResponse> =>
250
266
  apiRequest(this.config, 'POST', '/upload/fail', { body, signal }),
267
+
268
+ /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
269
+ multipart: {
270
+ /** Create a multipart upload — returns UploadId + storage key */
271
+ create: (body: MultipartCreateRequest, signal?: AbortSignal): Promise<MultipartCreateResponse> =>
272
+ apiRequest(this.config, 'POST', '/upload/r2/multipart/create', { body, signal }),
273
+
274
+ /** Short-lived presigned PUT URL for a single part */
275
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal): Promise<MultipartSignPartResponse> =>
276
+ apiRequest(this.config, 'GET', '/upload/r2/multipart/sign-part', {
277
+ query: { upload_id: uploadId, part_number: partNumber },
278
+ signal,
279
+ }),
280
+
281
+ /** List parts already uploaded — feeds Golden Retriever's resume logic */
282
+ listParts: (uploadId: string, signal?: AbortSignal): Promise<MultipartListPartsResponse> =>
283
+ apiRequest(this.config, 'GET', '/upload/r2/multipart/list-parts', {
284
+ query: { upload_id: uploadId },
285
+ signal,
286
+ }),
287
+
288
+ /** Finalize the multipart upload. Parts must include PartNumber + ETag. */
289
+ complete: (body: MultipartCompleteRequest, signal?: AbortSignal): Promise<MultipartCompleteResponse> =>
290
+ apiRequest(this.config, 'POST', '/upload/r2/multipart/complete', { body, signal }),
291
+
292
+ /** Abort the multipart upload and release reserved quota */
293
+ abort: (uploadId: string, signal?: AbortSignal): Promise<MultipartAbortResponse> =>
294
+ apiRequest(this.config, 'DELETE', '/upload/r2/multipart/abort', {
295
+ body: { upload_id: uploadId },
296
+ signal,
297
+ }),
298
+ },
251
299
  };
252
300
 
253
301
  // ─── My Files ─────────────────────────────────────────────────────────────
@@ -371,6 +419,38 @@ export class UnisourceClient {
371
419
  /** Mark a release upload as failed */
372
420
  fail: (releaseId: string, signal?: AbortSignal): Promise<ReleaseUploadFailResponse> =>
373
421
  apiRequest(this.config, 'POST', '/releases/upload/fail', { body: { release_id: releaseId }, signal }),
422
+
423
+ /** Multipart upload helpers — direct browser → R2 via S3 presigned URLs */
424
+ multipart: {
425
+ /** Create a multipart release upload — returns the R2 UploadId + storage key */
426
+ create: (body: ReleaseMultipartCreateRequest, signal?: AbortSignal): Promise<ReleaseMultipartCreateResponse> =>
427
+ apiRequest(this.config, 'POST', '/releases/upload/multipart/create', { body, signal }),
428
+
429
+ /** Short-lived presigned PUT URL for a single part */
430
+ signPart: (uploadId: string, partNumber: number, signal?: AbortSignal): Promise<ReleaseMultipartSignPartResponse> =>
431
+ apiRequest(this.config, 'GET', '/releases/upload/multipart/sign-part', {
432
+ query: { upload_id: uploadId, part_number: partNumber },
433
+ signal,
434
+ }),
435
+
436
+ /** List parts already uploaded — feeds Golden Retriever's resume logic */
437
+ listParts: (uploadId: string, signal?: AbortSignal): Promise<ReleaseMultipartListPartsResponse> =>
438
+ apiRequest(this.config, 'GET', '/releases/upload/multipart/list-parts', {
439
+ query: { upload_id: uploadId },
440
+ signal,
441
+ }),
442
+
443
+ /** Finalize the multipart upload — backend reads object size from R2 (no client size). */
444
+ complete: (body: ReleaseMultipartCompleteRequest, signal?: AbortSignal): Promise<ReleaseMultipartCompleteResponse> =>
445
+ apiRequest(this.config, 'POST', '/releases/upload/multipart/complete', { body, signal }),
446
+
447
+ /** Abort an in-flight multipart upload and mark the release as failed */
448
+ abort: (uploadId: string, signal?: AbortSignal): Promise<ReleaseMultipartAbortResponse> =>
449
+ apiRequest(this.config, 'DELETE', '/releases/upload/multipart/abort', {
450
+ body: { upload_id: uploadId },
451
+ signal,
452
+ }),
453
+ },
374
454
  },
375
455
 
376
456
  /** List releases for the configured service */
@@ -409,6 +489,13 @@ export class UnisourceClient {
409
489
  updateService: (body: AdminServiceUpdateRequest, signal?: AbortSignal): Promise<AdminServiceUpdateResponse> =>
410
490
  apiRequest(this.config, 'PATCH', '/admin/service', { body, signal }),
411
491
 
492
+ /** Update service-wide settings (e.g. recommended upload destination) */
493
+ updateServiceSettings: (
494
+ body: AdminServiceSettingsRequest,
495
+ signal?: AbortSignal
496
+ ): Promise<AdminServiceSettingsResponse> =>
497
+ apiRequest(this.config, 'PATCH', '/admin/service/settings', { body, signal }),
498
+
412
499
  /** Get real-time storage usage for the service */
413
500
  usage: (signal?: AbortSignal): Promise<ServiceUsageResponse> =>
414
501
  apiRequest(this.config, 'GET', '/admin/service/usage', { signal }),
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,
@@ -115,6 +141,8 @@ export type {
115
141
  ServiceDetailResponse,
116
142
  AdminServiceUpdateRequest,
117
143
  AdminServiceUpdateResponse,
144
+ AdminServiceSettingsRequest,
145
+ AdminServiceSettingsResponse,
118
146
  ServiceUsageResponse,
119
147
  AuditEventAction,
120
148
  AuditEvent,
@@ -149,6 +177,17 @@ export {
149
177
  releaseSyncRequestSchema,
150
178
  releaseSyncResultSchema,
151
179
  releaseSyncResponseSchema,
180
+ releaseMultipartCreateRequestSchema,
181
+ releaseMultipartCreateResponseSchema,
182
+ releaseMultipartSignPartQuerySchema,
183
+ releaseMultipartSignPartResponseSchema,
184
+ releaseMultipartListPartsQuerySchema,
185
+ releaseMultipartListPartsResponseSchema,
186
+ releaseMultipartPartSchema,
187
+ releaseMultipartCompleteRequestSchema,
188
+ releaseMultipartCompleteResponseSchema,
189
+ releaseMultipartAbortRequestSchema,
190
+ releaseMultipartAbortResponseSchema,
152
191
  } from './releases';
153
192
  export type {
154
193
  ReleaseDTO,
@@ -165,6 +204,17 @@ export type {
165
204
  ReleaseSyncRequest,
166
205
  ReleaseSyncResult,
167
206
  ReleaseSyncResponse,
207
+ ReleaseMultipartCreateRequest,
208
+ ReleaseMultipartCreateResponse,
209
+ ReleaseMultipartSignPartQuery,
210
+ ReleaseMultipartSignPartResponse,
211
+ ReleaseMultipartListPartsQuery,
212
+ ReleaseMultipartListPartsResponse,
213
+ ReleaseMultipartPart,
214
+ ReleaseMultipartCompleteRequest,
215
+ ReleaseMultipartCompleteResponse,
216
+ ReleaseMultipartAbortRequest,
217
+ ReleaseMultipartAbortResponse,
168
218
  } from './releases';
169
219
 
170
220
  // ─── Share Links ─────────────────────────────────────────────────────────────
package/src/releases.ts CHANGED
@@ -64,6 +64,84 @@ export const releaseUploadFailResponseSchema = z.object({
64
64
  });
65
65
  export type ReleaseUploadFailResponse = z.infer<typeof releaseUploadFailResponseSchema>;
66
66
 
67
+ // ─── Multipart Upload Lifecycle ──────────────────────────────────────────────
68
+
69
+ export const releaseMultipartCreateRequestSchema = z.object({
70
+ name: releaseNameSchema,
71
+ filename: releaseFilenameSchema,
72
+ /** Defaults server-side to `application/octet-stream` when omitted. */
73
+ mime_type: nonEmptyString.optional(),
74
+ tags: releaseTagsSchema.optional().default([]),
75
+ notes: releaseNotesSchema,
76
+ force_update: z.boolean().optional().default(false),
77
+ });
78
+ export type ReleaseMultipartCreateRequest = z.input<typeof releaseMultipartCreateRequestSchema>;
79
+
80
+ export const releaseMultipartCreateResponseSchema = z.object({
81
+ /** UniSource release id — the same id is used for sign/list/complete/abort. */
82
+ upload_id: nonEmptyString,
83
+ /** S3 (R2) multipart UploadId returned by CreateMultipartUpload. */
84
+ r2_upload_id: nonEmptyString,
85
+ /** R2 object key the parts are being uploaded against. */
86
+ key: nonEmptyString,
87
+ bucket: nonEmptyString,
88
+ expires_at: positiveInt,
89
+ });
90
+ export type ReleaseMultipartCreateResponse = z.infer<typeof releaseMultipartCreateResponseSchema>;
91
+
92
+ export const releaseMultipartSignPartQuerySchema = z.object({
93
+ upload_id: releaseIdSchema,
94
+ part_number: z.coerce.number().int().min(1).max(10_000),
95
+ });
96
+ export type ReleaseMultipartSignPartQuery = z.input<typeof releaseMultipartSignPartQuerySchema>;
97
+
98
+ export const releaseMultipartSignPartResponseSchema = z.object({
99
+ url: z.string().url(),
100
+ expires_at: positiveInt,
101
+ });
102
+ export type ReleaseMultipartSignPartResponse = z.infer<typeof releaseMultipartSignPartResponseSchema>;
103
+
104
+ export const releaseMultipartListPartsQuerySchema = z.object({
105
+ upload_id: releaseIdSchema,
106
+ });
107
+ export type ReleaseMultipartListPartsQuery = z.input<typeof releaseMultipartListPartsQuerySchema>;
108
+
109
+ export const releaseMultipartPartSchema = z.object({
110
+ PartNumber: z.number().int().min(1).max(10_000),
111
+ ETag: nonEmptyString,
112
+ Size: z.number().int().nonnegative(),
113
+ });
114
+ export type ReleaseMultipartPart = z.infer<typeof releaseMultipartPartSchema>;
115
+
116
+ export const releaseMultipartListPartsResponseSchema = z.object({
117
+ parts: z.array(releaseMultipartPartSchema),
118
+ });
119
+ export type ReleaseMultipartListPartsResponse = z.infer<typeof releaseMultipartListPartsResponseSchema>;
120
+
121
+ export const releaseMultipartCompleteRequestSchema = z.object({
122
+ upload_id: releaseIdSchema,
123
+ parts: z
124
+ .array(
125
+ z.object({
126
+ PartNumber: z.number().int().min(1).max(10_000),
127
+ ETag: nonEmptyString,
128
+ })
129
+ )
130
+ .min(1),
131
+ });
132
+ export type ReleaseMultipartCompleteRequest = z.input<typeof releaseMultipartCompleteRequestSchema>;
133
+
134
+ export const releaseMultipartCompleteResponseSchema = releaseUploadCompleteResponseSchema;
135
+ export type ReleaseMultipartCompleteResponse = z.infer<typeof releaseMultipartCompleteResponseSchema>;
136
+
137
+ export const releaseMultipartAbortRequestSchema = z.object({
138
+ upload_id: releaseIdSchema,
139
+ });
140
+ export type ReleaseMultipartAbortRequest = z.input<typeof releaseMultipartAbortRequestSchema>;
141
+
142
+ export const releaseMultipartAbortResponseSchema = releaseUploadFailResponseSchema;
143
+ export type ReleaseMultipartAbortResponse = z.infer<typeof releaseMultipartAbortResponseSchema>;
144
+
67
145
  // ─── List ───────────────────────────────────────────────────────────────────
68
146
 
69
147
  export const releasesListQuerySchema = z.object({
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({
package/src/uploads.ts CHANGED
@@ -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
 
@@ -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,