runlater-js 0.1.1 → 0.2.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
@@ -113,6 +113,12 @@ const { data, has_more } = await rl.tasks.list({ limit: 20 })
113
113
  // Get a specific task
114
114
  const task = await rl.tasks.get("task-id")
115
115
 
116
+ // Update a task
117
+ await rl.tasks.update("task-id", {
118
+ cron_expression: "0 7 * * *",
119
+ enabled: false,
120
+ })
121
+
116
122
  // Trigger a task manually
117
123
  await rl.tasks.trigger("task-id")
118
124
 
@@ -133,8 +139,16 @@ const monitor = await rl.monitors.create({
133
139
  grace: 600, // 10 min grace period
134
140
  })
135
141
 
136
- // Ping it from your cron job
137
- await fetch(monitor.ping_url)
142
+ // Update a monitor
143
+ await rl.monitors.update("monitor-id", {
144
+ grace_period_seconds: 1800,
145
+ })
146
+
147
+ // List pings
148
+ const pings = await rl.monitors.pings("monitor-id", 20)
149
+
150
+ // Ping from code (no API key needed — uses the token)
151
+ await rl.monitors.ping("pm_your_token_here")
138
152
  ```
139
153
 
140
154
  ### Declarative sync
package/dist/index.d.mts CHANGED
@@ -58,11 +58,12 @@ interface Task {
58
58
  cron_expression: string | null;
59
59
  scheduled_at: string | null;
60
60
  enabled: boolean;
61
- muted: boolean;
62
61
  timeout_ms: number;
63
62
  retry_attempts: number;
64
63
  callback_url: string | null;
65
64
  queue: string | null;
65
+ notify_on_failure: boolean | null;
66
+ notify_on_recovery: boolean | null;
66
67
  next_run_at: string | null;
67
68
  inserted_at: string;
68
69
  updated_at: string;
@@ -105,19 +106,56 @@ interface Monitor {
105
106
  grace_period_seconds: number;
106
107
  status: "new" | "up" | "down" | "paused";
107
108
  enabled: boolean;
108
- muted: boolean;
109
+ notify_on_failure: boolean | null;
110
+ notify_on_recovery: boolean | null;
109
111
  last_ping_at: string | null;
110
112
  next_expected_at: string | null;
111
113
  inserted_at: string;
112
114
  updated_at: string;
113
115
  }
116
+ interface UpdateTaskOptions {
117
+ name?: string;
118
+ url?: string;
119
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
120
+ headers?: Record<string, string>;
121
+ body?: string;
122
+ cron_expression?: string;
123
+ scheduled_at?: string;
124
+ timeout_ms?: number;
125
+ retry_attempts?: number;
126
+ callback_url?: string;
127
+ queue?: string;
128
+ enabled?: boolean;
129
+ notify_on_failure?: boolean | null;
130
+ notify_on_recovery?: boolean | null;
131
+ expected_status_codes?: string;
132
+ expected_body_pattern?: string;
133
+ }
114
134
  interface CreateMonitorOptions {
115
135
  name: string;
116
- schedule: string;
136
+ schedule?: string;
117
137
  interval?: number;
118
138
  grace?: number;
119
139
  enabled?: boolean;
120
140
  }
141
+ interface UpdateMonitorOptions {
142
+ name?: string;
143
+ schedule_type?: "cron" | "interval";
144
+ cron_expression?: string;
145
+ interval_seconds?: number;
146
+ grace_period_seconds?: number;
147
+ enabled?: boolean;
148
+ notify_on_failure?: boolean | null;
149
+ notify_on_recovery?: boolean | null;
150
+ }
151
+ interface Ping {
152
+ id: string;
153
+ received_at: string;
154
+ }
155
+ interface PingResponse {
156
+ status: string;
157
+ monitor: string;
158
+ }
121
159
  interface SyncOptions {
122
160
  tasks?: CronOptions[];
123
161
  monitors?: CreateMonitorOptions[];
@@ -211,6 +249,8 @@ declare class Runlater {
211
249
  * ```
212
250
  */
213
251
  sync(options: SyncOptions): Promise<SyncResponse>;
252
+ /** @internal */
253
+ getBaseUrl(): string;
214
254
  private buildTaskBody;
215
255
  /** @internal */
216
256
  request<T>(method: string, path: string, options?: {
@@ -225,6 +265,7 @@ declare class Tasks {
225
265
  get(id: string): Promise<Task>;
226
266
  delete(id: string): Promise<void>;
227
267
  trigger(id: string): Promise<TriggerResponse>;
268
+ update(id: string, options: UpdateTaskOptions): Promise<Task>;
228
269
  executions(id: string, limit?: number): Promise<Execution[]>;
229
270
  }
230
271
  declare class Monitors {
@@ -233,7 +274,10 @@ declare class Monitors {
233
274
  list(): Promise<Monitor[]>;
234
275
  get(id: string): Promise<Monitor>;
235
276
  create(options: CreateMonitorOptions): Promise<Monitor>;
277
+ update(id: string, options: UpdateMonitorOptions): Promise<Monitor>;
236
278
  delete(id: string): Promise<void>;
279
+ pings(id: string, limit?: number): Promise<Ping[]>;
280
+ ping(token: string): Promise<PingResponse>;
237
281
  }
238
282
 
239
- export { type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Execution, type ListOptions, type ListResponse, type Monitor, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse };
283
+ export { 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 };
package/dist/index.d.ts CHANGED
@@ -58,11 +58,12 @@ interface Task {
58
58
  cron_expression: string | null;
59
59
  scheduled_at: string | null;
60
60
  enabled: boolean;
61
- muted: boolean;
62
61
  timeout_ms: number;
63
62
  retry_attempts: number;
64
63
  callback_url: string | null;
65
64
  queue: string | null;
65
+ notify_on_failure: boolean | null;
66
+ notify_on_recovery: boolean | null;
66
67
  next_run_at: string | null;
67
68
  inserted_at: string;
68
69
  updated_at: string;
@@ -105,19 +106,56 @@ interface Monitor {
105
106
  grace_period_seconds: number;
106
107
  status: "new" | "up" | "down" | "paused";
107
108
  enabled: boolean;
108
- muted: boolean;
109
+ notify_on_failure: boolean | null;
110
+ notify_on_recovery: boolean | null;
109
111
  last_ping_at: string | null;
110
112
  next_expected_at: string | null;
111
113
  inserted_at: string;
112
114
  updated_at: string;
113
115
  }
116
+ interface UpdateTaskOptions {
117
+ name?: string;
118
+ url?: string;
119
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
120
+ headers?: Record<string, string>;
121
+ body?: string;
122
+ cron_expression?: string;
123
+ scheduled_at?: string;
124
+ timeout_ms?: number;
125
+ retry_attempts?: number;
126
+ callback_url?: string;
127
+ queue?: string;
128
+ enabled?: boolean;
129
+ notify_on_failure?: boolean | null;
130
+ notify_on_recovery?: boolean | null;
131
+ expected_status_codes?: string;
132
+ expected_body_pattern?: string;
133
+ }
114
134
  interface CreateMonitorOptions {
115
135
  name: string;
116
- schedule: string;
136
+ schedule?: string;
117
137
  interval?: number;
118
138
  grace?: number;
119
139
  enabled?: boolean;
120
140
  }
141
+ interface UpdateMonitorOptions {
142
+ name?: string;
143
+ schedule_type?: "cron" | "interval";
144
+ cron_expression?: string;
145
+ interval_seconds?: number;
146
+ grace_period_seconds?: number;
147
+ enabled?: boolean;
148
+ notify_on_failure?: boolean | null;
149
+ notify_on_recovery?: boolean | null;
150
+ }
151
+ interface Ping {
152
+ id: string;
153
+ received_at: string;
154
+ }
155
+ interface PingResponse {
156
+ status: string;
157
+ monitor: string;
158
+ }
121
159
  interface SyncOptions {
122
160
  tasks?: CronOptions[];
123
161
  monitors?: CreateMonitorOptions[];
@@ -211,6 +249,8 @@ declare class Runlater {
211
249
  * ```
212
250
  */
213
251
  sync(options: SyncOptions): Promise<SyncResponse>;
252
+ /** @internal */
253
+ getBaseUrl(): string;
214
254
  private buildTaskBody;
215
255
  /** @internal */
216
256
  request<T>(method: string, path: string, options?: {
@@ -225,6 +265,7 @@ declare class Tasks {
225
265
  get(id: string): Promise<Task>;
226
266
  delete(id: string): Promise<void>;
227
267
  trigger(id: string): Promise<TriggerResponse>;
268
+ update(id: string, options: UpdateTaskOptions): Promise<Task>;
228
269
  executions(id: string, limit?: number): Promise<Execution[]>;
229
270
  }
230
271
  declare class Monitors {
@@ -233,7 +274,10 @@ declare class Monitors {
233
274
  list(): Promise<Monitor[]>;
234
275
  get(id: string): Promise<Monitor>;
235
276
  create(options: CreateMonitorOptions): Promise<Monitor>;
277
+ update(id: string, options: UpdateMonitorOptions): Promise<Monitor>;
236
278
  delete(id: string): Promise<void>;
279
+ pings(id: string, limit?: number): Promise<Ping[]>;
280
+ ping(token: string): Promise<PingResponse>;
237
281
  }
238
282
 
239
- export { type CreateMonitorOptions, type CronOptions, type CronResponse, type DelayOptions, type Execution, type ListOptions, type ListResponse, type Monitor, Runlater, RunlaterError, type RunlaterOptions, type ScheduleOptions, type SendOptions, type SyncOptions, type SyncResponse, type Task, type TaskResponse, type TriggerResponse };
283
+ export { 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 };
package/dist/index.js CHANGED
@@ -192,6 +192,10 @@ var Runlater = class {
192
192
  const res = await this.request("PUT", "/sync", { body });
193
193
  return res.data;
194
194
  }
195
+ /** @internal */
196
+ getBaseUrl() {
197
+ return this.baseUrl;
198
+ }
195
199
  // --- Internal ---
196
200
  buildTaskBody(url, options) {
197
201
  return {
@@ -261,6 +265,12 @@ var Tasks = class {
261
265
  );
262
266
  return res.data;
263
267
  }
268
+ async update(id, options) {
269
+ const res = await this.client.request("PUT", `/tasks/${id}`, {
270
+ body: options
271
+ });
272
+ return res.data;
273
+ }
264
274
  async executions(id, limit = 50) {
265
275
  const res = await this.client.request(
266
276
  "GET",
@@ -294,9 +304,29 @@ var Monitors = class {
294
304
  });
295
305
  return res.data;
296
306
  }
307
+ async update(id, options) {
308
+ const res = await this.client.request("PUT", `/monitors/${id}`, {
309
+ body: options
310
+ });
311
+ return res.data;
312
+ }
297
313
  async delete(id) {
298
314
  await this.client.request("DELETE", `/monitors/${id}`);
299
315
  }
316
+ async pings(id, limit = 50) {
317
+ const res = await this.client.request(
318
+ "GET",
319
+ `/monitors/${id}/pings?limit=${limit}`
320
+ );
321
+ return res.data;
322
+ }
323
+ async ping(token) {
324
+ const response = await fetch(`${this.client.getBaseUrl()}/ping/${token}`);
325
+ if (!response.ok) {
326
+ throw new RunlaterError(response.status, "ping_failed", `HTTP ${response.status}`);
327
+ }
328
+ return await response.json();
329
+ }
300
330
  };
301
331
  function formatDelay(delay) {
302
332
  if (typeof delay === "number") return `${delay}s`;
package/dist/index.mjs CHANGED
@@ -165,6 +165,10 @@ var Runlater = class {
165
165
  const res = await this.request("PUT", "/sync", { body });
166
166
  return res.data;
167
167
  }
168
+ /** @internal */
169
+ getBaseUrl() {
170
+ return this.baseUrl;
171
+ }
168
172
  // --- Internal ---
169
173
  buildTaskBody(url, options) {
170
174
  return {
@@ -234,6 +238,12 @@ var Tasks = class {
234
238
  );
235
239
  return res.data;
236
240
  }
241
+ async update(id, options) {
242
+ const res = await this.client.request("PUT", `/tasks/${id}`, {
243
+ body: options
244
+ });
245
+ return res.data;
246
+ }
237
247
  async executions(id, limit = 50) {
238
248
  const res = await this.client.request(
239
249
  "GET",
@@ -267,9 +277,29 @@ var Monitors = class {
267
277
  });
268
278
  return res.data;
269
279
  }
280
+ async update(id, options) {
281
+ const res = await this.client.request("PUT", `/monitors/${id}`, {
282
+ body: options
283
+ });
284
+ return res.data;
285
+ }
270
286
  async delete(id) {
271
287
  await this.client.request("DELETE", `/monitors/${id}`);
272
288
  }
289
+ async pings(id, limit = 50) {
290
+ const res = await this.client.request(
291
+ "GET",
292
+ `/monitors/${id}/pings?limit=${limit}`
293
+ );
294
+ return res.data;
295
+ }
296
+ async ping(token) {
297
+ const response = await fetch(`${this.client.getBaseUrl()}/ping/${token}`);
298
+ if (!response.ok) {
299
+ throw new RunlaterError(response.status, "ping_failed", `HTTP ${response.status}`);
300
+ }
301
+ return await response.json();
302
+ }
273
303
  };
274
304
  function formatDelay(delay) {
275
305
  if (typeof delay === "number") return `${delay}s`;
@@ -0,0 +1,179 @@
1
+ export interface RunlaterOptions {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ export interface SendOptions {
6
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
7
+ headers?: Record<string, string>;
8
+ body?: unknown;
9
+ retries?: number;
10
+ timeout?: number;
11
+ queue?: string;
12
+ callback?: string;
13
+ idempotencyKey?: string;
14
+ }
15
+ export interface DelayOptions extends SendOptions {
16
+ delay: string | number;
17
+ }
18
+ export interface ScheduleOptions extends SendOptions {
19
+ at: string | Date;
20
+ }
21
+ export interface CronOptions {
22
+ url: string;
23
+ schedule: string;
24
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
25
+ headers?: Record<string, string>;
26
+ body?: unknown;
27
+ timeout?: number;
28
+ retries?: number;
29
+ queue?: string;
30
+ callback?: string;
31
+ enabled?: boolean;
32
+ }
33
+ export interface TaskResponse {
34
+ task_id: string;
35
+ execution_id: string;
36
+ status: string;
37
+ scheduled_for: string;
38
+ }
39
+ export interface CronResponse {
40
+ id: string;
41
+ name: string;
42
+ url: string;
43
+ method: string;
44
+ cron_expression: string;
45
+ enabled: boolean;
46
+ next_run_at: string | null;
47
+ inserted_at: string;
48
+ updated_at: string;
49
+ }
50
+ export interface Task {
51
+ id: string;
52
+ name: string;
53
+ url: string;
54
+ method: string;
55
+ headers: Record<string, string>;
56
+ body: string | null;
57
+ schedule_type: string;
58
+ cron_expression: string | null;
59
+ scheduled_at: string | null;
60
+ enabled: boolean;
61
+ muted: boolean;
62
+ timeout_ms: number;
63
+ retry_attempts: number;
64
+ callback_url: string | null;
65
+ queue: string | null;
66
+ next_run_at: string | null;
67
+ inserted_at: string;
68
+ updated_at: string;
69
+ }
70
+ export interface Execution {
71
+ id: string;
72
+ status: "pending" | "running" | "success" | "failed" | "timeout";
73
+ scheduled_for: string;
74
+ started_at: string | null;
75
+ finished_at: string | null;
76
+ status_code: number | null;
77
+ duration_ms: number | null;
78
+ error_message: string | null;
79
+ attempt: number;
80
+ }
81
+ export interface ListOptions {
82
+ queue?: string;
83
+ limit?: number;
84
+ offset?: number;
85
+ }
86
+ export interface ListResponse<T> {
87
+ data: T[];
88
+ has_more: boolean;
89
+ limit: number;
90
+ offset: number;
91
+ }
92
+ export interface TriggerResponse {
93
+ execution_id: string;
94
+ status: string;
95
+ scheduled_for: string;
96
+ }
97
+ export interface Monitor {
98
+ id: string;
99
+ name: string;
100
+ ping_token: string;
101
+ ping_url: string;
102
+ schedule_type: "cron" | "interval";
103
+ cron_expression: string | null;
104
+ interval_seconds: number | null;
105
+ grace_period_seconds: number;
106
+ status: "new" | "up" | "down" | "paused";
107
+ enabled: boolean;
108
+ muted: boolean;
109
+ last_ping_at: string | null;
110
+ next_expected_at: string | null;
111
+ inserted_at: string;
112
+ updated_at: string;
113
+ }
114
+ export interface UpdateTaskOptions {
115
+ name?: string;
116
+ url?: string;
117
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
118
+ headers?: Record<string, string>;
119
+ body?: string;
120
+ cron_expression?: string;
121
+ scheduled_at?: string;
122
+ timeout_ms?: number;
123
+ retry_attempts?: number;
124
+ callback_url?: string;
125
+ queue?: string;
126
+ enabled?: boolean;
127
+ muted?: boolean;
128
+ expected_status_codes?: string;
129
+ expected_body_pattern?: string;
130
+ }
131
+ export interface CreateMonitorOptions {
132
+ name: string;
133
+ schedule?: string;
134
+ interval?: number;
135
+ grace?: number;
136
+ enabled?: boolean;
137
+ }
138
+ export interface UpdateMonitorOptions {
139
+ name?: string;
140
+ schedule_type?: "cron" | "interval";
141
+ cron_expression?: string;
142
+ interval_seconds?: number;
143
+ grace_period_seconds?: number;
144
+ enabled?: boolean;
145
+ muted?: boolean;
146
+ }
147
+ export interface Ping {
148
+ id: string;
149
+ received_at: string;
150
+ }
151
+ export interface PingResponse {
152
+ status: string;
153
+ monitor: string;
154
+ }
155
+ export interface SyncOptions {
156
+ tasks?: CronOptions[];
157
+ monitors?: CreateMonitorOptions[];
158
+ deleteRemoved?: boolean;
159
+ }
160
+ export interface SyncResponse {
161
+ tasks: {
162
+ created: string[];
163
+ updated: string[];
164
+ deleted: string[];
165
+ };
166
+ monitors: {
167
+ created: string[];
168
+ updated: string[];
169
+ deleted: string[];
170
+ };
171
+ created_count: number;
172
+ updated_count: number;
173
+ deleted_count: number;
174
+ }
175
+ export declare class RunlaterError extends Error {
176
+ status: number;
177
+ code: string;
178
+ constructor(status: number, code: string, message: string);
179
+ }
package/dist/types.js ADDED
@@ -0,0 +1,10 @@
1
+ export class RunlaterError extends Error {
2
+ status;
3
+ code;
4
+ constructor(status, code, message) {
5
+ super(message);
6
+ this.name = "RunlaterError";
7
+ this.status = status;
8
+ this.code = code;
9
+ }
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runlater-js",
3
- "version": "0.1.1",
3
+ "version": "0.2.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",