@verygoodffmpeg/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.
@@ -0,0 +1,16 @@
1
+ // src/error.ts
2
+ var VGFError = class extends Error {
3
+ status;
4
+ body;
5
+ constructor(status, body) {
6
+ super(`VGF API error ${status}: ${body}`);
7
+ this.name = "VGFError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ };
12
+
13
+ export {
14
+ VGFError
15
+ };
16
+ //# sourceMappingURL=chunk-DSE47ZPQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/error.ts"],"sourcesContent":["export class VGFError extends Error {\n readonly status: number;\n readonly body: string;\n\n constructor(status: number, body: string) {\n super(`VGF API error ${status}: ${body}`);\n this.name = \"VGFError\";\n this.status = status;\n this.body = body;\n }\n}\n"],"mappings":";AAAO,IAAM,WAAN,cAAuB,MAAM;AAAA,EACzB;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAAc;AACxC,UAAM,iBAAiB,MAAM,KAAK,IAAI,EAAE;AACxC,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;","names":[]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ VGFError
3
+ } from "./chunk-DSE47ZPQ.js";
4
+ export {
5
+ VGFError
6
+ };
7
+ //# sourceMappingURL=error-RZNFPYQE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+
23
+ // src/error.ts
24
+ var error_exports = {};
25
+ __export(error_exports, {
26
+ VGFError: () => VGFError
27
+ });
28
+ var VGFError;
29
+ var init_error = __esm({
30
+ "src/error.ts"() {
31
+ "use strict";
32
+ VGFError = class extends Error {
33
+ status;
34
+ body;
35
+ constructor(status, body) {
36
+ super(`VGF API error ${status}: ${body}`);
37
+ this.name = "VGFError";
38
+ this.status = status;
39
+ this.body = body;
40
+ }
41
+ };
42
+ }
43
+ });
44
+
45
+ // src/index.ts
46
+ var index_exports = {};
47
+ __export(index_exports, {
48
+ VGF: () => VGF,
49
+ VGFError: () => VGFError,
50
+ default: () => index_default
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+ init_error();
54
+ var BASE_URL = "https://verygoodffmpeg.com/api";
55
+ var VGF = class {
56
+ jobs;
57
+ files;
58
+ apiKey;
59
+ baseUrl;
60
+ constructor(apiKey, options) {
61
+ if (!apiKey) throw new Error("API key is required");
62
+ this.apiKey = apiKey;
63
+ this.baseUrl = options?.baseUrl ?? BASE_URL;
64
+ this.jobs = new Jobs(this);
65
+ this.files = new Files(this);
66
+ }
67
+ async run(params, options = {}) {
68
+ const qs = options.wait ? "?wait=true" : "";
69
+ const body = {
70
+ input_files: params.input_files,
71
+ output_files: params.output_files,
72
+ ffmpeg_commands: params.ffmpeg_commands,
73
+ webhook_url: params.webhook_url,
74
+ machine: params.machine
75
+ };
76
+ const res = await this._request(
77
+ "POST",
78
+ `/ffmpeg${qs}`,
79
+ body
80
+ );
81
+ return res.data;
82
+ }
83
+ /** @internal */
84
+ async _request(method, path, body) {
85
+ const res = await fetch(`${this.baseUrl}${path}`, {
86
+ method,
87
+ headers: {
88
+ Authorization: `Bearer ${this.apiKey}`
89
+ // "Content-Type": "application/json",
90
+ },
91
+ body: body != null ? JSON.stringify(body) : void 0
92
+ });
93
+ if (!res.ok) {
94
+ const text = await res.text().catch(() => "");
95
+ const { VGFError: VGFError2 } = await Promise.resolve().then(() => (init_error(), error_exports));
96
+ throw new VGFError2(res.status, text);
97
+ }
98
+ return res.json();
99
+ }
100
+ };
101
+ var Jobs = class {
102
+ constructor(client) {
103
+ this.client = client;
104
+ }
105
+ client;
106
+ async list(params = {}) {
107
+ const qs = new URLSearchParams();
108
+ if (params.limit != null) qs.set("limit", String(params.limit));
109
+ if (params.offset != null) qs.set("offset", String(params.offset));
110
+ const query = qs.size ? `?${qs}` : "";
111
+ return this.client._request("GET", `/jobs${query}`);
112
+ }
113
+ async get(id) {
114
+ const res = await this.client._request(
115
+ "GET",
116
+ `/jobs/${encodeURIComponent(id)}`
117
+ );
118
+ return res.data;
119
+ }
120
+ async cancel(id) {
121
+ const res = await this.client._request(
122
+ "POST",
123
+ `/jobs/${encodeURIComponent(id)}/cancel`
124
+ );
125
+ return res.data;
126
+ }
127
+ };
128
+ var Files = class {
129
+ constructor(client) {
130
+ this.client = client;
131
+ }
132
+ client;
133
+ async prepareUpload() {
134
+ const res = await this.client._request(
135
+ "POST",
136
+ "/tmp-file"
137
+ );
138
+ return res.data;
139
+ }
140
+ /**
141
+ * Uploads a file to temporary storage and returns the download URL,
142
+ * which can be used as an input_files value in a job.
143
+ */
144
+ async upload(data, contentType = "application/octet-stream") {
145
+ const { upload_url, download_url } = await this.prepareUpload();
146
+ const res = await fetch(upload_url, {
147
+ method: "PUT",
148
+ headers: { "Content-Type": contentType },
149
+ body: data
150
+ });
151
+ if (!res.ok) {
152
+ const { VGFError: VGFError2 } = await Promise.resolve().then(() => (init_error(), error_exports));
153
+ throw new VGFError2(res.status, `File upload failed: ${res.statusText}`);
154
+ }
155
+ return download_url;
156
+ }
157
+ };
158
+ var index_default = VGF;
159
+ // Annotate the CommonJS export names for ESM import in node:
160
+ 0 && (module.exports = {
161
+ VGF,
162
+ VGFError
163
+ });
164
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/error.ts","../src/index.ts"],"sourcesContent":["export class VGFError extends Error {\n readonly status: number;\n readonly body: string;\n\n constructor(status: number, body: string) {\n super(`VGF API error ${status}: ${body}`);\n this.name = \"VGFError\";\n this.status = status;\n this.body = body;\n }\n}\n","import type {\n Job,\n RunParams,\n RunOptions,\n ListJobsParams,\n PagingParams,\n TmpFile,\n} from \"./types.js\";\n\nexport type {\n Job,\n RunParams,\n RunOptions,\n ListJobsParams,\n PagingParams,\n TmpFile,\n};\nexport { VGFError } from \"./error.js\";\n\nconst BASE_URL = \"https://verygoodffmpeg.com/api\";\n\nexport class VGF {\n readonly jobs: Jobs;\n readonly files: Files;\n\n private apiKey: string;\n private baseUrl: string;\n\n constructor(apiKey: string, options?: { baseUrl?: string }) {\n if (!apiKey) throw new Error(\"API key is required\");\n this.apiKey = apiKey;\n this.baseUrl = options?.baseUrl ?? BASE_URL;\n this.jobs = new Jobs(this);\n this.files = new Files(this);\n }\n\n async run(params: RunParams, options: RunOptions = {}): Promise<Job> {\n const qs = options.wait ? \"?wait=true\" : \"\";\n const body = {\n input_files: params.input_files,\n output_files: params.output_files,\n ffmpeg_commands: params.ffmpeg_commands,\n webhook_url: params.webhook_url,\n machine: params.machine,\n };\n const res = await this._request<{ data: Job }>(\n \"POST\",\n `/ffmpeg${qs}`,\n body,\n );\n return res.data;\n }\n\n /** @internal */\n async _request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n // \"Content-Type\": \"application/json\",\n },\n body: body != null ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const { VGFError } = await import(\"./error.js\");\n throw new VGFError(res.status, text);\n }\n\n return res.json() as Promise<T>;\n }\n}\n\nclass Jobs {\n constructor(private client: VGF) {}\n\n async list(\n params: ListJobsParams = {},\n ): Promise<{ data: Job[]; pagingParams: PagingParams }> {\n const qs = new URLSearchParams();\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n const query = qs.size ? `?${qs}` : \"\";\n return this.client._request(\"GET\", `/jobs${query}`);\n }\n\n async get(id: string): Promise<Job> {\n const res = await this.client._request<{ data: Job }>(\n \"GET\",\n `/jobs/${encodeURIComponent(id)}`,\n );\n return res.data;\n }\n\n async cancel(id: string): Promise<Job> {\n const res = await this.client._request<{ data: Job }>(\n \"POST\",\n `/jobs/${encodeURIComponent(id)}/cancel`,\n );\n return res.data;\n }\n}\n\nclass Files {\n constructor(private client: VGF) {}\n\n async prepareUpload(): Promise<TmpFile> {\n const res = await this.client._request<{ data: TmpFile }>(\n \"POST\",\n \"/tmp-file\",\n );\n return res.data;\n }\n\n /**\n * Uploads a file to temporary storage and returns the download URL,\n * which can be used as an input_files value in a job.\n */\n async upload(\n data: Buffer | Blob | ReadableStream | Uint8Array,\n contentType = \"application/octet-stream\",\n ): Promise<string> {\n const { upload_url, download_url } = await this.prepareUpload();\n const res = await fetch(upload_url, {\n method: \"PUT\",\n headers: { \"Content-Type\": contentType },\n body: data as BodyInit,\n });\n if (!res.ok) {\n const { VGFError } = await import(\"./error.js\");\n throw new VGFError(res.status, `File upload failed: ${res.statusText}`);\n }\n return download_url;\n }\n}\n\nexport default VGF;\n"],"mappings":"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","names":["VGFError"]}
@@ -0,0 +1,83 @@
1
+ type JobStatus = "queued" | "running" | "succeeded" | "failed" | "cancelled";
2
+ interface Job {
3
+ id: string;
4
+ status: JobStatus;
5
+ queued_at: string;
6
+ started_at: string | null;
7
+ finished_at: string | null;
8
+ created_at: string;
9
+ updated_at: string;
10
+ error_message: string;
11
+ ffmpeg_commands: string[];
12
+ input_files: Record<string, string>;
13
+ output_files: Record<string, string>;
14
+ webhook_url: string | null;
15
+ total_input_bytes: number | null;
16
+ total_output_bytes: number | null;
17
+ }
18
+ interface RunParams {
19
+ input_files: Record<string, string>;
20
+ output_files: string[];
21
+ ffmpeg_commands: string[];
22
+ webhook_url?: string;
23
+ machine?: "cpu" | "nvidia";
24
+ }
25
+ interface RunOptions {
26
+ /** Wait for the job to complete before returning. */
27
+ wait?: boolean;
28
+ }
29
+ interface ListJobsParams {
30
+ limit?: number;
31
+ offset?: number;
32
+ }
33
+ interface PagingParams {
34
+ limit: number;
35
+ offset: number;
36
+ total: number;
37
+ hasMore: boolean;
38
+ }
39
+ interface TmpFile {
40
+ upload_url: string;
41
+ download_url: string;
42
+ }
43
+
44
+ declare class VGFError extends Error {
45
+ readonly status: number;
46
+ readonly body: string;
47
+ constructor(status: number, body: string);
48
+ }
49
+
50
+ declare class VGF {
51
+ readonly jobs: Jobs;
52
+ readonly files: Files;
53
+ private apiKey;
54
+ private baseUrl;
55
+ constructor(apiKey: string, options?: {
56
+ baseUrl?: string;
57
+ });
58
+ run(params: RunParams, options?: RunOptions): Promise<Job>;
59
+ /** @internal */
60
+ _request<T>(method: string, path: string, body?: unknown): Promise<T>;
61
+ }
62
+ declare class Jobs {
63
+ private client;
64
+ constructor(client: VGF);
65
+ list(params?: ListJobsParams): Promise<{
66
+ data: Job[];
67
+ pagingParams: PagingParams;
68
+ }>;
69
+ get(id: string): Promise<Job>;
70
+ cancel(id: string): Promise<Job>;
71
+ }
72
+ declare class Files {
73
+ private client;
74
+ constructor(client: VGF);
75
+ prepareUpload(): Promise<TmpFile>;
76
+ /**
77
+ * Uploads a file to temporary storage and returns the download URL,
78
+ * which can be used as an input_files value in a job.
79
+ */
80
+ upload(data: Buffer | Blob | ReadableStream | Uint8Array, contentType?: string): Promise<string>;
81
+ }
82
+
83
+ export { type Job, type ListJobsParams, type PagingParams, type RunOptions, type RunParams, type TmpFile, VGF, VGFError, VGF as default };
@@ -0,0 +1,83 @@
1
+ type JobStatus = "queued" | "running" | "succeeded" | "failed" | "cancelled";
2
+ interface Job {
3
+ id: string;
4
+ status: JobStatus;
5
+ queued_at: string;
6
+ started_at: string | null;
7
+ finished_at: string | null;
8
+ created_at: string;
9
+ updated_at: string;
10
+ error_message: string;
11
+ ffmpeg_commands: string[];
12
+ input_files: Record<string, string>;
13
+ output_files: Record<string, string>;
14
+ webhook_url: string | null;
15
+ total_input_bytes: number | null;
16
+ total_output_bytes: number | null;
17
+ }
18
+ interface RunParams {
19
+ input_files: Record<string, string>;
20
+ output_files: string[];
21
+ ffmpeg_commands: string[];
22
+ webhook_url?: string;
23
+ machine?: "cpu" | "nvidia";
24
+ }
25
+ interface RunOptions {
26
+ /** Wait for the job to complete before returning. */
27
+ wait?: boolean;
28
+ }
29
+ interface ListJobsParams {
30
+ limit?: number;
31
+ offset?: number;
32
+ }
33
+ interface PagingParams {
34
+ limit: number;
35
+ offset: number;
36
+ total: number;
37
+ hasMore: boolean;
38
+ }
39
+ interface TmpFile {
40
+ upload_url: string;
41
+ download_url: string;
42
+ }
43
+
44
+ declare class VGFError extends Error {
45
+ readonly status: number;
46
+ readonly body: string;
47
+ constructor(status: number, body: string);
48
+ }
49
+
50
+ declare class VGF {
51
+ readonly jobs: Jobs;
52
+ readonly files: Files;
53
+ private apiKey;
54
+ private baseUrl;
55
+ constructor(apiKey: string, options?: {
56
+ baseUrl?: string;
57
+ });
58
+ run(params: RunParams, options?: RunOptions): Promise<Job>;
59
+ /** @internal */
60
+ _request<T>(method: string, path: string, body?: unknown): Promise<T>;
61
+ }
62
+ declare class Jobs {
63
+ private client;
64
+ constructor(client: VGF);
65
+ list(params?: ListJobsParams): Promise<{
66
+ data: Job[];
67
+ pagingParams: PagingParams;
68
+ }>;
69
+ get(id: string): Promise<Job>;
70
+ cancel(id: string): Promise<Job>;
71
+ }
72
+ declare class Files {
73
+ private client;
74
+ constructor(client: VGF);
75
+ prepareUpload(): Promise<TmpFile>;
76
+ /**
77
+ * Uploads a file to temporary storage and returns the download URL,
78
+ * which can be used as an input_files value in a job.
79
+ */
80
+ upload(data: Buffer | Blob | ReadableStream | Uint8Array, contentType?: string): Promise<string>;
81
+ }
82
+
83
+ export { type Job, type ListJobsParams, type PagingParams, type RunOptions, type RunParams, type TmpFile, VGF, VGFError, VGF as default };
package/dist/index.js ADDED
@@ -0,0 +1,116 @@
1
+ import {
2
+ VGFError
3
+ } from "./chunk-DSE47ZPQ.js";
4
+
5
+ // src/index.ts
6
+ var BASE_URL = "https://verygoodffmpeg.com/api";
7
+ var VGF = class {
8
+ jobs;
9
+ files;
10
+ apiKey;
11
+ baseUrl;
12
+ constructor(apiKey, options) {
13
+ if (!apiKey) throw new Error("API key is required");
14
+ this.apiKey = apiKey;
15
+ this.baseUrl = options?.baseUrl ?? BASE_URL;
16
+ this.jobs = new Jobs(this);
17
+ this.files = new Files(this);
18
+ }
19
+ async run(params, options = {}) {
20
+ const qs = options.wait ? "?wait=true" : "";
21
+ const body = {
22
+ input_files: params.input_files,
23
+ output_files: params.output_files,
24
+ ffmpeg_commands: params.ffmpeg_commands,
25
+ webhook_url: params.webhook_url,
26
+ machine: params.machine
27
+ };
28
+ const res = await this._request(
29
+ "POST",
30
+ `/ffmpeg${qs}`,
31
+ body
32
+ );
33
+ return res.data;
34
+ }
35
+ /** @internal */
36
+ async _request(method, path, body) {
37
+ const res = await fetch(`${this.baseUrl}${path}`, {
38
+ method,
39
+ headers: {
40
+ Authorization: `Bearer ${this.apiKey}`
41
+ // "Content-Type": "application/json",
42
+ },
43
+ body: body != null ? JSON.stringify(body) : void 0
44
+ });
45
+ if (!res.ok) {
46
+ const text = await res.text().catch(() => "");
47
+ const { VGFError: VGFError2 } = await import("./error-RZNFPYQE.js");
48
+ throw new VGFError2(res.status, text);
49
+ }
50
+ return res.json();
51
+ }
52
+ };
53
+ var Jobs = class {
54
+ constructor(client) {
55
+ this.client = client;
56
+ }
57
+ client;
58
+ async list(params = {}) {
59
+ const qs = new URLSearchParams();
60
+ if (params.limit != null) qs.set("limit", String(params.limit));
61
+ if (params.offset != null) qs.set("offset", String(params.offset));
62
+ const query = qs.size ? `?${qs}` : "";
63
+ return this.client._request("GET", `/jobs${query}`);
64
+ }
65
+ async get(id) {
66
+ const res = await this.client._request(
67
+ "GET",
68
+ `/jobs/${encodeURIComponent(id)}`
69
+ );
70
+ return res.data;
71
+ }
72
+ async cancel(id) {
73
+ const res = await this.client._request(
74
+ "POST",
75
+ `/jobs/${encodeURIComponent(id)}/cancel`
76
+ );
77
+ return res.data;
78
+ }
79
+ };
80
+ var Files = class {
81
+ constructor(client) {
82
+ this.client = client;
83
+ }
84
+ client;
85
+ async prepareUpload() {
86
+ const res = await this.client._request(
87
+ "POST",
88
+ "/tmp-file"
89
+ );
90
+ return res.data;
91
+ }
92
+ /**
93
+ * Uploads a file to temporary storage and returns the download URL,
94
+ * which can be used as an input_files value in a job.
95
+ */
96
+ async upload(data, contentType = "application/octet-stream") {
97
+ const { upload_url, download_url } = await this.prepareUpload();
98
+ const res = await fetch(upload_url, {
99
+ method: "PUT",
100
+ headers: { "Content-Type": contentType },
101
+ body: data
102
+ });
103
+ if (!res.ok) {
104
+ const { VGFError: VGFError2 } = await import("./error-RZNFPYQE.js");
105
+ throw new VGFError2(res.status, `File upload failed: ${res.statusText}`);
106
+ }
107
+ return download_url;
108
+ }
109
+ };
110
+ var index_default = VGF;
111
+ export {
112
+ VGF,
113
+ VGFError,
114
+ index_default as default
115
+ };
116
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n Job,\n RunParams,\n RunOptions,\n ListJobsParams,\n PagingParams,\n TmpFile,\n} from \"./types.js\";\n\nexport type {\n Job,\n RunParams,\n RunOptions,\n ListJobsParams,\n PagingParams,\n TmpFile,\n};\nexport { VGFError } from \"./error.js\";\n\nconst BASE_URL = \"https://verygoodffmpeg.com/api\";\n\nexport class VGF {\n readonly jobs: Jobs;\n readonly files: Files;\n\n private apiKey: string;\n private baseUrl: string;\n\n constructor(apiKey: string, options?: { baseUrl?: string }) {\n if (!apiKey) throw new Error(\"API key is required\");\n this.apiKey = apiKey;\n this.baseUrl = options?.baseUrl ?? BASE_URL;\n this.jobs = new Jobs(this);\n this.files = new Files(this);\n }\n\n async run(params: RunParams, options: RunOptions = {}): Promise<Job> {\n const qs = options.wait ? \"?wait=true\" : \"\";\n const body = {\n input_files: params.input_files,\n output_files: params.output_files,\n ffmpeg_commands: params.ffmpeg_commands,\n webhook_url: params.webhook_url,\n machine: params.machine,\n };\n const res = await this._request<{ data: Job }>(\n \"POST\",\n `/ffmpeg${qs}`,\n body,\n );\n return res.data;\n }\n\n /** @internal */\n async _request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n // \"Content-Type\": \"application/json\",\n },\n body: body != null ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const { VGFError } = await import(\"./error.js\");\n throw new VGFError(res.status, text);\n }\n\n return res.json() as Promise<T>;\n }\n}\n\nclass Jobs {\n constructor(private client: VGF) {}\n\n async list(\n params: ListJobsParams = {},\n ): Promise<{ data: Job[]; pagingParams: PagingParams }> {\n const qs = new URLSearchParams();\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n const query = qs.size ? `?${qs}` : \"\";\n return this.client._request(\"GET\", `/jobs${query}`);\n }\n\n async get(id: string): Promise<Job> {\n const res = await this.client._request<{ data: Job }>(\n \"GET\",\n `/jobs/${encodeURIComponent(id)}`,\n );\n return res.data;\n }\n\n async cancel(id: string): Promise<Job> {\n const res = await this.client._request<{ data: Job }>(\n \"POST\",\n `/jobs/${encodeURIComponent(id)}/cancel`,\n );\n return res.data;\n }\n}\n\nclass Files {\n constructor(private client: VGF) {}\n\n async prepareUpload(): Promise<TmpFile> {\n const res = await this.client._request<{ data: TmpFile }>(\n \"POST\",\n \"/tmp-file\",\n );\n return res.data;\n }\n\n /**\n * Uploads a file to temporary storage and returns the download URL,\n * which can be used as an input_files value in a job.\n */\n async upload(\n data: Buffer | Blob | ReadableStream | Uint8Array,\n contentType = \"application/octet-stream\",\n ): Promise<string> {\n const { upload_url, download_url } = await this.prepareUpload();\n const res = await fetch(upload_url, {\n method: \"PUT\",\n headers: { \"Content-Type\": contentType },\n body: data as BodyInit,\n });\n if (!res.ok) {\n const { VGFError } = await import(\"./error.js\");\n throw new VGFError(res.status, `File upload failed: ${res.statusText}`);\n }\n return download_url;\n }\n}\n\nexport default VGF;\n"],"mappings":"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","names":["VGFError"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@verygoodffmpeg/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for the Very Good FFmpeg API",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "registry": "https://registry.npmjs.org"
27
+ },
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^25.8.0",
33
+ "dotenv": "^17.4.2",
34
+ "tsup": "^8.5.1",
35
+ "typescript": "^5.4.0",
36
+ "vitest": "^4.1.6"
37
+ },
38
+ "scripts": {
39
+ "build": "tsup",
40
+ "dev": "tsup --watch",
41
+ "test": "vitest run"
42
+ }
43
+ }