@liqhtworks/sophon-sdk 0.1.2 → 0.1.4

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.
@@ -0,0 +1,63 @@
1
+ name: Open Generated SDK PR
2
+
3
+ # The sophon-api Sync SDK Update PRs workflow pushes generated branches into
4
+ # this repo. This workflow uses the repo-local GITHUB_TOKEN to open or update
5
+ # the PR, so the cross-repo token only needs contents:write.
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - "generated/sophon-api-*"
11
+
12
+ permissions:
13
+ contents: read
14
+ pull-requests: write
15
+
16
+ jobs:
17
+ open:
18
+ name: Open or update PR
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 1
24
+
25
+ - name: Open or update generated SDK PR
26
+ env:
27
+ GH_TOKEN: ${{ github.token }}
28
+ BRANCH: ${{ github.ref_name }}
29
+ shell: bash
30
+ run: |
31
+ set -euo pipefail
32
+
33
+ title="$(git log -1 --format=%s)"
34
+ body="$(git log -1 --format=%B | sed '1d')"
35
+ if [ -z "${body}" ]; then
36
+ body="Generated SDK update from sophon-api."
37
+ fi
38
+
39
+ existing="$(
40
+ gh api --method GET "repos/${GITHUB_REPOSITORY}/pulls" \
41
+ -f state=open \
42
+ -f head="${GITHUB_REPOSITORY_OWNER}:${BRANCH}" \
43
+ -f base=main \
44
+ --jq '.[0].number // empty'
45
+ )"
46
+
47
+ body_file="$(mktemp)"
48
+ printf '%s\n' "${body}" > "${body_file}"
49
+
50
+ if [ -n "${existing}" ]; then
51
+ gh pr edit "${existing}" \
52
+ --repo "${GITHUB_REPOSITORY}" \
53
+ --title "${title}" \
54
+ --body-file "${body_file}"
55
+ echo "Updated PR #${existing}"
56
+ else
57
+ gh pr create \
58
+ --repo "${GITHUB_REPOSITORY}" \
59
+ --base main \
60
+ --head "${BRANCH}" \
61
+ --title "${title}" \
62
+ --body-file "${body_file}"
63
+ fi
@@ -1,13 +1,15 @@
1
- name: Publish to npm
1
+ name: TypeScript SDK CI
2
2
 
3
- # Fires when the sophon-api "Publish SDKs" workflow pushes a v<version> tag
4
- # into this repo. The tag commit already contains the fully-generated SDK;
5
- # this workflow installs, builds, and publishes to npm.
3
+ # PRs and main pushes validate the generated package natively in the SDK repo.
4
+ # v<version> tags additionally publish the already-generated SDK to npm.
6
5
 
7
6
  on:
8
7
  push:
8
+ branches:
9
+ - main
9
10
  tags:
10
11
  - "v*"
12
+ pull_request:
11
13
  workflow_dispatch:
12
14
  inputs:
13
15
  tag:
@@ -19,8 +21,33 @@ permissions:
19
21
  id-token: write
20
22
 
21
23
  jobs:
24
+ validate:
25
+ name: install + build + pack
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - name: Checkout package
29
+ uses: actions/checkout@v4
30
+ with:
31
+ ref: ${{ github.event.inputs.tag || github.ref }}
32
+ fetch-depth: 1
33
+
34
+ - name: Set up Node
35
+ uses: actions/setup-node@v4
36
+ with:
37
+ node-version: "20"
38
+
39
+ - name: Install + build
40
+ run: |
41
+ if [ -f package-lock.json ]; then npm ci; else npm install; fi
42
+ npm run build
43
+
44
+ - name: Validate npm package contents
45
+ run: npm pack --dry-run
46
+
22
47
  publish:
23
48
  name: npm publish
49
+ needs: validate
50
+ if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag != '')
24
51
  runs-on: ubuntu-latest
25
52
  steps:
26
53
  - name: Checkout tag
@@ -43,15 +70,11 @@ jobs:
43
70
  - name: Verify tag matches package.json
44
71
  shell: bash
45
72
  env:
46
- # `GITHUB_REF_NAME` is the *dispatched* ref (often `main`), not the
47
- # checked-out tag. Prefer the explicit workflow_dispatch input,
48
- # then fall back to GITHUB_REF_NAME for the tag-push trigger.
49
73
  INPUT_TAG: ${{ github.event.inputs.tag }}
50
74
  run: |
51
- tag="${INPUT_TAG#v}"
52
- if [ -z "${tag}" ]; then
53
- tag="${GITHUB_REF_NAME#v}"
54
- fi
75
+ tag="${INPUT_TAG:-${GITHUB_REF_NAME}}"
76
+ tag="${tag#refs/tags/}"
77
+ tag="${tag#v}"
55
78
  pkg="$(node -p "require('./package.json').version")"
56
79
  if [ "${tag}" != "${pkg}" ]; then
57
80
  echo "::error::tag v${tag} does not match package.json version ${pkg}" >&2
@@ -60,7 +83,7 @@ jobs:
60
83
 
61
84
  - name: Install + build
62
85
  run: |
63
- npm ci || npm install
86
+ if [ -f package-lock.json ]; then npm ci; else npm install; fi
64
87
  npm run build
65
88
 
66
89
  - name: Publish
package/README.md CHANGED
@@ -1,164 +1,82 @@
1
- # @liqhtworks/sophon-sdk@0.1.0
1
+ # @liqhtworks/sophon-sdk
2
2
 
3
- A TypeScript SDK client for the api.liqhtworks.xyz API.
3
+ Official TypeScript SDK for the SOPHON Encoding API.
4
4
 
5
- ## Usage
5
+ This repository is generated from `Liqhtworks/sophon-api`. The curated
6
+ `README.md` and `examples/` directory are preserved across SDK regeneration.
6
7
 
7
- First, install the SDK from npm.
8
+ ## Install
8
9
 
9
10
  ```bash
10
- npm install @liqhtworks/sophon-sdk --save
11
+ npm install @liqhtworks/sophon-sdk
11
12
  ```
12
13
 
13
- Next, try it out.
14
+ Requires Node 18+ or a runtime with `fetch`, `Blob`, `AbortController`, and Web
15
+ Crypto.
14
16
 
17
+ ## Quick Start
15
18
 
16
19
  ```ts
17
20
  import {
18
21
  Configuration,
19
- DownloadsApi,
20
- } from '@liqhtworks/sophon-sdk';
21
- import type { DownloadRequest } from '@liqhtworks/sophon-sdk';
22
-
23
- async function example() {
24
- console.log("🚀 Testing @liqhtworks/sophon-sdk SDK...");
25
- const api = new DownloadsApi();
26
-
27
- const body = {
28
- // string | HMAC-signed download token encoding the object key and expiry.
29
- token: token_example,
30
- } satisfies DownloadRequest;
31
-
32
- try {
33
- const data = await api.download(body);
34
- console.log(data);
35
- } catch (error) {
36
- console.error(error);
37
- }
38
- }
39
-
40
- // Run the test
41
- example().catch(console.error);
22
+ UploadsApi,
23
+ uploadFile,
24
+ } from "@liqhtworks/sophon-sdk";
25
+ import { Blob } from "node:buffer";
26
+ import { readFile } from "node:fs/promises";
27
+
28
+ const config = new Configuration({
29
+ basePath: process.env.SOPHON_BASE_URL ?? "https://api.liqhtworks.xyz",
30
+ accessToken: process.env.SOPHON_API_KEY,
31
+ });
32
+
33
+ const uploads = new UploadsApi(config);
34
+
35
+ const bytes = await readFile("./source.mov");
36
+ const source = new Blob([bytes], { type: "video/quicktime" });
37
+
38
+ const upload = await uploadFile({
39
+ api: uploads,
40
+ source,
41
+ fileName: "source.mov",
42
+ mimeType: "video/quicktime",
43
+ concurrency: 4,
44
+ onProgress: (p) => console.log(`${p.partsDone}/${p.partsTotal} parts`),
45
+ });
46
+
47
+ console.log(upload.uploadId);
42
48
  ```
43
49
 
50
+ For a standalone file-path upload recipe, see
51
+ [`examples/upload-node-path.mjs`](./examples/upload-node-path.mjs).
44
52
 
45
- ## Documentation
46
-
47
- ### API Endpoints
48
-
49
- All URIs are relative to *https://api.liqhtworks.xyz*
50
-
51
- | Class | Method | HTTP request | Description
52
- | ----- | ------ | ------------ | -------------
53
- *DownloadsApi* | [**download**](docs/DownloadsApi.md#download) | **GET** /v1/downloads/{token} | Download an output file via signed token
54
- *HealthApi* | [**healthz**](docs/HealthApi.md#healthz) | **GET** /healthz | Liveness probe
55
- *HealthApi* | [**readyz**](docs/HealthApi.md#readyz) | **GET** /readyz | Readiness probe
56
- *JobsApi* | [**cancelJob**](docs/JobsApi.md#canceljob) | **DELETE** /v1/jobs/{id} | Cancel a job
57
- *JobsApi* | [**createJob**](docs/JobsApi.md#createjoboperation) | **POST** /v1/jobs | Submit an encoding job
58
- *JobsApi* | [**getJob**](docs/JobsApi.md#getjob) | **GET** /v1/jobs/{id} | Get a single job by ID
59
- *JobsApi* | [**getJobOutput**](docs/JobsApi.md#getjoboutput) | **GET** /v1/jobs/{id}/output | Get the encoded output file
60
- *JobsApi* | [**listJobs**](docs/JobsApi.md#listjobs) | **GET** /v1/jobs | List jobs with cursor pagination
61
- *UploadsApi* | [**cancelUpload**](docs/UploadsApi.md#cancelupload) | **DELETE** /v1/uploads/{id} | Cancel an upload session
62
- *UploadsApi* | [**completeUpload**](docs/UploadsApi.md#completeupload) | **POST** /v1/uploads/{id}/complete | Finalize a chunked upload
63
- *UploadsApi* | [**createUpload**](docs/UploadsApi.md#createuploadoperation) | **POST** /v1/uploads | Initialize a chunked upload session
64
- *UploadsApi* | [**getUpload**](docs/UploadsApi.md#getupload) | **GET** /v1/uploads/{id} | Get upload session status
65
- *UploadsApi* | [**uploadPart**](docs/UploadsApi.md#uploadpart) | **PUT** /v1/uploads/{id}/parts/{part_number} | Upload a single chunk
66
- *WebhooksApi* | [**createWebhook**](docs/WebhooksApi.md#createwebhookoperation) | **POST** /v1/webhooks | Register a webhook endpoint
67
- *WebhooksApi* | [**deleteWebhook**](docs/WebhooksApi.md#deletewebhook) | **DELETE** /v1/webhooks/{id} | Soft-delete a webhook endpoint
68
- *WebhooksApi* | [**listWebhooks**](docs/WebhooksApi.md#listwebhooks) | **GET** /v1/webhooks | List active webhook endpoints
69
-
70
-
71
- ### Models
72
-
73
- - [CompleteUploadResponse](docs/CompleteUploadResponse.md)
74
- - [CreateJobOutputOptions](docs/CreateJobOutputOptions.md)
75
- - [CreateJobRequest](docs/CreateJobRequest.md)
76
- - [CreateUploadRequest](docs/CreateUploadRequest.md)
77
- - [CreateUploadResponse](docs/CreateUploadResponse.md)
78
- - [CreateWebhookRequest](docs/CreateWebhookRequest.md)
79
- - [ErrorBody](docs/ErrorBody.md)
80
- - [ErrorEnvelope](docs/ErrorEnvelope.md)
81
- - [JobOutputInfo](docs/JobOutputInfo.md)
82
- - [JobProfile](docs/JobProfile.md)
83
- - [JobProgress](docs/JobProgress.md)
84
- - [JobResponse](docs/JobResponse.md)
85
- - [JobSourceInfo](docs/JobSourceInfo.md)
86
- - [JobSourceType](docs/JobSourceType.md)
87
- - [JobStatus](docs/JobStatus.md)
88
- - [ListJobsResponse](docs/ListJobsResponse.md)
89
- - [OutputContainer](docs/OutputContainer.md)
90
- - [ReadyResponse](docs/ReadyResponse.md)
91
- - [UploadJobSource](docs/UploadJobSource.md)
92
- - [UploadPartResponse](docs/UploadPartResponse.md)
93
- - [UploadStatusResponse](docs/UploadStatusResponse.md)
94
- - [WebhookDeliveryPayload](docs/WebhookDeliveryPayload.md)
95
- - [WebhookListItem](docs/WebhookListItem.md)
96
- - [WebhookListResponse](docs/WebhookListResponse.md)
97
- - [WebhookResponse](docs/WebhookResponse.md)
98
-
99
- ### Authorization
100
-
101
-
102
- Authentication schemes defined for the API:
103
- <a id="bearerApiKey"></a>
104
- #### bearerApiKey
105
-
106
-
107
- - **Type**: HTTP Bearer Token authentication
108
- <a id="sessionCookie"></a>
109
- #### sessionCookie
110
-
111
-
112
- - **Type**: API key
113
- - **API key parameter name**: `sophon_api_session`
114
- - **Location**:
115
-
116
- ## About
117
-
118
- This TypeScript SDK client supports the [Fetch API](https://fetch.spec.whatwg.org/)
119
- and is automatically generated by the
120
- [OpenAPI Generator](https://openapi-generator.tech) project:
121
-
122
- - API version: `1.0.0`
123
- - Package version: `0.1.0`
124
- - Generator version: `7.21.0`
125
- - Build package: `org.openapitools.codegen.languages.TypeScriptFetchClientCodegen`
126
-
127
- The generated npm module supports the following:
128
-
129
- - Environments
130
- * Node.js
131
- * Webpack
132
- * Browserify
133
- - Language levels
134
- * ES5 - you must have a Promises/A+ library installed
135
- * ES6
136
- - Module systems
137
- * CommonJS
138
- * ES6 module system
139
-
140
- For more information, please visit [https://liqhtworks.xyz](https://liqhtworks.xyz)
53
+ ## Webhooks
141
54
 
142
- ## Development
55
+ Use `verifyWebhookSignature` with the raw request body before JSON parsing.
143
56
 
144
- ### Building
57
+ See [`examples/webhook-server`](./examples/webhook-server) for an Express
58
+ handler that preserves the raw body, verifies `X-Turbo-Signature-256`, and only
59
+ then parses JSON.
145
60
 
146
- To build the TypeScript source code, you need to have Node.js and npm installed.
147
- After cloning the repository, navigate to the project directory and run:
61
+ ## Helpers
148
62
 
149
- ```bash
150
- npm install
151
- npm run build
152
- ```
63
+ | Helper | Purpose |
64
+ |---|---|
65
+ | `uploadFile` | Chunked upload orchestration with bounded concurrency, retries, resume, and progress callbacks. |
66
+ | `waitForJob` | Poll until terminal status with timeout and typed errors. |
67
+ | `verifyWebhookSignature` | Constant-time HMAC verification plus replay-window enforcement. |
153
68
 
154
- ### Publishing
69
+ ## API Docs
155
70
 
156
- Once you've built the package, you can publish it to npm:
71
+ Generated endpoint/model docs live under [`docs/`](./docs).
72
+
73
+ ## Development
157
74
 
158
75
  ```bash
159
- npm publish
76
+ npm install
77
+ npm run build
160
78
  ```
161
79
 
162
80
  ## License
163
81
 
164
- [Proprietary]()
82
+ Proprietary. See [`LICENSE`](./LICENSE).
@@ -1,3 +1,4 @@
1
1
  export * from "./uploads";
2
2
  export * from "./jobs";
3
+ export * from "./sources";
3
4
  export * from "./webhooks";
@@ -1,3 +1,4 @@
1
1
  export * from "./uploads";
2
2
  export * from "./jobs";
3
+ export * from "./sources";
3
4
  export * from "./webhooks";
@@ -0,0 +1,8 @@
1
+ export interface UploadJobSourceLike {
2
+ type: any;
3
+ upload_id: string;
4
+ }
5
+ export declare function uploadJobSource(uploadId: string): UploadJobSourceLike;
6
+ export declare const JobSource: Readonly<{
7
+ upload: typeof uploadJobSource;
8
+ }>;
@@ -0,0 +1,6 @@
1
+ export function uploadJobSource(uploadId) {
2
+ return { type: "upload", upload_id: uploadId };
3
+ }
4
+ export const JobSource = Object.freeze({
5
+ upload: uploadJobSource,
6
+ });
@@ -10,7 +10,6 @@ export interface UploadsApiLike {
10
10
  id: string;
11
11
  chunk_size: number;
12
12
  total_chunks: number;
13
- expires_at: string;
14
13
  }>;
15
14
  uploadPart(params: {
16
15
  id: string;
@@ -25,7 +24,6 @@ export interface UploadsApiLike {
25
24
  idempotencyKey: string;
26
25
  }): Promise<{
27
26
  id: string;
28
- status: string;
29
27
  sha256: string;
30
28
  bytes: number;
31
29
  }>;
@@ -33,7 +31,6 @@ export interface UploadsApiLike {
33
31
  id: string;
34
32
  }): Promise<{
35
33
  id: string;
36
- status: string;
37
34
  total_chunks: number;
38
35
  received_chunks: number[];
39
36
  }>;
@@ -1,3 +1,4 @@
1
1
  export * from "./uploads";
2
2
  export * from "./jobs";
3
+ export * from "./sources";
3
4
  export * from "./webhooks";
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./uploads"), exports);
18
18
  __exportStar(require("./jobs"), exports);
19
+ __exportStar(require("./sources"), exports);
19
20
  __exportStar(require("./webhooks"), exports);
@@ -0,0 +1,8 @@
1
+ export interface UploadJobSourceLike {
2
+ type: any;
3
+ upload_id: string;
4
+ }
5
+ export declare function uploadJobSource(uploadId: string): UploadJobSourceLike;
6
+ export declare const JobSource: Readonly<{
7
+ upload: typeof uploadJobSource;
8
+ }>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobSource = void 0;
4
+ exports.uploadJobSource = uploadJobSource;
5
+ function uploadJobSource(uploadId) {
6
+ return { type: "upload", upload_id: uploadId };
7
+ }
8
+ exports.JobSource = Object.freeze({
9
+ upload: uploadJobSource,
10
+ });
@@ -10,7 +10,6 @@ export interface UploadsApiLike {
10
10
  id: string;
11
11
  chunk_size: number;
12
12
  total_chunks: number;
13
- expires_at: string;
14
13
  }>;
15
14
  uploadPart(params: {
16
15
  id: string;
@@ -25,7 +24,6 @@ export interface UploadsApiLike {
25
24
  idempotencyKey: string;
26
25
  }): Promise<{
27
26
  id: string;
28
- status: string;
29
27
  sha256: string;
30
28
  bytes: number;
31
29
  }>;
@@ -33,7 +31,6 @@ export interface UploadsApiLike {
33
31
  id: string;
34
32
  }): Promise<{
35
33
  id: string;
36
- status: string;
37
34
  total_chunks: number;
38
35
  received_chunks: number[];
39
36
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liqhtworks/sophon-sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "OpenAPI client for @liqhtworks/sophon-sdk",
5
5
  "author": "OpenAPI-Generator",
6
6
  "repository": {
@@ -1,3 +1,4 @@
1
1
  export * from "./uploads";
2
2
  export * from "./jobs";
3
+ export * from "./sources";
3
4
  export * from "./webhooks";
@@ -0,0 +1,14 @@
1
+ export interface UploadJobSourceLike {
2
+ // `any` keeps the helper assignable to the generated string enum type while
3
+ // still centralizing the only valid runtime discriminator value.
4
+ type: any;
5
+ upload_id: string;
6
+ }
7
+
8
+ export function uploadJobSource(uploadId: string): UploadJobSourceLike {
9
+ return { type: "upload", upload_id: uploadId };
10
+ }
11
+
12
+ export const JobSource = Object.freeze({
13
+ upload: uploadJobSource,
14
+ });
@@ -4,11 +4,15 @@
4
4
  // separate calls; this wrapper handles chunk slicing, bounded concurrency,
5
5
  // per-part retry, resume against existing sessions, and progress reporting.
6
6
 
7
+ // Narrow structural type — only the fields the helper actually reads.
8
+ // Keeping it tight lets the generated UploadsApi (which carries Date /
9
+ // nullable / extra metadata fields) satisfy this interface without
10
+ // explicit casts at the call site.
7
11
  export interface UploadsApiLike {
8
12
  createUpload(params: {
9
13
  createUploadRequest: { file_name: string; file_size: number; mime_type: string };
10
14
  idempotencyKey: string;
11
- }): Promise<{ id: string; chunk_size: number; total_chunks: number; expires_at: string }>;
15
+ }): Promise<{ id: string; chunk_size: number; total_chunks: number }>;
12
16
 
13
17
  uploadPart(params: {
14
18
  id: string;
@@ -19,11 +23,10 @@ export interface UploadsApiLike {
19
23
  completeUpload(params: {
20
24
  id: string;
21
25
  idempotencyKey: string;
22
- }): Promise<{ id: string; status: string; sha256: string; bytes: number }>;
26
+ }): Promise<{ id: string; sha256: string; bytes: number }>;
23
27
 
24
28
  getUpload(params: { id: string }): Promise<{
25
29
  id: string;
26
- status: string;
27
30
  total_chunks: number;
28
31
  received_chunks: number[];
29
32
  }>;