@liqhtworks/sophon-sdk 0.1.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.
Files changed (230) hide show
  1. package/.github/workflows/publish.yml +56 -0
  2. package/.openapi-generator/FILES +73 -0
  3. package/.openapi-generator/VERSION +1 -0
  4. package/.openapi-generator-ignore +23 -0
  5. package/LICENSE +12 -0
  6. package/README.md +164 -0
  7. package/dist/apis/DownloadsApi.d.ts +63 -0
  8. package/dist/apis/DownloadsApi.js +58 -0
  9. package/dist/apis/HealthApi.d.ts +92 -0
  10. package/dist/apis/HealthApi.js +85 -0
  11. package/dist/apis/JobsApi.d.ts +225 -0
  12. package/dist/apis/JobsApi.js +245 -0
  13. package/dist/apis/UploadsApi.d.ts +228 -0
  14. package/dist/apis/UploadsApi.js +255 -0
  15. package/dist/apis/WebhooksApi.d.ts +138 -0
  16. package/dist/apis/WebhooksApi.js +152 -0
  17. package/dist/apis/index.d.ts +5 -0
  18. package/dist/apis/index.js +23 -0
  19. package/dist/esm/apis/DownloadsApi.d.ts +63 -0
  20. package/dist/esm/apis/DownloadsApi.js +54 -0
  21. package/dist/esm/apis/HealthApi.d.ts +92 -0
  22. package/dist/esm/apis/HealthApi.js +81 -0
  23. package/dist/esm/apis/JobsApi.d.ts +225 -0
  24. package/dist/esm/apis/JobsApi.js +241 -0
  25. package/dist/esm/apis/UploadsApi.d.ts +228 -0
  26. package/dist/esm/apis/UploadsApi.js +251 -0
  27. package/dist/esm/apis/WebhooksApi.d.ts +138 -0
  28. package/dist/esm/apis/WebhooksApi.js +148 -0
  29. package/dist/esm/apis/index.d.ts +5 -0
  30. package/dist/esm/apis/index.js +7 -0
  31. package/dist/esm/helpers/index.d.ts +3 -0
  32. package/dist/esm/helpers/index.js +3 -0
  33. package/dist/esm/helpers/jobs.d.ts +48 -0
  34. package/dist/esm/helpers/jobs.js +61 -0
  35. package/dist/esm/helpers/uploads.d.ts +71 -0
  36. package/dist/esm/helpers/uploads.js +146 -0
  37. package/dist/esm/helpers/webhooks.d.ts +23 -0
  38. package/dist/esm/helpers/webhooks.js +84 -0
  39. package/dist/esm/index.d.ts +4 -0
  40. package/dist/esm/index.js +6 -0
  41. package/dist/esm/models/CompleteUploadResponse.d.ts +57 -0
  42. package/dist/esm/models/CompleteUploadResponse.js +63 -0
  43. package/dist/esm/models/CreateJobOutputOptions.d.ts +55 -0
  44. package/dist/esm/models/CreateJobOutputOptions.js +46 -0
  45. package/dist/esm/models/CreateJobRequest.d.ts +61 -0
  46. package/dist/esm/models/CreateJobRequest.js +56 -0
  47. package/dist/esm/models/CreateUploadRequest.d.ts +44 -0
  48. package/dist/esm/models/CreateUploadRequest.js +51 -0
  49. package/dist/esm/models/CreateUploadResponse.d.ts +52 -0
  50. package/dist/esm/models/CreateUploadResponse.js +55 -0
  51. package/dist/esm/models/CreateWebhookRequest.d.ts +40 -0
  52. package/dist/esm/models/CreateWebhookRequest.js +45 -0
  53. package/dist/esm/models/ErrorBody.d.ts +72 -0
  54. package/dist/esm/models/ErrorBody.js +74 -0
  55. package/dist/esm/models/ErrorEnvelope.d.ts +33 -0
  56. package/dist/esm/models/ErrorEnvelope.js +44 -0
  57. package/dist/esm/models/JobOutputInfo.d.ts +95 -0
  58. package/dist/esm/models/JobOutputInfo.js +72 -0
  59. package/dist/esm/models/JobProfile.d.ts +49 -0
  60. package/dist/esm/models/JobProfile.js +69 -0
  61. package/dist/esm/models/JobProgress.d.ts +75 -0
  62. package/dist/esm/models/JobProgress.js +60 -0
  63. package/dist/esm/models/JobResponse.d.ts +134 -0
  64. package/dist/esm/models/JobResponse.js +94 -0
  65. package/dist/esm/models/JobSourceInfo.d.ts +62 -0
  66. package/dist/esm/models/JobSourceInfo.js +53 -0
  67. package/dist/esm/models/JobSourceType.d.ts +24 -0
  68. package/dist/esm/models/JobSourceType.js +44 -0
  69. package/dist/esm/models/JobStatus.d.ts +31 -0
  70. package/dist/esm/models/JobStatus.js +51 -0
  71. package/dist/esm/models/ListJobsResponse.d.ts +45 -0
  72. package/dist/esm/models/ListJobsResponse.js +50 -0
  73. package/dist/esm/models/OutputContainer.d.ts +27 -0
  74. package/dist/esm/models/OutputContainer.js +47 -0
  75. package/dist/esm/models/ReadyResponse.d.ts +38 -0
  76. package/dist/esm/models/ReadyResponse.js +45 -0
  77. package/dist/esm/models/UploadJobSource.d.ts +39 -0
  78. package/dist/esm/models/UploadJobSource.js +48 -0
  79. package/dist/esm/models/UploadPartResponse.d.ts +38 -0
  80. package/dist/esm/models/UploadPartResponse.js +47 -0
  81. package/dist/esm/models/UploadStatusResponse.d.ts +96 -0
  82. package/dist/esm/models/UploadStatusResponse.js +80 -0
  83. package/dist/esm/models/WebhookDeliveryPayload.d.ts +85 -0
  84. package/dist/esm/models/WebhookDeliveryPayload.js +83 -0
  85. package/dist/esm/models/WebhookListItem.d.ts +50 -0
  86. package/dist/esm/models/WebhookListItem.js +55 -0
  87. package/dist/esm/models/WebhookListResponse.d.ts +33 -0
  88. package/dist/esm/models/WebhookListResponse.js +44 -0
  89. package/dist/esm/models/WebhookResponse.d.ts +58 -0
  90. package/dist/esm/models/WebhookResponse.js +59 -0
  91. package/dist/esm/models/index.d.ts +25 -0
  92. package/dist/esm/models/index.js +27 -0
  93. package/dist/esm/runtime.d.ts +184 -0
  94. package/dist/esm/runtime.js +348 -0
  95. package/dist/helpers/index.d.ts +3 -0
  96. package/dist/helpers/index.js +19 -0
  97. package/dist/helpers/jobs.d.ts +48 -0
  98. package/dist/helpers/jobs.js +67 -0
  99. package/dist/helpers/uploads.d.ts +71 -0
  100. package/dist/helpers/uploads.js +149 -0
  101. package/dist/helpers/webhooks.d.ts +23 -0
  102. package/dist/helpers/webhooks.js +89 -0
  103. package/dist/index.d.ts +4 -0
  104. package/dist/index.js +22 -0
  105. package/dist/models/CompleteUploadResponse.d.ts +57 -0
  106. package/dist/models/CompleteUploadResponse.js +71 -0
  107. package/dist/models/CreateJobOutputOptions.d.ts +55 -0
  108. package/dist/models/CreateJobOutputOptions.js +53 -0
  109. package/dist/models/CreateJobRequest.d.ts +61 -0
  110. package/dist/models/CreateJobRequest.js +63 -0
  111. package/dist/models/CreateUploadRequest.d.ts +44 -0
  112. package/dist/models/CreateUploadRequest.js +58 -0
  113. package/dist/models/CreateUploadResponse.d.ts +52 -0
  114. package/dist/models/CreateUploadResponse.js +62 -0
  115. package/dist/models/CreateWebhookRequest.d.ts +40 -0
  116. package/dist/models/CreateWebhookRequest.js +52 -0
  117. package/dist/models/ErrorBody.d.ts +72 -0
  118. package/dist/models/ErrorBody.js +82 -0
  119. package/dist/models/ErrorEnvelope.d.ts +33 -0
  120. package/dist/models/ErrorEnvelope.js +51 -0
  121. package/dist/models/JobOutputInfo.d.ts +95 -0
  122. package/dist/models/JobOutputInfo.js +80 -0
  123. package/dist/models/JobProfile.d.ts +49 -0
  124. package/dist/models/JobProfile.js +77 -0
  125. package/dist/models/JobProgress.d.ts +75 -0
  126. package/dist/models/JobProgress.js +67 -0
  127. package/dist/models/JobResponse.d.ts +134 -0
  128. package/dist/models/JobResponse.js +101 -0
  129. package/dist/models/JobSourceInfo.d.ts +62 -0
  130. package/dist/models/JobSourceInfo.js +60 -0
  131. package/dist/models/JobSourceType.d.ts +24 -0
  132. package/dist/models/JobSourceType.js +52 -0
  133. package/dist/models/JobStatus.d.ts +31 -0
  134. package/dist/models/JobStatus.js +59 -0
  135. package/dist/models/ListJobsResponse.d.ts +45 -0
  136. package/dist/models/ListJobsResponse.js +57 -0
  137. package/dist/models/OutputContainer.d.ts +27 -0
  138. package/dist/models/OutputContainer.js +55 -0
  139. package/dist/models/ReadyResponse.d.ts +38 -0
  140. package/dist/models/ReadyResponse.js +52 -0
  141. package/dist/models/UploadJobSource.d.ts +39 -0
  142. package/dist/models/UploadJobSource.js +55 -0
  143. package/dist/models/UploadPartResponse.d.ts +38 -0
  144. package/dist/models/UploadPartResponse.js +54 -0
  145. package/dist/models/UploadStatusResponse.d.ts +96 -0
  146. package/dist/models/UploadStatusResponse.js +88 -0
  147. package/dist/models/WebhookDeliveryPayload.d.ts +85 -0
  148. package/dist/models/WebhookDeliveryPayload.js +91 -0
  149. package/dist/models/WebhookListItem.d.ts +50 -0
  150. package/dist/models/WebhookListItem.js +62 -0
  151. package/dist/models/WebhookListResponse.d.ts +33 -0
  152. package/dist/models/WebhookListResponse.js +51 -0
  153. package/dist/models/WebhookResponse.d.ts +58 -0
  154. package/dist/models/WebhookResponse.js +66 -0
  155. package/dist/models/index.d.ts +25 -0
  156. package/dist/models/index.js +43 -0
  157. package/dist/runtime.d.ts +184 -0
  158. package/dist/runtime.js +364 -0
  159. package/docs/CompleteUploadResponse.md +40 -0
  160. package/docs/CreateJobOutputOptions.md +39 -0
  161. package/docs/CreateJobRequest.md +42 -0
  162. package/docs/CreateUploadRequest.md +38 -0
  163. package/docs/CreateUploadResponse.md +40 -0
  164. package/docs/CreateWebhookRequest.md +36 -0
  165. package/docs/DownloadsApi.md +78 -0
  166. package/docs/ErrorBody.md +40 -0
  167. package/docs/ErrorEnvelope.md +34 -0
  168. package/docs/HealthApi.md +129 -0
  169. package/docs/JobOutputInfo.md +50 -0
  170. package/docs/JobProfile.md +33 -0
  171. package/docs/JobProgress.md +48 -0
  172. package/docs/JobResponse.md +62 -0
  173. package/docs/JobSourceInfo.md +44 -0
  174. package/docs/JobSourceType.md +33 -0
  175. package/docs/JobStatus.md +33 -0
  176. package/docs/JobsApi.md +407 -0
  177. package/docs/ListJobsResponse.md +38 -0
  178. package/docs/OutputContainer.md +33 -0
  179. package/docs/ReadyResponse.md +36 -0
  180. package/docs/UploadJobSource.md +37 -0
  181. package/docs/UploadPartResponse.md +36 -0
  182. package/docs/UploadStatusResponse.md +50 -0
  183. package/docs/UploadsApi.md +415 -0
  184. package/docs/WebhookDeliveryPayload.md +45 -0
  185. package/docs/WebhookEventsApi.md +91 -0
  186. package/docs/WebhookListItem.md +40 -0
  187. package/docs/WebhookListResponse.md +34 -0
  188. package/docs/WebhookResponse.md +42 -0
  189. package/docs/WebhooksApi.md +235 -0
  190. package/package.json +24 -0
  191. package/src/apis/DownloadsApi.ts +114 -0
  192. package/src/apis/HealthApi.ts +160 -0
  193. package/src/apis/JobsApi.ts +491 -0
  194. package/src/apis/UploadsApi.ts +522 -0
  195. package/src/apis/WebhooksApi.ts +298 -0
  196. package/src/apis/index.ts +7 -0
  197. package/src/helpers/index.ts +3 -0
  198. package/src/helpers/jobs.ts +112 -0
  199. package/src/helpers/uploads.ts +243 -0
  200. package/src/helpers/webhooks.ts +134 -0
  201. package/src/index.ts +7 -0
  202. package/src/models/CompleteUploadResponse.ts +102 -0
  203. package/src/models/CreateJobOutputOptions.ts +101 -0
  204. package/src/models/CreateJobRequest.ts +123 -0
  205. package/src/models/CreateUploadRequest.ts +84 -0
  206. package/src/models/CreateUploadResponse.ts +95 -0
  207. package/src/models/CreateWebhookRequest.ts +76 -0
  208. package/src/models/ErrorBody.ts +116 -0
  209. package/src/models/ErrorEnvelope.ts +74 -0
  210. package/src/models/JobOutputInfo.ts +149 -0
  211. package/src/models/JobProfile.ts +76 -0
  212. package/src/models/JobProgress.ts +133 -0
  213. package/src/models/JobResponse.ts +236 -0
  214. package/src/models/JobSourceInfo.ts +106 -0
  215. package/src/models/JobSourceType.ts +51 -0
  216. package/src/models/JobStatus.ts +58 -0
  217. package/src/models/ListJobsResponse.ts +91 -0
  218. package/src/models/OutputContainer.ts +54 -0
  219. package/src/models/ReadyResponse.ts +74 -0
  220. package/src/models/UploadJobSource.ts +85 -0
  221. package/src/models/UploadPartResponse.ts +75 -0
  222. package/src/models/UploadStatusResponse.ts +153 -0
  223. package/src/models/WebhookDeliveryPayload.ts +134 -0
  224. package/src/models/WebhookListItem.ts +93 -0
  225. package/src/models/WebhookListResponse.ts +74 -0
  226. package/src/models/WebhookResponse.ts +104 -0
  227. package/src/models/index.ts +27 -0
  228. package/src/runtime.ts +450 -0
  229. package/tsconfig.esm.json +7 -0
  230. package/tsconfig.json +20 -0
@@ -0,0 +1,148 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * SOPHON Encoding API
5
+ * REST API for submitting, monitoring, and retrieving SOPHON encoding jobs. Authentication is via Bearer API key or session cookie. All POST endpoints require an Idempotency-Key header. List endpoints use opaque cursor-based pagination.
6
+ *
7
+ * The version of the OpenAPI document: 1.0.0
8
+ *
9
+ *
10
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
11
+ * https://openapi-generator.tech
12
+ * Do not edit the class manually.
13
+ */
14
+ import * as runtime from '../runtime';
15
+ import { CreateWebhookRequestToJSON, WebhookListResponseFromJSON, WebhookResponseFromJSON, } from '../models/index';
16
+ /**
17
+ *
18
+ */
19
+ export class WebhooksApi extends runtime.BaseAPI {
20
+ /**
21
+ * Creates request options for createWebhook without sending the request
22
+ */
23
+ async createWebhookRequestOpts(requestParameters) {
24
+ if (requestParameters['idempotencyKey'] == null) {
25
+ throw new runtime.RequiredError('idempotencyKey', 'Required parameter "idempotencyKey" was null or undefined when calling createWebhook().');
26
+ }
27
+ if (requestParameters['createWebhookRequest'] == null) {
28
+ throw new runtime.RequiredError('createWebhookRequest', 'Required parameter "createWebhookRequest" was null or undefined when calling createWebhook().');
29
+ }
30
+ const queryParameters = {};
31
+ const headerParameters = {};
32
+ headerParameters['Content-Type'] = 'application/json';
33
+ if (requestParameters['idempotencyKey'] != null) {
34
+ headerParameters['Idempotency-Key'] = String(requestParameters['idempotencyKey']);
35
+ }
36
+ if (this.configuration && this.configuration.accessToken) {
37
+ const token = this.configuration.accessToken;
38
+ const tokenString = await token("bearerApiKey", []);
39
+ if (tokenString) {
40
+ headerParameters["Authorization"] = `Bearer ${tokenString}`;
41
+ }
42
+ }
43
+ let urlPath = `/v1/webhooks`;
44
+ return {
45
+ path: urlPath,
46
+ method: 'POST',
47
+ headers: headerParameters,
48
+ query: queryParameters,
49
+ body: CreateWebhookRequestToJSON(requestParameters['createWebhookRequest']),
50
+ };
51
+ }
52
+ /**
53
+ * Registers an HTTPS endpoint for terminal job events and returns the HMAC signing secret once at creation time.
54
+ * Register a webhook endpoint
55
+ */
56
+ async createWebhookRaw(requestParameters, initOverrides) {
57
+ const requestOptions = await this.createWebhookRequestOpts(requestParameters);
58
+ const response = await this.request(requestOptions, initOverrides);
59
+ return new runtime.JSONApiResponse(response, (jsonValue) => WebhookResponseFromJSON(jsonValue));
60
+ }
61
+ /**
62
+ * Registers an HTTPS endpoint for terminal job events and returns the HMAC signing secret once at creation time.
63
+ * Register a webhook endpoint
64
+ */
65
+ async createWebhook(requestParameters, initOverrides) {
66
+ const response = await this.createWebhookRaw(requestParameters, initOverrides);
67
+ return await response.value();
68
+ }
69
+ /**
70
+ * Creates request options for deleteWebhook without sending the request
71
+ */
72
+ async deleteWebhookRequestOpts(requestParameters) {
73
+ if (requestParameters['id'] == null) {
74
+ throw new runtime.RequiredError('id', 'Required parameter "id" was null or undefined when calling deleteWebhook().');
75
+ }
76
+ const queryParameters = {};
77
+ const headerParameters = {};
78
+ if (this.configuration && this.configuration.accessToken) {
79
+ const token = this.configuration.accessToken;
80
+ const tokenString = await token("bearerApiKey", []);
81
+ if (tokenString) {
82
+ headerParameters["Authorization"] = `Bearer ${tokenString}`;
83
+ }
84
+ }
85
+ let urlPath = `/v1/webhooks/{id}`;
86
+ urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id'])));
87
+ return {
88
+ path: urlPath,
89
+ method: 'DELETE',
90
+ headers: headerParameters,
91
+ query: queryParameters,
92
+ };
93
+ }
94
+ /**
95
+ * Sets the webhook to inactive. It will no longer receive deliveries.
96
+ * Soft-delete a webhook endpoint
97
+ */
98
+ async deleteWebhookRaw(requestParameters, initOverrides) {
99
+ const requestOptions = await this.deleteWebhookRequestOpts(requestParameters);
100
+ const response = await this.request(requestOptions, initOverrides);
101
+ return new runtime.VoidApiResponse(response);
102
+ }
103
+ /**
104
+ * Sets the webhook to inactive. It will no longer receive deliveries.
105
+ * Soft-delete a webhook endpoint
106
+ */
107
+ async deleteWebhook(requestParameters, initOverrides) {
108
+ await this.deleteWebhookRaw(requestParameters, initOverrides);
109
+ }
110
+ /**
111
+ * Creates request options for listWebhooks without sending the request
112
+ */
113
+ async listWebhooksRequestOpts() {
114
+ const queryParameters = {};
115
+ const headerParameters = {};
116
+ if (this.configuration && this.configuration.accessToken) {
117
+ const token = this.configuration.accessToken;
118
+ const tokenString = await token("bearerApiKey", []);
119
+ if (tokenString) {
120
+ headerParameters["Authorization"] = `Bearer ${tokenString}`;
121
+ }
122
+ }
123
+ let urlPath = `/v1/webhooks`;
124
+ return {
125
+ path: urlPath,
126
+ method: 'GET',
127
+ headers: headerParameters,
128
+ query: queryParameters,
129
+ };
130
+ }
131
+ /**
132
+ * Lists active webhook endpoints for the authenticated organization.
133
+ * List active webhook endpoints
134
+ */
135
+ async listWebhooksRaw(initOverrides) {
136
+ const requestOptions = await this.listWebhooksRequestOpts();
137
+ const response = await this.request(requestOptions, initOverrides);
138
+ return new runtime.JSONApiResponse(response, (jsonValue) => WebhookListResponseFromJSON(jsonValue));
139
+ }
140
+ /**
141
+ * Lists active webhook endpoints for the authenticated organization.
142
+ * List active webhook endpoints
143
+ */
144
+ async listWebhooks(initOverrides) {
145
+ const response = await this.listWebhooksRaw(initOverrides);
146
+ return await response.value();
147
+ }
148
+ }
@@ -0,0 +1,5 @@
1
+ export * from './DownloadsApi';
2
+ export * from './HealthApi';
3
+ export * from './JobsApi';
4
+ export * from './UploadsApi';
5
+ export * from './WebhooksApi';
@@ -0,0 +1,7 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export * from './DownloadsApi';
4
+ export * from './HealthApi';
5
+ export * from './JobsApi';
6
+ export * from './UploadsApi';
7
+ export * from './WebhooksApi';
@@ -0,0 +1,3 @@
1
+ export * from "./uploads";
2
+ export * from "./jobs";
3
+ export * from "./webhooks";
@@ -0,0 +1,3 @@
1
+ export * from "./uploads";
2
+ export * from "./jobs";
3
+ export * from "./webhooks";
@@ -0,0 +1,48 @@
1
+ export type JobTerminalStatus = "completed" | "failed" | "canceled";
2
+ export type JobStatusLike = JobTerminalStatus | "queued" | "probing" | "encoding" | "muxing" | "uploading_output";
3
+ export interface JobLike {
4
+ id: string;
5
+ status: JobStatusLike;
6
+ error?: string | null;
7
+ }
8
+ export interface JobsApiLike {
9
+ getJob(params: {
10
+ id: string;
11
+ }): Promise<JobLike>;
12
+ }
13
+ export interface WaitForJobParams<T extends JobLike = JobLike> {
14
+ api: {
15
+ getJob: (p: {
16
+ id: string;
17
+ }) => Promise<T>;
18
+ };
19
+ jobId: string;
20
+ /** Resolve only on these statuses. Default: the three terminal ones. */
21
+ until?: readonly JobStatusLike[];
22
+ /** Initial poll interval (ms). Default 1000. */
23
+ pollMinMs?: number;
24
+ /** Cap on poll interval (ms). Default 15000. */
25
+ pollMaxMs?: number;
26
+ /** Exponential backoff multiplier per poll. Default 1.5. */
27
+ pollBackoff?: number;
28
+ /** Abort and throw after this many ms. Default 3600000 (1h). */
29
+ timeoutMs?: number;
30
+ /** Called on every poll with the freshly fetched job. */
31
+ onProgress?: (job: T) => void;
32
+ signal?: AbortSignal;
33
+ }
34
+ export declare class JobTerminalError<T extends JobLike = JobLike> extends Error {
35
+ readonly job: T;
36
+ constructor(job: T);
37
+ }
38
+ export declare class JobTimeoutError extends Error {
39
+ readonly jobId: string;
40
+ constructor(jobId: string, waitedMs: number);
41
+ }
42
+ /**
43
+ * Polls `getJob` until the job hits a terminal status (or the requested
44
+ * `until` list), then returns the final job. Throws `JobTerminalError` on
45
+ * `failed` / `canceled` unless those are explicitly requested in `until`.
46
+ * Throws `JobTimeoutError` if the timeout elapses.
47
+ */
48
+ export declare function waitForJob<T extends JobLike = JobLike>(params: WaitForJobParams<T>): Promise<T>;
@@ -0,0 +1,61 @@
1
+ // Polling helper that resolves when a job hits a terminal state.
2
+ export class JobTerminalError extends Error {
3
+ job;
4
+ constructor(job) {
5
+ super(job.error ?? `job ${job.id} ended in status ${job.status}`);
6
+ this.name = "JobTerminalError";
7
+ this.job = job;
8
+ }
9
+ }
10
+ export class JobTimeoutError extends Error {
11
+ jobId;
12
+ constructor(jobId, waitedMs) {
13
+ super(`job ${jobId} did not finish within ${waitedMs}ms`);
14
+ this.name = "JobTimeoutError";
15
+ this.jobId = jobId;
16
+ }
17
+ }
18
+ const DEFAULT_TERMINAL = ["completed", "failed", "canceled"];
19
+ /**
20
+ * Polls `getJob` until the job hits a terminal status (or the requested
21
+ * `until` list), then returns the final job. Throws `JobTerminalError` on
22
+ * `failed` / `canceled` unless those are explicitly requested in `until`.
23
+ * Throws `JobTimeoutError` if the timeout elapses.
24
+ */
25
+ export async function waitForJob(params) {
26
+ const { api, jobId, until = DEFAULT_TERMINAL, pollMinMs = 1000, pollMaxMs = 15000, pollBackoff = 1.5, timeoutMs = 60 * 60 * 1000, onProgress, signal, } = params;
27
+ const start = Date.now();
28
+ let interval = pollMinMs;
29
+ while (true) {
30
+ if (signal?.aborted)
31
+ throw new DOMException("Aborted", "AbortError");
32
+ if (Date.now() - start > timeoutMs)
33
+ throw new JobTimeoutError(jobId, Date.now() - start);
34
+ const job = await api.getJob({ id: jobId });
35
+ onProgress?.(job);
36
+ if (until.some((s) => s === job.status)) {
37
+ // The caller opted into this status; only synthesize a JobTerminalError
38
+ // when they are waiting for the default-terminal set and we landed on a
39
+ // failed/canceled status.
40
+ if (until === DEFAULT_TERMINAL && (job.status === "failed" || job.status === "canceled")) {
41
+ throw new JobTerminalError(job);
42
+ }
43
+ return job;
44
+ }
45
+ await sleep(interval, signal);
46
+ interval = Math.min(Math.ceil(interval * pollBackoff), pollMaxMs);
47
+ }
48
+ }
49
+ function sleep(ms, signal) {
50
+ return new Promise((resolve, reject) => {
51
+ const t = setTimeout(() => {
52
+ signal?.removeEventListener("abort", onAbort);
53
+ resolve();
54
+ }, ms);
55
+ const onAbort = () => {
56
+ clearTimeout(t);
57
+ reject(new DOMException("Aborted", "AbortError"));
58
+ };
59
+ signal?.addEventListener("abort", onAbort, { once: true });
60
+ });
61
+ }
@@ -0,0 +1,71 @@
1
+ export interface UploadsApiLike {
2
+ createUpload(params: {
3
+ createUploadRequest: {
4
+ file_name: string;
5
+ file_size: number;
6
+ mime_type: string;
7
+ };
8
+ idempotencyKey: string;
9
+ }): Promise<{
10
+ id: string;
11
+ chunk_size: number;
12
+ total_chunks: number;
13
+ expires_at: string;
14
+ }>;
15
+ uploadPart(params: {
16
+ id: string;
17
+ partNumber: number;
18
+ body: Blob;
19
+ }): Promise<{
20
+ part_number: number;
21
+ received: boolean;
22
+ }>;
23
+ completeUpload(params: {
24
+ id: string;
25
+ idempotencyKey: string;
26
+ }): Promise<{
27
+ id: string;
28
+ status: string;
29
+ sha256: string;
30
+ bytes: number;
31
+ }>;
32
+ getUpload(params: {
33
+ id: string;
34
+ }): Promise<{
35
+ id: string;
36
+ status: string;
37
+ total_chunks: number;
38
+ received_chunks: number[];
39
+ }>;
40
+ }
41
+ export interface UploadProgress {
42
+ bytesUploaded: number;
43
+ bytesTotal: number;
44
+ partsDone: number;
45
+ partsTotal: number;
46
+ }
47
+ export interface UploadFileParams {
48
+ api: UploadsApiLike;
49
+ source: Blob;
50
+ fileName: string;
51
+ mimeType: string;
52
+ /** Resume a prior session instead of creating a new one. */
53
+ uploadId?: string;
54
+ /** Parallel in-flight chunks. Default 4. */
55
+ concurrency?: number;
56
+ /** Retries per chunk before aborting. Default 3. */
57
+ retries?: number;
58
+ /** Base backoff in ms; doubles each attempt. Default 500. */
59
+ retryBaseMs?: number;
60
+ /** Idempotency key reused for createUpload + completeUpload. Auto-generated if omitted. */
61
+ idempotencyKey?: string;
62
+ onProgress?: (p: UploadProgress) => void;
63
+ /** Abort the whole upload. Chunks in flight will still settle. */
64
+ signal?: AbortSignal;
65
+ }
66
+ export interface UploadFileResult {
67
+ uploadId: string;
68
+ sha256: string;
69
+ bytes: number;
70
+ }
71
+ export declare function uploadFile(params: UploadFileParams): Promise<UploadFileResult>;
@@ -0,0 +1,146 @@
1
+ // Upload orchestration on top of the generated UploadsApi.
2
+ //
3
+ // The generated SDK exposes createUpload / uploadPart / completeUpload as
4
+ // separate calls; this wrapper handles chunk slicing, bounded concurrency,
5
+ // per-part retry, resume against existing sessions, and progress reporting.
6
+ export async function uploadFile(params) {
7
+ const { api, source, fileName, mimeType, uploadId: resumeId, concurrency = 4, retries = 3, retryBaseMs = 500, idempotencyKey = randomIdempotencyKey(), onProgress, signal, } = params;
8
+ if (concurrency < 1)
9
+ throw new RangeError("concurrency must be >= 1");
10
+ if (retries < 0)
11
+ throw new RangeError("retries must be >= 0");
12
+ let uploadId;
13
+ let chunkSize;
14
+ let totalChunks;
15
+ let alreadyReceived = new Set();
16
+ if (resumeId) {
17
+ const status = await api.getUpload({ id: resumeId });
18
+ uploadId = status.id;
19
+ totalChunks = status.total_chunks;
20
+ alreadyReceived = new Set(status.received_chunks);
21
+ // Derive chunk size from file size / totalChunks. Last chunk may be smaller;
22
+ // we only need the head size to slice, so use ceil.
23
+ chunkSize = Math.ceil(source.size / totalChunks);
24
+ }
25
+ else {
26
+ const session = await api.createUpload({
27
+ createUploadRequest: {
28
+ file_name: fileName,
29
+ file_size: source.size,
30
+ mime_type: mimeType,
31
+ },
32
+ idempotencyKey,
33
+ });
34
+ uploadId = session.id;
35
+ chunkSize = session.chunk_size;
36
+ totalChunks = session.total_chunks;
37
+ }
38
+ const progress = {
39
+ bytesUploaded: 0,
40
+ bytesTotal: source.size,
41
+ partsDone: 0,
42
+ partsTotal: totalChunks,
43
+ };
44
+ // Seed progress from any resumed parts so callers see accurate counts.
45
+ for (const part of alreadyReceived) {
46
+ progress.partsDone += 1;
47
+ progress.bytesUploaded += partBytes(source.size, chunkSize, totalChunks, part);
48
+ }
49
+ onProgress?.({ ...progress });
50
+ const pending = [];
51
+ for (let i = 0; i < totalChunks; i++) {
52
+ if (!alreadyReceived.has(i))
53
+ pending.push(i);
54
+ }
55
+ let nextIdx = 0;
56
+ const workers = [];
57
+ for (let w = 0; w < Math.min(concurrency, pending.length); w++) {
58
+ workers.push((async () => {
59
+ while (true) {
60
+ if (signal?.aborted)
61
+ throw new DOMException("Aborted", "AbortError");
62
+ const idx = nextIdx++;
63
+ if (idx >= pending.length)
64
+ return;
65
+ const partNumber = pending[idx];
66
+ const start = partNumber * chunkSize;
67
+ const end = Math.min(start + chunkSize, source.size);
68
+ const chunk = source.slice(start, end, "application/octet-stream");
69
+ await withRetry(() => api.uploadPart({ id: uploadId, partNumber, body: chunk }), retries, retryBaseMs, signal);
70
+ progress.partsDone += 1;
71
+ progress.bytesUploaded += chunk.size;
72
+ onProgress?.({ ...progress });
73
+ }
74
+ })());
75
+ }
76
+ await Promise.all(workers);
77
+ const done = await api.completeUpload({ id: uploadId, idempotencyKey });
78
+ return { uploadId: done.id, sha256: done.sha256, bytes: done.bytes };
79
+ }
80
+ function partBytes(total, chunkSize, totalChunks, part) {
81
+ if (part < totalChunks - 1)
82
+ return chunkSize;
83
+ return total - chunkSize * (totalChunks - 1);
84
+ }
85
+ async function withRetry(fn, retries, baseMs, signal) {
86
+ let attempt = 0;
87
+ // One initial try + `retries` follow-ups.
88
+ while (true) {
89
+ try {
90
+ return await fn();
91
+ }
92
+ catch (err) {
93
+ if (signal?.aborted)
94
+ throw err;
95
+ if (attempt >= retries || !isRetryable(err))
96
+ throw err;
97
+ const delay = baseMs * 2 ** attempt + Math.floor(Math.random() * baseMs);
98
+ await sleep(delay, signal);
99
+ attempt += 1;
100
+ }
101
+ }
102
+ }
103
+ function isRetryable(err) {
104
+ if (err instanceof TypeError)
105
+ return true; // network-level fetch errors
106
+ const maybeResponse = err.response;
107
+ const status = maybeResponse?.status;
108
+ if (typeof status !== "number")
109
+ return false;
110
+ return status === 408 || status === 429 || (status >= 500 && status < 600);
111
+ }
112
+ function sleep(ms, signal) {
113
+ return new Promise((resolve, reject) => {
114
+ const t = setTimeout(() => {
115
+ signal?.removeEventListener("abort", onAbort);
116
+ resolve();
117
+ }, ms);
118
+ const onAbort = () => {
119
+ clearTimeout(t);
120
+ reject(new DOMException("Aborted", "AbortError"));
121
+ };
122
+ signal?.addEventListener("abort", onAbort, { once: true });
123
+ });
124
+ }
125
+ function randomIdempotencyKey() {
126
+ // Single capture of the global `crypto` object so the TS narrowing from
127
+ // one `in` check doesn't bleed into the next branch.
128
+ const c = typeof crypto !== "undefined"
129
+ ? crypto
130
+ : undefined;
131
+ if (c?.randomUUID)
132
+ return c.randomUUID();
133
+ // Fallback for very old runtimes without crypto.randomUUID. Web Crypto's
134
+ // getRandomValues has been in Node since 15 and all evergreen browsers, so
135
+ // this almost never runs — but we avoid Math.random so idempotency keys
136
+ // stay uncorrelated across callers even on ancient targets.
137
+ if (c?.getRandomValues) {
138
+ const bytes = new Uint8Array(16);
139
+ c.getRandomValues(bytes);
140
+ let hex = "";
141
+ for (const b of bytes)
142
+ hex += b.toString(16).padStart(2, "0");
143
+ return `idem_${hex}`;
144
+ }
145
+ throw new Error("crypto API unavailable; pass an explicit idempotencyKey to uploadFile");
146
+ }
@@ -0,0 +1,23 @@
1
+ export interface VerifyWebhookSignatureParams {
2
+ /** Raw HTTP body exactly as received, before any JSON parsing. */
3
+ rawBody: string | Uint8Array;
4
+ /** Value of `X-Turbo-Signature-256`, e.g. `"sha256=abc..."`. */
5
+ signatureHeader: string | null | undefined;
6
+ /** Value of `X-Turbo-Timestamp`. */
7
+ timestampHeader: string | null | undefined;
8
+ /** Webhook secret returned by `POST /v1/webhooks`. */
9
+ secret: string;
10
+ /** Maximum acceptable clock skew in ms. Default 5 min. Set 0 to disable. */
11
+ replayWindowMs?: number;
12
+ /** Override "now" for deterministic tests. */
13
+ now?: () => number;
14
+ }
15
+ export declare class WebhookSignatureError extends Error {
16
+ readonly reason: "missing_signature" | "missing_timestamp" | "invalid_timestamp" | "replay_window_exceeded" | "bad_prefix" | "bad_signature_encoding" | "signature_mismatch";
17
+ constructor(reason: WebhookSignatureError["reason"], message?: string);
18
+ }
19
+ /**
20
+ * Throws `WebhookSignatureError` if the delivery is not authentic. Returns
21
+ * a resolved promise on success.
22
+ */
23
+ export declare function verifyWebhookSignature(params: VerifyWebhookSignatureParams): Promise<void>;
@@ -0,0 +1,84 @@
1
+ // Webhook signature verification for inbound terminal-job deliveries.
2
+ //
3
+ // SOPHON signs each delivery with HMAC-SHA256 over `"{timestamp}.{raw_body}"`
4
+ // using the per-webhook secret. The hex digest is sent as
5
+ // `X-Turbo-Signature-256: sha256=<hex>`.
6
+ //
7
+ // Isomorphic: uses the Web Crypto API (`crypto.subtle`), available globally in
8
+ // Node 18+ and modern browsers. No Node-specific imports.
9
+ //
10
+ // Consumers call `verifyWebhookSignature` with the RAW request body (string or
11
+ // Uint8Array — NOT a parsed JSON object), the signature header, the timestamp
12
+ // header, and the webhook secret. The helper does a constant-time comparison
13
+ // and enforces a replay window by default.
14
+ export class WebhookSignatureError extends Error {
15
+ reason;
16
+ constructor(reason, message) {
17
+ super(message ?? reason);
18
+ this.name = "WebhookSignatureError";
19
+ this.reason = reason;
20
+ }
21
+ }
22
+ /**
23
+ * Throws `WebhookSignatureError` if the delivery is not authentic. Returns
24
+ * a resolved promise on success.
25
+ */
26
+ export async function verifyWebhookSignature(params) {
27
+ const { rawBody, signatureHeader, timestampHeader, secret, replayWindowMs = 5 * 60 * 1000, now = Date.now, } = params;
28
+ if (!signatureHeader)
29
+ throw new WebhookSignatureError("missing_signature");
30
+ if (!timestampHeader)
31
+ throw new WebhookSignatureError("missing_timestamp");
32
+ const deliveredTs = Date.parse(timestampHeader);
33
+ if (Number.isNaN(deliveredTs)) {
34
+ throw new WebhookSignatureError("invalid_timestamp");
35
+ }
36
+ if (replayWindowMs > 0) {
37
+ const drift = Math.abs(now() - deliveredTs);
38
+ if (drift > replayWindowMs) {
39
+ throw new WebhookSignatureError("replay_window_exceeded");
40
+ }
41
+ }
42
+ if (!signatureHeader.startsWith("sha256=")) {
43
+ throw new WebhookSignatureError("bad_prefix");
44
+ }
45
+ const deliveredHex = signatureHeader.slice("sha256=".length).trim();
46
+ const delivered = hexToBytes(deliveredHex);
47
+ if (!delivered) {
48
+ throw new WebhookSignatureError("bad_signature_encoding");
49
+ }
50
+ const bodyBytes = typeof rawBody === "string" ? new TextEncoder().encode(rawBody) : rawBody;
51
+ const payload = concatBytes(new TextEncoder().encode(`${timestampHeader}.`), bodyBytes);
52
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
53
+ const expected = new Uint8Array(
54
+ // TS 5.7+ tightened BufferSource to require ArrayBufferView<ArrayBuffer>;
55
+ // our concatenated Uint8Array is backed by an ArrayBuffer at runtime.
56
+ await crypto.subtle.sign("HMAC", key, payload));
57
+ if (!constantTimeEqual(delivered, expected)) {
58
+ throw new WebhookSignatureError("signature_mismatch");
59
+ }
60
+ }
61
+ function hexToBytes(hex) {
62
+ if (hex.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(hex))
63
+ return null;
64
+ const out = new Uint8Array(hex.length / 2);
65
+ for (let i = 0; i < out.length; i++) {
66
+ out[i] = parseInt(hex.substr(i * 2, 2), 16);
67
+ }
68
+ return out;
69
+ }
70
+ function concatBytes(a, b) {
71
+ const out = new Uint8Array(a.length + b.length);
72
+ out.set(a, 0);
73
+ out.set(b, a.length);
74
+ return out;
75
+ }
76
+ function constantTimeEqual(a, b) {
77
+ if (a.length !== b.length)
78
+ return false;
79
+ let diff = 0;
80
+ for (let i = 0; i < a.length; i++) {
81
+ diff |= (a[i] ?? 0) ^ (b[i] ?? 0);
82
+ }
83
+ return diff === 0;
84
+ }
@@ -0,0 +1,4 @@
1
+ export * from './runtime';
2
+ export * from './apis/index';
3
+ export * from './models/index';
4
+ export * from './helpers/index';
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export * from './runtime';
4
+ export * from './apis/index';
5
+ export * from './models/index';
6
+ export * from './helpers/index';
@@ -0,0 +1,57 @@
1
+ /**
2
+ * SOPHON Encoding API
3
+ * REST API for submitting, monitoring, and retrieving SOPHON encoding jobs. Authentication is via Bearer API key or session cookie. All POST endpoints require an Idempotency-Key header. List endpoints use opaque cursor-based pagination.
4
+ *
5
+ * The version of the OpenAPI document: 1.0.0
6
+ *
7
+ *
8
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9
+ * https://openapi-generator.tech
10
+ * Do not edit the class manually.
11
+ */
12
+ /**
13
+ *
14
+ * @export
15
+ * @interface CompleteUploadResponse
16
+ */
17
+ export interface CompleteUploadResponse {
18
+ /**
19
+ *
20
+ * @type {string}
21
+ * @memberof CompleteUploadResponse
22
+ */
23
+ id: string;
24
+ /**
25
+ *
26
+ * @type {CompleteUploadResponseStatusEnum}
27
+ * @memberof CompleteUploadResponse
28
+ */
29
+ status: CompleteUploadResponseStatusEnum;
30
+ /**
31
+ * SHA-256 hex digest of the assembled file.
32
+ * @type {string}
33
+ * @memberof CompleteUploadResponse
34
+ */
35
+ sha256: string;
36
+ /**
37
+ *
38
+ * @type {number}
39
+ * @memberof CompleteUploadResponse
40
+ */
41
+ bytes: number;
42
+ }
43
+ /**
44
+ * @export
45
+ * @enum {string}
46
+ */
47
+ export declare enum CompleteUploadResponseStatusEnum {
48
+ COMPLETED = "completed"
49
+ }
50
+ /**
51
+ * Check if a given object implements the CompleteUploadResponse interface.
52
+ */
53
+ export declare function instanceOfCompleteUploadResponse(value: object): value is CompleteUploadResponse;
54
+ export declare function CompleteUploadResponseFromJSON(json: any): CompleteUploadResponse;
55
+ export declare function CompleteUploadResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CompleteUploadResponse;
56
+ export declare function CompleteUploadResponseToJSON(json: any): CompleteUploadResponse;
57
+ export declare function CompleteUploadResponseToJSONTyped(value?: CompleteUploadResponse | null, ignoreDiscriminator?: boolean): any;