hyperclip 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.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # hyperclip
2
+
3
+ Official Node SDK for the [Hyperclip](https://hyperclip.co) API. Trigger flow runs, poll for completion, and pull the final video URL — without writing fetch boilerplate.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install hyperclip
9
+ ```
10
+
11
+ Requires Node 18+ (uses native `fetch`).
12
+
13
+ ## Quickstart
14
+
15
+ ```ts
16
+ import { Hyperclip } from "hyperclip";
17
+
18
+ const hc = new Hyperclip({
19
+ apiKey: process.env.HYPERCLIP_API_KEY,
20
+ baseUrl: "https://YOUR-PROJECT.supabase.co/functions/v1/api-v1",
21
+ });
22
+
23
+ const { id } = await hc.runs.create({
24
+ flow_id: "a3c7f1ea-1234-4abc-bb11-5faed63c7e90",
25
+ inputs: { prompts: { 0: "a lighthouse at dawn" } },
26
+ idempotency_key: crypto.randomUUID(),
27
+ });
28
+
29
+ const run = await hc.runs.wait(id, {
30
+ onUpdate: (r) => console.log(r.status, r.current_step),
31
+ });
32
+
33
+ if (run.status === "completed") {
34
+ console.log("Video:", run.video_url);
35
+ } else {
36
+ console.error(run.error_code, run.error_message);
37
+ }
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ | Option | Env var | Required |
43
+ |---|---|---|
44
+ | `apiKey` | `HYPERCLIP_API_KEY` | yes |
45
+ | `baseUrl` | `HYPERCLIP_BASE_URL` | yes |
46
+ | `fetch` | — | no (defaults to global) |
47
+
48
+ ## API
49
+
50
+ - `hc.runs.create(params)` — `POST /runs`
51
+ - `hc.runs.get(id)` — `GET /runs/:id`
52
+ - `hc.runs.list({ limit?, status? })` — `GET /runs`
53
+ - `hc.runs.cancel(id)` — `POST /runs/:id/cancel`
54
+ - `hc.runs.wait(id, { timeoutMs?, pollIntervalMs?, onUpdate?, signal? })` — polls until terminal
55
+ - `hc.flows.list()` — `GET /flows`
56
+ - `hc.flows.get(id)` — `GET /flows/:id`
57
+
58
+ Errors throw `HyperclipError` with `.status` and `.code`. Timeouts throw `HyperclipTimeoutError`.
@@ -0,0 +1,149 @@
1
+ type RunStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
2
+ interface FlowSchemaNode {
3
+ id: string;
4
+ type: string;
5
+ label: string;
6
+ position: {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ config: Record<string, unknown>;
11
+ }
12
+ interface FlowSchemaEdge {
13
+ id: string;
14
+ source: string;
15
+ sourceHandle: string;
16
+ target: string;
17
+ targetHandle: string;
18
+ }
19
+ interface FlowSchema {
20
+ version: 1;
21
+ metadata?: {
22
+ title?: string;
23
+ category?: string;
24
+ description?: string;
25
+ };
26
+ nodes: FlowSchemaNode[];
27
+ edges: FlowSchemaEdge[];
28
+ }
29
+ interface MediaInput {
30
+ url: string;
31
+ type: "image" | "video" | "audio";
32
+ }
33
+ interface RunInputs {
34
+ prompts?: Record<number, string>;
35
+ media?: Record<number, MediaInput>;
36
+ model_overrides?: Record<number, Record<string, unknown>>;
37
+ }
38
+ interface CreateRunParams {
39
+ flow_id?: string;
40
+ flow_schema?: FlowSchema;
41
+ inputs?: RunInputs;
42
+ idempotency_key?: string;
43
+ }
44
+ interface RunRef {
45
+ id: string;
46
+ status: RunStatus;
47
+ created_at: string;
48
+ }
49
+ interface Run {
50
+ id: string;
51
+ status: RunStatus;
52
+ current_step: number | null;
53
+ video_url: string | null;
54
+ error_code: string | null;
55
+ error_message: string | null;
56
+ credits_charged: number;
57
+ api_markup_multiplier: string;
58
+ created_at: string;
59
+ started_at: string | null;
60
+ completed_at: string | null;
61
+ }
62
+ interface RunListItem {
63
+ id: string;
64
+ status: RunStatus;
65
+ current_step: number | null;
66
+ video_url: string | null;
67
+ error_code: string | null;
68
+ credits_charged: number;
69
+ created_at: string;
70
+ completed_at: string | null;
71
+ }
72
+ interface FlowListItem {
73
+ id: string;
74
+ title: string;
75
+ description: string | null;
76
+ updated_at: string;
77
+ }
78
+ interface FlowDetail {
79
+ id: string;
80
+ title: string;
81
+ description: string | null;
82
+ flow_schema: FlowSchema;
83
+ required_inputs: Array<{
84
+ step_order: number;
85
+ node_type: string;
86
+ field: "prompt" | "media";
87
+ }>;
88
+ }
89
+ interface ListRunsParams {
90
+ limit?: number;
91
+ status?: RunStatus;
92
+ }
93
+ interface WaitOptions {
94
+ /** Total wait timeout in milliseconds. Default: 10 minutes. */
95
+ timeoutMs?: number;
96
+ /** Initial poll interval in milliseconds. Default: 4000. */
97
+ pollIntervalMs?: number;
98
+ /** Called on every poll with the latest run state. */
99
+ onUpdate?: (run: Run) => void;
100
+ /** AbortSignal to cancel the wait early. */
101
+ signal?: AbortSignal;
102
+ }
103
+
104
+ interface HyperclipOptions {
105
+ /** API key (`hck_live_<prefix>.<secret>`). Falls back to `HYPERCLIP_API_KEY`. */
106
+ apiKey?: string;
107
+ /**
108
+ * Full base URL — e.g. `https://your-project.supabase.co/functions/v1/api-v1`.
109
+ * Falls back to `HYPERCLIP_BASE_URL`.
110
+ */
111
+ baseUrl?: string;
112
+ /** Override the global fetch (e.g. for testing). */
113
+ fetch?: typeof fetch;
114
+ }
115
+ declare class Hyperclip {
116
+ private readonly apiKey;
117
+ private readonly baseUrl;
118
+ private readonly fetchImpl;
119
+ constructor(options?: HyperclipOptions);
120
+ readonly runs: {
121
+ create: (params: CreateRunParams) => Promise<RunRef>;
122
+ get: (id: string) => Promise<Run>;
123
+ list: (params?: ListRunsParams) => Promise<RunListItem[]>;
124
+ cancel: (id: string) => Promise<{
125
+ id: string;
126
+ status: "cancelled";
127
+ }>;
128
+ wait: (id: string, options?: WaitOptions) => Promise<Run>;
129
+ };
130
+ readonly flows: {
131
+ list: () => Promise<FlowListItem[]>;
132
+ get: (id: string) => Promise<FlowDetail>;
133
+ };
134
+ private createRun;
135
+ private listRuns;
136
+ private waitForRun;
137
+ private request;
138
+ }
139
+
140
+ declare class HyperclipError extends Error {
141
+ readonly status: number;
142
+ readonly code: string;
143
+ constructor(status: number, code: string, message: string);
144
+ }
145
+ declare class HyperclipTimeoutError extends Error {
146
+ constructor(message?: string);
147
+ }
148
+
149
+ export { type CreateRunParams, type FlowDetail, type FlowListItem, type FlowSchema, type FlowSchemaEdge, type FlowSchemaNode, Hyperclip, HyperclipError, type HyperclipOptions, HyperclipTimeoutError, type ListRunsParams, type MediaInput, type Run, type RunInputs, type RunListItem, type RunRef, type RunStatus, type WaitOptions };
@@ -0,0 +1,149 @@
1
+ type RunStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
2
+ interface FlowSchemaNode {
3
+ id: string;
4
+ type: string;
5
+ label: string;
6
+ position: {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ config: Record<string, unknown>;
11
+ }
12
+ interface FlowSchemaEdge {
13
+ id: string;
14
+ source: string;
15
+ sourceHandle: string;
16
+ target: string;
17
+ targetHandle: string;
18
+ }
19
+ interface FlowSchema {
20
+ version: 1;
21
+ metadata?: {
22
+ title?: string;
23
+ category?: string;
24
+ description?: string;
25
+ };
26
+ nodes: FlowSchemaNode[];
27
+ edges: FlowSchemaEdge[];
28
+ }
29
+ interface MediaInput {
30
+ url: string;
31
+ type: "image" | "video" | "audio";
32
+ }
33
+ interface RunInputs {
34
+ prompts?: Record<number, string>;
35
+ media?: Record<number, MediaInput>;
36
+ model_overrides?: Record<number, Record<string, unknown>>;
37
+ }
38
+ interface CreateRunParams {
39
+ flow_id?: string;
40
+ flow_schema?: FlowSchema;
41
+ inputs?: RunInputs;
42
+ idempotency_key?: string;
43
+ }
44
+ interface RunRef {
45
+ id: string;
46
+ status: RunStatus;
47
+ created_at: string;
48
+ }
49
+ interface Run {
50
+ id: string;
51
+ status: RunStatus;
52
+ current_step: number | null;
53
+ video_url: string | null;
54
+ error_code: string | null;
55
+ error_message: string | null;
56
+ credits_charged: number;
57
+ api_markup_multiplier: string;
58
+ created_at: string;
59
+ started_at: string | null;
60
+ completed_at: string | null;
61
+ }
62
+ interface RunListItem {
63
+ id: string;
64
+ status: RunStatus;
65
+ current_step: number | null;
66
+ video_url: string | null;
67
+ error_code: string | null;
68
+ credits_charged: number;
69
+ created_at: string;
70
+ completed_at: string | null;
71
+ }
72
+ interface FlowListItem {
73
+ id: string;
74
+ title: string;
75
+ description: string | null;
76
+ updated_at: string;
77
+ }
78
+ interface FlowDetail {
79
+ id: string;
80
+ title: string;
81
+ description: string | null;
82
+ flow_schema: FlowSchema;
83
+ required_inputs: Array<{
84
+ step_order: number;
85
+ node_type: string;
86
+ field: "prompt" | "media";
87
+ }>;
88
+ }
89
+ interface ListRunsParams {
90
+ limit?: number;
91
+ status?: RunStatus;
92
+ }
93
+ interface WaitOptions {
94
+ /** Total wait timeout in milliseconds. Default: 10 minutes. */
95
+ timeoutMs?: number;
96
+ /** Initial poll interval in milliseconds. Default: 4000. */
97
+ pollIntervalMs?: number;
98
+ /** Called on every poll with the latest run state. */
99
+ onUpdate?: (run: Run) => void;
100
+ /** AbortSignal to cancel the wait early. */
101
+ signal?: AbortSignal;
102
+ }
103
+
104
+ interface HyperclipOptions {
105
+ /** API key (`hck_live_<prefix>.<secret>`). Falls back to `HYPERCLIP_API_KEY`. */
106
+ apiKey?: string;
107
+ /**
108
+ * Full base URL — e.g. `https://your-project.supabase.co/functions/v1/api-v1`.
109
+ * Falls back to `HYPERCLIP_BASE_URL`.
110
+ */
111
+ baseUrl?: string;
112
+ /** Override the global fetch (e.g. for testing). */
113
+ fetch?: typeof fetch;
114
+ }
115
+ declare class Hyperclip {
116
+ private readonly apiKey;
117
+ private readonly baseUrl;
118
+ private readonly fetchImpl;
119
+ constructor(options?: HyperclipOptions);
120
+ readonly runs: {
121
+ create: (params: CreateRunParams) => Promise<RunRef>;
122
+ get: (id: string) => Promise<Run>;
123
+ list: (params?: ListRunsParams) => Promise<RunListItem[]>;
124
+ cancel: (id: string) => Promise<{
125
+ id: string;
126
+ status: "cancelled";
127
+ }>;
128
+ wait: (id: string, options?: WaitOptions) => Promise<Run>;
129
+ };
130
+ readonly flows: {
131
+ list: () => Promise<FlowListItem[]>;
132
+ get: (id: string) => Promise<FlowDetail>;
133
+ };
134
+ private createRun;
135
+ private listRuns;
136
+ private waitForRun;
137
+ private request;
138
+ }
139
+
140
+ declare class HyperclipError extends Error {
141
+ readonly status: number;
142
+ readonly code: string;
143
+ constructor(status: number, code: string, message: string);
144
+ }
145
+ declare class HyperclipTimeoutError extends Error {
146
+ constructor(message?: string);
147
+ }
148
+
149
+ export { type CreateRunParams, type FlowDetail, type FlowListItem, type FlowSchema, type FlowSchemaEdge, type FlowSchemaNode, Hyperclip, HyperclipError, type HyperclipOptions, HyperclipTimeoutError, type ListRunsParams, type MediaInput, type Run, type RunInputs, type RunListItem, type RunRef, type RunStatus, type WaitOptions };
package/dist/index.js ADDED
@@ -0,0 +1,157 @@
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 __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Hyperclip: () => Hyperclip,
24
+ HyperclipError: () => HyperclipError,
25
+ HyperclipTimeoutError: () => HyperclipTimeoutError
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/errors.ts
30
+ var HyperclipError = class extends Error {
31
+ constructor(status, code, message) {
32
+ super(message);
33
+ this.name = "HyperclipError";
34
+ this.status = status;
35
+ this.code = code;
36
+ }
37
+ };
38
+ var HyperclipTimeoutError = class extends Error {
39
+ constructor(message = "Run polling timed out") {
40
+ super(message);
41
+ this.name = "HyperclipTimeoutError";
42
+ }
43
+ };
44
+
45
+ // src/client.ts
46
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
47
+ var Hyperclip = class {
48
+ constructor(options = {}) {
49
+ this.runs = {
50
+ create: (params) => this.createRun(params),
51
+ get: (id) => this.request("GET", `/runs/${encodeURIComponent(id)}`),
52
+ list: (params = {}) => this.listRuns(params),
53
+ cancel: (id) => this.request("POST", `/runs/${encodeURIComponent(id)}/cancel`),
54
+ wait: (id, options) => this.waitForRun(id, options)
55
+ };
56
+ this.flows = {
57
+ list: async () => {
58
+ const res = await this.request("GET", "/flows");
59
+ return res.flows;
60
+ },
61
+ get: (id) => this.request("GET", `/flows/${encodeURIComponent(id)}`)
62
+ };
63
+ const apiKey = options.apiKey ?? process.env.HYPERCLIP_API_KEY;
64
+ const baseUrl = options.baseUrl ?? process.env.HYPERCLIP_BASE_URL;
65
+ if (!apiKey) {
66
+ throw new Error(
67
+ "Hyperclip: missing apiKey. Pass `apiKey` or set HYPERCLIP_API_KEY."
68
+ );
69
+ }
70
+ if (!baseUrl) {
71
+ throw new Error(
72
+ "Hyperclip: missing baseUrl. Pass `baseUrl` or set HYPERCLIP_BASE_URL (e.g. https://your-project.supabase.co/functions/v1/api-v1)."
73
+ );
74
+ }
75
+ this.apiKey = apiKey;
76
+ this.baseUrl = baseUrl.replace(/\/$/, "");
77
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
78
+ if (!this.fetchImpl) {
79
+ throw new Error("Hyperclip: no fetch implementation available. Use Node 18+ or pass `fetch`.");
80
+ }
81
+ }
82
+ async createRun(params) {
83
+ const headers = {};
84
+ if (params.idempotency_key) headers["Idempotency-Key"] = params.idempotency_key;
85
+ return this.request("POST", "/runs", params, headers);
86
+ }
87
+ async listRuns(params) {
88
+ const qs = new URLSearchParams();
89
+ if (params.limit !== void 0) qs.set("limit", String(params.limit));
90
+ if (params.status) qs.set("status", params.status);
91
+ const path = qs.toString() ? `/runs?${qs}` : "/runs";
92
+ const res = await this.request("GET", path);
93
+ return res.runs;
94
+ }
95
+ async waitForRun(id, options = {}) {
96
+ const { timeoutMs = 10 * 6e4, pollIntervalMs = 4e3, onUpdate, signal } = options;
97
+ const deadline = Date.now() + timeoutMs;
98
+ while (Date.now() < deadline) {
99
+ if (signal?.aborted) throw new HyperclipTimeoutError("Wait aborted");
100
+ const run = await this.runs.get(id);
101
+ onUpdate?.(run);
102
+ if (TERMINAL_STATUSES.has(run.status)) return run;
103
+ await sleep(pollIntervalMs, signal);
104
+ }
105
+ throw new HyperclipTimeoutError();
106
+ }
107
+ async request(method, path, body, extraHeaders = {}) {
108
+ const headers = {
109
+ Authorization: `Bearer ${this.apiKey}`,
110
+ ...extraHeaders
111
+ };
112
+ if (body !== void 0) headers["Content-Type"] = "application/json";
113
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
114
+ method,
115
+ headers,
116
+ body: body !== void 0 ? JSON.stringify(body) : void 0
117
+ });
118
+ const text = await res.text();
119
+ const data = text ? safeJson(text) : void 0;
120
+ if (!res.ok) {
121
+ const err = data?.error;
122
+ throw new HyperclipError(
123
+ res.status,
124
+ err?.code ?? "unknown_error",
125
+ err?.message ?? `HTTP ${res.status}`
126
+ );
127
+ }
128
+ return data;
129
+ }
130
+ };
131
+ function safeJson(text) {
132
+ try {
133
+ return JSON.parse(text);
134
+ } catch {
135
+ return void 0;
136
+ }
137
+ }
138
+ function sleep(ms, signal) {
139
+ return new Promise((resolve, reject) => {
140
+ if (signal?.aborted) return reject(new HyperclipTimeoutError("Wait aborted"));
141
+ const t = setTimeout(() => {
142
+ signal?.removeEventListener("abort", onAbort);
143
+ resolve();
144
+ }, ms);
145
+ const onAbort = () => {
146
+ clearTimeout(t);
147
+ reject(new HyperclipTimeoutError("Wait aborted"));
148
+ };
149
+ signal?.addEventListener("abort", onAbort, { once: true });
150
+ });
151
+ }
152
+ // Annotate the CommonJS export names for ESM import in node:
153
+ 0 && (module.exports = {
154
+ Hyperclip,
155
+ HyperclipError,
156
+ HyperclipTimeoutError
157
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,128 @@
1
+ // src/errors.ts
2
+ var HyperclipError = class extends Error {
3
+ constructor(status, code, message) {
4
+ super(message);
5
+ this.name = "HyperclipError";
6
+ this.status = status;
7
+ this.code = code;
8
+ }
9
+ };
10
+ var HyperclipTimeoutError = class extends Error {
11
+ constructor(message = "Run polling timed out") {
12
+ super(message);
13
+ this.name = "HyperclipTimeoutError";
14
+ }
15
+ };
16
+
17
+ // src/client.ts
18
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
19
+ var Hyperclip = class {
20
+ constructor(options = {}) {
21
+ this.runs = {
22
+ create: (params) => this.createRun(params),
23
+ get: (id) => this.request("GET", `/runs/${encodeURIComponent(id)}`),
24
+ list: (params = {}) => this.listRuns(params),
25
+ cancel: (id) => this.request("POST", `/runs/${encodeURIComponent(id)}/cancel`),
26
+ wait: (id, options) => this.waitForRun(id, options)
27
+ };
28
+ this.flows = {
29
+ list: async () => {
30
+ const res = await this.request("GET", "/flows");
31
+ return res.flows;
32
+ },
33
+ get: (id) => this.request("GET", `/flows/${encodeURIComponent(id)}`)
34
+ };
35
+ const apiKey = options.apiKey ?? process.env.HYPERCLIP_API_KEY;
36
+ const baseUrl = options.baseUrl ?? process.env.HYPERCLIP_BASE_URL;
37
+ if (!apiKey) {
38
+ throw new Error(
39
+ "Hyperclip: missing apiKey. Pass `apiKey` or set HYPERCLIP_API_KEY."
40
+ );
41
+ }
42
+ if (!baseUrl) {
43
+ throw new Error(
44
+ "Hyperclip: missing baseUrl. Pass `baseUrl` or set HYPERCLIP_BASE_URL (e.g. https://your-project.supabase.co/functions/v1/api-v1)."
45
+ );
46
+ }
47
+ this.apiKey = apiKey;
48
+ this.baseUrl = baseUrl.replace(/\/$/, "");
49
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
50
+ if (!this.fetchImpl) {
51
+ throw new Error("Hyperclip: no fetch implementation available. Use Node 18+ or pass `fetch`.");
52
+ }
53
+ }
54
+ async createRun(params) {
55
+ const headers = {};
56
+ if (params.idempotency_key) headers["Idempotency-Key"] = params.idempotency_key;
57
+ return this.request("POST", "/runs", params, headers);
58
+ }
59
+ async listRuns(params) {
60
+ const qs = new URLSearchParams();
61
+ if (params.limit !== void 0) qs.set("limit", String(params.limit));
62
+ if (params.status) qs.set("status", params.status);
63
+ const path = qs.toString() ? `/runs?${qs}` : "/runs";
64
+ const res = await this.request("GET", path);
65
+ return res.runs;
66
+ }
67
+ async waitForRun(id, options = {}) {
68
+ const { timeoutMs = 10 * 6e4, pollIntervalMs = 4e3, onUpdate, signal } = options;
69
+ const deadline = Date.now() + timeoutMs;
70
+ while (Date.now() < deadline) {
71
+ if (signal?.aborted) throw new HyperclipTimeoutError("Wait aborted");
72
+ const run = await this.runs.get(id);
73
+ onUpdate?.(run);
74
+ if (TERMINAL_STATUSES.has(run.status)) return run;
75
+ await sleep(pollIntervalMs, signal);
76
+ }
77
+ throw new HyperclipTimeoutError();
78
+ }
79
+ async request(method, path, body, extraHeaders = {}) {
80
+ const headers = {
81
+ Authorization: `Bearer ${this.apiKey}`,
82
+ ...extraHeaders
83
+ };
84
+ if (body !== void 0) headers["Content-Type"] = "application/json";
85
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
86
+ method,
87
+ headers,
88
+ body: body !== void 0 ? JSON.stringify(body) : void 0
89
+ });
90
+ const text = await res.text();
91
+ const data = text ? safeJson(text) : void 0;
92
+ if (!res.ok) {
93
+ const err = data?.error;
94
+ throw new HyperclipError(
95
+ res.status,
96
+ err?.code ?? "unknown_error",
97
+ err?.message ?? `HTTP ${res.status}`
98
+ );
99
+ }
100
+ return data;
101
+ }
102
+ };
103
+ function safeJson(text) {
104
+ try {
105
+ return JSON.parse(text);
106
+ } catch {
107
+ return void 0;
108
+ }
109
+ }
110
+ function sleep(ms, signal) {
111
+ return new Promise((resolve, reject) => {
112
+ if (signal?.aborted) return reject(new HyperclipTimeoutError("Wait aborted"));
113
+ const t = setTimeout(() => {
114
+ signal?.removeEventListener("abort", onAbort);
115
+ resolve();
116
+ }, ms);
117
+ const onAbort = () => {
118
+ clearTimeout(t);
119
+ reject(new HyperclipTimeoutError("Wait aborted"));
120
+ };
121
+ signal?.addEventListener("abort", onAbort, { once: true });
122
+ });
123
+ }
124
+ export {
125
+ Hyperclip,
126
+ HyperclipError,
127
+ HyperclipTimeoutError
128
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "hyperclip",
3
+ "version": "0.1.0",
4
+ "description": "Official Node SDK for the Hyperclip API — create, poll, and manage flow runs.",
5
+ "license": "MIT",
6
+ "homepage": "https://hyperclip.co",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/hyperclip/hyperclip-sdks.git",
10
+ "directory": "node"
11
+ },
12
+ "bugs": "https://github.com/hyperclip/hyperclip-sdks/issues",
13
+ "keywords": [
14
+ "hyperclip",
15
+ "video",
16
+ "ai-video",
17
+ "sdk",
18
+ "api"
19
+ ],
20
+ "main": "./dist/index.cjs",
21
+ "module": "./dist/index.mjs",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.mjs",
27
+ "require": "./dist/index.cjs"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "scripts": {
39
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
40
+ "lint": "tsc --noEmit",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "devDependencies": {
44
+ "tsup": "^8.0.0",
45
+ "typescript": "^5.4.0"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ }
50
+ }