@indreamai/client 0.2.1 → 0.3.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/dist/index.js CHANGED
@@ -79,6 +79,25 @@ var createApiError = (status, payload) => {
79
79
  return new APIError(problem);
80
80
  };
81
81
 
82
+ // src/resources/assets.ts
83
+ var AssetsResource = class {
84
+ constructor(client) {
85
+ this.client = client;
86
+ }
87
+ async get(assetId, options = {}) {
88
+ return await this.client.request(`/v1/assets/${assetId}`, {
89
+ method: "GET",
90
+ signal: options.signal
91
+ });
92
+ }
93
+ async delete(assetId, options = {}) {
94
+ return await this.client.request(`/v1/assets/${assetId}`, {
95
+ method: "DELETE",
96
+ signal: options.signal
97
+ });
98
+ }
99
+ };
100
+
82
101
  // src/resources/exports.ts
83
102
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["COMPLETED", "FAILED", "CANCELED"]);
84
103
  var sleep = async (ms) => {
@@ -184,6 +203,164 @@ var EditorResource = class {
184
203
  }
185
204
  };
186
205
 
206
+ // src/resources/projects.ts
207
+ var ProjectsResource = class {
208
+ constructor(client) {
209
+ this.client = client;
210
+ }
211
+ async create(payload, options = {}) {
212
+ var _a;
213
+ return await this.client.request("/v1/projects", {
214
+ method: "POST",
215
+ body: payload,
216
+ idempotencyKey: ((_a = options.idempotencyKey) == null ? void 0 : _a.trim()) || void 0,
217
+ signal: options.signal
218
+ });
219
+ }
220
+ async list(params) {
221
+ var _a;
222
+ const search = new URLSearchParams();
223
+ if (params == null ? void 0 : params.pageSize) {
224
+ search.set("pageSize", String(params.pageSize));
225
+ }
226
+ if (params == null ? void 0 : params.pageCursor) {
227
+ search.set("pageCursor", params.pageCursor);
228
+ }
229
+ const query = search.toString();
230
+ const envelope = await this.client.requestEnvelope(
231
+ `/v1/projects${query ? `?${query}` : ""}`,
232
+ {
233
+ method: "GET",
234
+ signal: params == null ? void 0 : params.signal
235
+ }
236
+ );
237
+ return {
238
+ items: envelope.data || [],
239
+ nextPageCursor: typeof ((_a = envelope.meta) == null ? void 0 : _a.nextPageCursor) === "string" ? envelope.meta.nextPageCursor : null
240
+ };
241
+ }
242
+ async get(projectId, options = {}) {
243
+ return await this.client.request(`/v1/projects/${projectId}`, {
244
+ method: "GET",
245
+ signal: options.signal
246
+ });
247
+ }
248
+ async update(projectId, payload, options = {}) {
249
+ return await this.client.request(`/v1/projects/${projectId}`, {
250
+ method: "PATCH",
251
+ body: payload,
252
+ signal: options.signal
253
+ });
254
+ }
255
+ async sync(projectId, payload, options = {}) {
256
+ return await this.client.request(`/v1/projects/${projectId}/sync`, {
257
+ method: "POST",
258
+ body: payload,
259
+ signal: options.signal
260
+ });
261
+ }
262
+ async delete(projectId, options = {}) {
263
+ return await this.client.request(`/v1/projects/${projectId}`, {
264
+ method: "DELETE",
265
+ signal: options.signal
266
+ });
267
+ }
268
+ async listAssets(params) {
269
+ var _a;
270
+ const search = new URLSearchParams();
271
+ if (params.pageSize) {
272
+ search.set("pageSize", String(params.pageSize));
273
+ }
274
+ if (params.pageCursor) {
275
+ search.set("pageCursor", params.pageCursor);
276
+ }
277
+ const query = search.toString();
278
+ const envelope = await this.client.requestEnvelope(
279
+ `/v1/projects/${params.projectId}/assets${query ? `?${query}` : ""}`,
280
+ {
281
+ method: "GET",
282
+ signal: params.signal
283
+ }
284
+ );
285
+ return {
286
+ items: envelope.data || [],
287
+ nextPageCursor: typeof ((_a = envelope.meta) == null ? void 0 : _a.nextPageCursor) === "string" ? envelope.meta.nextPageCursor : null
288
+ };
289
+ }
290
+ async addAsset(projectId, assetId, options = {}) {
291
+ return await this.client.request(
292
+ `/v1/projects/${projectId}/assets`,
293
+ {
294
+ method: "POST",
295
+ body: { assetId },
296
+ signal: options.signal
297
+ }
298
+ );
299
+ }
300
+ async removeAsset(projectId, assetId, options = {}) {
301
+ return await this.client.request(
302
+ `/v1/projects/${projectId}/assets/${assetId}`,
303
+ {
304
+ method: "DELETE",
305
+ signal: options.signal
306
+ }
307
+ );
308
+ }
309
+ async createExport(projectId, payload, options = {}) {
310
+ var _a;
311
+ return await this.client.request(`/v1/projects/${projectId}/exports`, {
312
+ method: "POST",
313
+ body: payload,
314
+ idempotencyKey: ((_a = options.idempotencyKey) == null ? void 0 : _a.trim()) || void 0,
315
+ signal: options.signal
316
+ });
317
+ }
318
+ };
319
+
320
+ // src/resources/uploads.ts
321
+ var resolveFilename = (body, options) => {
322
+ var _a;
323
+ if ((_a = options.filename) == null ? void 0 : _a.trim()) {
324
+ return options.filename.trim();
325
+ }
326
+ if (typeof File !== "undefined" && body instanceof File && typeof body.name === "string" && body.name.trim()) {
327
+ return body.name.trim();
328
+ }
329
+ throw new Error("filename is required for uploads.upload(...)");
330
+ };
331
+ var resolveContentType = (body, options) => {
332
+ var _a;
333
+ if ((_a = options.contentType) == null ? void 0 : _a.trim()) {
334
+ return options.contentType.trim();
335
+ }
336
+ if (typeof Blob !== "undefined" && body instanceof Blob && body.type.trim()) {
337
+ return body.type.trim();
338
+ }
339
+ throw new Error("contentType is required for uploads.upload(...)");
340
+ };
341
+ var UploadsResource = class {
342
+ constructor(client) {
343
+ this.client = client;
344
+ }
345
+ async upload(body, options = {}) {
346
+ var _a;
347
+ const headers = {
348
+ "x-file-name": resolveFilename(body, options),
349
+ "Content-Type": resolveContentType(body, options)
350
+ };
351
+ if ((_a = options.projectId) == null ? void 0 : _a.trim()) {
352
+ headers["x-project-id"] = options.projectId.trim();
353
+ }
354
+ return await this.client.request("/v1/uploads", {
355
+ method: "POST",
356
+ body,
357
+ headers,
358
+ signal: options.signal,
359
+ skipRetry: true
360
+ });
361
+ }
362
+ };
363
+
187
364
  // src/retry.ts
188
365
  var sleep2 = async (ms) => {
189
366
  await new Promise((resolve) => setTimeout(resolve, ms));
@@ -216,6 +393,16 @@ var withRetry = async (execute, options) => {
216
393
  };
217
394
 
218
395
  // src/client.ts
396
+ var isBodyInit = (value) => {
397
+ if (typeof value === "string") return true;
398
+ if (value instanceof URLSearchParams) return true;
399
+ if (value instanceof ArrayBuffer) return true;
400
+ if (ArrayBuffer.isView(value)) return true;
401
+ if (typeof Blob !== "undefined" && value instanceof Blob) return true;
402
+ if (typeof FormData !== "undefined" && value instanceof FormData) return true;
403
+ if (typeof ReadableStream !== "undefined" && value instanceof ReadableStream) return true;
404
+ return false;
405
+ };
219
406
  var IndreamClient = class {
220
407
  constructor(options) {
221
408
  if (!options.apiKey) {
@@ -229,6 +416,9 @@ var IndreamClient = class {
229
416
  this.fetchImpl = options.fetch || fetch;
230
417
  this.exports = new ExportsResource(this);
231
418
  this.editor = new EditorResource(this);
419
+ this.projects = new ProjectsResource(this);
420
+ this.uploads = new UploadsResource(this);
421
+ this.assets = new AssetsResource(this);
232
422
  }
233
423
  async request(path, init) {
234
424
  const envelope = await this.requestEnvelope(path, init);
@@ -236,7 +426,15 @@ var IndreamClient = class {
236
426
  }
237
427
  async requestEnvelope(path, init) {
238
428
  const url = `${this.baseURL}${path.startsWith("/") ? path : `/${path}`}`;
239
- const payload = init.body === void 0 ? void 0 : JSON.stringify(init.body);
429
+ const isJsonPayload = init.body !== void 0 && !isBodyInit(init.body);
430
+ let payload;
431
+ if (init.body !== void 0) {
432
+ if (isJsonPayload) {
433
+ payload = JSON.stringify(init.body);
434
+ } else if (isBodyInit(init.body)) {
435
+ payload = init.body;
436
+ }
437
+ }
240
438
  const execute = async () => {
241
439
  const controller = new AbortController();
242
440
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
@@ -255,19 +453,23 @@ var IndreamClient = class {
255
453
  "x-api-key": this.apiKey,
256
454
  Accept: "application/json"
257
455
  }, init.headers);
258
- if (payload !== void 0) {
456
+ if (isJsonPayload && payload !== void 0) {
259
457
  headers["Content-Type"] = "application/json";
260
458
  }
261
459
  if (init.idempotencyKey) {
262
460
  headers["Idempotency-Key"] = init.idempotencyKey;
263
461
  }
462
+ const requestInit = {
463
+ method: init.method,
464
+ body: payload,
465
+ headers,
466
+ signal: controller.signal
467
+ };
468
+ if (typeof ReadableStream !== "undefined" && payload instanceof ReadableStream) {
469
+ requestInit.duplex = "half";
470
+ }
264
471
  try {
265
- const response = await this.fetchImpl(url, {
266
- method: init.method,
267
- body: payload,
268
- headers,
269
- signal: controller.signal
270
- });
472
+ const response = await this.fetchImpl(url, requestInit);
271
473
  const text = await response.text();
272
474
  const parsed = text ? JSON.parse(text) : null;
273
475
  if (!response.ok) {
@@ -342,6 +544,7 @@ var TASK_STATUSES = /* @__PURE__ */ new Set([
342
544
  ]);
343
545
  var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
344
546
  var isNullableString = (value) => typeof value === "string" || value === null;
547
+ var isOptionalNullableString = (value) => value === void 0 || isNullableString(value);
345
548
  var toArrayBuffer = (bytes) => {
346
549
  const copy = new Uint8Array(bytes.byteLength);
347
550
  copy.set(bytes);
@@ -399,7 +602,7 @@ var isExportTaskSnapshot = (value) => {
399
602
  if (!isObject(value)) {
400
603
  return false;
401
604
  }
402
- return typeof value.taskId === "string" && isNullableString(value.createdByApiKeyId) && isNullableString(value.clientTaskId) && isTaskStatus(value.status) && typeof value.progress === "number" && isNullableString(value.error) && isNullableString(value.outputUrl) && typeof value.durationSeconds === "number" && typeof value.billedStandardSeconds === "number" && typeof value.chargedCredits === "string" && isNullableString(value.callbackUrl) && typeof value.createdAt === "string" && isNullableString(value.completedAt);
605
+ return typeof value.taskId === "string" && isOptionalNullableString(value.projectId) && isNullableString(value.createdByApiKeyId) && isNullableString(value.clientTaskId) && isTaskStatus(value.status) && typeof value.progress === "number" && isNullableString(value.error) && isNullableString(value.outputUrl) && typeof value.durationSeconds === "number" && typeof value.billedStandardSeconds === "number" && typeof value.chargedCredits === "string" && isNullableString(value.callbackUrl) && typeof value.createdAt === "string" && isNullableString(value.completedAt);
403
606
  };
404
607
  var isExportWebhookEvent = (value) => {
405
608
  if (!isObject(value)) {
@@ -473,9 +676,14 @@ var verifyExportWebhookRequest = async ({
473
676
  };
474
677
  export {
475
678
  APIError,
679
+ AssetsResource,
476
680
  AuthError,
681
+ EditorResource,
682
+ ExportsResource,
477
683
  IndreamClient,
684
+ ProjectsResource,
478
685
  RateLimitError,
686
+ UploadsResource,
479
687
  ValidationError,
480
688
  createApiError,
481
689
  isExportTaskSnapshot,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indreamai/client",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Official JavaScript client for Indream Open API (Node.js and Edge runtimes)",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",