@primitivedotdev/sdk 0.26.1 → 0.27.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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/api/index.js +3 -406
  3. package/dist/openapi/index.js +7631 -7
  4. package/package.json +6 -63
  5. package/bin/run.js +0 -20
  6. package/dist/api/generated/client/client.gen.js +0 -235
  7. package/dist/api/generated/client/index.js +0 -6
  8. package/dist/api/generated/client/types.gen.js +0 -2
  9. package/dist/api/generated/client/utils.gen.js +0 -228
  10. package/dist/api/generated/client.gen.js +0 -3
  11. package/dist/api/generated/core/auth.gen.js +0 -14
  12. package/dist/api/generated/core/bodySerializer.gen.js +0 -57
  13. package/dist/api/generated/core/params.gen.js +0 -100
  14. package/dist/api/generated/core/pathSerializer.gen.js +0 -106
  15. package/dist/api/generated/core/queryKeySerializer.gen.js +0 -92
  16. package/dist/api/generated/core/serverSentEvents.gen.js +0 -132
  17. package/dist/api/generated/core/types.gen.js +0 -2
  18. package/dist/api/generated/core/utils.gen.js +0 -87
  19. package/dist/api/generated/index.js +0 -2
  20. package/dist/api/generated/sdk.gen.js +0 -878
  21. package/dist/api/generated/types.gen.js +0 -2
  22. package/dist/api/verify-signature.js +0 -198
  23. package/dist/oclif/api-command.js +0 -755
  24. package/dist/oclif/auth.js +0 -223
  25. package/dist/oclif/commands/emails-latest.js +0 -185
  26. package/dist/oclif/commands/emails-poll.js +0 -121
  27. package/dist/oclif/commands/emails-wait.js +0 -171
  28. package/dist/oclif/commands/emails-watch.js +0 -165
  29. package/dist/oclif/commands/functions-deploy.js +0 -124
  30. package/dist/oclif/commands/functions-init.js +0 -256
  31. package/dist/oclif/commands/functions-redeploy.js +0 -113
  32. package/dist/oclif/commands/functions-set-secret.js +0 -213
  33. package/dist/oclif/commands/login.js +0 -237
  34. package/dist/oclif/commands/logout.js +0 -88
  35. package/dist/oclif/commands/send.js +0 -222
  36. package/dist/oclif/commands/whoami.js +0 -95
  37. package/dist/oclif/fish-completion.js +0 -87
  38. package/dist/oclif/index.js +0 -167
  39. package/dist/oclif/lint/raw-send-mail-fetch.js +0 -98
  40. package/dist/openapi/openapi.generated.js +0 -5754
  41. package/dist/openapi/operations.generated.js +0 -4626
  42. package/dist/parser/address-parser.js +0 -129
  43. package/dist/types.generated.js +0 -7
  44. package/dist/types.js +0 -53
  45. package/dist/webhook/errors.js +0 -224
  46. package/dist/webhook/received-email.js +0 -82
  47. package/oclif.manifest.json +0 -4380
@@ -1,878 +0,0 @@
1
- // This file is auto-generated by @hey-api/openapi-ts
2
- import { client } from './client.gen.js';
3
- /**
4
- * Start CLI browser login
5
- *
6
- * Starts a browser-assisted CLI login session. The response includes a
7
- * device code for polling and a user code that the user approves in the
8
- * browser. This endpoint does not require an API key.
9
- *
10
- */
11
- export const startCliLogin = (options) => (options?.client ?? client).post({
12
- url: '/cli/login/start',
13
- ...options,
14
- headers: {
15
- 'Content-Type': 'application/json',
16
- ...options?.headers
17
- }
18
- });
19
- /**
20
- * Poll CLI browser login
21
- *
22
- * Polls a CLI login session until the browser approval either succeeds,
23
- * is denied, expires, or is polled too quickly. The API key is generated
24
- * only after approval and is returned exactly once.
25
- *
26
- */
27
- export const pollCliLogin = (options) => (options.client ?? client).post({
28
- url: '/cli/login/poll',
29
- ...options,
30
- headers: {
31
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
32
- ...options.headers
33
- }
34
- });
35
- /**
36
- * Revoke the current CLI API key
37
- *
38
- * Revokes the API key used to authenticate the request. CLI clients use
39
- * this endpoint during `primitive logout` before removing local credentials.
40
- *
41
- */
42
- export const cliLogout = (options) => (options?.client ?? client).post({
43
- security: [{ scheme: 'bearer', type: 'http' }],
44
- url: '/cli/logout',
45
- ...options,
46
- headers: {
47
- 'Content-Type': 'application/json',
48
- ...options?.headers
49
- }
50
- });
51
- /**
52
- * Get account info
53
- */
54
- export const getAccount = (options) => (options?.client ?? client).get({
55
- security: [{ scheme: 'bearer', type: 'http' }],
56
- url: '/account',
57
- ...options
58
- });
59
- /**
60
- * Update account settings
61
- */
62
- export const updateAccount = (options) => (options.client ?? client).patch({
63
- security: [{ scheme: 'bearer', type: 'http' }],
64
- url: '/account',
65
- ...options,
66
- headers: {
67
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
68
- ...options.headers
69
- }
70
- });
71
- /**
72
- * Get storage usage
73
- */
74
- export const getStorageStats = (options) => (options?.client ?? client).get({
75
- security: [{ scheme: 'bearer', type: 'http' }],
76
- url: '/account/storage',
77
- ...options
78
- });
79
- /**
80
- * Get webhook signing secret
81
- *
82
- * Returns the webhook signing secret for your account. If no
83
- * secret exists yet, one is generated automatically on first
84
- * access.
85
- *
86
- * Signing is account-scoped, not per-endpoint. Every webhook
87
- * delivery from any of your registered endpoints is signed
88
- * with this single secret. Rotate via
89
- * `POST /account/webhook-secret/rotate`.
90
- *
91
- * **Secret format**: the returned string looks base64-shaped
92
- * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
93
- * Use it AS-IS as a UTF-8 string when computing HMAC over a
94
- * delivery body. Base64-decoding before HMAC will silently
95
- * produce mismatched signatures.
96
- *
97
- * See the API-level "Webhook signing" section for the full
98
- * wire format (header name, signed string shape, hash algo,
99
- * tolerance) including a language-agnostic verification
100
- * recipe.
101
- *
102
- */
103
- export const getWebhookSecret = (options) => (options?.client ?? client).get({
104
- security: [{ scheme: 'bearer', type: 'http' }],
105
- url: '/account/webhook-secret',
106
- ...options
107
- });
108
- /**
109
- * Rotate webhook signing secret
110
- *
111
- * Generates a new webhook signing secret, replacing the current one.
112
- * Rate limited to once per 60 minutes.
113
- *
114
- */
115
- export const rotateWebhookSecret = (options) => (options?.client ?? client).post({
116
- security: [{ scheme: 'bearer', type: 'http' }],
117
- url: '/account/webhook-secret/rotate',
118
- ...options
119
- });
120
- /**
121
- * List all domains
122
- *
123
- * Returns all verified and unverified domains for your organization,
124
- * sorted by creation date (newest first). Each domain includes a
125
- * `verified` boolean to distinguish between the two states.
126
- *
127
- */
128
- export const listDomains = (options) => (options?.client ?? client).get({
129
- security: [{ scheme: 'bearer', type: 'http' }],
130
- url: '/domains',
131
- ...options
132
- });
133
- /**
134
- * Claim a new domain
135
- *
136
- * Creates an unverified domain claim. You will receive a
137
- * `verification_token` to add as a DNS TXT record before
138
- * calling the verify endpoint.
139
- *
140
- */
141
- export const addDomain = (options) => (options.client ?? client).post({
142
- security: [{ scheme: 'bearer', type: 'http' }],
143
- url: '/domains',
144
- ...options,
145
- headers: {
146
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
147
- ...options.headers
148
- }
149
- });
150
- /**
151
- * Delete a domain
152
- *
153
- * Deletes a verified or unverified domain claim.
154
- */
155
- export const deleteDomain = (options) => (options.client ?? client).delete({
156
- security: [{ scheme: 'bearer', type: 'http' }],
157
- url: '/domains/{id}',
158
- ...options
159
- });
160
- /**
161
- * Update domain settings
162
- *
163
- * Update a verified domain's settings. Only verified domains can be
164
- * updated. Per-domain spam thresholds require a Pro plan.
165
- *
166
- */
167
- export const updateDomain = (options) => (options.client ?? client).patch({
168
- security: [{ scheme: 'bearer', type: 'http' }],
169
- url: '/domains/{id}',
170
- ...options,
171
- headers: {
172
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
173
- ...options.headers
174
- }
175
- });
176
- /**
177
- * Verify domain ownership
178
- *
179
- * Checks DNS records (MX and TXT) to verify domain ownership.
180
- * On success, the domain is promoted from unverified to verified.
181
- * On failure, returns which checks passed and which failed.
182
- *
183
- */
184
- export const verifyDomain = (options) => (options.client ?? client).post({
185
- security: [{ scheme: 'bearer', type: 'http' }],
186
- url: '/domains/{id}/verify',
187
- ...options
188
- });
189
- /**
190
- * List inbound emails
191
- *
192
- * Returns a paginated list of INBOUND emails received at your
193
- * verified domains. Outbound messages sent via /send-mail are
194
- * not included; this endpoint is the inbox view, not a
195
- * unified send/receive history.
196
- *
197
- * Supports filtering by domain, status, date range, and
198
- * free-text search across subject, sender, and recipient
199
- * fields.
200
- *
201
- * For a compact text-table summary of the most recent N
202
- * inbounds (no filters, no cursor pagination), the CLI ships
203
- * `primitive emails:latest` as a one-line-per-email shortcut.
204
- * It's TTY-aware so id columns are full UUIDs when piped, and
205
- * a `--json` flag returns the same envelope this endpoint
206
- * does. Use whichever fits the call site.
207
- *
208
- */
209
- export const listEmails = (options) => (options?.client ?? client).get({
210
- security: [{ scheme: 'bearer', type: 'http' }],
211
- url: '/emails',
212
- ...options
213
- });
214
- /**
215
- * Search inbound emails
216
- *
217
- * Searches inbound emails with structured filters and optional
218
- * full-text matching across parsed email fields. This endpoint is
219
- * optimized for filtered inbox views and CLI polling workflows:
220
- * callers that only need new accepted mail can pass
221
- * `sort=received_at_asc`, `snippet=false`, `include_facets=false`,
222
- * and a `date_from` timestamp.
223
- *
224
- * `q`, `subject`, and `body` use the same English full-text index
225
- * as the web inbox search. Structured filters such as `from`, `to`,
226
- * `domain_id`, status, attachment presence, and spam score bounds
227
- * are combined with the text query.
228
- *
229
- */
230
- export const searchEmails = (options) => (options?.client ?? client).get({
231
- security: [{ scheme: 'bearer', type: 'http' }],
232
- url: '/emails/search',
233
- ...options
234
- });
235
- /**
236
- * Delete an email
237
- */
238
- export const deleteEmail = (options) => (options.client ?? client).delete({
239
- security: [{ scheme: 'bearer', type: 'http' }],
240
- url: '/emails/{id}',
241
- ...options
242
- });
243
- /**
244
- * Get inbound email by id
245
- *
246
- * Returns the full record for an inbound email received at one
247
- * of your verified domains, including the parsed text and HTML
248
- * bodies, threading metadata, SMTP envelope detail, webhook
249
- * delivery state, and a `replies` array for any outbound sends
250
- * recorded as replies to this inbound.
251
- *
252
- * For listing inbound emails (with cursor pagination, status
253
- * and date filters, and free-text search), use
254
- * `/emails`. Outbound (sent) email records are NOT returned
255
- * here; use `/sent-emails/{id}` for those.
256
- *
257
- * The response carries four sender-shaped fields whose
258
- * meanings overlap. `from_email` is the canonical "who sent
259
- * this" field for most use cases (parsed bare address from
260
- * the `From:` header, with a `sender` fallback). `from_header`
261
- * is the raw header including any display name. `sender` and
262
- * `smtp_mail_from` both carry the SMTP envelope MAIL FROM
263
- * (return-path) and are equal by construction; `sender` is
264
- * the older field name retained for compatibility. See
265
- * `primitive describe emails:get-email | jq '.responseSchema.properties'`
266
- * for per-field detail.
267
- *
268
- */
269
- export const getEmail = (options) => (options.client ?? client).get({
270
- security: [{ scheme: 'bearer', type: 'http' }],
271
- url: '/emails/{id}',
272
- ...options
273
- });
274
- /**
275
- * Download raw email
276
- *
277
- * Downloads the raw RFC 822 email file (.eml). Authenticates via
278
- * a signed download token (provided in webhook payloads) or a
279
- * valid session.
280
- *
281
- */
282
- export const downloadRawEmail = (options) => (options.client ?? client).get({
283
- security: [{ scheme: 'bearer', type: 'http' }, {
284
- in: 'query',
285
- name: 'token',
286
- type: 'apiKey'
287
- }],
288
- url: '/emails/{id}/raw',
289
- ...options
290
- });
291
- /**
292
- * Download email attachments
293
- *
294
- * Downloads all attachments as a gzip-compressed tar archive.
295
- * Authenticates via a signed download token (provided in webhook
296
- * payloads) or a valid session.
297
- *
298
- */
299
- export const downloadAttachments = (options) => (options.client ?? client).get({
300
- security: [{ scheme: 'bearer', type: 'http' }, {
301
- in: 'query',
302
- name: 'token',
303
- type: 'apiKey'
304
- }],
305
- url: '/emails/{id}/attachments.tar.gz',
306
- ...options
307
- });
308
- /**
309
- * Reply to an inbound email
310
- *
311
- * Sends an outbound reply to the inbound email identified by `id`.
312
- * Threading headers (`In-Reply-To`, `References`), recipient
313
- * derivation (Reply-To, then From, then bare sender), and the
314
- * `Re:` subject prefix are all derived server-side from the
315
- * stored inbound row. The request body carries only the message
316
- * body and optional `wait` flag; passing any header or recipient
317
- * override is rejected by the schema (`additionalProperties:
318
- * false`).
319
- *
320
- * Forwards through the same gates as `/send-mail`: the response
321
- * status, error envelope, and `idempotent_replay` flag mirror
322
- * the send-mail contract verbatim.
323
- *
324
- */
325
- export const replyToEmail = (options) => (options.client ?? client).post({
326
- security: [{ scheme: 'bearer', type: 'http' }],
327
- url: '/emails/{id}/reply',
328
- ...options,
329
- headers: {
330
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
331
- ...options.headers
332
- }
333
- });
334
- /**
335
- * Replay email webhooks
336
- *
337
- * Re-delivers the webhook payload for this email to all active
338
- * endpoints matching the email's domain. Rate limited per-email
339
- * (short cooldown between successive replays of the same email)
340
- * and per-org (burst + sustained windows), sharing an org-wide
341
- * budget with delivery replays.
342
- *
343
- */
344
- export const replayEmailWebhooks = (options) => (options.client ?? client).post({
345
- security: [{ scheme: 'bearer', type: 'http' }],
346
- url: '/emails/{id}/replay',
347
- ...options
348
- });
349
- /**
350
- * Discard email content
351
- *
352
- * Permanently deletes the email's raw bytes, parsed body (text + HTML),
353
- * and attachments while preserving metadata (sender, recipient,
354
- * subject, timestamps, hashes, attachment manifest) for audit logs.
355
- * Idempotent: a second call returns success with
356
- * `already_discarded: true` and does no work.
357
- *
358
- * **Gated** on the customer's discard-content opt-in (managed in the
359
- * dashboard at Settings > Webhooks). When the toggle is off, this
360
- * endpoint returns `403` with code `discard_not_enabled` and a
361
- * message pointing the human at the dashboard. There is intentionally
362
- * no API to flip this toggle. Opting in to a destructive,
363
- * non-reversible operation must be a deliberate human click in the
364
- * UI.
365
- *
366
- */
367
- export const discardEmailContent = (options) => (options.client ?? client).post({
368
- security: [{ scheme: 'bearer', type: 'http' }],
369
- url: '/emails/{id}/discard-content',
370
- ...options
371
- });
372
- /**
373
- * List webhook endpoints
374
- *
375
- * Returns all active (non-deleted) webhook endpoints.
376
- */
377
- export const listEndpoints = (options) => (options?.client ?? client).get({
378
- security: [{ scheme: 'bearer', type: 'http' }],
379
- url: '/endpoints',
380
- ...options
381
- });
382
- /**
383
- * Create a webhook endpoint
384
- *
385
- * Creates a new webhook endpoint. If a deactivated endpoint
386
- * with the same URL and domain exists, it is reactivated
387
- * instead. Subject to plan limits on the number of active
388
- * endpoints.
389
- *
390
- * **Signing is account-scoped, not per-endpoint.** This call
391
- * does not return any signing material; every endpoint on the
392
- * account uses the same webhook secret, fetched via
393
- * `GET /account/webhook-secret`. See the API-level "Webhook
394
- * signing" section for the full wire format (header name,
395
- * signed string, hash algo, secret format, tolerance) and a
396
- * language-agnostic verification recipe.
397
- *
398
- * After creating the endpoint, fire a test delivery against
399
- * it via `POST /endpoints/{id}/test` to confirm your verifier
400
- * accepts the signature.
401
- *
402
- */
403
- export const createEndpoint = (options) => (options.client ?? client).post({
404
- security: [{ scheme: 'bearer', type: 'http' }],
405
- url: '/endpoints',
406
- ...options,
407
- headers: {
408
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
409
- ...options.headers
410
- }
411
- });
412
- /**
413
- * Delete a webhook endpoint
414
- *
415
- * Soft-deletes a webhook endpoint. The endpoint will no longer
416
- * receive webhook deliveries.
417
- *
418
- */
419
- export const deleteEndpoint = (options) => (options.client ?? client).delete({
420
- security: [{ scheme: 'bearer', type: 'http' }],
421
- url: '/endpoints/{id}',
422
- ...options
423
- });
424
- /**
425
- * Update a webhook endpoint
426
- *
427
- * Updates an active webhook endpoint. If the URL is changed, the old
428
- * endpoint is deactivated and a new one is created (or an existing
429
- * deactivated endpoint with the new URL is reactivated).
430
- *
431
- */
432
- export const updateEndpoint = (options) => (options.client ?? client).patch({
433
- security: [{ scheme: 'bearer', type: 'http' }],
434
- url: '/endpoints/{id}',
435
- ...options,
436
- headers: {
437
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
438
- ...options.headers
439
- }
440
- });
441
- /**
442
- * Send a test webhook
443
- *
444
- * Sends a sample `email.received` event to the endpoint. The request
445
- * includes SSRF protection (private IP rejection and DNS pinning).
446
- * Rate limited to 4 per minute and 30 per hour (non-exempt).
447
- * Successful deliveries and verified-domain endpoints are exempt
448
- * from the rate limit.
449
- *
450
- */
451
- export const testEndpoint = (options) => (options.client ?? client).post({
452
- security: [{ scheme: 'bearer', type: 'http' }],
453
- url: '/endpoints/{id}/test',
454
- ...options
455
- });
456
- /**
457
- * List filter rules
458
- *
459
- * Returns all whitelist and blocklist filter rules.
460
- */
461
- export const listFilters = (options) => (options?.client ?? client).get({
462
- security: [{ scheme: 'bearer', type: 'http' }],
463
- url: '/filters',
464
- ...options
465
- });
466
- /**
467
- * Create a filter rule
468
- *
469
- * Creates a new whitelist or blocklist filter. Per-domain filters
470
- * require a Pro plan. Patterns are stored as lowercase.
471
- *
472
- */
473
- export const createFilter = (options) => (options.client ?? client).post({
474
- security: [{ scheme: 'bearer', type: 'http' }],
475
- url: '/filters',
476
- ...options,
477
- headers: {
478
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
479
- ...options.headers
480
- }
481
- });
482
- /**
483
- * Delete a filter rule
484
- */
485
- export const deleteFilter = (options) => (options.client ?? client).delete({
486
- security: [{ scheme: 'bearer', type: 'http' }],
487
- url: '/filters/{id}',
488
- ...options
489
- });
490
- /**
491
- * Update a filter rule
492
- *
493
- * Toggle a filter's enabled state.
494
- */
495
- export const updateFilter = (options) => (options.client ?? client).patch({
496
- security: [{ scheme: 'bearer', type: 'http' }],
497
- url: '/filters/{id}',
498
- ...options,
499
- headers: {
500
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
501
- ...options.headers
502
- }
503
- });
504
- /**
505
- * List webhook deliveries
506
- *
507
- * Returns a paginated list of webhook delivery attempts. Each delivery
508
- * includes a nested `email` object with sender, recipient, and subject.
509
- *
510
- */
511
- export const listDeliveries = (options) => (options?.client ?? client).get({
512
- security: [{ scheme: 'bearer', type: 'http' }],
513
- url: '/webhooks/deliveries',
514
- ...options
515
- });
516
- /**
517
- * Replay a webhook delivery
518
- *
519
- * Re-sends the stored webhook payload from a previous delivery attempt.
520
- * If the original endpoint is still active, it is targeted. If the
521
- * original endpoint was deleted, the oldest active endpoint is used.
522
- * Deactivated endpoints cannot be replayed to. Rate limited per-org,
523
- * sharing an org-wide budget with email replays.
524
- *
525
- */
526
- export const replayDelivery = (options) => (options.client ?? client).post({
527
- security: [{ scheme: 'bearer', type: 'http' }],
528
- url: '/webhooks/deliveries/{id}/replay',
529
- ...options
530
- });
531
- /**
532
- * List send-permission rules
533
- *
534
- * Returns a flat list of rules describing every recipient the
535
- * caller may send to. Each rule has a `type`, a kind-specific
536
- * payload, and a human-readable `description`. If any rule
537
- * matches the recipient, /send-mail will accept the send under
538
- * the recipient-scope check.
539
- *
540
- * The endpoint is the answer to "where can I send" without
541
- * exposing internal entitlement names. Agents that don't
542
- * recognize a `type` can still read the `description` prose
543
- * and act on it.
544
- *
545
- * Rule kinds, ordered broadest-first so an agent can stop
546
- * scanning at the first match:
547
- *
548
- * 1. `any_recipient` (one entry, only when the org can send
549
- * anywhere): every other rule below it is redundant.
550
- * 2. `managed_zone` (always emitted, one per Primitive-managed
551
- * zone): sends to any address at *.primitive.email or
552
- * *.email.works always succeed; no entitlement required.
553
- * 3. `your_domain` (one per active verified outbound domain
554
- * owned by the org): sends to that domain are approved.
555
- * 4. `address` (one per address that has authenticated
556
- * inbound mail to the org, capped at `meta.address_cap`):
557
- * sends to that exact address are approved.
558
- *
559
- * The list is informational, not an authorization check.
560
- * /send-mail remains the source of truth on whether an
561
- * individual send will succeed (it also enforces the
562
- * from-address and the `send_mail` entitlement, which are
563
- * not recipient-scope concerns and are not represented here).
564
- *
565
- */
566
- export const getSendPermissions = (options) => (options?.client ?? client).get({
567
- security: [{ scheme: 'bearer', type: 'http' }],
568
- url: '/send-permissions',
569
- ...options
570
- });
571
- /**
572
- * Send outbound email
573
- *
574
- * Sends an outbound email through Primitive's outbound relay. By default
575
- * the request returns once the relay accepts the message for delivery.
576
- * Set `wait: true` to wait for the first downstream SMTP delivery outcome.
577
- *
578
- * **Host routing.** /send-mail is served by the attachments-
579
- * supporting host (`https://api.primitive.dev/v1`) so the
580
- * request body can carry inline attachments up to ~30 MiB raw.
581
- * The primary host (`https://www.primitive.dev/api/v1`) also
582
- * accepts /send-mail for attachment-free sends; sends WITH
583
- * attachments to the primary host return 413
584
- * `attachments_unsupported_on_this_endpoint`. The typed SDKs
585
- * route /send-mail to the attachments host automatically.
586
- *
587
- */
588
- export const sendEmail = (options) => (options.client ?? client).post({
589
- security: [{ scheme: 'bearer', type: 'http' }],
590
- url: '/send-mail',
591
- ...options,
592
- headers: {
593
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
594
- ...options.headers
595
- }
596
- });
597
- /**
598
- * List outbound sent emails
599
- *
600
- * Returns a paginated list of OUTBOUND emails the caller's
601
- * org has sent via /send-mail (and /emails/{id}/reply, which
602
- * forwards through /send-mail). Includes every recorded
603
- * attempt, including gate-denied attempts that the agent
604
- * never called and rows still in `queued` state.
605
- *
606
- * For inbound mail received at your verified domains, see
607
- * /emails. There is no unified send/receive history endpoint;
608
- * the two surfaces are intentionally separate because the
609
- * underlying tables, statuses, and lifecycle differ.
610
- *
611
- * Email bodies (`body_text`, `body_html`) are NOT included on
612
- * list rows so a 50-row page can't balloon into a multi-MB
613
- * response when sends are near the 5MB body cap. Use
614
- * /sent-emails/{id} to fetch a single row with bodies, or
615
- * cross-reference by `client_idempotency_key` if the caller
616
- * already has the body locally.
617
- *
618
- */
619
- export const listSentEmails = (options) => (options?.client ?? client).get({
620
- security: [{ scheme: 'bearer', type: 'http' }],
621
- url: '/sent-emails',
622
- ...options
623
- });
624
- /**
625
- * Get a sent email by id
626
- *
627
- * Returns the full sent-email record by id, including
628
- * `body_text` and `body_html` (omitted from the listing
629
- * endpoint to keep paginated responses small). Use this when
630
- * diagnosing a specific send, e.g. inspecting the receiver's
631
- * SMTP response on a `bounced` row or pulling the gate
632
- * denial detail on a `gate_denied` row.
633
- *
634
- */
635
- export const getSentEmail = (options) => (options.client ?? client).get({
636
- security: [{ scheme: 'bearer', type: 'http' }],
637
- url: '/sent-emails/{id}',
638
- ...options
639
- });
640
- /**
641
- * List functions
642
- *
643
- * Returns every active (non-deleted) function in the org, newest
644
- * first. Each entry carries the deploy status and the gateway URL
645
- * that the platform's webhook delivery loop posts to. To inspect
646
- * the source code or deploy errors, use `GET /functions/{id}`.
647
- *
648
- */
649
- export const listFunctions = (options) => (options?.client ?? client).get({
650
- security: [{ scheme: 'bearer', type: 'http' }],
651
- url: '/functions',
652
- ...options
653
- });
654
- /**
655
- * Deploy a function
656
- *
657
- * Creates and deploys a new function. The handler must be a single
658
- * ESM module whose default export is an object with an async
659
- * `fetch(request, env)` method (Workers-style). The gateway
660
- * HMAC-verifies the POST against the org's webhook secret before
661
- * invoking the handler; the request body parses to an
662
- * `email.received` event (see `EmailReceivedEvent` and the
663
- * Webhook payload section for the full schema). Code is bundled
664
- * before being uploaded; ship a single self-contained file rather
665
- * than relying on external imports.
666
- *
667
- * **Code limits.** `code` is capped at 1 MiB UTF-8. `sourceMap`
668
- * (optional) is capped at 5 MiB UTF-8 and is stored only on the
669
- * edge runtime side; it is not persisted in Primitive's database.
670
- *
671
- * **Auto-wiring.** On successful deploy, Primitive automatically
672
- * creates a webhook endpoint that delivers inbound mail to the
673
- * function. There is nothing to configure on the Endpoints API
674
- * for this to work; the gateway URL returned here is for
675
- * reference only and is not directly callable from outside.
676
- *
677
- * **Secrets.** New functions ship with the managed secrets
678
- * (`PRIMITIVE_WEBHOOK_SECRET`, `PRIMITIVE_API_KEY`) already
679
- * bound. Add user-set secrets via
680
- * `POST /functions/{id}/secrets`; secret writes only land in the
681
- * running handler on the next redeploy.
682
- *
683
- */
684
- export const createFunction = (options) => (options.client ?? client).post({
685
- security: [{ scheme: 'bearer', type: 'http' }],
686
- url: '/functions',
687
- ...options,
688
- headers: {
689
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
690
- ...options.headers
691
- }
692
- });
693
- /**
694
- * Delete a function
695
- *
696
- * Soft-deletes the function row, removes the script from the edge
697
- * runtime, and deactivates the auto-wired webhook endpoint so no
698
- * further inbound mail is delivered. Past deploy history,
699
- * invocations, and logs are retained.
700
- *
701
- * Returns 502 if the runtime delete fails partway; the function
702
- * row stays in place and the call is safe to retry until it
703
- * succeeds.
704
- *
705
- */
706
- export const deleteFunction = (options) => (options.client ?? client).delete({
707
- security: [{ scheme: 'bearer', type: 'http' }],
708
- url: '/functions/{id}',
709
- ...options
710
- });
711
- /**
712
- * Get a function
713
- *
714
- * Returns the full record for a function, including its current
715
- * source code and the deploy status / error from the most recent
716
- * deploy attempt.
717
- *
718
- */
719
- export const getFunction = (options) => (options.client ?? client).get({
720
- security: [{ scheme: 'bearer', type: 'http' }],
721
- url: '/functions/{id}',
722
- ...options
723
- });
724
- /**
725
- * Update and redeploy a function
726
- *
727
- * Replaces the function's source code with the body's `code` and
728
- * triggers a redeploy. Same size limits as `POST /functions`.
729
- * Use this verb to push secret writes into the running handler:
730
- * passing the same `code` re-runs the deploy and refreshes the
731
- * binding set with the latest values from the secrets table.
732
- *
733
- * On a 502 deploy failure, the previously-deployed code stays
734
- * live; the runtime never serves a half-built bundle. The
735
- * `deploy_error` field on the returned record carries the error
736
- * that came back from the runtime so you can surface it to users
737
- * without polling.
738
- *
739
- */
740
- export const updateFunction = (options) => (options.client ?? client).put({
741
- security: [{ scheme: 'bearer', type: 'http' }],
742
- url: '/functions/{id}',
743
- ...options,
744
- headers: {
745
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
746
- ...options.headers
747
- }
748
- });
749
- /**
750
- * Send a test invocation
751
- *
752
- * Sends a real test email from a Primitive-controlled sender to a
753
- * local-part on one of the org's verified inbound domains. By
754
- * default the recipient is a synthetic
755
- * `__primitive_function_test+<random>@<domain>` address that
756
- * every handler's catch-all routing receives identically; pass
757
- * `local_part` to override and exercise routing logic that
758
- * branches on a specific recipient (the common pattern when one
759
- * function handles multiple inboxes like `summarize@` and
760
- * `action@`). The function fires through the normal MX delivery
761
- * path, so reply / send-mail calls from inside the handler
762
- * against the inbound's `email.id` work the same as in
763
- * production. Returns immediately after the send is queued; the
764
- * invocation appears on the function's invocations list within a
765
- * few seconds.
766
- *
767
- * Requires that the function is currently `deployed`. Returns 422
768
- * if the function is in `pending` or `failed` state, or if the
769
- * org has no verified inbound domain to receive the test mail.
770
- * Returns 400 if `local_part` is set to a value that does not
771
- * match the local-part character set.
772
- *
773
- */
774
- export const testFunction = (options) => (options.client ?? client).post({
775
- security: [{ scheme: 'bearer', type: 'http' }],
776
- url: '/functions/{id}/test',
777
- ...options,
778
- headers: {
779
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
780
- ...options.headers
781
- }
782
- });
783
- /**
784
- * List a function's secrets
785
- *
786
- * Returns metadata for every secret bound to the function, with
787
- * managed entries (provisioned by Primitive) listed first and
788
- * user-set entries listed alphabetically after. **Values are
789
- * never returned.** Secret writes are write-only.
790
- *
791
- * Managed entries (e.g. `PRIMITIVE_WEBHOOK_SECRET`,
792
- * `PRIMITIVE_API_KEY`) carry a `description` instead of
793
- * `created_at` / `updated_at`. They cannot be created, updated,
794
- * or deleted via this API.
795
- *
796
- */
797
- export const listFunctionSecrets = (options) => (options.client ?? client).get({
798
- security: [{ scheme: 'bearer', type: 'http' }],
799
- url: '/functions/{id}/secrets',
800
- ...options
801
- });
802
- /**
803
- * Create or update a secret
804
- *
805
- * Idempotent insert-or-update keyed on `(function_id, key)`.
806
- * Returns 201 the first time the key is set, 200 on subsequent
807
- * updates. Values are encrypted at rest and only become visible
808
- * to the running handler on the next deploy (`PUT /functions/{id}`
809
- * with the existing code is sufficient to refresh bindings).
810
- *
811
- * Keys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,
812
- * digits, underscores; first character is a letter or
813
- * underscore). Values are at most 4096 UTF-8 bytes. System-
814
- * managed keys are reserved and rejected.
815
- *
816
- */
817
- export const createFunctionSecret = (options) => (options.client ?? client).post({
818
- security: [{ scheme: 'bearer', type: 'http' }],
819
- url: '/functions/{id}/secrets',
820
- ...options,
821
- headers: {
822
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
823
- ...options.headers
824
- }
825
- });
826
- /**
827
- * Delete a secret
828
- *
829
- * Removes the secret. The binding stays live in the running
830
- * handler until the next deploy refreshes the binding set
831
- * (`PUT /functions/{id}` with the existing code is sufficient).
832
- * Returns 404 if the key did not exist. Managed system keys
833
- * cannot be deleted.
834
- *
835
- */
836
- export const deleteFunctionSecret = (options) => (options.client ?? client).delete({
837
- security: [{ scheme: 'bearer', type: 'http' }],
838
- url: '/functions/{id}/secrets/{key}',
839
- ...options
840
- });
841
- /**
842
- * Set a secret by key
843
- *
844
- * Path-keyed companion to `POST /functions/{id}/secrets`.
845
- * Idempotent: returns 201 the first time the key is set, 200 on
846
- * subsequent updates. Same validation rules and same write-only
847
- * guarantees as the POST verb; the new value lands in the running
848
- * handler on the next deploy.
849
- *
850
- */
851
- export const setFunctionSecret = (options) => (options.client ?? client).put({
852
- security: [{ scheme: 'bearer', type: 'http' }],
853
- url: '/functions/{id}/secrets/{key}',
854
- ...options,
855
- headers: {
856
- ...(options.body !== undefined && { 'Content-Type': 'application/json' }),
857
- ...options.headers
858
- }
859
- });
860
- /**
861
- * List a function's execution logs
862
- *
863
- * Returns the most recent `function_logs` rows for the function,
864
- * newest first. Each row is a single `console.log` / `console.error`
865
- * invocation captured from the running handler.
866
- *
867
- * Page through history with the opaque `cursor` returned as
868
- * `next_cursor`; pass it back as the `cursor` query param on the
869
- * next call. `next_cursor` is `null` when there are no further
870
- * rows. The cursor format is an implementation detail and should
871
- * not be parsed by callers.
872
- *
873
- */
874
- export const listFunctionLogs = (options) => (options.client ?? client).get({
875
- security: [{ scheme: 'bearer', type: 'http' }],
876
- url: '/functions/{id}/logs',
877
- ...options
878
- });