@unisource/sdk 1.0.0 → 1.1.0-beta.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/src/releases.ts DELETED
@@ -1,236 +0,0 @@
1
- import { z } from 'zod';
2
- import { nonEmptyString, positiveInt, uploadStatusSchema } from './primitives';
3
-
4
- const releaseIdSchema = z.string().trim().min(1).max(128);
5
- const releaseNameSchema = z.string().trim().min(1).max(256);
6
- const releaseFilenameSchema = z.string().trim().min(1).max(255);
7
- const releaseTagsSchema = z.array(z.string().trim().min(1).max(64)).max(32);
8
- const releaseNotesSchema = z.string().trim().max(10_000).nullable().optional();
9
- const releaseR2KeySchema = z.string().trim().min(1).max(1024);
10
-
11
- // ─── Release DTO ─────────────────────────────────────────────────────────────
12
-
13
- export const releaseDTOSchema = z.object({
14
- id: nonEmptyString,
15
- service_id: nonEmptyString,
16
- name: nonEmptyString,
17
- size: z.number().int().nonnegative(),
18
- r2_key: nonEmptyString,
19
- tags: z.array(nonEmptyString),
20
- notes: z.string().nullable(),
21
- force_update: z.boolean(),
22
- uploaded_by: nonEmptyString,
23
- upload_status: uploadStatusSchema,
24
- created_at: nonEmptyString,
25
- });
26
- export type ReleaseDTO = z.infer<typeof releaseDTOSchema>;
27
-
28
- // ─── Upload Lifecycle ───────────────────────────────────────────────────────
29
-
30
- export const releaseUploadInitRequestSchema = z.object({
31
- name: releaseNameSchema,
32
- filename: releaseFilenameSchema,
33
- tags: releaseTagsSchema.optional().default([]),
34
- notes: releaseNotesSchema,
35
- force_update: z.boolean().optional().default(false),
36
- });
37
- export type ReleaseUploadInitRequest = z.input<typeof releaseUploadInitRequestSchema>;
38
-
39
- export const releaseUploadInitResponseSchema = z.object({
40
- release_id: nonEmptyString,
41
- presigned_url: z.string().url(),
42
- r2_key: nonEmptyString,
43
- expires_at: positiveInt,
44
- });
45
- export type ReleaseUploadInitResponse = z.infer<typeof releaseUploadInitResponseSchema>;
46
-
47
- export const releaseUploadCompleteRequestSchema = z.object({
48
- release_id: releaseIdSchema,
49
- size: z.number().int().nonnegative(),
50
- });
51
- export type ReleaseUploadCompleteRequest = z.infer<typeof releaseUploadCompleteRequestSchema>;
52
-
53
- export const releaseUploadCompleteResponseSchema = z.object({
54
- success: z.literal(true),
55
- release_id: nonEmptyString,
56
- status: z.literal('completed'),
57
- });
58
- export type ReleaseUploadCompleteResponse = z.infer<typeof releaseUploadCompleteResponseSchema>;
59
-
60
- export const releaseUploadFailResponseSchema = z.object({
61
- success: z.literal(true),
62
- release_id: nonEmptyString,
63
- status: z.literal('failed'),
64
- });
65
- export type ReleaseUploadFailResponse = z.infer<typeof releaseUploadFailResponseSchema>;
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
-
145
- // ─── List ───────────────────────────────────────────────────────────────────
146
-
147
- export const releasesListQuerySchema = z.object({
148
- limit: z.number().int().positive().max(100).optional(),
149
- cursor: nonEmptyString.optional(),
150
- });
151
- export type ReleasesListQuery = z.infer<typeof releasesListQuerySchema>;
152
-
153
- export const releasesListResponseSchema = z.object({
154
- items: z.array(releaseDTOSchema),
155
- next_cursor: z.string().nullable(),
156
- });
157
- export type ReleasesListResponse = z.infer<typeof releasesListResponseSchema>;
158
-
159
- // ─── Update ─────────────────────────────────────────────────────────────────
160
-
161
- export const releaseUpdateRequestSchema = z
162
- .object({
163
- name: releaseNameSchema.optional(),
164
- tags: releaseTagsSchema.optional(),
165
- notes: releaseNotesSchema,
166
- force_update: z.boolean().optional(),
167
- })
168
- .refine((body) => Object.values(body).some((value) => value !== undefined), {
169
- message: 'At least one field must be provided',
170
- });
171
- export type ReleaseUpdateRequest = z.infer<typeof releaseUpdateRequestSchema>;
172
-
173
- // ─── Delete ─────────────────────────────────────────────────────────────────
174
-
175
- export const releaseDeleteResponseSchema = z.object({
176
- success: z.literal(true),
177
- release_id: nonEmptyString,
178
- });
179
- export type ReleaseDeleteResponse = z.infer<typeof releaseDeleteResponseSchema>;
180
-
181
- // ─── Sync ───────────────────────────────────────────────────────────────────
182
-
183
- export const releaseSyncManifestSchema = z.object({
184
- id: releaseIdSchema.optional(),
185
- name: releaseNameSchema,
186
- r2_key: releaseR2KeySchema,
187
- size: z.number().int().nonnegative(),
188
- tags: releaseTagsSchema.optional().default([]),
189
- notes: releaseNotesSchema,
190
- force_update: z.boolean().optional().default(false),
191
- });
192
- export type ReleaseSyncManifest = z.input<typeof releaseSyncManifestSchema>;
193
-
194
- export const releaseSyncRequestSchema = z.object({
195
- releases: z.array(releaseSyncManifestSchema).min(1).max(100),
196
- });
197
- export type ReleaseSyncRequest = z.input<typeof releaseSyncRequestSchema>;
198
-
199
- export const releaseSyncResultSchema = z.object({
200
- release_id: nonEmptyString,
201
- success: z.boolean(),
202
- status: uploadStatusSchema,
203
- });
204
- export type ReleaseSyncResult = z.infer<typeof releaseSyncResultSchema>;
205
-
206
- export const releaseSyncResponseSchema = z.object({
207
- synced: z.number().int().nonnegative(),
208
- results: z.array(releaseSyncResultSchema),
209
- });
210
- export type ReleaseSyncResponse = z.infer<typeof releaseSyncResponseSchema>;
211
-
212
- // ─── App-facing /app/releases/latest ─────────────────────────────────────────
213
-
214
- /**
215
- * Response of `GET /app/releases/latest?channel=...` — used by client apps to
216
- * discover the most recent completed release for a given distribution channel
217
- * (e.g. `stable`, `beta`). Includes a short-lived presigned download URL.
218
- */
219
- export const appReleaseLatestQuerySchema = z.object({
220
- channel: nonEmptyString.optional().default('stable'),
221
- });
222
- export type AppReleaseLatestQuery = z.input<typeof appReleaseLatestQuerySchema>;
223
-
224
- export const appReleaseLatestResponseSchema = z.object({
225
- id: nonEmptyString,
226
- name: nonEmptyString,
227
- size: z.number().int().nonnegative(),
228
- r2_key: nonEmptyString,
229
- tags: z.array(nonEmptyString),
230
- notes: z.string().nullable(),
231
- force_update: z.boolean(),
232
- created_at: nonEmptyString,
233
- download_url: z.string().url(),
234
- download_url_expires_at: positiveInt,
235
- });
236
- export type AppReleaseLatestResponse = z.infer<typeof appReleaseLatestResponseSchema>;
package/src/services.ts DELETED
@@ -1,169 +0,0 @@
1
- import { z } from 'zod';
2
- import { nonEmptyString, positiveInt, recommendedUploadDestinationSchema, unixTimestamp } from './primitives';
3
-
4
- // ─── Service record ───────────────────────────────────────────────────────────
5
-
6
- /** Public service info returned to admins. Never exposes secrets. */
7
- export const serviceSchema = z.object({
8
- id: nonEmptyString,
9
- name: nonEmptyString,
10
- max_storage_bytes: positiveInt,
11
- current_used_bytes: z.number().int().nonnegative(),
12
- max_file_size_bytes: positiveInt,
13
- recommended_upload_destination: recommendedUploadDestinationSchema.optional(),
14
- created_at: unixTimestamp,
15
- });
16
- export type Service = z.infer<typeof serviceSchema>;
17
-
18
- export const serviceDetailResponseSchema = z.object({
19
- service: serviceSchema,
20
- });
21
- export type ServiceDetailResponse = z.infer<typeof serviceDetailResponseSchema>;
22
-
23
- export const adminServiceUpdateRequestSchema = z
24
- .object({
25
- max_storage_bytes: positiveInt.optional(),
26
- max_file_size_bytes: positiveInt.optional(),
27
- })
28
- .refine(
29
- (v) => v.max_storage_bytes !== undefined || v.max_file_size_bytes !== undefined,
30
- { message: 'At least one of max_storage_bytes or max_file_size_bytes must be provided' }
31
- );
32
- export type AdminServiceUpdateRequest = z.infer<typeof adminServiceUpdateRequestSchema>;
33
-
34
- export const adminServiceUpdateResponseSchema = serviceDetailResponseSchema;
35
- export type AdminServiceUpdateResponse = z.infer<typeof adminServiceUpdateResponseSchema>;
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: recommendedUploadDestinationSchema.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
-
56
- // ─── Service usage summary ────────────────────────────────────────────────────
57
-
58
- export const serviceUsageResponseSchema = z.object({
59
- service_id: nonEmptyString,
60
- max_storage_bytes: positiveInt,
61
- current_used_bytes: z.number().int().nonnegative(),
62
- used_percent: z.number().min(0).max(100),
63
- });
64
- export type ServiceUsageResponse = z.infer<typeof serviceUsageResponseSchema>;
65
-
66
- // ─── Audit log event ──────────────────────────────────────────────────────────
67
-
68
- export const auditEventActionSchema = z.enum([
69
- 'upload_completed',
70
- 'file_deleted',
71
- 'folder_deleted',
72
- 'quota_exceeded',
73
- 'share_link_accessed',
74
- 'quota_reconciled',
75
- ]);
76
- export type AuditEventAction = z.infer<typeof auditEventActionSchema>;
77
-
78
- export const auditEventSchema = z.object({
79
- id: nonEmptyString,
80
- service_id: nonEmptyString,
81
- user_id: nonEmptyString,
82
- action: auditEventActionSchema,
83
- resource_type: z.enum(['file', 'folder', 'service']),
84
- resource_id: nonEmptyString,
85
- metadata: z.record(z.string(), z.unknown()).nullable(),
86
- ip_address: z.string().nullable(),
87
- actor_id: z.string().nullable().optional(),
88
- target_user_id: z.string().nullable().optional(),
89
- created_at: unixTimestamp,
90
- });
91
- export type AuditEvent = z.infer<typeof auditEventSchema>;
92
-
93
- export const auditLogListQuerySchema = z.object({
94
- user_id: nonEmptyString.optional(),
95
- action: auditEventActionSchema.optional(),
96
- resource_type: z.enum(['file', 'folder', 'service']).optional(),
97
- cursor: nonEmptyString.optional(),
98
- limit: z.number().int().min(1).max(200).optional(),
99
- });
100
- export type AuditLogListQuery = z.infer<typeof auditLogListQuerySchema>;
101
-
102
- export const auditLogListResponseSchema = z.object({
103
- items: z.array(auditEventSchema),
104
- next_cursor: z.string().nullable(),
105
- limit: positiveInt,
106
- });
107
- export type AuditLogListResponse = z.infer<typeof auditLogListResponseSchema>;
108
-
109
- export const adminUserSchema = z.object({
110
- id: nonEmptyString,
111
- name: z.string(),
112
- email: z.string().email(),
113
- status: z.boolean(),
114
- labels: z.array(z.string()),
115
- role: nonEmptyString,
116
- has_service_access: z.boolean(),
117
- max_storage_bytes: positiveInt.nullable(),
118
- effective_max_storage_bytes: positiveInt,
119
- current_used_bytes: z.number().int().nonnegative(),
120
- registration: unixTimestamp,
121
- email_verification: z.boolean(),
122
- });
123
- export type AdminUser = z.infer<typeof adminUserSchema>;
124
-
125
- export const adminUserListResponseSchema = z.object({
126
- items: z.array(adminUserSchema),
127
- total: z.number().int().nonnegative(),
128
- offset: z.number().int().nonnegative(),
129
- limit: positiveInt,
130
- });
131
- export type AdminUserListResponse = z.infer<typeof adminUserListResponseSchema>;
132
-
133
- export const adminUserUpdateRequestSchema = z.object({
134
- name: z.string().trim().min(1).max(128).optional(),
135
- email: z.string().trim().email().optional(),
136
- status: z.boolean().optional(),
137
- labels: z.array(z.string().trim().min(1)).max(32).optional(),
138
- role: z.enum(['user', 'plus', 'admin']).optional(),
139
- max_storage_bytes: positiveInt.nullable().optional(),
140
- });
141
- export type AdminUserUpdateRequest = z.infer<typeof adminUserUpdateRequestSchema>;
142
-
143
- export const adminUserUpdateResponseSchema = z.object({
144
- user: adminUserSchema,
145
- });
146
- export type AdminUserUpdateResponse = z.infer<typeof adminUserUpdateResponseSchema>;
147
-
148
- export const adminUserPasswordResetRequestSchema = z.object({
149
- password: z.string().min(8).max(256),
150
- });
151
- export type AdminUserPasswordResetRequest = z.infer<typeof adminUserPasswordResetRequestSchema>;
152
-
153
- export const adminUserPasswordResetResponseSchema = z.object({
154
- success: z.literal(true),
155
- user_id: nonEmptyString,
156
- });
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 DELETED
@@ -1,109 +0,0 @@
1
- import { z } from 'zod';
2
- import { nonEmptyString, positiveInt, unixTimestamp } from './primitives';
3
-
4
- export const shareLinkSchema = z.object({
5
- id: nonEmptyString,
6
- service_id: nonEmptyString,
7
- file_id: nonEmptyString,
8
- user_id: nonEmptyString,
9
- slug: nonEmptyString,
10
- name: z.string().nullable(),
11
- has_password: z.boolean(),
12
- expires_at: unixTimestamp.nullable(),
13
- download_count: z.number().int().nonnegative(),
14
- max_downloads: positiveInt.nullable(),
15
- is_active: z.boolean(),
16
- created_at: unixTimestamp,
17
- updated_at: unixTimestamp,
18
- });
19
- export type ShareLink = z.infer<typeof shareLinkSchema>;
20
-
21
- export const shareLinkCreateRequestSchema = z.object({
22
- slug: z.string().trim().min(3).max(64).optional(),
23
- name: z.string().trim().max(128).optional(),
24
- password: z.string().min(1).optional(),
25
- expires_at: unixTimestamp.optional(),
26
- max_downloads: positiveInt.optional(),
27
- });
28
- export type ShareLinkCreateRequest = z.infer<typeof shareLinkCreateRequestSchema>;
29
-
30
- export const shareLinkUpdateRequestSchema = z
31
- .object({
32
- name: z.string().trim().max(128).nullable().optional(),
33
- is_active: z.boolean().optional(),
34
- password: z.string().min(1).nullable().optional(),
35
- expires_at: unixTimestamp.nullable().optional(),
36
- max_downloads: positiveInt.nullable().optional(),
37
- })
38
- .refine(
39
- (v) =>
40
- v.name !== undefined ||
41
- v.is_active !== undefined ||
42
- v.password !== undefined ||
43
- v.expires_at !== undefined ||
44
- v.max_downloads !== undefined,
45
- { message: 'At least one field must be provided' }
46
- );
47
- export type ShareLinkUpdateRequest = z.infer<typeof shareLinkUpdateRequestSchema>;
48
-
49
- export const shareLinkListResponseSchema = z.object({
50
- items: z.array(shareLinkSchema),
51
- });
52
- export type ShareLinkListResponse = z.infer<typeof shareLinkListResponseSchema>;
53
-
54
- export const shareLinkCreateResponseSchema = z.object({
55
- link: shareLinkSchema,
56
- });
57
- export type ShareLinkCreateResponse = z.infer<typeof shareLinkCreateResponseSchema>;
58
-
59
- export const shareLinkUpdateResponseSchema = z.object({
60
- link: shareLinkSchema,
61
- });
62
- export type ShareLinkUpdateResponse = z.infer<typeof shareLinkUpdateResponseSchema>;
63
-
64
- // Returned when link has no password OR after unlock
65
- export const publicFileAccessResponseSchema = z.object({
66
- file_id: nonEmptyString,
67
- filename: nonEmptyString,
68
- size: positiveInt,
69
- mime_type: nonEmptyString,
70
- requires_password: z.literal(false),
71
- download_url: z.string().url(),
72
- url_expires_at: unixTimestamp,
73
- link_name: z.string().nullable(),
74
- link_expires_at: unixTimestamp.nullable(),
75
- });
76
- export type PublicFileAccessResponse = z.infer<typeof publicFileAccessResponseSchema>;
77
-
78
- // Returned when link requires password (no download URL)
79
- export const publicFileLockedResponseSchema = z.object({
80
- filename: nonEmptyString,
81
- size: positiveInt,
82
- mime_type: nonEmptyString,
83
- requires_password: z.literal(true),
84
- link_name: z.string().nullable(),
85
- });
86
- export type PublicFileLockedResponse = z.infer<typeof publicFileLockedResponseSchema>;
87
-
88
- // ─── Delete ───────────────────────────────────────────────────────────────────
89
- export const shareLinkDeleteResponseSchema = z.object({
90
- success: z.literal(true),
91
- id: nonEmptyString,
92
- });
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>;