@subscribe.dev/client
Version:
JavaScript/TypeScript client for SubscribeDev API - A drop-in for AI generation across 100+ models with built-in billing and rate limiting
1,361 lines (1,360 loc) • 54.9 kB
JavaScript
import A from "p-queue";
function C(S) {
return S && S.__esModule && Object.prototype.hasOwnProperty.call(S, "default") ? S.default : S;
}
var T = { exports: {} }, O;
function P() {
return O || (O = 1, (function(S) {
var e = Object.prototype.hasOwnProperty, t = "~";
function i() {
}
Object.create && (i.prototype = /* @__PURE__ */ Object.create(null), new i().__proto__ || (t = !1));
function r(d, u, a) {
this.fn = d, this.context = u, this.once = a || !1;
}
function p(d, u, a, n, m) {
if (typeof a != "function")
throw new TypeError("The listener must be a function");
var c = new r(a, n || d, m), s = t ? t + u : u;
return d._events[s] ? d._events[s].fn ? d._events[s] = [d._events[s], c] : d._events[s].push(c) : (d._events[s] = c, d._eventsCount++), d;
}
function h(d, u) {
--d._eventsCount === 0 ? d._events = new i() : delete d._events[u];
}
function f() {
this._events = new i(), this._eventsCount = 0;
}
f.prototype.eventNames = function() {
var u = [], a, n;
if (this._eventsCount === 0) return u;
for (n in a = this._events)
e.call(a, n) && u.push(t ? n.slice(1) : n);
return Object.getOwnPropertySymbols ? u.concat(Object.getOwnPropertySymbols(a)) : u;
}, f.prototype.listeners = function(u) {
var a = t ? t + u : u, n = this._events[a];
if (!n) return [];
if (n.fn) return [n.fn];
for (var m = 0, c = n.length, s = new Array(c); m < c; m++)
s[m] = n[m].fn;
return s;
}, f.prototype.listenerCount = function(u) {
var a = t ? t + u : u, n = this._events[a];
return n ? n.fn ? 1 : n.length : 0;
}, f.prototype.emit = function(u, a, n, m, c, s) {
var l = t ? t + u : u;
if (!this._events[l]) return !1;
var o = this._events[l], b = arguments.length, y, g;
if (o.fn) {
switch (o.once && this.removeListener(u, o.fn, void 0, !0), b) {
case 1:
return o.fn.call(o.context), !0;
case 2:
return o.fn.call(o.context, a), !0;
case 3:
return o.fn.call(o.context, a, n), !0;
case 4:
return o.fn.call(o.context, a, n, m), !0;
case 5:
return o.fn.call(o.context, a, n, m, c), !0;
case 6:
return o.fn.call(o.context, a, n, m, c, s), !0;
}
for (g = 1, y = new Array(b - 1); g < b; g++)
y[g - 1] = arguments[g];
o.fn.apply(o.context, y);
} else {
var v = o.length, E;
for (g = 0; g < v; g++)
switch (o[g].once && this.removeListener(u, o[g].fn, void 0, !0), b) {
case 1:
o[g].fn.call(o[g].context);
break;
case 2:
o[g].fn.call(o[g].context, a);
break;
case 3:
o[g].fn.call(o[g].context, a, n);
break;
case 4:
o[g].fn.call(o[g].context, a, n, m);
break;
default:
if (!y) for (E = 1, y = new Array(b - 1); E < b; E++)
y[E - 1] = arguments[E];
o[g].fn.apply(o[g].context, y);
}
}
return !0;
}, f.prototype.on = function(u, a, n) {
return p(this, u, a, n, !1);
}, f.prototype.once = function(u, a, n) {
return p(this, u, a, n, !0);
}, f.prototype.removeListener = function(u, a, n, m) {
var c = t ? t + u : u;
if (!this._events[c]) return this;
if (!a)
return h(this, c), this;
var s = this._events[c];
if (s.fn)
s.fn === a && (!m || s.once) && (!n || s.context === n) && h(this, c);
else {
for (var l = 0, o = [], b = s.length; l < b; l++)
(s[l].fn !== a || m && !s[l].once || n && s[l].context !== n) && o.push(s[l]);
o.length ? this._events[c] = o.length === 1 ? o[0] : o : h(this, c);
}
return this;
}, f.prototype.removeAllListeners = function(u) {
var a;
return u ? (a = t ? t + u : u, this._events[a] && h(this, a)) : (this._events = new i(), this._eventsCount = 0), this;
}, f.prototype.off = f.prototype.removeListener, f.prototype.addListener = f.prototype.on, f.prefixed = t, f.EventEmitter = f, S.exports = f;
})(T)), T.exports;
}
var j = P();
const R = /* @__PURE__ */ C(j);
class _ extends Error {
constructor(e, t, i, r, p) {
super(e), this.name = "SubscribeDevError", this.code = t, this.statusCode = i, this.details = r, this.requestId = p;
}
}
class q extends _ {
constructor(e, t, i, r) {
super(e, "INSUFFICIENT_BALANCE", 402, {
remainingCredits: t,
requiredCredits: i
}, r), this.name = "InsufficientBalanceError";
}
}
class L extends _ {
constructor(e, t, i, r) {
super(e, "RATE_LIMIT_EXCEEDED", 429, {
resetTime: t,
retryAfter: i
}, r), this.name = "RateLimitError", this.resetTime = t, this.retryAfter = i;
}
}
class $ extends _ {
constructor(e, t) {
super(e, "AUTHENTICATION_FAILED", 401, void 0, t), this.name = "AuthenticationError";
}
}
class B extends _ {
constructor(e, t) {
super(e, "ACCESS_DENIED", 403, void 0, t), this.name = "AccessDeniedError";
}
}
class G extends _ {
constructor(e, t) {
super(e, "NOT_FOUND", 404, void 0, t), this.name = "NotFoundError";
}
}
class k extends _ {
constructor(e, t, i) {
super(e, "VALIDATION_ERROR", 400, t, i), this.name = "ValidationError";
}
}
class M extends _ {
constructor(e, t) {
super(e, "USER_UNSUBSCRIBED", 402, void 0, t), this.name = "UnsubscribedError";
}
}
class z extends _ {
constructor(e, t, i, r, p, h) {
super(e, "PLAN_UPGRADE_REQUIRED", 402, {
upgradeUrl: t,
currentPlan: i,
currentLimit: r,
required: p
}, h), this.name = "PlanUpgradeRequiredError", this.upgradeUrl = t, this.currentPlan = i, this.currentLimit = r, this.required = p;
}
}
class J extends _ {
constructor(e, t) {
super(e, "WORKFLOW_UNAVAILABLE", 503, void 0, t), this.name = "WorkflowUnavailableError";
}
}
function K(S) {
const e = Object.values(S).filter((i) => typeof i == "number");
return Object.entries(S).filter(([i, r]) => e.indexOf(+i) === -1).map(([i, r]) => r);
}
class U {
constructor() {
this._map = /* @__PURE__ */ new WeakMap(), this._idmap = /* @__PURE__ */ new Map();
}
add(e, ...t) {
const i = t[0];
if (this._map.set(e, i), i && typeof i == "object" && "id" in i) {
if (this._idmap.has(i.id))
throw new Error(`ID ${i.id} already exists in the registry`);
this._idmap.set(i.id, e);
}
return this;
}
clear() {
return this._map = /* @__PURE__ */ new WeakMap(), this._idmap = /* @__PURE__ */ new Map(), this;
}
remove(e) {
const t = this._map.get(e);
return t && typeof t == "object" && "id" in t && this._idmap.delete(t.id), this._map.delete(e), this;
}
get(e) {
const t = e._zod.parent;
if (t) {
const i = { ...this.get(t) ?? {} };
delete i.id;
const r = { ...i, ...this._map.get(e) };
return Object.keys(r).length ? r : void 0;
}
return this._map.get(e);
}
has(e) {
return this._map.has(e);
}
}
function V() {
return new U();
}
const F = /* @__PURE__ */ V();
class I {
constructor(e) {
this.counter = 0, this.metadataRegistry = e?.metadata ?? F, this.target = e?.target ?? "draft-2020-12", this.unrepresentable = e?.unrepresentable ?? "throw", this.override = e?.override ?? (() => {
}), this.io = e?.io ?? "output", this.seen = /* @__PURE__ */ new Map();
}
process(e, t = { path: [], schemaPath: [] }) {
var i;
const r = e._zod.def, p = {
guid: "uuid",
url: "uri",
datetime: "date-time",
json_string: "json-string",
regex: ""
// do not set
}, h = this.seen.get(e);
if (h)
return h.count++, t.schemaPath.includes(e) && (h.cycle = t.path), h.schema;
const f = { schema: {}, count: 1, cycle: void 0, path: t.path };
this.seen.set(e, f);
const d = e._zod.toJSONSchema?.();
if (d)
f.schema = d;
else {
const n = {
...t,
schemaPath: [...t.schemaPath, e],
path: t.path
}, m = e._zod.parent;
if (m)
f.ref = m, this.process(m, n), this.seen.get(m).isParent = !0;
else {
const c = f.schema;
switch (r.type) {
case "string": {
const s = c;
s.type = "string";
const { minimum: l, maximum: o, format: b, patterns: y, contentEncoding: g } = e._zod.bag;
if (typeof l == "number" && (s.minLength = l), typeof o == "number" && (s.maxLength = o), b && (s.format = p[b] ?? b, s.format === "" && delete s.format), g && (s.contentEncoding = g), y && y.size > 0) {
const v = [...y];
v.length === 1 ? s.pattern = v[0].source : v.length > 1 && (f.schema.allOf = [
...v.map((E) => ({
...this.target === "draft-7" || this.target === "draft-4" || this.target === "openapi-3.0" ? { type: "string" } : {},
pattern: E.source
}))
]);
}
break;
}
case "number": {
const s = c, { minimum: l, maximum: o, format: b, multipleOf: y, exclusiveMaximum: g, exclusiveMinimum: v } = e._zod.bag;
typeof b == "string" && b.includes("int") ? s.type = "integer" : s.type = "number", typeof v == "number" && (this.target === "draft-4" || this.target === "openapi-3.0" ? (s.minimum = v, s.exclusiveMinimum = !0) : s.exclusiveMinimum = v), typeof l == "number" && (s.minimum = l, typeof v == "number" && this.target !== "draft-4" && (v >= l ? delete s.minimum : delete s.exclusiveMinimum)), typeof g == "number" && (this.target === "draft-4" || this.target === "openapi-3.0" ? (s.maximum = g, s.exclusiveMaximum = !0) : s.exclusiveMaximum = g), typeof o == "number" && (s.maximum = o, typeof g == "number" && this.target !== "draft-4" && (g <= o ? delete s.maximum : delete s.exclusiveMaximum)), typeof y == "number" && (s.multipleOf = y);
break;
}
case "boolean": {
const s = c;
s.type = "boolean";
break;
}
case "bigint": {
if (this.unrepresentable === "throw")
throw new Error("BigInt cannot be represented in JSON Schema");
break;
}
case "symbol": {
if (this.unrepresentable === "throw")
throw new Error("Symbols cannot be represented in JSON Schema");
break;
}
case "null": {
this.target === "openapi-3.0" ? (c.type = "string", c.nullable = !0, c.enum = [null]) : c.type = "null";
break;
}
case "any":
break;
case "unknown":
break;
case "undefined": {
if (this.unrepresentable === "throw")
throw new Error("Undefined cannot be represented in JSON Schema");
break;
}
case "void": {
if (this.unrepresentable === "throw")
throw new Error("Void cannot be represented in JSON Schema");
break;
}
case "never": {
c.not = {};
break;
}
case "date": {
if (this.unrepresentable === "throw")
throw new Error("Date cannot be represented in JSON Schema");
break;
}
case "array": {
const s = c, { minimum: l, maximum: o } = e._zod.bag;
typeof l == "number" && (s.minItems = l), typeof o == "number" && (s.maxItems = o), s.type = "array", s.items = this.process(r.element, { ...n, path: [...n.path, "items"] });
break;
}
case "object": {
const s = c;
s.type = "object", s.properties = {};
const l = r.shape;
for (const y in l)
s.properties[y] = this.process(l[y], {
...n,
path: [...n.path, "properties", y]
});
const o = new Set(Object.keys(l)), b = new Set([...o].filter((y) => {
const g = r.shape[y]._zod;
return this.io === "input" ? g.optin === void 0 : g.optout === void 0;
}));
b.size > 0 && (s.required = Array.from(b)), r.catchall?._zod.def.type === "never" ? s.additionalProperties = !1 : r.catchall ? r.catchall && (s.additionalProperties = this.process(r.catchall, {
...n,
path: [...n.path, "additionalProperties"]
})) : this.io === "output" && (s.additionalProperties = !1);
break;
}
case "union": {
const s = c, l = r.options.map((o, b) => this.process(o, {
...n,
path: [...n.path, "anyOf", b]
}));
s.anyOf = l;
break;
}
case "intersection": {
const s = c, l = this.process(r.left, {
...n,
path: [...n.path, "allOf", 0]
}), o = this.process(r.right, {
...n,
path: [...n.path, "allOf", 1]
}), b = (g) => "allOf" in g && Object.keys(g).length === 1, y = [
...b(l) ? l.allOf : [l],
...b(o) ? o.allOf : [o]
];
s.allOf = y;
break;
}
case "tuple": {
const s = c;
s.type = "array";
const l = this.target === "draft-2020-12" ? "prefixItems" : "items", o = this.target === "draft-2020-12" || this.target === "openapi-3.0" ? "items" : "additionalItems", b = r.items.map((E, D) => this.process(E, {
...n,
path: [...n.path, l, D]
})), y = r.rest ? this.process(r.rest, {
...n,
path: [...n.path, o, ...this.target === "openapi-3.0" ? [r.items.length] : []]
}) : null;
this.target === "draft-2020-12" ? (s.prefixItems = b, y && (s.items = y)) : this.target === "openapi-3.0" ? (s.items = {
anyOf: b
}, y && s.items.anyOf.push(y), s.minItems = b.length, y || (s.maxItems = b.length)) : (s.items = b, y && (s.additionalItems = y));
const { minimum: g, maximum: v } = e._zod.bag;
typeof g == "number" && (s.minItems = g), typeof v == "number" && (s.maxItems = v);
break;
}
case "record": {
const s = c;
s.type = "object", (this.target === "draft-7" || this.target === "draft-2020-12") && (s.propertyNames = this.process(r.keyType, {
...n,
path: [...n.path, "propertyNames"]
})), s.additionalProperties = this.process(r.valueType, {
...n,
path: [...n.path, "additionalProperties"]
});
break;
}
case "map": {
if (this.unrepresentable === "throw")
throw new Error("Map cannot be represented in JSON Schema");
break;
}
case "set": {
if (this.unrepresentable === "throw")
throw new Error("Set cannot be represented in JSON Schema");
break;
}
case "enum": {
const s = c, l = K(r.entries);
l.every((o) => typeof o == "number") && (s.type = "number"), l.every((o) => typeof o == "string") && (s.type = "string"), s.enum = l;
break;
}
case "literal": {
const s = c, l = [];
for (const o of r.values)
if (o === void 0) {
if (this.unrepresentable === "throw")
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
} else if (typeof o == "bigint") {
if (this.unrepresentable === "throw")
throw new Error("BigInt literals cannot be represented in JSON Schema");
l.push(Number(o));
} else
l.push(o);
if (l.length !== 0) if (l.length === 1) {
const o = l[0];
s.type = o === null ? "null" : typeof o, this.target === "draft-4" || this.target === "openapi-3.0" ? s.enum = [o] : s.const = o;
} else
l.every((o) => typeof o == "number") && (s.type = "number"), l.every((o) => typeof o == "string") && (s.type = "string"), l.every((o) => typeof o == "boolean") && (s.type = "string"), l.every((o) => o === null) && (s.type = "null"), s.enum = l;
break;
}
case "file": {
const s = c, l = {
type: "string",
format: "binary",
contentEncoding: "binary"
}, { minimum: o, maximum: b, mime: y } = e._zod.bag;
o !== void 0 && (l.minLength = o), b !== void 0 && (l.maxLength = b), y ? y.length === 1 ? (l.contentMediaType = y[0], Object.assign(s, l)) : s.anyOf = y.map((g) => ({ ...l, contentMediaType: g })) : Object.assign(s, l);
break;
}
case "transform": {
if (this.unrepresentable === "throw")
throw new Error("Transforms cannot be represented in JSON Schema");
break;
}
case "nullable": {
const s = this.process(r.innerType, n);
this.target === "openapi-3.0" ? (f.ref = r.innerType, c.nullable = !0) : c.anyOf = [s, { type: "null" }];
break;
}
case "nonoptional": {
this.process(r.innerType, n), f.ref = r.innerType;
break;
}
case "success": {
const s = c;
s.type = "boolean";
break;
}
case "default": {
this.process(r.innerType, n), f.ref = r.innerType, c.default = JSON.parse(JSON.stringify(r.defaultValue));
break;
}
case "prefault": {
this.process(r.innerType, n), f.ref = r.innerType, this.io === "input" && (c._prefault = JSON.parse(JSON.stringify(r.defaultValue)));
break;
}
case "catch": {
this.process(r.innerType, n), f.ref = r.innerType;
let s;
try {
s = r.catchValue(void 0);
} catch {
throw new Error("Dynamic catch values are not supported in JSON Schema");
}
c.default = s;
break;
}
case "nan": {
if (this.unrepresentable === "throw")
throw new Error("NaN cannot be represented in JSON Schema");
break;
}
case "template_literal": {
const s = c, l = e._zod.pattern;
if (!l)
throw new Error("Pattern not found in template literal");
s.type = "string", s.pattern = l.source;
break;
}
case "pipe": {
const s = this.io === "input" ? r.in._zod.def.type === "transform" ? r.out : r.in : r.out;
this.process(s, n), f.ref = s;
break;
}
case "readonly": {
this.process(r.innerType, n), f.ref = r.innerType, c.readOnly = !0;
break;
}
// passthrough types
case "promise": {
this.process(r.innerType, n), f.ref = r.innerType;
break;
}
case "optional": {
this.process(r.innerType, n), f.ref = r.innerType;
break;
}
case "lazy": {
const s = e._zod.innerType;
this.process(s, n), f.ref = s;
break;
}
case "custom": {
if (this.unrepresentable === "throw")
throw new Error("Custom types cannot be represented in JSON Schema");
break;
}
case "function": {
if (this.unrepresentable === "throw")
throw new Error("Function types cannot be represented in JSON Schema");
break;
}
}
}
}
const u = this.metadataRegistry.get(e);
return u && Object.assign(f.schema, u), this.io === "input" && w(e) && (delete f.schema.examples, delete f.schema.default), this.io === "input" && f.schema._prefault && ((i = f.schema).default ?? (i.default = f.schema._prefault)), delete f.schema._prefault, this.seen.get(e).schema;
}
emit(e, t) {
const i = {
cycles: t?.cycles ?? "ref",
reused: t?.reused ?? "inline",
// unrepresentable: _params?.unrepresentable ?? "throw",
// uri: _params?.uri ?? ((id) => `${id}`),
external: t?.external ?? void 0
}, r = this.seen.get(e);
if (!r)
throw new Error("Unprocessed schema. This is a bug in Zod.");
const p = (a) => {
const n = this.target === "draft-2020-12" ? "$defs" : "definitions";
if (i.external) {
const l = i.external.registry.get(a[0])?.id, o = i.external.uri ?? ((y) => y);
if (l)
return { ref: o(l) };
const b = a[1].defId ?? a[1].schema.id ?? `schema${this.counter++}`;
return a[1].defId = b, { defId: b, ref: `${o("__shared")}#/${n}/${b}` };
}
if (a[1] === r)
return { ref: "#" };
const c = `#/${n}/`, s = a[1].schema.id ?? `__schema${this.counter++}`;
return { defId: s, ref: c + s };
}, h = (a) => {
if (a[1].schema.$ref)
return;
const n = a[1], { ref: m, defId: c } = p(a);
n.def = { ...n.schema }, c && (n.defId = c);
const s = n.schema;
for (const l in s)
delete s[l];
s.$ref = m;
};
if (i.cycles === "throw")
for (const a of this.seen.entries()) {
const n = a[1];
if (n.cycle)
throw new Error(`Cycle detected: #/${n.cycle?.join("/")}/<root>
Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`);
}
for (const a of this.seen.entries()) {
const n = a[1];
if (e === a[0]) {
h(a);
continue;
}
if (i.external) {
const c = i.external.registry.get(a[0])?.id;
if (e !== a[0] && c) {
h(a);
continue;
}
}
if (this.metadataRegistry.get(a[0])?.id) {
h(a);
continue;
}
if (n.cycle) {
h(a);
continue;
}
if (n.count > 1 && i.reused === "ref") {
h(a);
continue;
}
}
const f = (a, n) => {
const m = this.seen.get(a), c = m.def ?? m.schema, s = { ...c };
if (m.ref === null)
return;
const l = m.ref;
if (m.ref = null, l) {
f(l, n);
const o = this.seen.get(l).schema;
o.$ref && (n.target === "draft-7" || n.target === "draft-4" || n.target === "openapi-3.0") ? (c.allOf = c.allOf ?? [], c.allOf.push(o)) : (Object.assign(c, o), Object.assign(c, s));
}
m.isParent || this.override({
zodSchema: a,
jsonSchema: c,
path: m.path ?? []
});
};
for (const a of [...this.seen.entries()].reverse())
f(a[0], { target: this.target });
const d = {};
if (this.target === "draft-2020-12" ? d.$schema = "https://json-schema.org/draft/2020-12/schema" : this.target === "draft-7" ? d.$schema = "http://json-schema.org/draft-07/schema#" : this.target === "draft-4" ? d.$schema = "http://json-schema.org/draft-04/schema#" : this.target === "openapi-3.0" || console.warn(`Invalid target: ${this.target}`), i.external?.uri) {
const a = i.external.registry.get(e)?.id;
if (!a)
throw new Error("Schema is missing an `id` property");
d.$id = i.external.uri(a);
}
Object.assign(d, r.def);
const u = i.external?.defs ?? {};
for (const a of this.seen.entries()) {
const n = a[1];
n.def && n.defId && (u[n.defId] = n.def);
}
i.external || Object.keys(u).length > 0 && (this.target === "draft-2020-12" ? d.$defs = u : d.definitions = u);
try {
return JSON.parse(JSON.stringify(d));
} catch {
throw new Error("Error converting schema to JSON.");
}
}
}
function W(S, e) {
if (S instanceof U) {
const i = new I(e), r = {};
for (const f of S._idmap.entries()) {
const [d, u] = f;
i.process(u);
}
const p = {}, h = {
registry: S,
uri: e?.uri,
defs: r
};
for (const f of S._idmap.entries()) {
const [d, u] = f;
p[d] = i.emit(u, {
...e,
external: h
});
}
if (Object.keys(r).length > 0) {
const f = i.target === "draft-2020-12" ? "$defs" : "definitions";
p.__shared = {
[f]: r
};
}
return { schemas: p };
}
const t = new I(e);
return t.process(S), t.emit(S, e);
}
function w(S, e) {
const t = e ?? { seen: /* @__PURE__ */ new Set() };
if (t.seen.has(S))
return !1;
t.seen.add(S);
const r = S._zod.def;
switch (r.type) {
case "string":
case "number":
case "bigint":
case "boolean":
case "date":
case "symbol":
case "undefined":
case "null":
case "any":
case "unknown":
case "never":
case "void":
case "literal":
case "enum":
case "nan":
case "file":
case "template_literal":
return !1;
case "array":
return w(r.element, t);
case "object": {
for (const p in r.shape)
if (w(r.shape[p], t))
return !0;
return !1;
}
case "union": {
for (const p of r.options)
if (w(p, t))
return !0;
return !1;
}
case "intersection":
return w(r.left, t) || w(r.right, t);
case "tuple": {
for (const p of r.items)
if (w(p, t))
return !0;
return !!(r.rest && w(r.rest, t));
}
case "record":
return w(r.keyType, t) || w(r.valueType, t);
case "map":
return w(r.keyType, t) || w(r.valueType, t);
case "set":
return w(r.valueType, t);
// inner types
case "promise":
case "optional":
case "nonoptional":
case "nullable":
case "readonly":
return w(r.innerType, t);
case "lazy":
return w(r.getter(), t);
case "default":
return w(r.innerType, t);
case "prefault":
return w(r.innerType, t);
case "custom":
return !1;
case "transform":
return !0;
case "pipe":
return w(r.in, t) || w(r.out, t);
case "success":
return !1;
case "catch":
return !1;
case "function":
return !1;
}
throw new Error(`Unknown schema type: ${r.type}`);
}
class x extends R {
constructor(e) {
super(), this._isConsumed = !1, this._accumulatedResult = null, this._promiseResolver = null, this._promiseRejecter = null, this._consumePromise = null, this.sourceIterable = e;
}
/**
* Async iterator implementation - supports `for await...of` loops
*/
async *[Symbol.asyncIterator]() {
if (this._isConsumed)
throw new Error("StreamableResponse can only be consumed once. Use .clone() to consume multiple times.");
this._isConsumed = !0;
try {
for await (const e of this.sourceIterable)
this._accumulatedResult = e, this.emit("data", e), yield e;
this.emit("end"), this._promiseResolver && this._accumulatedResult !== null && this._promiseResolver(this._accumulatedResult);
} catch (e) {
const t = e instanceof Error ? e : new Error(String(e));
throw this.emit("error", t), this._promiseRejecter && this._promiseRejecter(t), t;
}
}
/**
* Promise implementation - enables `await response` to get final result
*/
then(e, t) {
return this._consumePromise || (this._consumePromise = new Promise((i, r) => {
this._promiseResolver = i, this._promiseRejecter = r, this._isConsumed || this._consumeInBackground();
})), this._consumePromise.then(e, t);
}
/**
* Promise catch implementation
*/
catch(e) {
return this.then(void 0, e);
}
/**
* Promise finally implementation
*/
finally(e) {
return this.then(
(t) => (e?.(), t),
(t) => {
throw e?.(), t;
}
);
}
on(e, t) {
return e === "data" && !this._isConsumed && !this._consumePromise && this._consumeInBackground(), super.on(e, t);
}
once(e, t) {
return e === "data" && !this._isConsumed && !this._consumePromise && this._consumeInBackground(), super.once(e, t);
}
/**
* Start consuming the stream in the background for event listeners and promise resolution
*/
async _consumeInBackground() {
try {
for await (const e of this)
;
} catch {
}
}
/**
* Clone the streamable response to allow multiple consumption patterns
* Note: This requires the underlying source to be re-iterable or cloneable
*/
clone() {
if (this._isConsumed)
throw new Error("Cannot clone a StreamableResponse that has already been consumed");
return new x(this.sourceIterable);
}
/**
* Check if the stream has been consumed
*/
get isConsumed() {
return this._isConsumed;
}
}
function Z() {
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
class N extends R {
constructor(e) {
super(), this.__LOCAL_CLIENT_WITH_EVENTS__ = !0;
const t = e.baseUrl || "https://api.subscribe.dev";
if (this._config = {
baseUrl: t,
authorizationUrl: e.authorizationUrl || t.replace("api", "auth"),
timeout: e.timeout || 6e5,
// 10 minutes
maxRetries: e.maxRetries || 2,
debug: e.debug || !1,
...e
}, this.queue = new A({
concurrency: 10,
// Max concurrent requests
interval: 6e4,
// 1 minute
intervalCap: 60
// Max requests per minute
}), this.fetch = globalThis.fetch?.bind(globalThis), !this.fetch)
throw new Error("fetch is not available. Please provide a fetch polyfill.");
this.debug("SubscribeDevClient initialized", { baseUrl: this._config.baseUrl });
}
get config() {
return this._config;
}
get pricingUrl() {
return `${this._config.baseUrl}/subscribe`;
}
get authorizationUrl() {
return !this._config.accessToken && !this._config.apiKey ? `${this._config.authorizationUrl}/demo` : this._config.authorizationUrl;
}
/**
* Run a prediction
* Note: Now returns completed predictions directly - no polling needed
*
* @param model - The model to use for the prediction
* @param options - Configuration options for the prediction
* @param options.input - Input data (can contain prompt OR messages array with multimodal content)
* @param options.response_format - Optional response format specification. Supports:
* - `{ type: 'json_object' }` - Returns a JSON object
* - `{ type: 'json_schema', json_schema: { name: string, schema: object } }` - Returns JSON matching the schema
* - `MyZodSchema` - Pass a Zod schema directly for automatic JSON schema conversion
* @param options.wait - For compatibility - ignored since predictions complete synchronously
* @returns Promise resolving to the prediction result
*
* @example
* ```typescript
* // Basic usage with JSON object response
* const result = await client.run('gpt-4', {
* input: { prompt: 'Hello world' },
* response_format: { type: 'json_object' }
* });
*
* // Using Zod schema directly
* import { z } from 'zod';
* const UserSchema = z.object({
* name: z.string(),
* age: z.number()
* });
*
* const result = await client.run('gpt-4', {
* input: { prompt: 'Generate a user' },
* response_format: UserSchema
* });
* ```
*/
run(e, t, i) {
const { input: r, response_format: p, stream: h } = t, f = i?.streamBy || "chunk", d = Z(), u = Date.now();
this.emit("ai-call-start", {
type: "ai-call-start",
timestamp: u,
requestId: d,
model: e,
input: r,
responseFormat: p,
isStreaming: !!h
}), console.log("[SubscribeDevClient] STREAMING DEBUG - Starting prediction", {
model: e,
input: typeof r,
response_format: p,
stream: h,
streamFromOptions: t.stream,
streamTruthy: !!h,
streamType: typeof h,
optionsKeys: Object.keys(t)
}), console.log("[SubscribeDevClient] STREAMING DEBUG - Stream parameter check", {
stream: h,
streamFromOptions: t.stream,
streamTruthy: !!h,
optionsStream: "stream" in t,
streamValue: t.stream
});
const a = {
model: e,
input: t.input
};
if (t.response_format && (a.response_format = this.processResponseFormat(t.response_format)), h && (a.stream = !0, console.log("[SubscribeDevClient] STREAMING DEBUG - Added stream to payload", {
stream: h,
requestPayload: a
})), console.log("[SubscribeDevClient] STREAMING DEBUG - Final request payload", {
requestPayload: a,
hasStream: "stream" in a,
streamValue: a.stream
}), console.log("[SubscribeDevClient] STREAMING DEBUG - Request payload stringified", {
payloadString: JSON.stringify(a)
}), h) {
console.log("[SubscribeDevClient] STREAMING DEBUG - Creating lazy streaming response");
const n = this, m = {
[Symbol.asyncIterator]: async function* () {
try {
console.log("[SubscribeDevClient] STREAMING DEBUG - Starting lazy request execution");
const c = await n.makeStreamingRequest("POST", "/v1/run", a, f, t.signal);
n.debug("Streaming request completed successfully:", {
type: typeof c,
hasAsyncIterator: !!(c && typeof c[Symbol.asyncIterator] == "function"),
isAsyncIterable: c instanceof Object && Symbol.asyncIterator in c
}), n.emit("usage-changed", { operation: "run", model: e });
let s = [];
for await (const l of c)
s.push(l), yield l;
n.emit("ai-call-complete", {
type: "ai-call-complete",
timestamp: Date.now(),
requestId: d,
model: e,
input: r,
output: s,
duration: Date.now() - u,
success: !0,
responseFormat: p,
isStreaming: !0
});
} catch (c) {
throw n.debug("Streaming request failed:", {
error: c instanceof Error ? c.message : String(c),
errorType: c instanceof Error ? c.constructor.name : typeof c
}), n.emit("ai-call-error", {
type: "ai-call-error",
timestamp: Date.now(),
requestId: d,
model: e,
input: r,
error: c instanceof Error ? c.message : String(c),
duration: Date.now() - u,
success: !1,
responseFormat: p,
isStreaming: !0
}), c;
}
}
};
return new x(m);
} else
return console.log("[SubscribeDevClient] STREAMING DEBUG - Making regular request (stream was false)", {
stream: h,
streamTruthy: !!h,
requestPayload: a
}), (async () => {
try {
const n = await this.makeRequest("POST", "/v1/run", a, t.signal);
if (this.debug("Prediction completed", {
hasOutput: !!n.output
}), this.emit("usage-changed", { operation: "run", model: e }), this.isZodSchema(t?.response_format))
try {
const m = t.response_format, c = n.output?.[0] ?? "{}";
n.output[0] = m.parse(typeof c == "string" ? JSON.parse(c) : c);
} catch (m) {
console.error("Could not parse incoming record to Zod schema: ", m, n.output[0]);
}
return this.emit("ai-call-complete", {
type: "ai-call-complete",
timestamp: Date.now(),
requestId: d,
model: e,
input: r,
output: n.output,
duration: Date.now() - u,
success: !0,
responseFormat: p,
isStreaming: !1
}), n;
} catch (n) {
throw this.emit("ai-call-error", {
type: "ai-call-error",
timestamp: Date.now(),
requestId: d,
model: e,
input: r,
error: n instanceof Error ? n.message : String(n),
duration: Date.now() - u,
success: !1,
responseFormat: p,
isStreaming: !1
}), n;
}
})();
}
/**
* Process response format, converting Zod schemas to json_schema format
*/
processResponseFormat(e) {
return this.isZodSchema(e) ? this.convertZodSchema(e, "native Zod schema") : e;
}
/**
* Check if the provided object looks like a Zod schema
*/
isZodSchema(e) {
return e && typeof e == "object" && (typeof e._def == "object" || typeof e.parse == "function") && // Make sure it's not already a proper ResponseFormat object
!e.type;
}
/**
* Convert a Zod schema to json_schema format
*/
convertZodSchema(e, t) {
if (!e || typeof e != "object")
return this.debug("Invalid Zod schema provided, falling back to json_object", { source: t }), { type: "json_object" };
try {
return {
type: "json_schema",
json_schema: {
name: e._def?.typeName || "ZodSchema",
strict: !0,
schema: W(e)
}
};
} catch (i) {
const r = i instanceof Error ? i.message : "Unknown error";
return this.debug("Failed to convert Zod schema, falling back to json_object", { error: r, source: t }), { type: "json_object" };
}
}
/**
* Get account balance information
*/
async getBalance() {
const t = (await this.makeRequest("GET", "/v1/subscriptions/usage")).credits?.userBalance;
return {
allocatedCredits: t?.allocatedCredits || 0,
usedCredits: t?.usedCredits || 0,
remainingCredits: t?.remainingCredits || 0
};
}
/**
* Get user storage data using auth context
*/
async getStorage(e = {}) {
const t = new URLSearchParams();
e.appVersion && t.set("appVersion", e.appVersion);
const i = `/v1/storage${t.toString() ? "?" + t.toString() : ""}`;
return this.makeRequest("GET", i);
}
/**
* Update user storage data using auth context
*/
async setStorage(e, t = {}) {
const i = new URLSearchParams();
t.appVersion && i.set("appVersion", t.appVersion);
const r = `/v1/storage${i.toString() ? "?" + i.toString() : ""}`;
return this.makeRequest("PUT", r, { sessionData: e });
}
/**
* Delete user storage data using auth context
*/
async deleteStorage(e = {}) {
const t = new URLSearchParams();
e.appVersion && t.set("appVersion", e.appVersion);
const i = `/v1/storage${t.toString() ? "?" + t.toString() : ""}`;
await this.makeRequest("DELETE", i);
}
/**
* Get user's subscription status using userKey authentication
* Requires userKey to be provided in client configuration
*/
async getSubscriptionStatus() {
if (console.log("[SubscribeDevClient] getSubscriptionStatus called"), !this._config.userKey)
throw console.log("[SubscribeDevClient] No userKey provided, throwing ValidationError"), new k(
"User key is required to get subscription status. Provide userKey in client configuration.",
{ method: "getSubscriptionStatus" }
);
console.log("[SubscribeDevClient] Making request to /v1/subscriptions/plan with userKey:", this._config.userKey.substring(0, 10) + "...");
try {
const e = await this.makeRequest("GET", "/v1/subscriptions/plan");
console.log("[SubscribeDevClient] Received response:", {
hasUserPlan: !!e.userPlan,
planId: e.userPlan?.planId,
status: e.userPlan?.status,
hasPlanDetails: !!e.userPlan?.plan
});
const t = e.userPlan;
if (!t || t.status === "none" || !t.plan)
return console.log("[SubscribeDevClient] User has no active subscription, returning none status"), {
hasActiveSubscription: !1,
status: t?.status || "none"
};
const i = {
hasActiveSubscription: t.status === "active",
plan: t.plan ? {
id: t.plan.id || t.planId,
name: t.plan.name,
price: t.plan.price,
tokenLimit: t.plan.tokenLimit || t.plan.token_limit,
subtitle: t.plan.subtitle,
description: t.plan.description,
features: t.plan.features
} : void 0,
status: t.status,
startedAt: t.startedAt,
endsAt: t.endsAt
};
return console.log("[SubscribeDevClient] Returning subscription statuSSSSs:", {
hasActiveSubscription: i.hasActiveSubscription,
status: i.status,
planName: i.plan?.name
}), i;
} catch (e) {
throw console.log("[SubscribeDevClient] Error in getSubscriptionStatus:", {
errorType: e.constructor.name,
message: e.message
}), e;
}
}
/**
* Get comprehensive usage limits and current consumption
* Requires userKey to be provided in client configuration
*/
async getUsageLimits() {
if (!this._config.userKey)
throw new k(
"User key is required to get usage limits. Provide userKey in client configuration.",
{ method: "getUsageLimits" }
);
return this.makeRequest("GET", "/v1/subscriptions/usage");
}
/**
* Get comprehensive usage information including credits, rate limits, and consumption
* Alias for getUsageLimits() - Requires userKey to be provided in client configuration
*/
async getUsage() {
return this.getUsageLimits();
}
/**
* Get or create a demo project with a public API key
* Requires userKey (userToken) to be provided in client configuration
* The returned API key is public and safe to share
*/
async getDemoProject() {
if (!this._config.userKey)
throw new k(
"User key is required to get demo project. Provide userKey in client configuration.",
{ method: "getDemoProject" }
);
this.debug("Getting demo project");
const e = await this.makePlatformRequest("POST", "/v1/platform/projects/demo");
this.debug("Demo project retrieved", {
hasApiKey: !!e.apiKey,
projectId: e.id,
isDemo: e.isDemo
});
const t = e.apiKey;
return console.log("Demo project API key (public and safe to share):", t), e;
}
/**
* Upload a file and get back the final public URL
*
* This is a convenience method that:
* 1. Gets a presigned S3 URL from the API
* 2. Uploads the file directly to S3
* 3. Returns the final public download URL
*
* @param file - File object to upload (e.g., from input[type="file"])
* @param options - Optional configuration (userId for organizing uploads)
* @returns Promise resolving to the public S3 URL of the uploaded file
*
* @example
* ```typescript
* const fileInput = document.querySelector('input[type="file"]')
* const file = fileInput.files[0]
*
* const imageUrl = await client.uploadFile(file)
* console.log('Uploaded to:', imageUrl)
* // => "https://bucket.s3.amazonaws.com/uploads/proj-123/user-456/photo.jpg"
* ```
*/
async uploadFile(e, t) {
this.debug("Starting file upload", {
filename: e.name,
size: e.size,
type: e.type,
userId: t?.userId
});
const i = new URLSearchParams();
i.set("filename", e.name), i.set("contentType", e.type), t?.userId && i.set("userId", t.userId);
const r = `/v1/upload-url?${i.toString()}`, p = await this.makeRequest("GET", r);
this.debug("Got presigned URL", {
key: p.key,
expiresIn: p.expiresIn
});
try {
const h = await this.fetch(p.presignedUrl, {
method: "PUT",
body: e,
headers: {
"Content-Type": e.type
},
signal: AbortSignal.timeout(this._config.timeout)
});
if (!h.ok)
throw new Error(`S3 upload failed: ${h.status} ${h.statusText}`);
return this.debug("File uploaded successfully", {
downloadUrl: p.downloadUrl
}), p.downloadUrl;
} catch (h) {
throw this.debug("S3 upload failed", {
error: h instanceof Error ? h.message : String(h)
}), new Error(
`Failed to upload file to S3: ${h instanceof Error ? h.message : "Unknown error"}`
);
}
}
/**
* Make authenticated HTTP request to platform API using userToken as Bearer token
*/
async makePlatformRequest(e, t, i) {
const r = `${this._config.baseUrl}${t}`, p = {
Authorization: `Bearer ${this._config.userKey}`,
"Content-Type": "application/json",
"User-Agent": "@subscribe.dev/client/0.1.0"
}, h = {
method: e,
headers: p,
signal: AbortSignal.timeout(this._config.timeout)
};
i && ["POST", "PUT", "PATCH"].includes(e) && (h.body = JSON.stringify(i)), this.debug("Making platform request", { method: e, url: r, headers: { ...p, Authorization: "[redacted]" } });
const f = await this.fetch(r, h), d = await f.text();
let u;
try {
u = d ? JSON.parse(d) : null;
} catch {
u = { error: { message: d } };
}
return f.ok || this.handleErrorResponse(f, u), this.debug("Platform request successful", { status: f.status, data: u }), u;
}
/**
* Make authenticated HTTP request to SubscribeDev API
*/
async makeRequest(e, t, i, r) {
return this.queue.add(async () => {
const p = `${this._config.baseUrl}${t}`, h = {
"Content-Type": "application/json",
"User-Agent": "@subscribe.dev/client/0.1.0"
};
if (this._config.accessToken)
h["x-sub-dev-access-token"] = this._config.accessToken, this.debug("Using universal auth with x-sub-dev-access-token", {
tokenPrefix: this._config.accessToken.substring(0, 10) + "..."
});
else if (this._config.apiKey) {
const n = this._config.apiKey.trim().replace(/=+$/, "");
h.Authorization = `Bearer ${n}`, this.debug("Using project auth with Authorization header"), this._config.userKey && (h["X-User-Token"] = this._config.userKey, this.debug("Adding X-User-Token for user context"));
} else
this.debug("No authentication tokens available - unauthenticated request");
const f = {
method: e,
headers: h,
signal: r || AbortSignal.timeout(this._config.timeout)
};
i && ["POST", "PUT", "PATCH"].includes(e) && (f.body = JSON.stringify(i), this.debug("Regular request body stringified:", {
originalBody: i,
stringifiedBody: f.body,
bodyContainsStream: JSON.stringify(i).includes('"stream"'),
streamValue: i?.stream
})), this.debug("Making request", {
method: e,
url: p,
body: i,
hasStream: i?.stream,
stringifiedBody: f.body,
headers: { ...h, Authorization: "[redacted]" }
});
const d = await this.fetch(p, f), u = await d.text();
let a;
try {
a = u ? JSON.parse(u) : null;
} catch {
a = { error: { message: u } };
}
return d.ok || this.handleErrorResponse(d, a), this.debug("Request successful", { status: d.status, data: a }), a;
});
}
/**
* Make authenticated HTTP streaming request to SubscribeDev API
*/
async makeStreamingRequest(e, t, i, r = "chunk", p) {
const h = `${this._config.baseUrl}${t}`, f = {
"Content-Type": "application/json",
"User-Agent": "@subscribe.dev/client/0.1.0",
Accept: "text/event-stream",
"Cache-Control": "no-cache"
};
if (this._config.accessToken)
f["x-sub-dev-access-token"] = this._config.accessToken, this.debug("Using universal auth with x-sub-dev-access-token for streaming", {
tokenPrefix: this._config.accessToken.substring(0, 10) + "..."
});
else if (this._config.apiKey) {
const c = this._config.apiKey.trim().replace(/=+$/, "");
f.Authorization = `Bearer ${c}`, this.debug("Using project auth with Authorization header for streaming"), this._config.userKey && (f["X-User-Token"] = this._config.userKey, this.debug("Adding X-User-Token for user context in streaming"));
} else
this.debug("No authentication tokens available for streaming - unauthenticated request");
const d = {
method: e,
headers: f,
signal: p || AbortSignal.timeout(this._config.timeout)
};
i && ["POST", "PUT", "PATCH"].includes(e) && (d.body = JSON.stringify(i), this.debug("Streaming request body stringified:", {
originalBody: i,
stringifiedBody: d.body,
bodyContainsStream: JSON.stringify(i).includes('"stream"'),
streamValue: i?.stream
})), this.debug("Making streaming request", {
method: e,
url: h,
body: i,
hasStream: i?.stream,
stringifiedBody: d.body,
headers: { ...f, Authorization: "[redacted]" }
}), console.log("[SubscribeDevClient] STREAMING DEBUG - About to fetch streaming request");
const u = await this.fetch(h, d);
if (console.log("[SubscribeDevClient] STREAMING DEBUG - Streaming response received:", {
status: u.status,
statusText: u.statusText,
headers: Object.fromEntries(u.headers.entries()),
contentType: u.headers.get("content-type"),
hasBody: !!u.body,
bodyLocked: u.body?.locked,
ok: u.ok
}), !u.ok) {
const c = await u.text();
let s;
try {
s = c ? JSON.parse(c) : null;
} catch {
s = { error: { message: c } };
}
this.handleErrorResponse(u, s);
}
if (!u.body)
throw console.log("[SubscribeDevClient] STREAMING DEBUG - No response body received"), new Error("No response body received for streaming request");
console.log("[SubscribeDevClient] STREAMING DE