runlater-js 0.4.0 → 0.6.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/README.md CHANGED
@@ -151,6 +151,46 @@ const pings = await rl.monitors.pings("monitor-id", 20)
151
151
  await rl.monitors.ping("pm_your_token_here")
152
152
  ```
153
153
 
154
+ ### Endpoints (webhook gateway)
155
+
156
+ ```js
157
+ // Create an endpoint with Lua scripting
158
+ const endpoint = await rl.endpoints.create({
159
+ name: "Stripe webhooks",
160
+ forward_urls: ["https://myapp.com/webhooks/stripe"],
161
+ script: `
162
+ function verify(event, secrets)
163
+ local sig = event.headers["stripe-signature"]
164
+ if not sig then return false end
165
+ local ts, hash = sig:match("t=(%d+),v1=(%S+)")
166
+ if not ts or not hash then return false end
167
+ local expected = hmac_sha256(secrets.signing_key, ts .. "." .. event.body)
168
+ return expected == hash
169
+ end
170
+ `,
171
+ secrets: { signing_key: "whsec_..." },
172
+ })
173
+
174
+ console.log(endpoint.inbound_url) // Give this URL to Stripe
175
+
176
+ // List endpoints
177
+ const { data } = await rl.endpoints.list()
178
+
179
+ // Update script
180
+ await rl.endpoints.update("endpoint-id", {
181
+ script: "function filter(event) return true end",
182
+ })
183
+
184
+ // View events
185
+ const events = await rl.endpoints.events("endpoint-id")
186
+
187
+ // Replay an event
188
+ await rl.endpoints.replay("endpoint-id", "event-id")
189
+
190
+ // Delete
191
+ await rl.endpoints.delete("endpoint-id")
192
+ ```
193
+
154
194
  ### Declarative sync
155
195
 
156
196
  Push your task configuration from code. Matched by name.
package/dist/index.d.mts CHANGED
@@ -13,6 +13,7 @@ interface SendOptions {
13
13
  idempotencyKey?: string;
14
14
  on_failure_url?: string;
15
15
  on_recovery_url?: string;
16
+ script?: string;
16
17
  }
17
18
  interface DelayOptions extends SendOptions {
18
19
  delay: string | number;
@@ -33,6 +34,7 @@ interface CronOptions {
33
34
  enabled?: boolean;
34
35
  on_failure_url?: string;
35
36
  on_recovery_url?: string;
37
+ script?: string;
36
38
  }
37
39
  interface TaskResponse {
38
40
  task_id: string;
@@ -70,6 +72,7 @@ interface Task {
70
72
  notify_on_recovery: boolean | null;
71
73
  on_failure_url: string | null;
72
74
  on_recovery_url: string | null;
75
+ script: string | null;
73
76
  next_run_at: string | null;
74
77
  inserted_at: string;
75
78
  updated_at: string;
@@ -84,6 +87,7 @@ interface Execution {
84
87
  duration_ms: number | null;
85
88
  error_message: string | null;
86
89
  attempt: number;
90
+ script_logs: string[];
87
91
  }
88
92
  interface ListOptions {
89
93
  queue?: string;
@@ -160,6 +164,7 @@ interface UpdateTaskOptions {
160
164
  on_recovery_url?: string;
161
165
  expected_status_codes?: string;
162
166
  expected_body_pattern?: string;
167
+ script?: string | null;
163
168
  }
164
169
  interface CreateMonitorOptions {
165
170
  name: string;
@@ -210,6 +215,60 @@ interface SyncResponse {
210
215
  updated_count: number;
211
216
  deleted_count: number;
212
217
  }
218
+ interface Endpoint {
219
+ id: string;
220
+ name: string;
221
+ slug: string;
222
+ inbound_url: string;
223
+ forward_urls: string[];
224
+ enabled: boolean;
225
+ retry_attempts: number;
226
+ use_queue: boolean;
227
+ notify_on_failure: boolean | null;
228
+ notify_on_recovery: boolean | null;
229
+ on_failure_url: string | null;
230
+ on_recovery_url: string | null;
231
+ forward_headers: Record<string, string> | null;
232
+ forward_body: string | null;
233
+ forward_method: string | null;
234
+ script: string | null;
235
+ secrets_keys: string[];
236
+ inserted_at: string;
237
+ updated_at: string;
238
+ }
239
+ interface CreateEndpointOptions {
240
+ name: string;
241
+ forward_urls: string[];
242
+ retry_attempts?: number;
243
+ use_queue?: boolean;
244
+ enabled?: boolean;
245
+ forward_headers?: Record<string, string>;
246
+ forward_body?: string;
247
+ forward_method?: string;
248
+ script?: string;
249
+ secrets?: Record<string, string>;
250
+ }
251
+ interface UpdateEndpointOptions {
252
+ name?: string;
253
+ forward_urls?: string[];
254
+ retry_attempts?: number;
255
+ use_queue?: boolean;
256
+ enabled?: boolean;
257
+ forward_headers?: Record<string, string>;
258
+ forward_body?: string;
259
+ forward_method?: string;
260
+ script?: string;
261
+ secrets?: Record<string, string>;
262
+ }
263
+ interface InboundEvent {
264
+ id: string;
265
+ method: string;
266
+ source_ip: string;
267
+ received_at: string;
268
+ task_ids: string[];
269
+ lua_rejected: boolean;
270
+ lua_logs: string[];
271
+ }
213
272
  declare class RunlaterError extends Error {
214
273
  status: number;
215
274
  code: string;
@@ -221,6 +280,7 @@ declare class Runlater {
221
280
  private baseUrl;
222
281
  tasks: Tasks;
223
282
  monitors: Monitors;
283
+ endpoints: Endpoints;
224
284
  constructor(options: RunlaterOptions | string);
225
285
  /**
226
286
  * Send a request immediately with reliable delivery and retries.
@@ -344,5 +404,16 @@ declare class Monitors {
344
404
  pings(id: string, limit?: number): Promise<Ping[]>;
345
405
  ping(token: string): Promise<PingResponse>;
346
406
  }
407
+ declare class Endpoints {
408
+ private client;
409
+ constructor(client: Runlater);
410
+ list(): Promise<ListResponse<Endpoint>>;
411
+ get(id: string): Promise<Endpoint>;
412
+ create(options: CreateEndpointOptions): Promise<Endpoint>;
413
+ update(id: string, options: UpdateEndpointOptions): Promise<Endpoint>;
414
+ delete(id: string): Promise<void>;
415
+ events(id: string, limit?: number): Promise<InboundEvent[]>;
416
+ replay(endpointId: string, eventId: string): Promise<void>;
417
+ }
347
418
 
348
- export { type BatchOptions, type BatchResponse, type CancelQueueResponse, type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Execution, type ListOptions, type ListResponse, type Monitor, type Ping, type PingResponse, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse, type UpdateMonitorOptions, type UpdateTaskOptions };
419
+ export { type BatchOptions, type BatchResponse, type CancelQueueResponse, type CreateEndpointOptions, type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Endpoint, type Execution, type InboundEvent, type ListOptions, type ListResponse, type Monitor, type Ping, type PingResponse, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse, type UpdateEndpointOptions, type UpdateMonitorOptions, type UpdateTaskOptions };
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface SendOptions {
13
13
  idempotencyKey?: string;
14
14
  on_failure_url?: string;
15
15
  on_recovery_url?: string;
16
+ script?: string;
16
17
  }
17
18
  interface DelayOptions extends SendOptions {
18
19
  delay: string | number;
@@ -33,6 +34,7 @@ interface CronOptions {
33
34
  enabled?: boolean;
34
35
  on_failure_url?: string;
35
36
  on_recovery_url?: string;
37
+ script?: string;
36
38
  }
37
39
  interface TaskResponse {
38
40
  task_id: string;
@@ -70,6 +72,7 @@ interface Task {
70
72
  notify_on_recovery: boolean | null;
71
73
  on_failure_url: string | null;
72
74
  on_recovery_url: string | null;
75
+ script: string | null;
73
76
  next_run_at: string | null;
74
77
  inserted_at: string;
75
78
  updated_at: string;
@@ -84,6 +87,7 @@ interface Execution {
84
87
  duration_ms: number | null;
85
88
  error_message: string | null;
86
89
  attempt: number;
90
+ script_logs: string[];
87
91
  }
88
92
  interface ListOptions {
89
93
  queue?: string;
@@ -160,6 +164,7 @@ interface UpdateTaskOptions {
160
164
  on_recovery_url?: string;
161
165
  expected_status_codes?: string;
162
166
  expected_body_pattern?: string;
167
+ script?: string | null;
163
168
  }
164
169
  interface CreateMonitorOptions {
165
170
  name: string;
@@ -210,6 +215,60 @@ interface SyncResponse {
210
215
  updated_count: number;
211
216
  deleted_count: number;
212
217
  }
218
+ interface Endpoint {
219
+ id: string;
220
+ name: string;
221
+ slug: string;
222
+ inbound_url: string;
223
+ forward_urls: string[];
224
+ enabled: boolean;
225
+ retry_attempts: number;
226
+ use_queue: boolean;
227
+ notify_on_failure: boolean | null;
228
+ notify_on_recovery: boolean | null;
229
+ on_failure_url: string | null;
230
+ on_recovery_url: string | null;
231
+ forward_headers: Record<string, string> | null;
232
+ forward_body: string | null;
233
+ forward_method: string | null;
234
+ script: string | null;
235
+ secrets_keys: string[];
236
+ inserted_at: string;
237
+ updated_at: string;
238
+ }
239
+ interface CreateEndpointOptions {
240
+ name: string;
241
+ forward_urls: string[];
242
+ retry_attempts?: number;
243
+ use_queue?: boolean;
244
+ enabled?: boolean;
245
+ forward_headers?: Record<string, string>;
246
+ forward_body?: string;
247
+ forward_method?: string;
248
+ script?: string;
249
+ secrets?: Record<string, string>;
250
+ }
251
+ interface UpdateEndpointOptions {
252
+ name?: string;
253
+ forward_urls?: string[];
254
+ retry_attempts?: number;
255
+ use_queue?: boolean;
256
+ enabled?: boolean;
257
+ forward_headers?: Record<string, string>;
258
+ forward_body?: string;
259
+ forward_method?: string;
260
+ script?: string;
261
+ secrets?: Record<string, string>;
262
+ }
263
+ interface InboundEvent {
264
+ id: string;
265
+ method: string;
266
+ source_ip: string;
267
+ received_at: string;
268
+ task_ids: string[];
269
+ lua_rejected: boolean;
270
+ lua_logs: string[];
271
+ }
213
272
  declare class RunlaterError extends Error {
214
273
  status: number;
215
274
  code: string;
@@ -221,6 +280,7 @@ declare class Runlater {
221
280
  private baseUrl;
222
281
  tasks: Tasks;
223
282
  monitors: Monitors;
283
+ endpoints: Endpoints;
224
284
  constructor(options: RunlaterOptions | string);
225
285
  /**
226
286
  * Send a request immediately with reliable delivery and retries.
@@ -344,5 +404,16 @@ declare class Monitors {
344
404
  pings(id: string, limit?: number): Promise<Ping[]>;
345
405
  ping(token: string): Promise<PingResponse>;
346
406
  }
407
+ declare class Endpoints {
408
+ private client;
409
+ constructor(client: Runlater);
410
+ list(): Promise<ListResponse<Endpoint>>;
411
+ get(id: string): Promise<Endpoint>;
412
+ create(options: CreateEndpointOptions): Promise<Endpoint>;
413
+ update(id: string, options: UpdateEndpointOptions): Promise<Endpoint>;
414
+ delete(id: string): Promise<void>;
415
+ events(id: string, limit?: number): Promise<InboundEvent[]>;
416
+ replay(endpointId: string, eventId: string): Promise<void>;
417
+ }
347
418
 
348
- export { type BatchOptions, type BatchResponse, type CancelQueueResponse, type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Execution, type ListOptions, type ListResponse, type Monitor, type Ping, type PingResponse, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse, type UpdateMonitorOptions, type UpdateTaskOptions };
419
+ export { type BatchOptions, type BatchResponse, type CancelQueueResponse, type CreateEndpointOptions, type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Endpoint, type Execution, type InboundEvent, type ListOptions, type ListResponse, type Monitor, type Ping, type PingResponse, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse, type UpdateEndpointOptions, type UpdateMonitorOptions, type UpdateTaskOptions };
package/dist/index.js CHANGED
@@ -44,6 +44,7 @@ var Runlater = class {
44
44
  baseUrl;
45
45
  tasks;
46
46
  monitors;
47
+ endpoints;
47
48
  constructor(options) {
48
49
  if (typeof options === "string") {
49
50
  this.apiKey = options;
@@ -54,6 +55,7 @@ var Runlater = class {
54
55
  }
55
56
  this.tasks = new Tasks(this);
56
57
  this.monitors = new Monitors(this);
58
+ this.endpoints = new Endpoints(this);
57
59
  }
58
60
  /**
59
61
  * Send a request immediately with reliable delivery and retries.
@@ -140,7 +142,8 @@ var Runlater = class {
140
142
  retry_attempts: options.retries,
141
143
  queue: options.queue,
142
144
  callback_url: options.callback,
143
- enabled: options.enabled
145
+ enabled: options.enabled,
146
+ script: options.script
144
147
  }
145
148
  });
146
149
  return res.data;
@@ -173,7 +176,8 @@ var Runlater = class {
173
176
  retry_attempts: t.retries,
174
177
  queue: t.queue,
175
178
  callback_url: t.callback,
176
- enabled: t.enabled
179
+ enabled: t.enabled,
180
+ script: t.script
177
181
  }));
178
182
  }
179
183
  if (options.monitors) {
@@ -206,7 +210,8 @@ var Runlater = class {
206
210
  timeout_ms: options.timeout,
207
211
  retry_attempts: options.retries,
208
212
  queue: options.queue,
209
- callback_url: options.callback
213
+ callback_url: options.callback,
214
+ script: options.script
210
215
  };
211
216
  }
212
217
  /** @internal */
@@ -386,6 +391,43 @@ var Monitors = class {
386
391
  return await response.json();
387
392
  }
388
393
  };
394
+ var Endpoints = class {
395
+ constructor(client) {
396
+ this.client = client;
397
+ }
398
+ async list() {
399
+ return this.client.request("GET", "/endpoints");
400
+ }
401
+ async get(id) {
402
+ const res = await this.client.request("GET", `/endpoints/${id}`);
403
+ return res.data;
404
+ }
405
+ async create(options) {
406
+ const res = await this.client.request("POST", "/endpoints", {
407
+ body: options
408
+ });
409
+ return res.data;
410
+ }
411
+ async update(id, options) {
412
+ const res = await this.client.request("PUT", `/endpoints/${id}`, {
413
+ body: options
414
+ });
415
+ return res.data;
416
+ }
417
+ async delete(id) {
418
+ await this.client.request("DELETE", `/endpoints/${id}`);
419
+ }
420
+ async events(id, limit = 50) {
421
+ const res = await this.client.request(
422
+ "GET",
423
+ `/endpoints/${id}/events?limit=${limit}`
424
+ );
425
+ return res.data;
426
+ }
427
+ async replay(endpointId, eventId) {
428
+ await this.client.request("POST", `/endpoints/${endpointId}/events/${eventId}/replay`);
429
+ }
430
+ };
389
431
  function formatDelay(delay) {
390
432
  if (typeof delay === "number") return `${delay}s`;
391
433
  return delay;
package/dist/index.mjs CHANGED
@@ -17,6 +17,7 @@ var Runlater = class {
17
17
  baseUrl;
18
18
  tasks;
19
19
  monitors;
20
+ endpoints;
20
21
  constructor(options) {
21
22
  if (typeof options === "string") {
22
23
  this.apiKey = options;
@@ -27,6 +28,7 @@ var Runlater = class {
27
28
  }
28
29
  this.tasks = new Tasks(this);
29
30
  this.monitors = new Monitors(this);
31
+ this.endpoints = new Endpoints(this);
30
32
  }
31
33
  /**
32
34
  * Send a request immediately with reliable delivery and retries.
@@ -113,7 +115,8 @@ var Runlater = class {
113
115
  retry_attempts: options.retries,
114
116
  queue: options.queue,
115
117
  callback_url: options.callback,
116
- enabled: options.enabled
118
+ enabled: options.enabled,
119
+ script: options.script
117
120
  }
118
121
  });
119
122
  return res.data;
@@ -146,7 +149,8 @@ var Runlater = class {
146
149
  retry_attempts: t.retries,
147
150
  queue: t.queue,
148
151
  callback_url: t.callback,
149
- enabled: t.enabled
152
+ enabled: t.enabled,
153
+ script: t.script
150
154
  }));
151
155
  }
152
156
  if (options.monitors) {
@@ -179,7 +183,8 @@ var Runlater = class {
179
183
  timeout_ms: options.timeout,
180
184
  retry_attempts: options.retries,
181
185
  queue: options.queue,
182
- callback_url: options.callback
186
+ callback_url: options.callback,
187
+ script: options.script
183
188
  };
184
189
  }
185
190
  /** @internal */
@@ -359,6 +364,43 @@ var Monitors = class {
359
364
  return await response.json();
360
365
  }
361
366
  };
367
+ var Endpoints = class {
368
+ constructor(client) {
369
+ this.client = client;
370
+ }
371
+ async list() {
372
+ return this.client.request("GET", "/endpoints");
373
+ }
374
+ async get(id) {
375
+ const res = await this.client.request("GET", `/endpoints/${id}`);
376
+ return res.data;
377
+ }
378
+ async create(options) {
379
+ const res = await this.client.request("POST", "/endpoints", {
380
+ body: options
381
+ });
382
+ return res.data;
383
+ }
384
+ async update(id, options) {
385
+ const res = await this.client.request("PUT", `/endpoints/${id}`, {
386
+ body: options
387
+ });
388
+ return res.data;
389
+ }
390
+ async delete(id) {
391
+ await this.client.request("DELETE", `/endpoints/${id}`);
392
+ }
393
+ async events(id, limit = 50) {
394
+ const res = await this.client.request(
395
+ "GET",
396
+ `/endpoints/${id}/events?limit=${limit}`
397
+ );
398
+ return res.data;
399
+ }
400
+ async replay(endpointId, eventId) {
401
+ await this.client.request("POST", `/endpoints/${endpointId}/events/${eventId}/replay`);
402
+ }
403
+ };
362
404
  function formatDelay(delay) {
363
405
  if (typeof delay === "number") return `${delay}s`;
364
406
  return delay;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runlater-js",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Delayed tasks, cron jobs, and reliable webhooks. No infrastructure required.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",