@spooled/sdk 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -19
- package/dist/{index-ZwiiavfA.d.cts → index-C1TpK-_a.d.cts} +35 -2
- package/dist/{index-ZwiiavfA.d.ts → index-C1TpK-_a.d.ts} +35 -2
- package/dist/index.cjs +40 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +1 -1
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +1 -1
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,13 @@ Official Node.js/TypeScript SDK for [Spooled Cloud](https://spooled.cloud) - a m
|
|
|
14
14
|
- **Realtime events** via WebSocket and SSE
|
|
15
15
|
- **Worker runtime** for processing jobs
|
|
16
16
|
- **Workflow DAGs** for complex job dependencies
|
|
17
|
-
- **gRPC streaming** for high-performance workers
|
|
17
|
+
- **gRPC streaming** for high-performance workers (with automatic limit enforcement)
|
|
18
|
+
- **Tier-based limits** with automatic enforcement across all endpoints
|
|
19
|
+
- **Organization management** with usage tracking
|
|
20
|
+
- **Webhook management** with automatic retries
|
|
21
|
+
- **Dead Letter Queue (DLQ)** operations
|
|
22
|
+
- **API Key management** with Redis caching (~28x faster authentication)
|
|
23
|
+
- **Billing integration** via Stripe
|
|
18
24
|
- **Automatic case conversion** between camelCase (SDK) and snake_case (API)
|
|
19
25
|
|
|
20
26
|
## Installation
|
|
@@ -165,6 +171,161 @@ await realtime.connect();
|
|
|
165
171
|
await realtime.subscribe({ queueName: 'my-queue' });
|
|
166
172
|
```
|
|
167
173
|
|
|
174
|
+
### Organization Management
|
|
175
|
+
|
|
176
|
+
Manage your organization and track usage:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Get current usage and limits
|
|
180
|
+
const usage = await client.organizations.getUsage();
|
|
181
|
+
console.log(`Active jobs: ${usage.active_jobs.current}/${usage.active_jobs.limit}`);
|
|
182
|
+
console.log(`Plan: ${usage.plan.tier}`);
|
|
183
|
+
|
|
184
|
+
// Generate a unique slug for a new organization
|
|
185
|
+
const { slug } = await client.organizations.generateSlug('My Company');
|
|
186
|
+
|
|
187
|
+
// Check if a slug is available
|
|
188
|
+
const { available } = await client.organizations.checkSlug('my-company');
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Webhooks
|
|
192
|
+
|
|
193
|
+
Configure outgoing webhooks for job events:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Create webhook
|
|
197
|
+
const webhook = await client.webhooks.create({
|
|
198
|
+
url: 'https://your-app.com/webhooks/spooled',
|
|
199
|
+
events: ['job.completed', 'job.failed'],
|
|
200
|
+
queueName: 'my-queue',
|
|
201
|
+
secret: 'webhook_secret_key'
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Retry a failed delivery
|
|
205
|
+
await client.webhooks.retryDelivery(webhookId, deliveryId);
|
|
206
|
+
|
|
207
|
+
// Get delivery history
|
|
208
|
+
const deliveries = await client.webhooks.getDeliveries(webhookId);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Dead Letter Queue (DLQ)
|
|
212
|
+
|
|
213
|
+
Manage jobs that have exhausted all retries:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// List DLQ jobs
|
|
217
|
+
const dlqJobs = await client.jobs.dlq.list({ limit: 100 });
|
|
218
|
+
|
|
219
|
+
// Retry specific jobs from DLQ
|
|
220
|
+
await client.jobs.dlq.retry({
|
|
221
|
+
jobIds: ['job-1', 'job-2'],
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Retry jobs by queue
|
|
225
|
+
await client.jobs.dlq.retry({
|
|
226
|
+
queueName: 'my-queue',
|
|
227
|
+
limit: 50
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Purge DLQ (requires confirmation)
|
|
231
|
+
await client.jobs.dlq.purge({
|
|
232
|
+
queueName: 'my-queue',
|
|
233
|
+
confirm: true
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### API Key Management
|
|
238
|
+
|
|
239
|
+
Manage API keys programmatically:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
// Create a new API key
|
|
243
|
+
const apiKey = await client.apiKeys.create({
|
|
244
|
+
name: 'Production Worker',
|
|
245
|
+
queues: ['emails', 'notifications'],
|
|
246
|
+
rateLimit: 1000
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
console.log(`Save this key: ${apiKey.key}`); // Only shown once!
|
|
250
|
+
|
|
251
|
+
// List all API keys
|
|
252
|
+
const keys = await client.apiKeys.list();
|
|
253
|
+
|
|
254
|
+
// Revoke a key
|
|
255
|
+
await client.apiKeys.revoke(keyId);
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Billing & Subscriptions
|
|
259
|
+
|
|
260
|
+
Manage billing via Stripe integration:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Get billing status
|
|
264
|
+
const status = await client.billing.getStatus();
|
|
265
|
+
|
|
266
|
+
// Create customer portal session
|
|
267
|
+
const { url } = await client.billing.createPortal({
|
|
268
|
+
returnUrl: 'https://your-app.com/settings'
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Redirect user to: url
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Authentication
|
|
275
|
+
|
|
276
|
+
Email-based passwordless authentication:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
// Start email login flow
|
|
280
|
+
await client.auth.startEmailLogin('user@example.com');
|
|
281
|
+
// User receives email with login link
|
|
282
|
+
|
|
283
|
+
// Check if email exists
|
|
284
|
+
const { exists } = await client.auth.checkEmail('user@example.com');
|
|
285
|
+
|
|
286
|
+
// Exchange API key for JWT
|
|
287
|
+
const { accessToken, refreshToken } = await client.auth.login({
|
|
288
|
+
apiKey: 'sk_live_...'
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// Use JWT for subsequent requests
|
|
292
|
+
const jwtClient = new SpooledClient({ accessToken });
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Plan Limits
|
|
296
|
+
|
|
297
|
+
All operations automatically enforce tier-based limits:
|
|
298
|
+
|
|
299
|
+
| Tier | Active Jobs | Daily Jobs | Queues | Workers | Webhooks |
|
|
300
|
+
|------|-------------|------------|--------|---------|----------|
|
|
301
|
+
| **Free** | 10 | 1,000 | 5 | 3 | 2 |
|
|
302
|
+
| **Starter** | 100 | 100,000 | 25 | 25 | 10 |
|
|
303
|
+
| **Enterprise** | Unlimited | Unlimited | Unlimited | Unlimited | Unlimited |
|
|
304
|
+
|
|
305
|
+
**Limits are enforced on:**
|
|
306
|
+
- ✅ HTTP job creation (`POST /jobs`, `POST /jobs/bulk`)
|
|
307
|
+
- ✅ gRPC job enqueue
|
|
308
|
+
- ✅ Workflow creation (counts all jobs in workflow)
|
|
309
|
+
- ✅ Schedule triggers
|
|
310
|
+
- ✅ DLQ retry operations
|
|
311
|
+
- ✅ Worker registration
|
|
312
|
+
- ✅ Queue creation
|
|
313
|
+
- ✅ Webhook creation
|
|
314
|
+
|
|
315
|
+
When limits are exceeded, you'll receive a `403 Forbidden` response with details:
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
try {
|
|
319
|
+
await client.jobs.create({ /* ... */ });
|
|
320
|
+
} catch (error) {
|
|
321
|
+
if (error.statusCode === 403 && error.code === 'limit_exceeded') {
|
|
322
|
+
console.log(`Limit: ${error.message}`);
|
|
323
|
+
console.log(`Current: ${error.current}, Max: ${error.limit}`);
|
|
324
|
+
console.log(`Upgrade to: ${error.upgradeTo}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
168
329
|
## Error Handling
|
|
169
330
|
|
|
170
331
|
All errors extend `SpooledError` with specific subclasses:
|
|
@@ -174,6 +335,7 @@ import {
|
|
|
174
335
|
NotFoundError,
|
|
175
336
|
RateLimitError,
|
|
176
337
|
ValidationError,
|
|
338
|
+
LimitExceededError,
|
|
177
339
|
isSpooledError,
|
|
178
340
|
} from '@spooled/sdk';
|
|
179
341
|
|
|
@@ -182,6 +344,9 @@ try {
|
|
|
182
344
|
} catch (error) {
|
|
183
345
|
if (error instanceof NotFoundError) {
|
|
184
346
|
console.log('Job not found');
|
|
347
|
+
} else if (error instanceof LimitExceededError) {
|
|
348
|
+
console.log(`Plan limit: ${error.message}`);
|
|
349
|
+
console.log(`Upgrade to ${error.upgradeTo} for more capacity`);
|
|
185
350
|
} else if (error instanceof RateLimitError) {
|
|
186
351
|
console.log(`Retry after ${error.getRetryAfter()} seconds`);
|
|
187
352
|
} else if (isSpooledError(error)) {
|
|
@@ -192,35 +357,57 @@ try {
|
|
|
192
357
|
|
|
193
358
|
## gRPC API
|
|
194
359
|
|
|
195
|
-
For high-throughput workers, use the native gRPC API:
|
|
360
|
+
For high-throughput workers, use the native gRPC API with the included gRPC client:
|
|
196
361
|
|
|
197
362
|
```typescript
|
|
198
|
-
import
|
|
199
|
-
import * as protoLoader from '@grpc/proto-loader';
|
|
363
|
+
import { SpooledGrpcClient } from '@spooled/sdk';
|
|
200
364
|
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
const client = new spooled.QueueService(
|
|
365
|
+
// Connect to gRPC server
|
|
366
|
+
const grpcClient = new SpooledGrpcClient(
|
|
205
367
|
'grpc.spooled.cloud:443',
|
|
206
|
-
|
|
368
|
+
'sk_live_your_key'
|
|
207
369
|
);
|
|
208
370
|
|
|
209
|
-
|
|
210
|
-
|
|
371
|
+
// Register worker
|
|
372
|
+
const { workerId } = await grpcClient.workers.register({
|
|
373
|
+
queueName: 'emails',
|
|
374
|
+
hostname: 'worker-1',
|
|
375
|
+
maxConcurrency: 10
|
|
376
|
+
});
|
|
211
377
|
|
|
212
|
-
//
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
378
|
+
// Enqueue job (enforces plan limits automatically)
|
|
379
|
+
const { jobId } = await grpcClient.queue.enqueue({
|
|
380
|
+
queueName: 'emails',
|
|
381
|
+
payload: { to: 'user@example.com' },
|
|
382
|
+
priority: 5
|
|
383
|
+
});
|
|
218
384
|
|
|
219
|
-
|
|
220
|
-
|
|
385
|
+
// Dequeue jobs in batch
|
|
386
|
+
const { jobs } = await grpcClient.queue.dequeue({
|
|
387
|
+
queueName: 'emails',
|
|
388
|
+
workerId,
|
|
389
|
+
batchSize: 10,
|
|
390
|
+
leaseDurationSecs: 300
|
|
221
391
|
});
|
|
392
|
+
|
|
393
|
+
// Process and complete
|
|
394
|
+
for (const job of jobs) {
|
|
395
|
+
await processJob(job);
|
|
396
|
+
await grpcClient.queue.complete({
|
|
397
|
+
jobId: job.id,
|
|
398
|
+
workerId,
|
|
399
|
+
result: { success: true }
|
|
400
|
+
});
|
|
401
|
+
}
|
|
222
402
|
```
|
|
223
403
|
|
|
404
|
+
**gRPC Features:**
|
|
405
|
+
- ⚡ **~28x faster** than HTTP (with Redis cache: ~50ms vs 1400ms)
|
|
406
|
+
- 🛡️ **Automatic plan limit enforcement** on enqueue operations
|
|
407
|
+
- 📦 **Batch operations** for higher throughput
|
|
408
|
+
- 🔄 **Streaming support** for real-time job processing
|
|
409
|
+
- 🔐 **Secure authentication** via API key metadata
|
|
410
|
+
|
|
224
411
|
See [gRPC Guide](docs/grpc.md) for complete documentation.
|
|
225
412
|
|
|
226
413
|
## TypeScript Support
|
|
@@ -107,11 +107,11 @@ declare const DEFAULT_CONFIG: {
|
|
|
107
107
|
successThreshold: number;
|
|
108
108
|
timeout: number;
|
|
109
109
|
};
|
|
110
|
-
readonly userAgent: "@spooled/sdk-nodejs/1.0.
|
|
110
|
+
readonly userAgent: "@spooled/sdk-nodejs/1.0.14";
|
|
111
111
|
readonly autoRefreshToken: true;
|
|
112
112
|
};
|
|
113
113
|
/** SDK version */
|
|
114
|
-
declare const SDK_VERSION = "1.0.
|
|
114
|
+
declare const SDK_VERSION = "1.0.14";
|
|
115
115
|
/** API version prefix */
|
|
116
116
|
declare const API_VERSION = "v1";
|
|
117
117
|
/**
|
|
@@ -422,6 +422,19 @@ declare class AuthResource {
|
|
|
422
422
|
* Validate a token
|
|
423
423
|
*/
|
|
424
424
|
validate(params: ValidateTokenParams): Promise<ValidateTokenResponse>;
|
|
425
|
+
/**
|
|
426
|
+
* Start email-based login flow (sends magic link)
|
|
427
|
+
*/
|
|
428
|
+
startEmailLogin(email: string): Promise<{
|
|
429
|
+
success: boolean;
|
|
430
|
+
message: string;
|
|
431
|
+
}>;
|
|
432
|
+
/**
|
|
433
|
+
* Check if an email address exists in the system
|
|
434
|
+
*/
|
|
435
|
+
checkEmail(email: string): Promise<{
|
|
436
|
+
exists: boolean;
|
|
437
|
+
}>;
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
/**
|
|
@@ -1284,6 +1297,13 @@ declare class WorkflowsResource {
|
|
|
1284
1297
|
* Cancel a workflow
|
|
1285
1298
|
*/
|
|
1286
1299
|
cancel(id: string): Promise<WorkflowResponse>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Retry a failed workflow
|
|
1302
|
+
*
|
|
1303
|
+
* Resets all failed/deadletter jobs back to pending and resumes the workflow.
|
|
1304
|
+
* Only workflows with status 'failed' can be retried.
|
|
1305
|
+
*/
|
|
1306
|
+
retry(id: string): Promise<WorkflowResponse>;
|
|
1287
1307
|
private getJobDependencies;
|
|
1288
1308
|
private addJobDependencies;
|
|
1289
1309
|
}
|
|
@@ -1388,6 +1408,13 @@ declare class WebhooksResource {
|
|
|
1388
1408
|
* Get webhook delivery history
|
|
1389
1409
|
*/
|
|
1390
1410
|
getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Retry a specific webhook delivery
|
|
1413
|
+
*/
|
|
1414
|
+
retryDelivery(webhookId: string, deliveryId: string): Promise<{
|
|
1415
|
+
success: boolean;
|
|
1416
|
+
message: string;
|
|
1417
|
+
}>;
|
|
1391
1418
|
}
|
|
1392
1419
|
|
|
1393
1420
|
/**
|
|
@@ -1633,6 +1660,12 @@ declare class OrganizationsResource {
|
|
|
1633
1660
|
* Check slug availability
|
|
1634
1661
|
*/
|
|
1635
1662
|
checkSlug(slug: string): Promise<CheckSlugResponse>;
|
|
1663
|
+
/**
|
|
1664
|
+
* Generate a unique slug from an organization name
|
|
1665
|
+
*/
|
|
1666
|
+
generateSlug(name: string): Promise<{
|
|
1667
|
+
slug: string;
|
|
1668
|
+
}>;
|
|
1636
1669
|
}
|
|
1637
1670
|
|
|
1638
1671
|
/**
|
|
@@ -107,11 +107,11 @@ declare const DEFAULT_CONFIG: {
|
|
|
107
107
|
successThreshold: number;
|
|
108
108
|
timeout: number;
|
|
109
109
|
};
|
|
110
|
-
readonly userAgent: "@spooled/sdk-nodejs/1.0.
|
|
110
|
+
readonly userAgent: "@spooled/sdk-nodejs/1.0.14";
|
|
111
111
|
readonly autoRefreshToken: true;
|
|
112
112
|
};
|
|
113
113
|
/** SDK version */
|
|
114
|
-
declare const SDK_VERSION = "1.0.
|
|
114
|
+
declare const SDK_VERSION = "1.0.14";
|
|
115
115
|
/** API version prefix */
|
|
116
116
|
declare const API_VERSION = "v1";
|
|
117
117
|
/**
|
|
@@ -422,6 +422,19 @@ declare class AuthResource {
|
|
|
422
422
|
* Validate a token
|
|
423
423
|
*/
|
|
424
424
|
validate(params: ValidateTokenParams): Promise<ValidateTokenResponse>;
|
|
425
|
+
/**
|
|
426
|
+
* Start email-based login flow (sends magic link)
|
|
427
|
+
*/
|
|
428
|
+
startEmailLogin(email: string): Promise<{
|
|
429
|
+
success: boolean;
|
|
430
|
+
message: string;
|
|
431
|
+
}>;
|
|
432
|
+
/**
|
|
433
|
+
* Check if an email address exists in the system
|
|
434
|
+
*/
|
|
435
|
+
checkEmail(email: string): Promise<{
|
|
436
|
+
exists: boolean;
|
|
437
|
+
}>;
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
/**
|
|
@@ -1284,6 +1297,13 @@ declare class WorkflowsResource {
|
|
|
1284
1297
|
* Cancel a workflow
|
|
1285
1298
|
*/
|
|
1286
1299
|
cancel(id: string): Promise<WorkflowResponse>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Retry a failed workflow
|
|
1302
|
+
*
|
|
1303
|
+
* Resets all failed/deadletter jobs back to pending and resumes the workflow.
|
|
1304
|
+
* Only workflows with status 'failed' can be retried.
|
|
1305
|
+
*/
|
|
1306
|
+
retry(id: string): Promise<WorkflowResponse>;
|
|
1287
1307
|
private getJobDependencies;
|
|
1288
1308
|
private addJobDependencies;
|
|
1289
1309
|
}
|
|
@@ -1388,6 +1408,13 @@ declare class WebhooksResource {
|
|
|
1388
1408
|
* Get webhook delivery history
|
|
1389
1409
|
*/
|
|
1390
1410
|
getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Retry a specific webhook delivery
|
|
1413
|
+
*/
|
|
1414
|
+
retryDelivery(webhookId: string, deliveryId: string): Promise<{
|
|
1415
|
+
success: boolean;
|
|
1416
|
+
message: string;
|
|
1417
|
+
}>;
|
|
1391
1418
|
}
|
|
1392
1419
|
|
|
1393
1420
|
/**
|
|
@@ -1633,6 +1660,12 @@ declare class OrganizationsResource {
|
|
|
1633
1660
|
* Check slug availability
|
|
1634
1661
|
*/
|
|
1635
1662
|
checkSlug(slug: string): Promise<CheckSlugResponse>;
|
|
1663
|
+
/**
|
|
1664
|
+
* Generate a unique slug from an organization name
|
|
1665
|
+
*/
|
|
1666
|
+
generateSlug(name: string): Promise<{
|
|
1667
|
+
slug: string;
|
|
1668
|
+
}>;
|
|
1636
1669
|
}
|
|
1637
1670
|
|
|
1638
1671
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -56,10 +56,10 @@ var DEFAULT_CONFIG = {
|
|
|
56
56
|
successThreshold: 3,
|
|
57
57
|
timeout: 3e4
|
|
58
58
|
},
|
|
59
|
-
userAgent: "@spooled/sdk-nodejs/1.0.
|
|
59
|
+
userAgent: "@spooled/sdk-nodejs/1.0.14",
|
|
60
60
|
autoRefreshToken: true
|
|
61
61
|
};
|
|
62
|
-
var SDK_VERSION = "1.0.
|
|
62
|
+
var SDK_VERSION = "1.0.14";
|
|
63
63
|
var API_VERSION = "v1";
|
|
64
64
|
var API_BASE_PATH = `/api/${API_VERSION}`;
|
|
65
65
|
function resolveConfig(options) {
|
|
@@ -947,6 +947,20 @@ var AuthResource = class {
|
|
|
947
947
|
async validate(params) {
|
|
948
948
|
return this.http.post("/auth/validate", params);
|
|
949
949
|
}
|
|
950
|
+
/**
|
|
951
|
+
* Start email-based login flow (sends magic link)
|
|
952
|
+
*/
|
|
953
|
+
async startEmailLogin(email) {
|
|
954
|
+
return this.http.post("/auth/email/start", { email });
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Check if an email address exists in the system
|
|
958
|
+
*/
|
|
959
|
+
async checkEmail(email) {
|
|
960
|
+
return this.http.get("/auth/check-email", {
|
|
961
|
+
params: { email }
|
|
962
|
+
});
|
|
963
|
+
}
|
|
950
964
|
};
|
|
951
965
|
|
|
952
966
|
// src/resources/jobs.ts
|
|
@@ -1254,6 +1268,15 @@ var WorkflowsResource = class {
|
|
|
1254
1268
|
async cancel(id) {
|
|
1255
1269
|
return this.http.post(`/workflows/${id}/cancel`);
|
|
1256
1270
|
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Retry a failed workflow
|
|
1273
|
+
*
|
|
1274
|
+
* Resets all failed/deadletter jobs back to pending and resumes the workflow.
|
|
1275
|
+
* Only workflows with status 'failed' can be retried.
|
|
1276
|
+
*/
|
|
1277
|
+
async retry(id) {
|
|
1278
|
+
return this.http.post(`/workflows/${id}/retry`);
|
|
1279
|
+
}
|
|
1257
1280
|
// Job dependency operations (private implementations)
|
|
1258
1281
|
async getJobDependencies(jobId) {
|
|
1259
1282
|
return this.http.get(`/jobs/${jobId}/dependencies`);
|
|
@@ -1310,6 +1333,14 @@ var WebhooksResource = class {
|
|
|
1310
1333
|
async getDeliveries(id) {
|
|
1311
1334
|
return this.http.get(`/outgoing-webhooks/${id}/deliveries`);
|
|
1312
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Retry a specific webhook delivery
|
|
1338
|
+
*/
|
|
1339
|
+
async retryDelivery(webhookId, deliveryId) {
|
|
1340
|
+
return this.http.post(
|
|
1341
|
+
`/outgoing-webhooks/${webhookId}/retry/${deliveryId}`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1313
1344
|
};
|
|
1314
1345
|
|
|
1315
1346
|
// src/resources/api-keys.ts
|
|
@@ -1404,6 +1435,12 @@ var OrganizationsResource = class {
|
|
|
1404
1435
|
params: { slug }
|
|
1405
1436
|
});
|
|
1406
1437
|
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Generate a unique slug from an organization name
|
|
1440
|
+
*/
|
|
1441
|
+
async generateSlug(name) {
|
|
1442
|
+
return this.http.post("/organizations/generate-slug", { name });
|
|
1443
|
+
}
|
|
1407
1444
|
};
|
|
1408
1445
|
|
|
1409
1446
|
// src/resources/billing.ts
|
|
@@ -2940,7 +2977,7 @@ var SpooledWorker = class {
|
|
|
2940
2977
|
...DEFAULT_OPTIONS,
|
|
2941
2978
|
hostname: os.hostname(),
|
|
2942
2979
|
workerType: "nodejs",
|
|
2943
|
-
version: "1.0.
|
|
2980
|
+
version: "1.0.14",
|
|
2944
2981
|
metadata: {},
|
|
2945
2982
|
...options
|
|
2946
2983
|
};
|