@curviate/sdk 0.41.0 → 0.42.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
@@ -180,6 +180,28 @@ var ERROR_CODES = [
180
180
  // was charged. Stop and surface it to a human (or support) rather than
181
181
  // backing off.
182
182
  "STRIPE_DRIFT_DETECTED",
183
+ // Drafts and scheduled posts (`/v1/drafts`). Each is user_fixable and none
184
+ // clears on an unchanged retry; read the code, then change the request.
185
+ //
186
+ // - `DRAFT_LIMIT_REACHED` (422): the bucket (one account, or "no account")
187
+ // already holds 50 Drafts. Delete one, or use another account.
188
+ // - `MEDIA_QUOTA_EXCEEDED` (422): the file would take the bucket past its
189
+ // media quota; nothing was stored. Delete media first.
190
+ // - `ACCOUNT_REQUIRED` (422): publishing or scheduling needs an account on the
191
+ // Draft (also `account_id: null` on a scheduled Draft: unschedule first).
192
+ // - `DRAFT_NOT_PUBLISHABLE` (422): a content gap (empty text, ...); the
193
+ // message names the field.
194
+ // - `SCHEDULE_CONFLICT` (422): another scheduled Draft on the same account is
195
+ // within 5 minutes of this `scheduled_at`; the message names it.
196
+ // - `DRAFT_PUBLISHING` (409): a publish of this Draft is in flight (or its
197
+ // outcome is being settled). Read the Draft again in a few seconds; if it
198
+ // says to check the account's posts first, do that before retrying.
199
+ "DRAFT_LIMIT_REACHED",
200
+ "MEDIA_QUOTA_EXCEEDED",
201
+ "ACCOUNT_REQUIRED",
202
+ "DRAFT_NOT_PUBLISHABLE",
203
+ "SCHEDULE_CONFLICT",
204
+ "DRAFT_PUBLISHING",
183
205
  // Generic
184
206
  "INTERNAL"
185
207
  ];
@@ -357,6 +379,11 @@ function buildInit(method, opts, signal) {
357
379
  authorization: `Bearer ${opts.apiKey}`
358
380
  };
359
381
  const init = { method, headers, signal };
382
+ if (opts.rawBody !== void 0 && method !== "GET" && method !== "HEAD") {
383
+ headers["content-type"] = opts.rawBody.contentType;
384
+ init.body = opts.rawBody.data;
385
+ return init;
386
+ }
360
387
  if (method === "GET" || method === "HEAD" || opts.body === void 0) {
361
388
  return init;
362
389
  }
@@ -487,7 +514,8 @@ function createContext(config, accountId) {
487
514
  maxRetries: config.maxRetries,
488
515
  ...config.fetch ? { fetch: config.fetch } : {},
489
516
  ...args.query !== void 0 ? { query: args.query } : {},
490
- ...args.body !== void 0 ? { body: args.body } : {}
517
+ ...args.body !== void 0 ? { body: args.body } : {},
518
+ ...args.rawBody !== void 0 ? { rawBody: args.rawBody } : {}
491
519
  });
492
520
  };
493
521
  return { request, accountId };
@@ -3089,6 +3117,145 @@ var WebhooksResource = class {
3089
3117
  }
3090
3118
  };
3091
3119
 
3120
+ // src/resources/drafts.ts
3121
+ var DraftsResource = class {
3122
+ constructor(ctx) {
3123
+ this.ctx = ctx;
3124
+ }
3125
+ /**
3126
+ * Store a Draft. Every field is optional, `account_id` and `text` included.
3127
+ * `POST /v1/drafts`
3128
+ *
3129
+ * With `scheduled_at` (ISO 8601 with offset, between 5 minutes and 365 days
3130
+ * ahead) the Draft is scheduled in the same call and needs an account and
3131
+ * publishable text. Up to 50 Drafts and 2 GiB of media per account, and per
3132
+ * no-account. A retry creates a second Draft.
3133
+ *
3134
+ * @example
3135
+ * const draft = await curviate.drafts.create({
3136
+ * account_id: "acc_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
3137
+ * text: "Three things we learned shipping our first agent integration.",
3138
+ * scheduled_at: "2026-10-12T09:00:00+02:00",
3139
+ * });
3140
+ * // draft.status === "scheduled"
3141
+ */
3142
+ create(body = {}) {
3143
+ return this.ctx.request({
3144
+ method: "POST",
3145
+ path: "/v1/drafts",
3146
+ body
3147
+ });
3148
+ }
3149
+ /**
3150
+ * List Drafts, cursor-paginated. `GET /v1/drafts`
3151
+ *
3152
+ * `status` defaults to `["draft", "scheduled", "failed"]`; add `"published"`
3153
+ * to include publish records (`object: "publish_record"`, never Drafts).
3154
+ * `account_id` is an `acc_` id or `"none"`. `from`/`to` are a half-open
3155
+ * `[from, to)` range on each item's own date.
3156
+ *
3157
+ * @example
3158
+ * const page = await curviate.drafts.list({ status: ["scheduled"], order: "asc" });
3159
+ */
3160
+ list(params) {
3161
+ const { status, ...rest } = params ?? {};
3162
+ return this.ctx.request({
3163
+ method: "GET",
3164
+ path: "/v1/drafts",
3165
+ query: { ...rest, ...status !== void 0 ? { status: status.join(",") } : {} }
3166
+ });
3167
+ }
3168
+ /**
3169
+ * Return one Draft, with a fresh signed link (valid 1 hour) per attachment.
3170
+ * `GET /v1/drafts/{id}`
3171
+ *
3172
+ * @example
3173
+ * const draft = await curviate.drafts.get("drf_01J8Z3K9P0Q1R2S3T4V5W6X7Y8");
3174
+ */
3175
+ get(id) {
3176
+ return this.ctx.request({
3177
+ method: "GET",
3178
+ path: apiPath`/v1/drafts/${id}`
3179
+ });
3180
+ }
3181
+ /**
3182
+ * Partial update: an omitted field is left as is, `null` clears it.
3183
+ * `PATCH /v1/drafts/{id}`
3184
+ *
3185
+ * `attachments` replaces the whole list (`{ id }` keeps a file, a base64
3186
+ * object adds one, anything left out is deleted). `scheduled_at` schedules,
3187
+ * reschedules or, with `null`, unschedules. Editing a `failed` Draft clears
3188
+ * its `failure`. A Draft being published answers `409 DRAFT_PUBLISHING`.
3189
+ *
3190
+ * @example
3191
+ * await curviate.drafts.update(id, { scheduled_at: null }); // unschedule
3192
+ */
3193
+ update(id, body) {
3194
+ return this.ctx.request({
3195
+ method: "PATCH",
3196
+ path: apiPath`/v1/drafts/${id}`,
3197
+ body
3198
+ });
3199
+ }
3200
+ /**
3201
+ * Delete the Draft and its stored media (bodyless, 204).
3202
+ * `DELETE /v1/drafts/{id}`
3203
+ *
3204
+ * @example
3205
+ * await curviate.drafts.delete(id);
3206
+ */
3207
+ async delete(id) {
3208
+ await this.ctx.request({
3209
+ method: "DELETE",
3210
+ path: apiPath`/v1/drafts/${id}`
3211
+ });
3212
+ }
3213
+ /**
3214
+ * Publish the Draft now, under the same rules and safety limits as
3215
+ * `posts.create`. `POST /v1/drafts/{id}/publish`
3216
+ *
3217
+ * Success deletes the Draft and its media, writes a publish record and
3218
+ * returns `{ object: "post_created", id }`; no webhook is sent. A known
3219
+ * failure leaves the Draft unchanged. A `504` or `502` whose message says
3220
+ * the outcome is unknown means the post may be live: check the account's
3221
+ * posts before retrying.
3222
+ *
3223
+ * @example
3224
+ * const { id: postId } = await curviate.drafts.publish(draftId);
3225
+ */
3226
+ publish(id) {
3227
+ return this.ctx.request({
3228
+ method: "POST",
3229
+ path: apiPath`/v1/drafts/${id}/publish`
3230
+ });
3231
+ }
3232
+ /**
3233
+ * Add one file to the Draft as the raw request body, for media too large to
3234
+ * send inline: an MP4 video or a PDF, each up to 50 MiB. An image is capped at 5 MiB on
3235
+ * every route. One file per call.
3236
+ * `POST /v1/drafts/{id}/attachments?filename=...`
3237
+ *
3238
+ * Small files (up to 5 MiB) can instead ride inline in `create` / `update`
3239
+ * as base64. Resolves with the Draft, the new attachment last.
3240
+ *
3241
+ * @example
3242
+ * const bytes = await readFile("clip.mp4");
3243
+ * const draft = await curviate.drafts.uploadAttachment(id, bytes, {
3244
+ * filename: "clip.mp4",
3245
+ * contentType: "video/mp4",
3246
+ * });
3247
+ */
3248
+ uploadAttachment(id, data, options) {
3249
+ const contentType = options.contentType ?? (data instanceof Blob ? data.type : "");
3250
+ return this.ctx.request({
3251
+ method: "POST",
3252
+ path: apiPath`/v1/drafts/${id}/attachments`,
3253
+ query: { filename: options.filename },
3254
+ rawBody: { data, contentType }
3255
+ });
3256
+ }
3257
+ };
3258
+
3092
3259
  // src/resources/index.ts
3093
3260
  function buildNamespaces(ctx) {
3094
3261
  return {
@@ -3109,14 +3276,16 @@ function buildNamespaces(ctx) {
3109
3276
  recruiter: new RecruiterResource(ctx),
3110
3277
  jobs: new JobsResource(ctx),
3111
3278
  companies: new CompaniesResource(ctx),
3112
- webhooks: new WebhooksResource(ctx)
3279
+ webhooks: new WebhooksResource(ctx),
3280
+ drafts: new DraftsResource(ctx)
3113
3281
  };
3114
3282
  }
3115
3283
  function buildRootNamespaces(ctx) {
3116
3284
  return {
3117
3285
  accounts: new AccountsResource(ctx),
3118
3286
  auth: new AuthResource(ctx),
3119
- webhooks: new WebhooksResource(ctx)
3287
+ webhooks: new WebhooksResource(ctx),
3288
+ drafts: new DraftsResource(ctx)
3120
3289
  };
3121
3290
  }
3122
3291
  function buildAccountScopedNamespaces(ctx) {
@@ -3124,11 +3293,13 @@ function buildAccountScopedNamespaces(ctx) {
3124
3293
  accounts: _accounts,
3125
3294
  auth: _auth,
3126
3295
  webhooks: _webhooks,
3296
+ drafts: _drafts,
3127
3297
  ...rest
3128
3298
  } = buildNamespaces(ctx);
3129
3299
  void _accounts;
3130
3300
  void _auth;
3131
3301
  void _webhooks;
3302
+ void _drafts;
3132
3303
  return rest;
3133
3304
  }
3134
3305
 
@@ -3141,6 +3312,7 @@ var Curviate = class {
3141
3312
  this.accounts = ns.accounts;
3142
3313
  this.auth = ns.auth;
3143
3314
  this.webhooks = ns.webhooks;
3315
+ this.drafts = ns.drafts;
3144
3316
  }
3145
3317
  /**
3146
3318
  * Return an account-scoped accessor that fixes `account_id` on every call,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/sdk",
3
- "version": "0.41.0",
3
+ "version": "0.42.0",
4
4
  "private": false,
5
5
  "description": "TypeScript SDK for the Curviate API.",
6
6
  "license": "MIT",