@upstash/qstash 2.1.9 → 2.1.11-canary
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +111 -90
- package/dist/index.d.ts +111 -90
- package/dist/index.js +85 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +85 -79
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -113,73 +113,6 @@ type RetryConfig = false | {
|
|
|
113
113
|
backoff?: (retryCount: number) => number;
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
-
type Endpoint = {
|
|
117
|
-
/**
|
|
118
|
-
* The name of the endpoint (optional)
|
|
119
|
-
*/
|
|
120
|
-
name?: string;
|
|
121
|
-
/**
|
|
122
|
-
* The url of the endpoint
|
|
123
|
-
*/
|
|
124
|
-
url: string;
|
|
125
|
-
};
|
|
126
|
-
type AddEndpointsRequest = {
|
|
127
|
-
/**
|
|
128
|
-
* The name of the topic.
|
|
129
|
-
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
130
|
-
*/
|
|
131
|
-
name: string;
|
|
132
|
-
endpoints: Endpoint[];
|
|
133
|
-
};
|
|
134
|
-
type RemoveEndpointsRequest = {
|
|
135
|
-
/**
|
|
136
|
-
* The name of the topic.
|
|
137
|
-
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
138
|
-
*/
|
|
139
|
-
name: string;
|
|
140
|
-
endpoints: ({
|
|
141
|
-
name: string;
|
|
142
|
-
url?: string;
|
|
143
|
-
} | {
|
|
144
|
-
name?: string;
|
|
145
|
-
url: string;
|
|
146
|
-
})[];
|
|
147
|
-
};
|
|
148
|
-
type Topic = {
|
|
149
|
-
/**
|
|
150
|
-
* The name of this topic.
|
|
151
|
-
*/
|
|
152
|
-
name: string;
|
|
153
|
-
/**
|
|
154
|
-
* A list of all subscribed endpoints
|
|
155
|
-
*/
|
|
156
|
-
endpoints: Endpoint[];
|
|
157
|
-
};
|
|
158
|
-
declare class Topics {
|
|
159
|
-
private readonly http;
|
|
160
|
-
constructor(http: Requester);
|
|
161
|
-
/**
|
|
162
|
-
* Create a new topic with the given name and endpoints
|
|
163
|
-
*/
|
|
164
|
-
addEndpoints(req: AddEndpointsRequest): Promise<void>;
|
|
165
|
-
/**
|
|
166
|
-
* Remove endpoints from a topic.
|
|
167
|
-
*/
|
|
168
|
-
removeEndpoints(req: RemoveEndpointsRequest): Promise<void>;
|
|
169
|
-
/**
|
|
170
|
-
* Get a list of all topics.
|
|
171
|
-
*/
|
|
172
|
-
list(): Promise<Topic[]>;
|
|
173
|
-
/**
|
|
174
|
-
* Get a single topic
|
|
175
|
-
*/
|
|
176
|
-
get(name: string): Promise<Topic>;
|
|
177
|
-
/**
|
|
178
|
-
* Delete a topic
|
|
179
|
-
*/
|
|
180
|
-
delete(name: string): Promise<void>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
116
|
type Message = {
|
|
184
117
|
/**
|
|
185
118
|
* A unique identifier for this message.
|
|
@@ -214,13 +147,17 @@ type Message = {
|
|
|
214
147
|
*/
|
|
215
148
|
notBefore?: number;
|
|
216
149
|
/**
|
|
217
|
-
* A unix timestamp (milliseconds) when this messages was
|
|
150
|
+
* A unix timestamp (milliseconds) when this messages was created.
|
|
218
151
|
*/
|
|
219
152
|
createdAt: number;
|
|
220
153
|
/**
|
|
221
154
|
* The callback url if configured.
|
|
222
155
|
*/
|
|
223
156
|
callback?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The failure callback url if configured.
|
|
159
|
+
*/
|
|
160
|
+
failureCallback?: string;
|
|
224
161
|
};
|
|
225
162
|
declare class Messages {
|
|
226
163
|
private readonly http;
|
|
@@ -235,6 +172,27 @@ declare class Messages {
|
|
|
235
172
|
delete(messageId: string): Promise<void>;
|
|
236
173
|
}
|
|
237
174
|
|
|
175
|
+
type DlqMessage = Message & {
|
|
176
|
+
dlqId: string;
|
|
177
|
+
};
|
|
178
|
+
declare class DLQ {
|
|
179
|
+
private readonly http;
|
|
180
|
+
constructor(http: Requester);
|
|
181
|
+
/**
|
|
182
|
+
* List messages in the dlq
|
|
183
|
+
*/
|
|
184
|
+
listMessages(opts?: {
|
|
185
|
+
cursor?: string;
|
|
186
|
+
}): Promise<{
|
|
187
|
+
messages: DlqMessage[];
|
|
188
|
+
cursor?: string;
|
|
189
|
+
}>;
|
|
190
|
+
/**
|
|
191
|
+
* Remove a message from the dlq using it's `dlqId`
|
|
192
|
+
*/
|
|
193
|
+
delete(dlqMessageId: string): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
|
|
238
196
|
type Schedule = {
|
|
239
197
|
scheduleId: string;
|
|
240
198
|
cron: string;
|
|
@@ -246,6 +204,7 @@ type Schedule = {
|
|
|
246
204
|
retries: number;
|
|
247
205
|
delay?: number;
|
|
248
206
|
callback?: string;
|
|
207
|
+
failureCallback?: string;
|
|
249
208
|
};
|
|
250
209
|
type CreateScheduleRequest = {
|
|
251
210
|
/**
|
|
@@ -277,7 +236,7 @@ type CreateScheduleRequest = {
|
|
|
277
236
|
*/
|
|
278
237
|
delay?: number;
|
|
279
238
|
/**
|
|
280
|
-
* In case your destination server is
|
|
239
|
+
* In case your destination server is unavailable or returns a status code outside of the 200-299
|
|
281
240
|
* range, we will retry the request after a certain amount of time.
|
|
282
241
|
*
|
|
283
242
|
* Configure how many times you would like the delivery to be retried
|
|
@@ -293,6 +252,14 @@ type CreateScheduleRequest = {
|
|
|
293
252
|
* @default undefined
|
|
294
253
|
*/
|
|
295
254
|
callback?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Use a failure callback url to handle messages that could not be delivered.
|
|
257
|
+
*
|
|
258
|
+
* The failure callback url must be publicly accessible
|
|
259
|
+
*
|
|
260
|
+
* @default undefined
|
|
261
|
+
*/
|
|
262
|
+
failureCallback?: string;
|
|
296
263
|
/**
|
|
297
264
|
* The method to use when sending a request to your API
|
|
298
265
|
*
|
|
@@ -327,6 +294,73 @@ declare class Schedules {
|
|
|
327
294
|
delete(scheduleId: string): Promise<void>;
|
|
328
295
|
}
|
|
329
296
|
|
|
297
|
+
type Endpoint = {
|
|
298
|
+
/**
|
|
299
|
+
* The name of the endpoint (optional)
|
|
300
|
+
*/
|
|
301
|
+
name?: string;
|
|
302
|
+
/**
|
|
303
|
+
* The url of the endpoint
|
|
304
|
+
*/
|
|
305
|
+
url: string;
|
|
306
|
+
};
|
|
307
|
+
type AddEndpointsRequest = {
|
|
308
|
+
/**
|
|
309
|
+
* The name of the topic.
|
|
310
|
+
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
311
|
+
*/
|
|
312
|
+
name: string;
|
|
313
|
+
endpoints: Endpoint[];
|
|
314
|
+
};
|
|
315
|
+
type RemoveEndpointsRequest = {
|
|
316
|
+
/**
|
|
317
|
+
* The name of the topic.
|
|
318
|
+
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
319
|
+
*/
|
|
320
|
+
name: string;
|
|
321
|
+
endpoints: ({
|
|
322
|
+
name: string;
|
|
323
|
+
url?: string;
|
|
324
|
+
} | {
|
|
325
|
+
name?: string;
|
|
326
|
+
url: string;
|
|
327
|
+
})[];
|
|
328
|
+
};
|
|
329
|
+
type Topic = {
|
|
330
|
+
/**
|
|
331
|
+
* The name of this topic.
|
|
332
|
+
*/
|
|
333
|
+
name: string;
|
|
334
|
+
/**
|
|
335
|
+
* A list of all subscribed endpoints
|
|
336
|
+
*/
|
|
337
|
+
endpoints: Endpoint[];
|
|
338
|
+
};
|
|
339
|
+
declare class Topics {
|
|
340
|
+
private readonly http;
|
|
341
|
+
constructor(http: Requester);
|
|
342
|
+
/**
|
|
343
|
+
* Create a new topic with the given name and endpoints
|
|
344
|
+
*/
|
|
345
|
+
addEndpoints(req: AddEndpointsRequest): Promise<void>;
|
|
346
|
+
/**
|
|
347
|
+
* Remove endpoints from a topic.
|
|
348
|
+
*/
|
|
349
|
+
removeEndpoints(req: RemoveEndpointsRequest): Promise<void>;
|
|
350
|
+
/**
|
|
351
|
+
* Get a list of all topics.
|
|
352
|
+
*/
|
|
353
|
+
list(): Promise<Topic[]>;
|
|
354
|
+
/**
|
|
355
|
+
* Get a single topic
|
|
356
|
+
*/
|
|
357
|
+
get(name: string): Promise<Topic>;
|
|
358
|
+
/**
|
|
359
|
+
* Delete a topic
|
|
360
|
+
*/
|
|
361
|
+
delete(name: string): Promise<void>;
|
|
362
|
+
}
|
|
363
|
+
|
|
330
364
|
type State = "CREATED" | "ACTIVE" | "DELIVERED" | "ERROR" | "RETRY" | "FAILED";
|
|
331
365
|
type Event = {
|
|
332
366
|
time: number;
|
|
@@ -342,27 +376,6 @@ type WithCursor<T> = T & {
|
|
|
342
376
|
cursor?: number;
|
|
343
377
|
};
|
|
344
378
|
|
|
345
|
-
type DlqMessage = Message & {
|
|
346
|
-
dlqId: string;
|
|
347
|
-
};
|
|
348
|
-
declare class DLQ {
|
|
349
|
-
private readonly http;
|
|
350
|
-
constructor(http: Requester);
|
|
351
|
-
/**
|
|
352
|
-
* List messages in the dlq
|
|
353
|
-
*/
|
|
354
|
-
listMessages(opts?: {
|
|
355
|
-
cursor?: string;
|
|
356
|
-
}): Promise<{
|
|
357
|
-
messages: DlqMessage[];
|
|
358
|
-
cursor?: string;
|
|
359
|
-
}>;
|
|
360
|
-
/**
|
|
361
|
-
* Remove a message from the dlq using it's `dlqId`
|
|
362
|
-
*/
|
|
363
|
-
delete(dlqMessageId: string): Promise<void>;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
379
|
type ClientConfig = {
|
|
367
380
|
/**
|
|
368
381
|
* Url of the qstash api server.
|
|
@@ -461,6 +474,14 @@ type PublishRequest<TBody = BodyInit> = {
|
|
|
461
474
|
* @default undefined
|
|
462
475
|
*/
|
|
463
476
|
callback?: string;
|
|
477
|
+
/**
|
|
478
|
+
* Use a failure callback url to handle messages that could not be delivered.
|
|
479
|
+
*
|
|
480
|
+
* The failure callback url must be publicly accessible
|
|
481
|
+
*
|
|
482
|
+
* @default undefined
|
|
483
|
+
*/
|
|
484
|
+
failureCallback?: string;
|
|
464
485
|
/**
|
|
465
486
|
* The method to use when sending a request to your API
|
|
466
487
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -113,73 +113,6 @@ type RetryConfig = false | {
|
|
|
113
113
|
backoff?: (retryCount: number) => number;
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
-
type Endpoint = {
|
|
117
|
-
/**
|
|
118
|
-
* The name of the endpoint (optional)
|
|
119
|
-
*/
|
|
120
|
-
name?: string;
|
|
121
|
-
/**
|
|
122
|
-
* The url of the endpoint
|
|
123
|
-
*/
|
|
124
|
-
url: string;
|
|
125
|
-
};
|
|
126
|
-
type AddEndpointsRequest = {
|
|
127
|
-
/**
|
|
128
|
-
* The name of the topic.
|
|
129
|
-
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
130
|
-
*/
|
|
131
|
-
name: string;
|
|
132
|
-
endpoints: Endpoint[];
|
|
133
|
-
};
|
|
134
|
-
type RemoveEndpointsRequest = {
|
|
135
|
-
/**
|
|
136
|
-
* The name of the topic.
|
|
137
|
-
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
138
|
-
*/
|
|
139
|
-
name: string;
|
|
140
|
-
endpoints: ({
|
|
141
|
-
name: string;
|
|
142
|
-
url?: string;
|
|
143
|
-
} | {
|
|
144
|
-
name?: string;
|
|
145
|
-
url: string;
|
|
146
|
-
})[];
|
|
147
|
-
};
|
|
148
|
-
type Topic = {
|
|
149
|
-
/**
|
|
150
|
-
* The name of this topic.
|
|
151
|
-
*/
|
|
152
|
-
name: string;
|
|
153
|
-
/**
|
|
154
|
-
* A list of all subscribed endpoints
|
|
155
|
-
*/
|
|
156
|
-
endpoints: Endpoint[];
|
|
157
|
-
};
|
|
158
|
-
declare class Topics {
|
|
159
|
-
private readonly http;
|
|
160
|
-
constructor(http: Requester);
|
|
161
|
-
/**
|
|
162
|
-
* Create a new topic with the given name and endpoints
|
|
163
|
-
*/
|
|
164
|
-
addEndpoints(req: AddEndpointsRequest): Promise<void>;
|
|
165
|
-
/**
|
|
166
|
-
* Remove endpoints from a topic.
|
|
167
|
-
*/
|
|
168
|
-
removeEndpoints(req: RemoveEndpointsRequest): Promise<void>;
|
|
169
|
-
/**
|
|
170
|
-
* Get a list of all topics.
|
|
171
|
-
*/
|
|
172
|
-
list(): Promise<Topic[]>;
|
|
173
|
-
/**
|
|
174
|
-
* Get a single topic
|
|
175
|
-
*/
|
|
176
|
-
get(name: string): Promise<Topic>;
|
|
177
|
-
/**
|
|
178
|
-
* Delete a topic
|
|
179
|
-
*/
|
|
180
|
-
delete(name: string): Promise<void>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
116
|
type Message = {
|
|
184
117
|
/**
|
|
185
118
|
* A unique identifier for this message.
|
|
@@ -214,13 +147,17 @@ type Message = {
|
|
|
214
147
|
*/
|
|
215
148
|
notBefore?: number;
|
|
216
149
|
/**
|
|
217
|
-
* A unix timestamp (milliseconds) when this messages was
|
|
150
|
+
* A unix timestamp (milliseconds) when this messages was created.
|
|
218
151
|
*/
|
|
219
152
|
createdAt: number;
|
|
220
153
|
/**
|
|
221
154
|
* The callback url if configured.
|
|
222
155
|
*/
|
|
223
156
|
callback?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The failure callback url if configured.
|
|
159
|
+
*/
|
|
160
|
+
failureCallback?: string;
|
|
224
161
|
};
|
|
225
162
|
declare class Messages {
|
|
226
163
|
private readonly http;
|
|
@@ -235,6 +172,27 @@ declare class Messages {
|
|
|
235
172
|
delete(messageId: string): Promise<void>;
|
|
236
173
|
}
|
|
237
174
|
|
|
175
|
+
type DlqMessage = Message & {
|
|
176
|
+
dlqId: string;
|
|
177
|
+
};
|
|
178
|
+
declare class DLQ {
|
|
179
|
+
private readonly http;
|
|
180
|
+
constructor(http: Requester);
|
|
181
|
+
/**
|
|
182
|
+
* List messages in the dlq
|
|
183
|
+
*/
|
|
184
|
+
listMessages(opts?: {
|
|
185
|
+
cursor?: string;
|
|
186
|
+
}): Promise<{
|
|
187
|
+
messages: DlqMessage[];
|
|
188
|
+
cursor?: string;
|
|
189
|
+
}>;
|
|
190
|
+
/**
|
|
191
|
+
* Remove a message from the dlq using it's `dlqId`
|
|
192
|
+
*/
|
|
193
|
+
delete(dlqMessageId: string): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
|
|
238
196
|
type Schedule = {
|
|
239
197
|
scheduleId: string;
|
|
240
198
|
cron: string;
|
|
@@ -246,6 +204,7 @@ type Schedule = {
|
|
|
246
204
|
retries: number;
|
|
247
205
|
delay?: number;
|
|
248
206
|
callback?: string;
|
|
207
|
+
failureCallback?: string;
|
|
249
208
|
};
|
|
250
209
|
type CreateScheduleRequest = {
|
|
251
210
|
/**
|
|
@@ -277,7 +236,7 @@ type CreateScheduleRequest = {
|
|
|
277
236
|
*/
|
|
278
237
|
delay?: number;
|
|
279
238
|
/**
|
|
280
|
-
* In case your destination server is
|
|
239
|
+
* In case your destination server is unavailable or returns a status code outside of the 200-299
|
|
281
240
|
* range, we will retry the request after a certain amount of time.
|
|
282
241
|
*
|
|
283
242
|
* Configure how many times you would like the delivery to be retried
|
|
@@ -293,6 +252,14 @@ type CreateScheduleRequest = {
|
|
|
293
252
|
* @default undefined
|
|
294
253
|
*/
|
|
295
254
|
callback?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Use a failure callback url to handle messages that could not be delivered.
|
|
257
|
+
*
|
|
258
|
+
* The failure callback url must be publicly accessible
|
|
259
|
+
*
|
|
260
|
+
* @default undefined
|
|
261
|
+
*/
|
|
262
|
+
failureCallback?: string;
|
|
296
263
|
/**
|
|
297
264
|
* The method to use when sending a request to your API
|
|
298
265
|
*
|
|
@@ -327,6 +294,73 @@ declare class Schedules {
|
|
|
327
294
|
delete(scheduleId: string): Promise<void>;
|
|
328
295
|
}
|
|
329
296
|
|
|
297
|
+
type Endpoint = {
|
|
298
|
+
/**
|
|
299
|
+
* The name of the endpoint (optional)
|
|
300
|
+
*/
|
|
301
|
+
name?: string;
|
|
302
|
+
/**
|
|
303
|
+
* The url of the endpoint
|
|
304
|
+
*/
|
|
305
|
+
url: string;
|
|
306
|
+
};
|
|
307
|
+
type AddEndpointsRequest = {
|
|
308
|
+
/**
|
|
309
|
+
* The name of the topic.
|
|
310
|
+
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
311
|
+
*/
|
|
312
|
+
name: string;
|
|
313
|
+
endpoints: Endpoint[];
|
|
314
|
+
};
|
|
315
|
+
type RemoveEndpointsRequest = {
|
|
316
|
+
/**
|
|
317
|
+
* The name of the topic.
|
|
318
|
+
* Must be unique and only contain alphanumeric, hyphen, underscore and periods.
|
|
319
|
+
*/
|
|
320
|
+
name: string;
|
|
321
|
+
endpoints: ({
|
|
322
|
+
name: string;
|
|
323
|
+
url?: string;
|
|
324
|
+
} | {
|
|
325
|
+
name?: string;
|
|
326
|
+
url: string;
|
|
327
|
+
})[];
|
|
328
|
+
};
|
|
329
|
+
type Topic = {
|
|
330
|
+
/**
|
|
331
|
+
* The name of this topic.
|
|
332
|
+
*/
|
|
333
|
+
name: string;
|
|
334
|
+
/**
|
|
335
|
+
* A list of all subscribed endpoints
|
|
336
|
+
*/
|
|
337
|
+
endpoints: Endpoint[];
|
|
338
|
+
};
|
|
339
|
+
declare class Topics {
|
|
340
|
+
private readonly http;
|
|
341
|
+
constructor(http: Requester);
|
|
342
|
+
/**
|
|
343
|
+
* Create a new topic with the given name and endpoints
|
|
344
|
+
*/
|
|
345
|
+
addEndpoints(req: AddEndpointsRequest): Promise<void>;
|
|
346
|
+
/**
|
|
347
|
+
* Remove endpoints from a topic.
|
|
348
|
+
*/
|
|
349
|
+
removeEndpoints(req: RemoveEndpointsRequest): Promise<void>;
|
|
350
|
+
/**
|
|
351
|
+
* Get a list of all topics.
|
|
352
|
+
*/
|
|
353
|
+
list(): Promise<Topic[]>;
|
|
354
|
+
/**
|
|
355
|
+
* Get a single topic
|
|
356
|
+
*/
|
|
357
|
+
get(name: string): Promise<Topic>;
|
|
358
|
+
/**
|
|
359
|
+
* Delete a topic
|
|
360
|
+
*/
|
|
361
|
+
delete(name: string): Promise<void>;
|
|
362
|
+
}
|
|
363
|
+
|
|
330
364
|
type State = "CREATED" | "ACTIVE" | "DELIVERED" | "ERROR" | "RETRY" | "FAILED";
|
|
331
365
|
type Event = {
|
|
332
366
|
time: number;
|
|
@@ -342,27 +376,6 @@ type WithCursor<T> = T & {
|
|
|
342
376
|
cursor?: number;
|
|
343
377
|
};
|
|
344
378
|
|
|
345
|
-
type DlqMessage = Message & {
|
|
346
|
-
dlqId: string;
|
|
347
|
-
};
|
|
348
|
-
declare class DLQ {
|
|
349
|
-
private readonly http;
|
|
350
|
-
constructor(http: Requester);
|
|
351
|
-
/**
|
|
352
|
-
* List messages in the dlq
|
|
353
|
-
*/
|
|
354
|
-
listMessages(opts?: {
|
|
355
|
-
cursor?: string;
|
|
356
|
-
}): Promise<{
|
|
357
|
-
messages: DlqMessage[];
|
|
358
|
-
cursor?: string;
|
|
359
|
-
}>;
|
|
360
|
-
/**
|
|
361
|
-
* Remove a message from the dlq using it's `dlqId`
|
|
362
|
-
*/
|
|
363
|
-
delete(dlqMessageId: string): Promise<void>;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
379
|
type ClientConfig = {
|
|
367
380
|
/**
|
|
368
381
|
* Url of the qstash api server.
|
|
@@ -461,6 +474,14 @@ type PublishRequest<TBody = BodyInit> = {
|
|
|
461
474
|
* @default undefined
|
|
462
475
|
*/
|
|
463
476
|
callback?: string;
|
|
477
|
+
/**
|
|
478
|
+
* Use a failure callback url to handle messages that could not be delivered.
|
|
479
|
+
*
|
|
480
|
+
* The failure callback url must be publicly accessible
|
|
481
|
+
*
|
|
482
|
+
* @default undefined
|
|
483
|
+
*/
|
|
484
|
+
failureCallback?: string;
|
|
464
485
|
/**
|
|
465
486
|
* The method to use when sending a request to your API
|
|
466
487
|
*
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,38 @@
|
|
|
6
6
|
|
|
7
7
|
var _chunkEQTYEU4Ujs = require('./chunk-EQTYEU4U.js');
|
|
8
8
|
|
|
9
|
+
// src/client/dlq.ts
|
|
10
|
+
var DLQ = class {
|
|
11
|
+
constructor(http) {
|
|
12
|
+
this.http = http;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* List messages in the dlq
|
|
16
|
+
*/
|
|
17
|
+
listMessages(opts) {
|
|
18
|
+
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
19
|
+
return yield this.http.request({
|
|
20
|
+
method: "GET",
|
|
21
|
+
path: ["v2", "dlq"],
|
|
22
|
+
query: { cursor: opts == null ? void 0 : opts.cursor }
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Remove a message from the dlq using it's `dlqId`
|
|
28
|
+
*/
|
|
29
|
+
delete(dlqMessageId) {
|
|
30
|
+
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
31
|
+
return yield this.http.request({
|
|
32
|
+
method: "DELETE",
|
|
33
|
+
path: ["v2", "dlq", dlqMessageId],
|
|
34
|
+
parseResponseAsJson: false
|
|
35
|
+
// there is no response
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
9
41
|
// src/client/error.ts
|
|
10
42
|
var QstashError = class extends Error {
|
|
11
43
|
constructor(message) {
|
|
@@ -90,75 +122,6 @@ var HttpClient = class {
|
|
|
90
122
|
}
|
|
91
123
|
};
|
|
92
124
|
|
|
93
|
-
// src/client/topics.ts
|
|
94
|
-
var Topics = class {
|
|
95
|
-
constructor(http) {
|
|
96
|
-
this.http = http;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a new topic with the given name and endpoints
|
|
100
|
-
*/
|
|
101
|
-
addEndpoints(req) {
|
|
102
|
-
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
103
|
-
yield this.http.request({
|
|
104
|
-
method: "POST",
|
|
105
|
-
path: ["v2", "topics", req.name, "endpoints"],
|
|
106
|
-
headers: { "Content-Type": "application/json" },
|
|
107
|
-
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
108
|
-
parseResponseAsJson: false
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Remove endpoints from a topic.
|
|
114
|
-
*/
|
|
115
|
-
removeEndpoints(req) {
|
|
116
|
-
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
117
|
-
yield this.http.request({
|
|
118
|
-
method: "DELETE",
|
|
119
|
-
path: ["v2", "topics", req.name, "endpoints"],
|
|
120
|
-
headers: { "Content-Type": "application/json" },
|
|
121
|
-
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
122
|
-
parseResponseAsJson: false
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Get a list of all topics.
|
|
128
|
-
*/
|
|
129
|
-
list() {
|
|
130
|
-
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
131
|
-
return yield this.http.request({
|
|
132
|
-
method: "GET",
|
|
133
|
-
path: ["v2", "topics"]
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get a single topic
|
|
139
|
-
*/
|
|
140
|
-
get(name) {
|
|
141
|
-
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
142
|
-
return yield this.http.request({
|
|
143
|
-
method: "GET",
|
|
144
|
-
path: ["v2", "topics", name]
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Delete a topic
|
|
150
|
-
*/
|
|
151
|
-
delete(name) {
|
|
152
|
-
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
153
|
-
return yield this.http.request({
|
|
154
|
-
method: "DELETE",
|
|
155
|
-
path: ["v2", "topics", name],
|
|
156
|
-
parseResponseAsJson: false
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
125
|
// src/client/messages.ts
|
|
163
126
|
var Messages = class {
|
|
164
127
|
constructor(http) {
|
|
@@ -216,6 +179,9 @@ var Schedules = class {
|
|
|
216
179
|
if (typeof req.callback !== "undefined") {
|
|
217
180
|
headers.set("Upstash-Callback", req.callback);
|
|
218
181
|
}
|
|
182
|
+
if (typeof req.failureCallback !== "undefined") {
|
|
183
|
+
headers.set("Upstash-Failure-Callback", req.failureCallback);
|
|
184
|
+
}
|
|
219
185
|
return yield this.http.request({
|
|
220
186
|
method: "POST",
|
|
221
187
|
headers,
|
|
@@ -260,33 +226,70 @@ var Schedules = class {
|
|
|
260
226
|
}
|
|
261
227
|
};
|
|
262
228
|
|
|
263
|
-
// src/client/
|
|
264
|
-
var
|
|
229
|
+
// src/client/topics.ts
|
|
230
|
+
var Topics = class {
|
|
265
231
|
constructor(http) {
|
|
266
232
|
this.http = http;
|
|
267
233
|
}
|
|
268
234
|
/**
|
|
269
|
-
*
|
|
235
|
+
* Create a new topic with the given name and endpoints
|
|
270
236
|
*/
|
|
271
|
-
|
|
237
|
+
addEndpoints(req) {
|
|
238
|
+
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
239
|
+
yield this.http.request({
|
|
240
|
+
method: "POST",
|
|
241
|
+
path: ["v2", "topics", req.name, "endpoints"],
|
|
242
|
+
headers: { "Content-Type": "application/json" },
|
|
243
|
+
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
244
|
+
parseResponseAsJson: false
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Remove endpoints from a topic.
|
|
250
|
+
*/
|
|
251
|
+
removeEndpoints(req) {
|
|
252
|
+
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
253
|
+
yield this.http.request({
|
|
254
|
+
method: "DELETE",
|
|
255
|
+
path: ["v2", "topics", req.name, "endpoints"],
|
|
256
|
+
headers: { "Content-Type": "application/json" },
|
|
257
|
+
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
258
|
+
parseResponseAsJson: false
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get a list of all topics.
|
|
264
|
+
*/
|
|
265
|
+
list() {
|
|
272
266
|
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
273
267
|
return yield this.http.request({
|
|
274
268
|
method: "GET",
|
|
275
|
-
path: ["v2", "
|
|
276
|
-
query: { cursor: opts == null ? void 0 : opts.cursor }
|
|
269
|
+
path: ["v2", "topics"]
|
|
277
270
|
});
|
|
278
271
|
});
|
|
279
272
|
}
|
|
280
273
|
/**
|
|
281
|
-
*
|
|
274
|
+
* Get a single topic
|
|
282
275
|
*/
|
|
283
|
-
|
|
276
|
+
get(name) {
|
|
277
|
+
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
278
|
+
return yield this.http.request({
|
|
279
|
+
method: "GET",
|
|
280
|
+
path: ["v2", "topics", name]
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Delete a topic
|
|
286
|
+
*/
|
|
287
|
+
delete(name) {
|
|
284
288
|
return _chunkEQTYEU4Ujs.__async.call(void 0, this, null, function* () {
|
|
285
289
|
return yield this.http.request({
|
|
286
290
|
method: "DELETE",
|
|
287
|
-
path: ["v2", "
|
|
291
|
+
path: ["v2", "topics", name],
|
|
288
292
|
parseResponseAsJson: false
|
|
289
|
-
// there is no response
|
|
290
293
|
});
|
|
291
294
|
});
|
|
292
295
|
}
|
|
@@ -356,6 +359,9 @@ var Client = class {
|
|
|
356
359
|
if (typeof req.callback !== "undefined") {
|
|
357
360
|
headers.set("Upstash-Callback", req.callback);
|
|
358
361
|
}
|
|
362
|
+
if (typeof req.failureCallback !== "undefined") {
|
|
363
|
+
headers.set("Upstash-Failure-Callback", req.failureCallback);
|
|
364
|
+
}
|
|
359
365
|
const res = yield this.http.request({
|
|
360
366
|
path: ["v2", "publish", (_b = req.url) != null ? _b : req.topic],
|
|
361
367
|
body: req.body,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/error.ts","../src/client/http.ts","../src/client/topics.ts","../src/client/messages.ts","../src/client/schedules.ts","../src/client/dlq.ts","../src/client/client.ts"],"names":[],"mappings":";;;;;;;;;AAGO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,YAAY;AAAA,EACpD,YAAY,MAAe;AACzB,UAAM,8BAA8B,KAAK,UAAU,IAAI,CAAC,GAAG;AAAA,EAC7D;AACF;;;ACwDO,IAAM,aAAN,MAAsC;AAAA,EAYpC,YAAY,QAA0B;AAlF/C;AAmFI,SAAK,UAAU,OAAO,QAAQ,QAAQ,OAAO,EAAE;AAE/C,SAAK,gBAAgB,OAAO;AAE5B,QAAI,QAAO,iCAAQ,WAAU,cAAa,iCAAQ,WAAU,OAAO;AACjE,WAAK,QAAQ;AAAA,QACX,UAAU;AAAA,QACV,SAAS,MAAM;AAAA,MACjB;AAAA,IACF,OAAO;AACL,WAAK,QAAQ;AAAA,QACX,YAAU,YAAO,UAAP,mBAAc,WAAU,OAAO,MAAM,UAAU,IAAI;AAAA,QAC7D,UAAS,kBAAO,UAAP,mBAAc,YAAd,YAA0B,CAAC,eAAe,KAAK,IAAI,UAAU,IAAI;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAAA,EAEa,QAAiB,KAAwD;AAAA;AApGxF;AAqGI,YAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AACvC,cAAQ,IAAI,iBAAiB,KAAK,aAAa;AAE/C,YAAM,iBAAqD;AAAA,QACzD,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA,MAAM,IAAI;AAAA,QACV,WAAW,IAAI;AAAA,MACjB;AAEA,YAAM,MAAM,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,SAAI,SAAJ,YAAY,CAAC,CAAE,EAAE,KAAK,GAAG,CAAC;AACjE,UAAI,IAAI,OAAO;AACb,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,KAAK,GAAG;AACpD,cAAI,OAAO,UAAU,aAAa;AAChC,gBAAI,aAAa,IAAI,KAAK,MAAM,SAAS,CAAC;AAAA,UAC5C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAuB;AAC3B,UAAI,QAAsB;AAC1B,eAAS,IAAI,GAAG,IAAI,KAAK,MAAM,UAAU,KAAK;AAC5C,YAAI;AACF,gBAAM,MAAM,MAAM,IAAI,SAAS,GAAG,cAAc;AAChD;AAAA,QACF,SAAS,KAAK;AACZ,kBAAQ;AACR,gBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC;AAAA,QAC/D;AAAA,MACF;AACA,UAAI,CAAC,KAAK;AACR,cAAM,wBAAS,IAAI,MAAM,uBAAuB;AAAA,MAClD;AACA,UAAI,IAAI,WAAW,KAAK;AACtB,cAAM,IAAI,qBAAqB;AAAA,UAC7B,OAAO,IAAI,QAAQ,IAAI,uBAAuB;AAAA,UAC9C,WAAW,IAAI,QAAQ,IAAI,2BAA2B;AAAA,UACtD,OAAO,IAAI,QAAQ,IAAI,uBAAuB;AAAA,QAChD,CAAC;AAAA,MACH;AAEA,UAAI,IAAI,SAAS,OAAO,IAAI,UAAU,KAAK;AACzC,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAM,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,iBAAiB,IAAI,MAAM,EAAE;AAAA,MAC9E;AACA,UAAI,IAAI,wBAAwB,OAAO;AACrC,eAAO;AAAA,MACT,OAAO;AACL,eAAQ,MAAM,IAAI,KAAK;AAAA,MACzB;AAAA,IACF;AAAA;AACF;;;ACjGO,IAAM,SAAN,MAAa;AAAA,EAGlB,YAAY,MAAiB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKa,aAAa,KAAyC;AAAA;AACjE,YAAM,KAAK,KAAK,QAAe;AAAA,QAC7B,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,UAAU,IAAI,MAAM,WAAW;AAAA,QAC5C,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,WAAW,IAAI,UAAU,CAAC;AAAA,QACjD,qBAAqB;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,gBAAgB,KAA4C;AAAA;AACvE,YAAM,KAAK,KAAK,QAAe;AAAA,QAC7B,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,UAAU,IAAI,MAAM,WAAW;AAAA,QAC5C,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,WAAW,IAAI,UAAU,CAAC;AAAA,QACjD,qBAAqB;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAAyB;AAAA;AACpC,aAAO,MAAM,KAAK,KAAK,QAAiB;AAAA,QACtC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,QAAQ;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,IAAI,MAA8B;AAAA;AAC7C,aAAO,MAAM,KAAK,KAAK,QAAe;AAAA,QACpC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,UAAU,IAAI;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAAO,MAA6B;AAAA;AAC/C,aAAO,MAAM,KAAK,KAAK,QAAc;AAAA,QACnC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,UAAU,IAAI;AAAA,QAC3B,qBAAqB;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AACF;;;AChEO,IAAM,WAAN,MAAe;AAAA,EAGpB,YAAY,MAAiB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKa,IAAI,WAAqC;AAAA;AACpD,aAAO,MAAM,KAAK,KAAK,QAAiB;AAAA,QACtC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,YAAY,SAAS;AAAA,MACpC,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAAO,WAAkC;AAAA;AACpD,aAAO,MAAM,KAAK,KAAK,QAAc;AAAA,QACnC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,YAAY,SAAS;AAAA,QAClC,qBAAqB;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AACF;;;ACDO,IAAM,YAAN,MAAgB;AAAA,EAGrB,YAAY,MAAiB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKa,OAAO,KAA6D;AAAA;AAC/E,YAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AAEvC,UAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,gBAAQ,IAAI,gBAAgB,kBAAkB;AAAA,MAChD;AAEA,cAAQ,IAAI,gBAAgB,IAAI,IAAI;AAEpC,UAAI,OAAO,IAAI,WAAW,aAAa;AACrC,gBAAQ,IAAI,kBAAkB,IAAI,MAAM;AAAA,MAC1C;AAEA,UAAI,OAAO,IAAI,UAAU,aAAa;AACpC,gBAAQ,IAAI,iBAAiB,GAAG,IAAI,MAAM,QAAQ,CAAC,GAAG;AAAA,MACxD;AAEA,UAAI,OAAO,IAAI,YAAY,aAAa;AACtC,gBAAQ,IAAI,mBAAmB,IAAI,QAAQ,QAAQ,CAAC;AAAA,MACtD;AAEA,UAAI,OAAO,IAAI,aAAa,aAAa;AACvC,gBAAQ,IAAI,oBAAoB,IAAI,QAAQ;AAAA,MAC9C;AAEA,aAAO,MAAM,KAAK,KAAK,QAAQ;AAAA,QAC7B,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,CAAC,MAAM,aAAa,IAAI,WAAW;AAAA,QACzC,MAAM,IAAI;AAAA,MACZ,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,IAAI,YAAuC;AAAA;AACtD,aAAO,MAAM,KAAK,KAAK,QAAkB;AAAA,QACvC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,aAAa,UAAU;AAAA,MACtC,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAA4B;AAAA;AACvC,aAAO,MAAM,KAAK,KAAK,QAAoB;AAAA,QACzC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,WAAW;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAAO,YAAmC;AAAA;AACrD,aAAO,MAAM,KAAK,KAAK,QAAc;AAAA,QACnC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,aAAa,UAAU;AAAA,QACpC,qBAAqB;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AACF;;;AClJO,IAAM,MAAN,MAAU;AAAA,EAGf,YAAY,MAAiB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKa,aAAa,MAGvB;AAAA;AACD,aAAO,MAAM,KAAK,KAAK,QAAQ;AAAA,QAC7B,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,KAAK;AAAA,QAClB,OAAO,EAAE,QAAQ,6BAAM,OAAO;AAAA,MAChC,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKa,OAAO,cAAqC;AAAA;AACvD,aAAO,MAAM,KAAK,KAAK,QAAc;AAAA,QACnC,QAAQ;AAAA,QACR,MAAM,CAAC,MAAM,OAAO,YAAY;AAAA,QAChC,qBAAqB;AAAA;AAAA,MACvB,CAAC;AAAA,IACH;AAAA;AACF;;;ACqHO,IAAM,SAAN,MAAa;AAAA,EAGX,YAAY,QAAsB;AACvC,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,OAAO,OAAO;AAAA,MACd,SAAS,OAAO,UAAU,OAAO,QAAQ,QAAQ,OAAO,EAAE,IAAI;AAAA,MAC9D,eAAe,UAAU,OAAO,KAAK;AAAA,IACvC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,SAAiB;AAC1B,WAAO,IAAI,OAAO,KAAK,IAAI;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,MAAW;AACpB,WAAO,IAAI,IAAI,KAAK,IAAI;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,WAAqB;AAC9B,WAAO,IAAI,SAAS,KAAK,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,YAAuB;AAChC,WAAO,IAAI,UAAU,KAAK,IAAI;AAAA,EAChC;AAAA,EACa,QACX,KACoC;AAAA;AA3MxC;AA4MI,YAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AAEvC,cAAQ,IAAI,mBAAkB,SAAI,WAAJ,YAAc,MAAM;AAElD,UAAI,OAAO,IAAI,UAAU,aAAa;AACpC,gBAAQ,IAAI,iBAAiB,GAAG,IAAI,MAAM,QAAQ,CAAC,GAAG;AAAA,MACxD;AAEA,UAAI,OAAO,IAAI,cAAc,aAAa;AACxC,gBAAQ,IAAI,sBAAsB,IAAI,UAAU,QAAQ,CAAC;AAAA,MAC3D;AAEA,UAAI,OAAO,IAAI,oBAAoB,aAAa;AAC9C,gBAAQ,IAAI,4BAA4B,IAAI,eAAe;AAAA,MAC7D;AAEA,UAAI,OAAO,IAAI,8BAA8B,aAAa;AACxD,gBAAQ,IAAI,uCAAuC,MAAM;AAAA,MAC3D;AAEA,UAAI,OAAO,IAAI,YAAY,aAAa;AACtC,gBAAQ,IAAI,mBAAmB,IAAI,QAAQ,QAAQ,CAAC;AAAA,MACtD;AAEA,UAAI,OAAO,IAAI,aAAa,aAAa;AACvC,gBAAQ,IAAI,oBAAoB,IAAI,QAAQ;AAAA,MAC9C;AAEA,YAAM,MAAM,MAAM,KAAK,KAAK,QAAmC;AAAA,QAC7D,MAAM,CAAC,MAAM,YAAW,SAAI,QAAJ,YAAW,IAAI,KAAK;AAAA,QAC5C,MAAM,IAAI;AAAA,QACV;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AACD,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMa,YAGX,KAAmD;AAAA;AACnD,YAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AACvC,cAAQ,IAAI,gBAAgB,kBAAkB;AAG9C,YAAM,MAAM,MAAM,KAAK,QAAkB,iCACpC,MADoC;AAAA,QAEvC;AAAA,QACA,MAAM,KAAK,UAAU,IAAI,IAAI;AAAA,MAC/B,EAAmB;AACnB,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBa,OAAO,KAAiD;AAAA;AACnE,YAAM,QAAgC,CAAC;AACvC,WAAI,2BAAK,WAAU,IAAI,SAAS,GAAG;AACjC,cAAM,SAAS,IAAI;AAAA,MACrB;AACA,YAAM,MAAM,MAAM,KAAK,KAAK,QAA2B;AAAA,QACrD,MAAM,CAAC,MAAM,QAAQ;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA;AACF","sourcesContent":["/**\n * Result of 500 Internal Server Error\n */\nexport class QstashError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"QstashError\";\n }\n}\n\nexport class QstashRatelimitError extends QstashError {\n constructor(args: unknown) {\n super(`You have been ratelimited. ${JSON.stringify(args)} `);\n }\n}\n","import { QstashError, QstashRatelimitError } from \"./error\";\n\nexport type UpstashRequest = {\n /**\n * The path to the resource.\n */\n path: string[];\n\n /**\n * A BodyInit object or null to set request's body.\n */\n body?: BodyInit | null;\n\n /**\n * A Headers object, an object literal, or an array of two-item arrays to set\n * request's headers.\n */\n headers?: HeadersInit;\n\n /**\n * A boolean to set request's keepalive.\n */\n keepalive?: boolean;\n\n /**\n * A string to set request's method.\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\n query?: Record<string, string | number | boolean | undefined>;\n\n /**\n * if enabled, call `res.json()`\n *\n * @default true\n */\n parseResponseAsJson?: boolean;\n};\nexport type UpstashResponse<TResult> = TResult & { error?: string };\n\nexport interface Requester {\n request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;\n}\n\nexport type RetryConfig =\n | false\n | {\n /**\n * The number of retries to attempt before giving up.\n *\n * @default 5\n */\n retries?: number;\n /**\n * A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.\n *\n * @default\n * ```ts\n * Math.exp(retryCount) * 50\n * ```\n */\n backoff?: (retryCount: number) => number;\n };\n\nexport type HttpClientConfig = {\n baseUrl: string;\n authorization: string;\n retry?: RetryConfig;\n};\n\nexport class HttpClient implements Requester {\n public readonly baseUrl: string;\n\n public readonly authorization: string;\n\n public readonly options?: { backend?: string };\n\n public retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n\n this.authorization = config.authorization;\n\n if (typeof config?.retry === \"boolean\" && config?.retry === false) {\n this.retry = {\n attempts: 1,\n backoff: () => 0,\n };\n } else {\n this.retry = {\n attempts: config.retry?.retries ? config.retry.retries + 1 : 5,\n backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50),\n };\n }\n }\n\n public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {\n const headers = new Headers(req.headers);\n headers.set(\"Authorization\", this.authorization);\n\n const requestOptions: RequestInit & { backend?: string } = {\n method: req.method,\n headers,\n body: req.body,\n keepalive: req.keepalive,\n };\n\n const url = new URL([this.baseUrl, ...(req.path ?? [])].join(\"/\"));\n if (req.query) {\n for (const [key, value] of Object.entries(req.query)) {\n if (typeof value !== \"undefined\") {\n url.searchParams.set(key, value.toString());\n }\n }\n }\n\n let res: Response | null = null;\n let error: Error | null = null;\n for (let i = 0; i < this.retry.attempts; i++) {\n try {\n res = await fetch(url.toString(), requestOptions);\n break;\n } catch (err) {\n error = err as Error;\n await new Promise((r) => setTimeout(r, this.retry.backoff(i)));\n }\n }\n if (!res) {\n throw error ?? new Error(\"Exhausted all retries\");\n }\n if (res.status === 429) {\n throw new QstashRatelimitError({\n limit: res.headers.get(\"Burst-RateLimit-Limit\"),\n remaining: res.headers.get(\"Burst-RateLimit-Remaining\"),\n reset: res.headers.get(\"Burst-RateLimit-Reset\"),\n });\n }\n\n if (res.status < 200 || res.status >= 300) {\n const body = await res.text();\n throw new QstashError(body.length > 0 ? body : `Error: status=${res.status}`);\n }\n if (req.parseResponseAsJson === false) {\n return undefined as unknown as UpstashResponse<TResult>;\n } else {\n return (await res.json()) as UpstashResponse<TResult>;\n }\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Endpoint = {\n /**\n * The name of the endpoint (optional)\n */\n name?: string;\n\n /**\n * The url of the endpoint\n */\n url: string;\n};\n\nexport type AddEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: Endpoint[];\n};\n\nexport type RemoveEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: (\n | {\n name: string;\n url?: string;\n }\n | {\n name?: string;\n url: string;\n }\n )[];\n};\n\nexport type Topic = {\n /**\n * The name of this topic.\n */\n name: string;\n\n /**\n * A list of all subscribed endpoints\n */\n endpoints: Endpoint[];\n};\n\nexport class Topics {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a new topic with the given name and endpoints\n */\n public async addEndpoints(req: AddEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"POST\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Remove endpoints from a topic.\n */\n public async removeEndpoints(req: RemoveEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Get a list of all topics.\n */\n public async list(): Promise<Topic[]> {\n return await this.http.request<Topic[]>({\n method: \"GET\",\n path: [\"v2\", \"topics\"],\n });\n }\n\n /**\n * Get a single topic\n */\n public async get(name: string): Promise<Topic> {\n return await this.http.request<Topic>({\n method: \"GET\",\n path: [\"v2\", \"topics\", name],\n });\n }\n\n /**\n * Delete a topic\n */\n public async delete(name: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", name],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Message = {\n /**\n * A unique identifier for this message.\n */\n messageId: string;\n\n /**\n * The topic name if this message was sent to a topic.\n */\n topicName?: string;\n\n /**\n * The url where this message is sent to.\n */\n url: string;\n\n /**\n * The http method used to deliver the message\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * The http headers sent along with the message to your API.\n */\n header?: Record<string, string[]>;\n\n /**\n * The http body sent to your API\n */\n body?: string;\n\n /**\n * Maxmimum number of retries.\n */\n maxRetries?: number;\n\n /**\n * A unix timestamp (milliseconds) after which this message may get delivered.\n */\n notBefore?: number;\n\n /**\n * A unix timestamp (milliseconds) when this messages was crated.\n */\n createdAt: number;\n\n /**\n * The callback url if configured.\n */\n callback?: string;\n};\n\nexport class Messages {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Get a message\n */\n public async get(messageId: string): Promise<Message> {\n return await this.http.request<Message>({\n method: \"GET\",\n path: [\"v2\", \"messages\", messageId],\n });\n }\n\n /**\n * Cancel a message\n */\n public async delete(messageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"messages\", messageId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Schedule = {\n scheduleId: string;\n cron: string;\n createdAt: number;\n destination: string;\n method: string;\n header?: Record<string, string[]>;\n body?: string;\n retries: number;\n delay?: number;\n callback?: string;\n};\n\nexport type CreateScheduleRequest = {\n /**\n * Either a URL or topic name\n */\n destination: string;\n\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: BodyInit;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * Specify a cron expression to repeatedly send this message to the destination.\n */\n cron: string;\n};\n\nexport class Schedules {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a schedule\n */\n public async create(req: CreateScheduleRequest): Promise<{ scheduleId: string }> {\n const headers = new Headers(req.headers);\n\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n headers.set(\"Upstash-Cron\", req.cron);\n\n if (typeof req.method !== \"undefined\") {\n headers.set(\"Upstash-Method\", req.method);\n }\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n return await this.http.request({\n method: \"POST\",\n headers,\n path: [\"v2\", \"schedules\", req.destination],\n body: req.body,\n });\n }\n\n /**\n * Get a schedule\n */\n public async get(scheduleId: string): Promise<Schedule> {\n return await this.http.request<Schedule>({\n method: \"GET\",\n path: [\"v2\", \"schedules\", scheduleId],\n });\n }\n\n /**\n * List your schedules\n */\n public async list(): Promise<Schedule[]> {\n return await this.http.request<Schedule[]>({\n method: \"GET\",\n path: [\"v2\", \"schedules\"],\n });\n }\n\n /**\n * Delete a schedule\n */\n public async delete(scheduleId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"schedules\", scheduleId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\nimport type { Message } from \"./messages\";\n\ntype DlqMessage = Message & {\n dlqId: string;\n};\n\nexport class DLQ {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * List messages in the dlq\n */\n public async listMessages(opts?: { cursor?: string }): Promise<{\n messages: DlqMessage[];\n cursor?: string;\n }> {\n return await this.http.request({\n method: \"GET\",\n path: [\"v2\", \"dlq\"],\n query: { cursor: opts?.cursor },\n });\n }\n\n /**\n * Remove a message from the dlq using it's `dlqId`\n */\n public async delete(dlqMessageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"dlq\", dlqMessageId],\n parseResponseAsJson: false, // there is no response\n });\n }\n}\n","import { HttpClient, Requester, RetryConfig } from \"./http\";\nimport { Topics } from \"./topics\";\nimport { Messages } from \"./messages\";\nimport { Schedules } from \"./schedules\";\nimport { Event } from \"./types\";\nimport { DLQ } from \"./dlq\";\ntype ClientConfig = {\n /**\n * Url of the qstash api server.\n *\n * This is only used for testing.\n *\n * @default \"https://qstash.upstash.io\"\n */\n baseUrl?: string;\n\n /**\n * The authorization token from the upstash console.\n */\n token: string;\n\n /**\n * Configure how the client should retry requests.\n */\n retry?: RetryConfig;\n};\n\nexport type PublishRequest<TBody = BodyInit> = {\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: TBody;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * Optionally set the absolute delay of this message.\n * This will override the delay option.\n * The message will not delivered until the specified time.\n *\n * Unix timestamp in seconds.\n *\n * @default undefined\n */\n notBefore?: number;\n\n /**\n * Provide a unique id for deduplication. This id will be used to detect duplicate messages.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default undefined\n */\n deduplicationId?: string;\n\n /**\n * If true, the message content will get hashed and used as deduplication id.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * The content based hash includes the following values:\n * - All headers, except Upstash-Authorization, this includes all headers you are sending.\n * - The entire raw request body The destination from the url path\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default false\n */\n contentBasedDeduplication?: boolean;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n} & (\n | {\n /**\n * The url where the message should be sent to.\n */\n url: string;\n topic?: never;\n }\n | {\n url?: never;\n /**\n * The url where the message should be sent to.\n */\n topic: string;\n }\n);\n\nexport type PublishJsonRequest = Omit<PublishRequest, \"body\"> & {\n /**\n * The message to send.\n * This can be anything as long as it can be serialized to JSON.\n */\n body: unknown;\n};\n\nexport type EventsRequest = {\n cursor?: number;\n};\n\nexport type GetEventsResponse = {\n cursor?: number;\n events: Event[];\n};\n\nexport class Client {\n public http: Requester;\n\n public constructor(config: ClientConfig) {\n this.http = new HttpClient({\n retry: config.retry,\n baseUrl: config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"https://qstash.upstash.io\",\n authorization: `Bearer ${config.token}`,\n });\n }\n\n /**\n * Access the topic API.\n *\n * Create, read, update or delete topics.\n */\n public get topics(): Topics {\n return new Topics(this.http);\n }\n\n /**\n * Access the dlq API.\n *\n * List or remove messages from the DLQ.\n */\n public get dlq(): DLQ {\n return new DLQ(this.http);\n }\n\n /**\n * Access the message API.\n *\n * Read or cancel messages.\n */\n public get messages(): Messages {\n return new Messages(this.http);\n }\n\n /**\n * Access the schedule API.\n *\n * Create, read or delete schedules.\n */\n public get schedules(): Schedules {\n return new Schedules(this.http);\n }\n public async publish<TRequest extends PublishRequest>(\n req: TRequest,\n ): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n\n headers.set(\"Upstash-Method\", req.method ?? \"POST\");\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.notBefore !== \"undefined\") {\n headers.set(\"Upstash-Not-Before\", req.notBefore.toFixed());\n }\n\n if (typeof req.deduplicationId !== \"undefined\") {\n headers.set(\"Upstash-Deduplication-Id\", req.deduplicationId);\n }\n\n if (typeof req.contentBasedDeduplication !== \"undefined\") {\n headers.set(\"Upstash-Content-Based-Deduplication\", \"true\");\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n const res = await this.http.request<PublishResponse<TRequest>>({\n path: [\"v2\", \"publish\", req.url ?? req.topic],\n body: req.body,\n headers,\n method: \"POST\",\n });\n return res;\n }\n\n /**\n * publishJSON is a utility wrapper around `publish` that automatically serializes the body\n * and sets the `Content-Type` header to `application/json`.\n */\n public async publishJSON<\n TBody = unknown,\n TRequest extends PublishRequest<TBody> = PublishRequest<TBody>,\n >(req: TRequest): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n // @ts-ignore it's just internal\n const res = await this.publish<TRequest>({\n ...req,\n headers,\n body: JSON.stringify(req.body),\n } as PublishRequest);\n return res;\n }\n\n /**\n * Retrieve your logs.\n *\n * The logs endpoint is paginated and returns only 100 logs at a time.\n * If you want to receive more logs, you can use the cursor to paginate.\n *\n * The cursor is a unix timestamp with millisecond precision\n *\n * @example\n * ```ts\n * let cursor = Date.now()\n * const logs: Log[] = []\n * while (cursor > 0) {\n * const res = await qstash.logs({ cursor })\n * logs.push(...res.logs)\n * cursor = res.cursor ?? 0\n * }\n * ```\n */\n public async events(req?: EventsRequest): Promise<GetEventsResponse> {\n const query: Record<string, number> = {};\n if (req?.cursor && req.cursor > 0) {\n query.cursor = req.cursor;\n }\n const res = await this.http.request<GetEventsResponse>({\n path: [\"v2\", \"events\"],\n method: \"GET\",\n query,\n });\n return res;\n }\n}\ntype PublishToUrlResponse = {\n messageId: string;\n url: string;\n deduplicated?: boolean;\n};\n\ntype PublishToTopicResponse = PublishToUrlResponse[];\n\ntype PublishResponse<R> = R extends { url: string } ? PublishToUrlResponse : PublishToTopicResponse;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/dlq.ts","../src/client/error.ts","../src/client/http.ts","../src/client/messages.ts","../src/client/schedules.ts","../src/client/topics.ts","../src/client/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { Requester } from \"./http\";\nimport type { Message } from \"./messages\";\n\ntype DlqMessage = Message & {\n dlqId: string;\n};\n\nexport class DLQ {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * List messages in the dlq\n */\n public async listMessages(opts?: { cursor?: string }): Promise<{\n messages: DlqMessage[];\n cursor?: string;\n }> {\n return await this.http.request({\n method: \"GET\",\n path: [\"v2\", \"dlq\"],\n query: { cursor: opts?.cursor },\n });\n }\n\n /**\n * Remove a message from the dlq using it's `dlqId`\n */\n public async delete(dlqMessageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"dlq\", dlqMessageId],\n parseResponseAsJson: false, // there is no response\n });\n }\n}\n","/**\n * Result of 500 Internal Server Error\n */\nexport class QstashError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"QstashError\";\n }\n}\n\nexport class QstashRatelimitError extends QstashError {\n constructor(args: unknown) {\n super(`You have been ratelimited. ${JSON.stringify(args)} `);\n }\n}\n","import { QstashError, QstashRatelimitError } from \"./error\";\n\nexport type UpstashRequest = {\n /**\n * The path to the resource.\n */\n path: string[];\n\n /**\n * A BodyInit object or null to set request's body.\n */\n body?: BodyInit | null;\n\n /**\n * A Headers object, an object literal, or an array of two-item arrays to set\n * request's headers.\n */\n headers?: HeadersInit;\n\n /**\n * A boolean to set request's keepalive.\n */\n keepalive?: boolean;\n\n /**\n * A string to set request's method.\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\n query?: Record<string, string | number | boolean | undefined>;\n\n /**\n * if enabled, call `res.json()`\n *\n * @default true\n */\n parseResponseAsJson?: boolean;\n};\nexport type UpstashResponse<TResult> = TResult & { error?: string };\n\nexport interface Requester {\n request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;\n}\n\nexport type RetryConfig =\n | false\n | {\n /**\n * The number of retries to attempt before giving up.\n *\n * @default 5\n */\n retries?: number;\n /**\n * A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.\n *\n * @default\n * ```ts\n * Math.exp(retryCount) * 50\n * ```\n */\n backoff?: (retryCount: number) => number;\n };\n\nexport type HttpClientConfig = {\n baseUrl: string;\n authorization: string;\n retry?: RetryConfig;\n};\n\nexport class HttpClient implements Requester {\n public readonly baseUrl: string;\n\n public readonly authorization: string;\n\n public readonly options?: { backend?: string };\n\n public retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n\n this.authorization = config.authorization;\n\n if (typeof config?.retry === \"boolean\" && config?.retry === false) {\n this.retry = {\n attempts: 1,\n backoff: () => 0,\n };\n } else {\n this.retry = {\n attempts: config.retry?.retries ? config.retry.retries + 1 : 5,\n backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50),\n };\n }\n }\n\n public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {\n const headers = new Headers(req.headers);\n headers.set(\"Authorization\", this.authorization);\n\n const requestOptions: RequestInit & { backend?: string } = {\n method: req.method,\n headers,\n body: req.body,\n keepalive: req.keepalive,\n };\n\n const url = new URL([this.baseUrl, ...(req.path ?? [])].join(\"/\"));\n if (req.query) {\n for (const [key, value] of Object.entries(req.query)) {\n if (typeof value !== \"undefined\") {\n url.searchParams.set(key, value.toString());\n }\n }\n }\n\n let res: Response | null = null;\n let error: Error | null = null;\n for (let i = 0; i < this.retry.attempts; i++) {\n try {\n res = await fetch(url.toString(), requestOptions);\n break;\n } catch (err) {\n error = err as Error;\n await new Promise((r) => setTimeout(r, this.retry.backoff(i)));\n }\n }\n if (!res) {\n throw error ?? new Error(\"Exhausted all retries\");\n }\n if (res.status === 429) {\n throw new QstashRatelimitError({\n limit: res.headers.get(\"Burst-RateLimit-Limit\"),\n remaining: res.headers.get(\"Burst-RateLimit-Remaining\"),\n reset: res.headers.get(\"Burst-RateLimit-Reset\"),\n });\n }\n\n if (res.status < 200 || res.status >= 300) {\n const body = await res.text();\n throw new QstashError(body.length > 0 ? body : `Error: status=${res.status}`);\n }\n if (req.parseResponseAsJson === false) {\n return undefined as unknown as UpstashResponse<TResult>;\n } else {\n return (await res.json()) as UpstashResponse<TResult>;\n }\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Message = {\n /**\n * A unique identifier for this message.\n */\n messageId: string;\n\n /**\n * The topic name if this message was sent to a topic.\n */\n topicName?: string;\n\n /**\n * The url where this message is sent to.\n */\n url: string;\n\n /**\n * The http method used to deliver the message\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * The http headers sent along with the message to your API.\n */\n header?: Record<string, string[]>;\n\n /**\n * The http body sent to your API\n */\n body?: string;\n\n /**\n * Maxmimum number of retries.\n */\n maxRetries?: number;\n\n /**\n * A unix timestamp (milliseconds) after which this message may get delivered.\n */\n notBefore?: number;\n\n /**\n * A unix timestamp (milliseconds) when this messages was created.\n */\n createdAt: number;\n\n /**\n * The callback url if configured.\n */\n callback?: string;\n\n /**\n * The failure callback url if configured.\n */\n failureCallback?: string;\n};\n\nexport class Messages {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Get a message\n */\n public async get(messageId: string): Promise<Message> {\n return await this.http.request<Message>({\n method: \"GET\",\n path: [\"v2\", \"messages\", messageId],\n });\n }\n\n /**\n * Cancel a message\n */\n public async delete(messageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"messages\", messageId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Schedule = {\n scheduleId: string;\n cron: string;\n createdAt: number;\n destination: string;\n method: string;\n header?: Record<string, string[]>;\n body?: string;\n retries: number;\n delay?: number;\n callback?: string;\n failureCallback?: string;\n};\n\nexport type CreateScheduleRequest = {\n /**\n * Either a URL or topic name\n */\n destination: string;\n\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: BodyInit;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * In case your destination server is unavailable or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * Use a failure callback url to handle messages that could not be delivered.\n *\n * The failure callback url must be publicly accessible\n *\n * @default undefined\n */\n failureCallback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * Specify a cron expression to repeatedly send this message to the destination.\n */\n cron: string;\n};\n\nexport class Schedules {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a schedule\n */\n public async create(req: CreateScheduleRequest): Promise<{ scheduleId: string }> {\n const headers = new Headers(req.headers);\n\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n headers.set(\"Upstash-Cron\", req.cron);\n\n if (typeof req.method !== \"undefined\") {\n headers.set(\"Upstash-Method\", req.method);\n }\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n if (typeof req.failureCallback !== \"undefined\") {\n headers.set(\"Upstash-Failure-Callback\", req.failureCallback);\n }\n\n return await this.http.request({\n method: \"POST\",\n headers,\n path: [\"v2\", \"schedules\", req.destination],\n body: req.body,\n });\n }\n\n /**\n * Get a schedule\n */\n public async get(scheduleId: string): Promise<Schedule> {\n return await this.http.request<Schedule>({\n method: \"GET\",\n path: [\"v2\", \"schedules\", scheduleId],\n });\n }\n\n /**\n * List your schedules\n */\n public async list(): Promise<Schedule[]> {\n return await this.http.request<Schedule[]>({\n method: \"GET\",\n path: [\"v2\", \"schedules\"],\n });\n }\n\n /**\n * Delete a schedule\n */\n public async delete(scheduleId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"schedules\", scheduleId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Endpoint = {\n /**\n * The name of the endpoint (optional)\n */\n name?: string;\n\n /**\n * The url of the endpoint\n */\n url: string;\n};\n\nexport type AddEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: Endpoint[];\n};\n\nexport type RemoveEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: (\n | {\n name: string;\n url?: string;\n }\n | {\n name?: string;\n url: string;\n }\n )[];\n};\n\nexport type Topic = {\n /**\n * The name of this topic.\n */\n name: string;\n\n /**\n * A list of all subscribed endpoints\n */\n endpoints: Endpoint[];\n};\n\nexport class Topics {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a new topic with the given name and endpoints\n */\n public async addEndpoints(req: AddEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"POST\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Remove endpoints from a topic.\n */\n public async removeEndpoints(req: RemoveEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Get a list of all topics.\n */\n public async list(): Promise<Topic[]> {\n return await this.http.request<Topic[]>({\n method: \"GET\",\n path: [\"v2\", \"topics\"],\n });\n }\n\n /**\n * Get a single topic\n */\n public async get(name: string): Promise<Topic> {\n return await this.http.request<Topic>({\n method: \"GET\",\n path: [\"v2\", \"topics\", name],\n });\n }\n\n /**\n * Delete a topic\n */\n public async delete(name: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", name],\n parseResponseAsJson: false,\n });\n }\n}\n","import { DLQ } from \"./dlq\";\nimport { HttpClient, Requester, RetryConfig } from \"./http\";\nimport { Messages } from \"./messages\";\nimport { Schedules } from \"./schedules\";\nimport { Topics } from \"./topics\";\nimport { Event } from \"./types\";\ntype ClientConfig = {\n /**\n * Url of the qstash api server.\n *\n * This is only used for testing.\n *\n * @default \"https://qstash.upstash.io\"\n */\n baseUrl?: string;\n\n /**\n * The authorization token from the upstash console.\n */\n token: string;\n\n /**\n * Configure how the client should retry requests.\n */\n retry?: RetryConfig;\n};\n\nexport type PublishRequest<TBody = BodyInit> = {\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: TBody;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * Optionally set the absolute delay of this message.\n * This will override the delay option.\n * The message will not delivered until the specified time.\n *\n * Unix timestamp in seconds.\n *\n * @default undefined\n */\n notBefore?: number;\n\n /**\n * Provide a unique id for deduplication. This id will be used to detect duplicate messages.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default undefined\n */\n deduplicationId?: string;\n\n /**\n * If true, the message content will get hashed and used as deduplication id.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * The content based hash includes the following values:\n * - All headers, except Upstash-Authorization, this includes all headers you are sending.\n * - The entire raw request body The destination from the url path\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default false\n */\n contentBasedDeduplication?: boolean;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * Use a failure callback url to handle messages that could not be delivered.\n *\n * The failure callback url must be publicly accessible\n *\n * @default undefined\n */\n failureCallback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n} & (\n | {\n /**\n * The url where the message should be sent to.\n */\n url: string;\n topic?: never;\n }\n | {\n url?: never;\n /**\n * The url where the message should be sent to.\n */\n topic: string;\n }\n);\n\nexport type PublishJsonRequest = Omit<PublishRequest, \"body\"> & {\n /**\n * The message to send.\n * This can be anything as long as it can be serialized to JSON.\n */\n body: unknown;\n};\n\nexport type EventsRequest = {\n cursor?: number;\n};\n\nexport type GetEventsResponse = {\n cursor?: number;\n events: Event[];\n};\n\nexport class Client {\n public http: Requester;\n\n public constructor(config: ClientConfig) {\n this.http = new HttpClient({\n retry: config.retry,\n baseUrl: config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"https://qstash.upstash.io\",\n authorization: `Bearer ${config.token}`,\n });\n }\n\n /**\n * Access the topic API.\n *\n * Create, read, update or delete topics.\n */\n public get topics(): Topics {\n return new Topics(this.http);\n }\n\n /**\n * Access the dlq API.\n *\n * List or remove messages from the DLQ.\n */\n public get dlq(): DLQ {\n return new DLQ(this.http);\n }\n\n /**\n * Access the message API.\n *\n * Read or cancel messages.\n */\n public get messages(): Messages {\n return new Messages(this.http);\n }\n\n /**\n * Access the schedule API.\n *\n * Create, read or delete schedules.\n */\n public get schedules(): Schedules {\n return new Schedules(this.http);\n }\n public async publish<TRequest extends PublishRequest>(\n req: TRequest,\n ): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n\n headers.set(\"Upstash-Method\", req.method ?? \"POST\");\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.notBefore !== \"undefined\") {\n headers.set(\"Upstash-Not-Before\", req.notBefore.toFixed());\n }\n\n if (typeof req.deduplicationId !== \"undefined\") {\n headers.set(\"Upstash-Deduplication-Id\", req.deduplicationId);\n }\n\n if (typeof req.contentBasedDeduplication !== \"undefined\") {\n headers.set(\"Upstash-Content-Based-Deduplication\", \"true\");\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n if (typeof req.failureCallback !== \"undefined\") {\n headers.set(\"Upstash-Failure-Callback\", req.failureCallback);\n }\n\n const res = await this.http.request<PublishResponse<TRequest>>({\n path: [\"v2\", \"publish\", req.url ?? req.topic],\n body: req.body,\n headers,\n method: \"POST\",\n });\n return res;\n }\n\n /**\n * publishJSON is a utility wrapper around `publish` that automatically serializes the body\n * and sets the `Content-Type` header to `application/json`.\n */\n public async publishJSON<\n TBody = unknown,\n TRequest extends PublishRequest<TBody> = PublishRequest<TBody>,\n >(req: TRequest): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n // @ts-ignore it's just internal\n const res = await this.publish<TRequest>({\n ...req,\n headers,\n body: JSON.stringify(req.body),\n } as PublishRequest);\n return res;\n }\n\n /**\n * Retrieve your logs.\n *\n * The logs endpoint is paginated and returns only 100 logs at a time.\n * If you want to receive more logs, you can use the cursor to paginate.\n *\n * The cursor is a unix timestamp with millisecond precision\n *\n * @example\n * ```ts\n * let cursor = Date.now()\n * const logs: Log[] = []\n * while (cursor > 0) {\n * const res = await qstash.logs({ cursor })\n * logs.push(...res.logs)\n * cursor = res.cursor ?? 0\n * }\n * ```\n */\n public async events(req?: EventsRequest): Promise<GetEventsResponse> {\n const query: Record<string, number> = {};\n if (req?.cursor && req.cursor > 0) {\n query.cursor = req.cursor;\n }\n const res = await this.http.request<GetEventsResponse>({\n path: [\"v2\", \"events\"],\n method: \"GET\",\n query,\n });\n return res;\n }\n}\ntype PublishToUrlResponse = {\n messageId: string;\n url: string;\n deduplicated?: boolean;\n};\n\ntype PublishToTopicResponse = PublishToUrlResponse[];\n\ntype PublishResponse<R> = R extends { url: string } ? PublishToUrlResponse : PublishToTopicResponse;\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,38 @@ import {
|
|
|
6
6
|
__spreadValues
|
|
7
7
|
} from "./chunk-G4FL5XMG.mjs";
|
|
8
8
|
|
|
9
|
+
// src/client/dlq.ts
|
|
10
|
+
var DLQ = class {
|
|
11
|
+
constructor(http) {
|
|
12
|
+
this.http = http;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* List messages in the dlq
|
|
16
|
+
*/
|
|
17
|
+
listMessages(opts) {
|
|
18
|
+
return __async(this, null, function* () {
|
|
19
|
+
return yield this.http.request({
|
|
20
|
+
method: "GET",
|
|
21
|
+
path: ["v2", "dlq"],
|
|
22
|
+
query: { cursor: opts == null ? void 0 : opts.cursor }
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Remove a message from the dlq using it's `dlqId`
|
|
28
|
+
*/
|
|
29
|
+
delete(dlqMessageId) {
|
|
30
|
+
return __async(this, null, function* () {
|
|
31
|
+
return yield this.http.request({
|
|
32
|
+
method: "DELETE",
|
|
33
|
+
path: ["v2", "dlq", dlqMessageId],
|
|
34
|
+
parseResponseAsJson: false
|
|
35
|
+
// there is no response
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
9
41
|
// src/client/error.ts
|
|
10
42
|
var QstashError = class extends Error {
|
|
11
43
|
constructor(message) {
|
|
@@ -90,75 +122,6 @@ var HttpClient = class {
|
|
|
90
122
|
}
|
|
91
123
|
};
|
|
92
124
|
|
|
93
|
-
// src/client/topics.ts
|
|
94
|
-
var Topics = class {
|
|
95
|
-
constructor(http) {
|
|
96
|
-
this.http = http;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a new topic with the given name and endpoints
|
|
100
|
-
*/
|
|
101
|
-
addEndpoints(req) {
|
|
102
|
-
return __async(this, null, function* () {
|
|
103
|
-
yield this.http.request({
|
|
104
|
-
method: "POST",
|
|
105
|
-
path: ["v2", "topics", req.name, "endpoints"],
|
|
106
|
-
headers: { "Content-Type": "application/json" },
|
|
107
|
-
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
108
|
-
parseResponseAsJson: false
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Remove endpoints from a topic.
|
|
114
|
-
*/
|
|
115
|
-
removeEndpoints(req) {
|
|
116
|
-
return __async(this, null, function* () {
|
|
117
|
-
yield this.http.request({
|
|
118
|
-
method: "DELETE",
|
|
119
|
-
path: ["v2", "topics", req.name, "endpoints"],
|
|
120
|
-
headers: { "Content-Type": "application/json" },
|
|
121
|
-
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
122
|
-
parseResponseAsJson: false
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Get a list of all topics.
|
|
128
|
-
*/
|
|
129
|
-
list() {
|
|
130
|
-
return __async(this, null, function* () {
|
|
131
|
-
return yield this.http.request({
|
|
132
|
-
method: "GET",
|
|
133
|
-
path: ["v2", "topics"]
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get a single topic
|
|
139
|
-
*/
|
|
140
|
-
get(name) {
|
|
141
|
-
return __async(this, null, function* () {
|
|
142
|
-
return yield this.http.request({
|
|
143
|
-
method: "GET",
|
|
144
|
-
path: ["v2", "topics", name]
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Delete a topic
|
|
150
|
-
*/
|
|
151
|
-
delete(name) {
|
|
152
|
-
return __async(this, null, function* () {
|
|
153
|
-
return yield this.http.request({
|
|
154
|
-
method: "DELETE",
|
|
155
|
-
path: ["v2", "topics", name],
|
|
156
|
-
parseResponseAsJson: false
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
125
|
// src/client/messages.ts
|
|
163
126
|
var Messages = class {
|
|
164
127
|
constructor(http) {
|
|
@@ -216,6 +179,9 @@ var Schedules = class {
|
|
|
216
179
|
if (typeof req.callback !== "undefined") {
|
|
217
180
|
headers.set("Upstash-Callback", req.callback);
|
|
218
181
|
}
|
|
182
|
+
if (typeof req.failureCallback !== "undefined") {
|
|
183
|
+
headers.set("Upstash-Failure-Callback", req.failureCallback);
|
|
184
|
+
}
|
|
219
185
|
return yield this.http.request({
|
|
220
186
|
method: "POST",
|
|
221
187
|
headers,
|
|
@@ -260,33 +226,70 @@ var Schedules = class {
|
|
|
260
226
|
}
|
|
261
227
|
};
|
|
262
228
|
|
|
263
|
-
// src/client/
|
|
264
|
-
var
|
|
229
|
+
// src/client/topics.ts
|
|
230
|
+
var Topics = class {
|
|
265
231
|
constructor(http) {
|
|
266
232
|
this.http = http;
|
|
267
233
|
}
|
|
268
234
|
/**
|
|
269
|
-
*
|
|
235
|
+
* Create a new topic with the given name and endpoints
|
|
270
236
|
*/
|
|
271
|
-
|
|
237
|
+
addEndpoints(req) {
|
|
238
|
+
return __async(this, null, function* () {
|
|
239
|
+
yield this.http.request({
|
|
240
|
+
method: "POST",
|
|
241
|
+
path: ["v2", "topics", req.name, "endpoints"],
|
|
242
|
+
headers: { "Content-Type": "application/json" },
|
|
243
|
+
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
244
|
+
parseResponseAsJson: false
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Remove endpoints from a topic.
|
|
250
|
+
*/
|
|
251
|
+
removeEndpoints(req) {
|
|
252
|
+
return __async(this, null, function* () {
|
|
253
|
+
yield this.http.request({
|
|
254
|
+
method: "DELETE",
|
|
255
|
+
path: ["v2", "topics", req.name, "endpoints"],
|
|
256
|
+
headers: { "Content-Type": "application/json" },
|
|
257
|
+
body: JSON.stringify({ endpoints: req.endpoints }),
|
|
258
|
+
parseResponseAsJson: false
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get a list of all topics.
|
|
264
|
+
*/
|
|
265
|
+
list() {
|
|
272
266
|
return __async(this, null, function* () {
|
|
273
267
|
return yield this.http.request({
|
|
274
268
|
method: "GET",
|
|
275
|
-
path: ["v2", "
|
|
276
|
-
query: { cursor: opts == null ? void 0 : opts.cursor }
|
|
269
|
+
path: ["v2", "topics"]
|
|
277
270
|
});
|
|
278
271
|
});
|
|
279
272
|
}
|
|
280
273
|
/**
|
|
281
|
-
*
|
|
274
|
+
* Get a single topic
|
|
282
275
|
*/
|
|
283
|
-
|
|
276
|
+
get(name) {
|
|
277
|
+
return __async(this, null, function* () {
|
|
278
|
+
return yield this.http.request({
|
|
279
|
+
method: "GET",
|
|
280
|
+
path: ["v2", "topics", name]
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Delete a topic
|
|
286
|
+
*/
|
|
287
|
+
delete(name) {
|
|
284
288
|
return __async(this, null, function* () {
|
|
285
289
|
return yield this.http.request({
|
|
286
290
|
method: "DELETE",
|
|
287
|
-
path: ["v2", "
|
|
291
|
+
path: ["v2", "topics", name],
|
|
288
292
|
parseResponseAsJson: false
|
|
289
|
-
// there is no response
|
|
290
293
|
});
|
|
291
294
|
});
|
|
292
295
|
}
|
|
@@ -356,6 +359,9 @@ var Client = class {
|
|
|
356
359
|
if (typeof req.callback !== "undefined") {
|
|
357
360
|
headers.set("Upstash-Callback", req.callback);
|
|
358
361
|
}
|
|
362
|
+
if (typeof req.failureCallback !== "undefined") {
|
|
363
|
+
headers.set("Upstash-Failure-Callback", req.failureCallback);
|
|
364
|
+
}
|
|
359
365
|
const res = yield this.http.request({
|
|
360
366
|
path: ["v2", "publish", (_b = req.url) != null ? _b : req.topic],
|
|
361
367
|
body: req.body,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/error.ts","../src/client/http.ts","../src/client/topics.ts","../src/client/messages.ts","../src/client/schedules.ts","../src/client/dlq.ts","../src/client/client.ts"],"sourcesContent":["/**\n * Result of 500 Internal Server Error\n */\nexport class QstashError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"QstashError\";\n }\n}\n\nexport class QstashRatelimitError extends QstashError {\n constructor(args: unknown) {\n super(`You have been ratelimited. ${JSON.stringify(args)} `);\n }\n}\n","import { QstashError, QstashRatelimitError } from \"./error\";\n\nexport type UpstashRequest = {\n /**\n * The path to the resource.\n */\n path: string[];\n\n /**\n * A BodyInit object or null to set request's body.\n */\n body?: BodyInit | null;\n\n /**\n * A Headers object, an object literal, or an array of two-item arrays to set\n * request's headers.\n */\n headers?: HeadersInit;\n\n /**\n * A boolean to set request's keepalive.\n */\n keepalive?: boolean;\n\n /**\n * A string to set request's method.\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\n query?: Record<string, string | number | boolean | undefined>;\n\n /**\n * if enabled, call `res.json()`\n *\n * @default true\n */\n parseResponseAsJson?: boolean;\n};\nexport type UpstashResponse<TResult> = TResult & { error?: string };\n\nexport interface Requester {\n request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;\n}\n\nexport type RetryConfig =\n | false\n | {\n /**\n * The number of retries to attempt before giving up.\n *\n * @default 5\n */\n retries?: number;\n /**\n * A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.\n *\n * @default\n * ```ts\n * Math.exp(retryCount) * 50\n * ```\n */\n backoff?: (retryCount: number) => number;\n };\n\nexport type HttpClientConfig = {\n baseUrl: string;\n authorization: string;\n retry?: RetryConfig;\n};\n\nexport class HttpClient implements Requester {\n public readonly baseUrl: string;\n\n public readonly authorization: string;\n\n public readonly options?: { backend?: string };\n\n public retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n\n this.authorization = config.authorization;\n\n if (typeof config?.retry === \"boolean\" && config?.retry === false) {\n this.retry = {\n attempts: 1,\n backoff: () => 0,\n };\n } else {\n this.retry = {\n attempts: config.retry?.retries ? config.retry.retries + 1 : 5,\n backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50),\n };\n }\n }\n\n public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {\n const headers = new Headers(req.headers);\n headers.set(\"Authorization\", this.authorization);\n\n const requestOptions: RequestInit & { backend?: string } = {\n method: req.method,\n headers,\n body: req.body,\n keepalive: req.keepalive,\n };\n\n const url = new URL([this.baseUrl, ...(req.path ?? [])].join(\"/\"));\n if (req.query) {\n for (const [key, value] of Object.entries(req.query)) {\n if (typeof value !== \"undefined\") {\n url.searchParams.set(key, value.toString());\n }\n }\n }\n\n let res: Response | null = null;\n let error: Error | null = null;\n for (let i = 0; i < this.retry.attempts; i++) {\n try {\n res = await fetch(url.toString(), requestOptions);\n break;\n } catch (err) {\n error = err as Error;\n await new Promise((r) => setTimeout(r, this.retry.backoff(i)));\n }\n }\n if (!res) {\n throw error ?? new Error(\"Exhausted all retries\");\n }\n if (res.status === 429) {\n throw new QstashRatelimitError({\n limit: res.headers.get(\"Burst-RateLimit-Limit\"),\n remaining: res.headers.get(\"Burst-RateLimit-Remaining\"),\n reset: res.headers.get(\"Burst-RateLimit-Reset\"),\n });\n }\n\n if (res.status < 200 || res.status >= 300) {\n const body = await res.text();\n throw new QstashError(body.length > 0 ? body : `Error: status=${res.status}`);\n }\n if (req.parseResponseAsJson === false) {\n return undefined as unknown as UpstashResponse<TResult>;\n } else {\n return (await res.json()) as UpstashResponse<TResult>;\n }\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Endpoint = {\n /**\n * The name of the endpoint (optional)\n */\n name?: string;\n\n /**\n * The url of the endpoint\n */\n url: string;\n};\n\nexport type AddEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: Endpoint[];\n};\n\nexport type RemoveEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: (\n | {\n name: string;\n url?: string;\n }\n | {\n name?: string;\n url: string;\n }\n )[];\n};\n\nexport type Topic = {\n /**\n * The name of this topic.\n */\n name: string;\n\n /**\n * A list of all subscribed endpoints\n */\n endpoints: Endpoint[];\n};\n\nexport class Topics {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a new topic with the given name and endpoints\n */\n public async addEndpoints(req: AddEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"POST\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Remove endpoints from a topic.\n */\n public async removeEndpoints(req: RemoveEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Get a list of all topics.\n */\n public async list(): Promise<Topic[]> {\n return await this.http.request<Topic[]>({\n method: \"GET\",\n path: [\"v2\", \"topics\"],\n });\n }\n\n /**\n * Get a single topic\n */\n public async get(name: string): Promise<Topic> {\n return await this.http.request<Topic>({\n method: \"GET\",\n path: [\"v2\", \"topics\", name],\n });\n }\n\n /**\n * Delete a topic\n */\n public async delete(name: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", name],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Message = {\n /**\n * A unique identifier for this message.\n */\n messageId: string;\n\n /**\n * The topic name if this message was sent to a topic.\n */\n topicName?: string;\n\n /**\n * The url where this message is sent to.\n */\n url: string;\n\n /**\n * The http method used to deliver the message\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * The http headers sent along with the message to your API.\n */\n header?: Record<string, string[]>;\n\n /**\n * The http body sent to your API\n */\n body?: string;\n\n /**\n * Maxmimum number of retries.\n */\n maxRetries?: number;\n\n /**\n * A unix timestamp (milliseconds) after which this message may get delivered.\n */\n notBefore?: number;\n\n /**\n * A unix timestamp (milliseconds) when this messages was crated.\n */\n createdAt: number;\n\n /**\n * The callback url if configured.\n */\n callback?: string;\n};\n\nexport class Messages {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Get a message\n */\n public async get(messageId: string): Promise<Message> {\n return await this.http.request<Message>({\n method: \"GET\",\n path: [\"v2\", \"messages\", messageId],\n });\n }\n\n /**\n * Cancel a message\n */\n public async delete(messageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"messages\", messageId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Schedule = {\n scheduleId: string;\n cron: string;\n createdAt: number;\n destination: string;\n method: string;\n header?: Record<string, string[]>;\n body?: string;\n retries: number;\n delay?: number;\n callback?: string;\n};\n\nexport type CreateScheduleRequest = {\n /**\n * Either a URL or topic name\n */\n destination: string;\n\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: BodyInit;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * Specify a cron expression to repeatedly send this message to the destination.\n */\n cron: string;\n};\n\nexport class Schedules {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a schedule\n */\n public async create(req: CreateScheduleRequest): Promise<{ scheduleId: string }> {\n const headers = new Headers(req.headers);\n\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n headers.set(\"Upstash-Cron\", req.cron);\n\n if (typeof req.method !== \"undefined\") {\n headers.set(\"Upstash-Method\", req.method);\n }\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n return await this.http.request({\n method: \"POST\",\n headers,\n path: [\"v2\", \"schedules\", req.destination],\n body: req.body,\n });\n }\n\n /**\n * Get a schedule\n */\n public async get(scheduleId: string): Promise<Schedule> {\n return await this.http.request<Schedule>({\n method: \"GET\",\n path: [\"v2\", \"schedules\", scheduleId],\n });\n }\n\n /**\n * List your schedules\n */\n public async list(): Promise<Schedule[]> {\n return await this.http.request<Schedule[]>({\n method: \"GET\",\n path: [\"v2\", \"schedules\"],\n });\n }\n\n /**\n * Delete a schedule\n */\n public async delete(scheduleId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"schedules\", scheduleId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\nimport type { Message } from \"./messages\";\n\ntype DlqMessage = Message & {\n dlqId: string;\n};\n\nexport class DLQ {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * List messages in the dlq\n */\n public async listMessages(opts?: { cursor?: string }): Promise<{\n messages: DlqMessage[];\n cursor?: string;\n }> {\n return await this.http.request({\n method: \"GET\",\n path: [\"v2\", \"dlq\"],\n query: { cursor: opts?.cursor },\n });\n }\n\n /**\n * Remove a message from the dlq using it's `dlqId`\n */\n public async delete(dlqMessageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"dlq\", dlqMessageId],\n parseResponseAsJson: false, // there is no response\n });\n }\n}\n","import { HttpClient, Requester, RetryConfig } from \"./http\";\nimport { Topics } from \"./topics\";\nimport { Messages } from \"./messages\";\nimport { Schedules } from \"./schedules\";\nimport { Event } from \"./types\";\nimport { DLQ } from \"./dlq\";\ntype ClientConfig = {\n /**\n * Url of the qstash api server.\n *\n * This is only used for testing.\n *\n * @default \"https://qstash.upstash.io\"\n */\n baseUrl?: string;\n\n /**\n * The authorization token from the upstash console.\n */\n token: string;\n\n /**\n * Configure how the client should retry requests.\n */\n retry?: RetryConfig;\n};\n\nexport type PublishRequest<TBody = BodyInit> = {\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: TBody;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * Optionally set the absolute delay of this message.\n * This will override the delay option.\n * The message will not delivered until the specified time.\n *\n * Unix timestamp in seconds.\n *\n * @default undefined\n */\n notBefore?: number;\n\n /**\n * Provide a unique id for deduplication. This id will be used to detect duplicate messages.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default undefined\n */\n deduplicationId?: string;\n\n /**\n * If true, the message content will get hashed and used as deduplication id.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * The content based hash includes the following values:\n * - All headers, except Upstash-Authorization, this includes all headers you are sending.\n * - The entire raw request body The destination from the url path\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default false\n */\n contentBasedDeduplication?: boolean;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n} & (\n | {\n /**\n * The url where the message should be sent to.\n */\n url: string;\n topic?: never;\n }\n | {\n url?: never;\n /**\n * The url where the message should be sent to.\n */\n topic: string;\n }\n);\n\nexport type PublishJsonRequest = Omit<PublishRequest, \"body\"> & {\n /**\n * The message to send.\n * This can be anything as long as it can be serialized to JSON.\n */\n body: unknown;\n};\n\nexport type EventsRequest = {\n cursor?: number;\n};\n\nexport type GetEventsResponse = {\n cursor?: number;\n events: Event[];\n};\n\nexport class Client {\n public http: Requester;\n\n public constructor(config: ClientConfig) {\n this.http = new HttpClient({\n retry: config.retry,\n baseUrl: config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"https://qstash.upstash.io\",\n authorization: `Bearer ${config.token}`,\n });\n }\n\n /**\n * Access the topic API.\n *\n * Create, read, update or delete topics.\n */\n public get topics(): Topics {\n return new Topics(this.http);\n }\n\n /**\n * Access the dlq API.\n *\n * List or remove messages from the DLQ.\n */\n public get dlq(): DLQ {\n return new DLQ(this.http);\n }\n\n /**\n * Access the message API.\n *\n * Read or cancel messages.\n */\n public get messages(): Messages {\n return new Messages(this.http);\n }\n\n /**\n * Access the schedule API.\n *\n * Create, read or delete schedules.\n */\n public get schedules(): Schedules {\n return new Schedules(this.http);\n }\n public async publish<TRequest extends PublishRequest>(\n req: TRequest,\n ): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n\n headers.set(\"Upstash-Method\", req.method ?? \"POST\");\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.notBefore !== \"undefined\") {\n headers.set(\"Upstash-Not-Before\", req.notBefore.toFixed());\n }\n\n if (typeof req.deduplicationId !== \"undefined\") {\n headers.set(\"Upstash-Deduplication-Id\", req.deduplicationId);\n }\n\n if (typeof req.contentBasedDeduplication !== \"undefined\") {\n headers.set(\"Upstash-Content-Based-Deduplication\", \"true\");\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n const res = await this.http.request<PublishResponse<TRequest>>({\n path: [\"v2\", \"publish\", req.url ?? req.topic],\n body: req.body,\n headers,\n method: \"POST\",\n });\n return res;\n }\n\n /**\n * publishJSON is a utility wrapper around `publish` that automatically serializes the body\n * and sets the `Content-Type` header to `application/json`.\n */\n public async publishJSON<\n TBody = unknown,\n TRequest extends PublishRequest<TBody> = PublishRequest<TBody>,\n >(req: TRequest): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n // @ts-ignore it's just internal\n const res = await this.publish<TRequest>({\n ...req,\n headers,\n body: JSON.stringify(req.body),\n } as PublishRequest);\n return res;\n }\n\n /**\n * Retrieve your logs.\n *\n * The logs endpoint is paginated and returns only 100 logs at a time.\n * If you want to receive more logs, you can use the cursor to paginate.\n *\n * The cursor is a unix timestamp with millisecond precision\n *\n * @example\n * ```ts\n * let cursor = Date.now()\n * const logs: Log[] = []\n * while (cursor > 0) {\n * const res = await qstash.logs({ cursor })\n * logs.push(...res.logs)\n * cursor = res.cursor ?? 0\n * }\n * ```\n */\n public async events(req?: EventsRequest): Promise<GetEventsResponse> {\n const query: Record<string, number> = {};\n if (req?.cursor && req.cursor > 0) {\n query.cursor = req.cursor;\n }\n const res = await this.http.request<GetEventsResponse>({\n path: [\"v2\", \"events\"],\n method: \"GET\",\n query,\n });\n return res;\n }\n}\ntype PublishToUrlResponse = {\n messageId: string;\n url: string;\n deduplicated?: boolean;\n};\n\ntype PublishToTopicResponse = PublishToUrlResponse[];\n\ntype PublishResponse<R> = R extends { url: string } ? PublishToUrlResponse : PublishToTopicResponse;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client/dlq.ts","../src/client/error.ts","../src/client/http.ts","../src/client/messages.ts","../src/client/schedules.ts","../src/client/topics.ts","../src/client/client.ts"],"sourcesContent":["import { Requester } from \"./http\";\nimport type { Message } from \"./messages\";\n\ntype DlqMessage = Message & {\n dlqId: string;\n};\n\nexport class DLQ {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * List messages in the dlq\n */\n public async listMessages(opts?: { cursor?: string }): Promise<{\n messages: DlqMessage[];\n cursor?: string;\n }> {\n return await this.http.request({\n method: \"GET\",\n path: [\"v2\", \"dlq\"],\n query: { cursor: opts?.cursor },\n });\n }\n\n /**\n * Remove a message from the dlq using it's `dlqId`\n */\n public async delete(dlqMessageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"dlq\", dlqMessageId],\n parseResponseAsJson: false, // there is no response\n });\n }\n}\n","/**\n * Result of 500 Internal Server Error\n */\nexport class QstashError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"QstashError\";\n }\n}\n\nexport class QstashRatelimitError extends QstashError {\n constructor(args: unknown) {\n super(`You have been ratelimited. ${JSON.stringify(args)} `);\n }\n}\n","import { QstashError, QstashRatelimitError } from \"./error\";\n\nexport type UpstashRequest = {\n /**\n * The path to the resource.\n */\n path: string[];\n\n /**\n * A BodyInit object or null to set request's body.\n */\n body?: BodyInit | null;\n\n /**\n * A Headers object, an object literal, or an array of two-item arrays to set\n * request's headers.\n */\n headers?: HeadersInit;\n\n /**\n * A boolean to set request's keepalive.\n */\n keepalive?: boolean;\n\n /**\n * A string to set request's method.\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\n query?: Record<string, string | number | boolean | undefined>;\n\n /**\n * if enabled, call `res.json()`\n *\n * @default true\n */\n parseResponseAsJson?: boolean;\n};\nexport type UpstashResponse<TResult> = TResult & { error?: string };\n\nexport interface Requester {\n request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;\n}\n\nexport type RetryConfig =\n | false\n | {\n /**\n * The number of retries to attempt before giving up.\n *\n * @default 5\n */\n retries?: number;\n /**\n * A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.\n *\n * @default\n * ```ts\n * Math.exp(retryCount) * 50\n * ```\n */\n backoff?: (retryCount: number) => number;\n };\n\nexport type HttpClientConfig = {\n baseUrl: string;\n authorization: string;\n retry?: RetryConfig;\n};\n\nexport class HttpClient implements Requester {\n public readonly baseUrl: string;\n\n public readonly authorization: string;\n\n public readonly options?: { backend?: string };\n\n public retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n\n this.authorization = config.authorization;\n\n if (typeof config?.retry === \"boolean\" && config?.retry === false) {\n this.retry = {\n attempts: 1,\n backoff: () => 0,\n };\n } else {\n this.retry = {\n attempts: config.retry?.retries ? config.retry.retries + 1 : 5,\n backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50),\n };\n }\n }\n\n public async request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> {\n const headers = new Headers(req.headers);\n headers.set(\"Authorization\", this.authorization);\n\n const requestOptions: RequestInit & { backend?: string } = {\n method: req.method,\n headers,\n body: req.body,\n keepalive: req.keepalive,\n };\n\n const url = new URL([this.baseUrl, ...(req.path ?? [])].join(\"/\"));\n if (req.query) {\n for (const [key, value] of Object.entries(req.query)) {\n if (typeof value !== \"undefined\") {\n url.searchParams.set(key, value.toString());\n }\n }\n }\n\n let res: Response | null = null;\n let error: Error | null = null;\n for (let i = 0; i < this.retry.attempts; i++) {\n try {\n res = await fetch(url.toString(), requestOptions);\n break;\n } catch (err) {\n error = err as Error;\n await new Promise((r) => setTimeout(r, this.retry.backoff(i)));\n }\n }\n if (!res) {\n throw error ?? new Error(\"Exhausted all retries\");\n }\n if (res.status === 429) {\n throw new QstashRatelimitError({\n limit: res.headers.get(\"Burst-RateLimit-Limit\"),\n remaining: res.headers.get(\"Burst-RateLimit-Remaining\"),\n reset: res.headers.get(\"Burst-RateLimit-Reset\"),\n });\n }\n\n if (res.status < 200 || res.status >= 300) {\n const body = await res.text();\n throw new QstashError(body.length > 0 ? body : `Error: status=${res.status}`);\n }\n if (req.parseResponseAsJson === false) {\n return undefined as unknown as UpstashResponse<TResult>;\n } else {\n return (await res.json()) as UpstashResponse<TResult>;\n }\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Message = {\n /**\n * A unique identifier for this message.\n */\n messageId: string;\n\n /**\n * The topic name if this message was sent to a topic.\n */\n topicName?: string;\n\n /**\n * The url where this message is sent to.\n */\n url: string;\n\n /**\n * The http method used to deliver the message\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * The http headers sent along with the message to your API.\n */\n header?: Record<string, string[]>;\n\n /**\n * The http body sent to your API\n */\n body?: string;\n\n /**\n * Maxmimum number of retries.\n */\n maxRetries?: number;\n\n /**\n * A unix timestamp (milliseconds) after which this message may get delivered.\n */\n notBefore?: number;\n\n /**\n * A unix timestamp (milliseconds) when this messages was created.\n */\n createdAt: number;\n\n /**\n * The callback url if configured.\n */\n callback?: string;\n\n /**\n * The failure callback url if configured.\n */\n failureCallback?: string;\n};\n\nexport class Messages {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Get a message\n */\n public async get(messageId: string): Promise<Message> {\n return await this.http.request<Message>({\n method: \"GET\",\n path: [\"v2\", \"messages\", messageId],\n });\n }\n\n /**\n * Cancel a message\n */\n public async delete(messageId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"messages\", messageId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Schedule = {\n scheduleId: string;\n cron: string;\n createdAt: number;\n destination: string;\n method: string;\n header?: Record<string, string[]>;\n body?: string;\n retries: number;\n delay?: number;\n callback?: string;\n failureCallback?: string;\n};\n\nexport type CreateScheduleRequest = {\n /**\n * Either a URL or topic name\n */\n destination: string;\n\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: BodyInit;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * In case your destination server is unavailable or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * Use a failure callback url to handle messages that could not be delivered.\n *\n * The failure callback url must be publicly accessible\n *\n * @default undefined\n */\n failureCallback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n /**\n * Specify a cron expression to repeatedly send this message to the destination.\n */\n cron: string;\n};\n\nexport class Schedules {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a schedule\n */\n public async create(req: CreateScheduleRequest): Promise<{ scheduleId: string }> {\n const headers = new Headers(req.headers);\n\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n headers.set(\"Upstash-Cron\", req.cron);\n\n if (typeof req.method !== \"undefined\") {\n headers.set(\"Upstash-Method\", req.method);\n }\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n if (typeof req.failureCallback !== \"undefined\") {\n headers.set(\"Upstash-Failure-Callback\", req.failureCallback);\n }\n\n return await this.http.request({\n method: \"POST\",\n headers,\n path: [\"v2\", \"schedules\", req.destination],\n body: req.body,\n });\n }\n\n /**\n * Get a schedule\n */\n public async get(scheduleId: string): Promise<Schedule> {\n return await this.http.request<Schedule>({\n method: \"GET\",\n path: [\"v2\", \"schedules\", scheduleId],\n });\n }\n\n /**\n * List your schedules\n */\n public async list(): Promise<Schedule[]> {\n return await this.http.request<Schedule[]>({\n method: \"GET\",\n path: [\"v2\", \"schedules\"],\n });\n }\n\n /**\n * Delete a schedule\n */\n public async delete(scheduleId: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"schedules\", scheduleId],\n parseResponseAsJson: false,\n });\n }\n}\n","import { Requester } from \"./http\";\n\nexport type Endpoint = {\n /**\n * The name of the endpoint (optional)\n */\n name?: string;\n\n /**\n * The url of the endpoint\n */\n url: string;\n};\n\nexport type AddEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: Endpoint[];\n};\n\nexport type RemoveEndpointsRequest = {\n /**\n * The name of the topic.\n * Must be unique and only contain alphanumeric, hyphen, underscore and periods.\n */\n name: string;\n\n endpoints: (\n | {\n name: string;\n url?: string;\n }\n | {\n name?: string;\n url: string;\n }\n )[];\n};\n\nexport type Topic = {\n /**\n * The name of this topic.\n */\n name: string;\n\n /**\n * A list of all subscribed endpoints\n */\n endpoints: Endpoint[];\n};\n\nexport class Topics {\n private readonly http: Requester;\n\n constructor(http: Requester) {\n this.http = http;\n }\n\n /**\n * Create a new topic with the given name and endpoints\n */\n public async addEndpoints(req: AddEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"POST\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Remove endpoints from a topic.\n */\n public async removeEndpoints(req: RemoveEndpointsRequest): Promise<void> {\n await this.http.request<Topic>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", req.name, \"endpoints\"],\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ endpoints: req.endpoints }),\n parseResponseAsJson: false,\n });\n }\n\n /**\n * Get a list of all topics.\n */\n public async list(): Promise<Topic[]> {\n return await this.http.request<Topic[]>({\n method: \"GET\",\n path: [\"v2\", \"topics\"],\n });\n }\n\n /**\n * Get a single topic\n */\n public async get(name: string): Promise<Topic> {\n return await this.http.request<Topic>({\n method: \"GET\",\n path: [\"v2\", \"topics\", name],\n });\n }\n\n /**\n * Delete a topic\n */\n public async delete(name: string): Promise<void> {\n return await this.http.request<void>({\n method: \"DELETE\",\n path: [\"v2\", \"topics\", name],\n parseResponseAsJson: false,\n });\n }\n}\n","import { DLQ } from \"./dlq\";\nimport { HttpClient, Requester, RetryConfig } from \"./http\";\nimport { Messages } from \"./messages\";\nimport { Schedules } from \"./schedules\";\nimport { Topics } from \"./topics\";\nimport { Event } from \"./types\";\ntype ClientConfig = {\n /**\n * Url of the qstash api server.\n *\n * This is only used for testing.\n *\n * @default \"https://qstash.upstash.io\"\n */\n baseUrl?: string;\n\n /**\n * The authorization token from the upstash console.\n */\n token: string;\n\n /**\n * Configure how the client should retry requests.\n */\n retry?: RetryConfig;\n};\n\nexport type PublishRequest<TBody = BodyInit> = {\n /**\n * The message to send.\n *\n * This can be anything, but please set the `Content-Type` header accordingly.\n *\n * You can leave this empty if you want to send a message with no body.\n */\n body?: TBody;\n\n /**\n * Optionally send along headers with the message.\n * These headers will be sent to your destination.\n *\n * We highly recommend sending a `Content-Type` header along, as this will help your destination\n * server to understand the content of the message.\n */\n headers?: HeadersInit;\n\n /**\n * Optionally delay the delivery of this message.\n *\n * In seconds.\n *\n * @default undefined\n */\n delay?: number;\n\n /**\n * Optionally set the absolute delay of this message.\n * This will override the delay option.\n * The message will not delivered until the specified time.\n *\n * Unix timestamp in seconds.\n *\n * @default undefined\n */\n notBefore?: number;\n\n /**\n * Provide a unique id for deduplication. This id will be used to detect duplicate messages.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default undefined\n */\n deduplicationId?: string;\n\n /**\n * If true, the message content will get hashed and used as deduplication id.\n * If a duplicate message is detected, the request will be accepted but not enqueued.\n *\n * The content based hash includes the following values:\n * - All headers, except Upstash-Authorization, this includes all headers you are sending.\n * - The entire raw request body The destination from the url path\n *\n * We store deduplication ids for 90 days. Afterwards it is possible that the message with the\n * same deduplication id is delivered again.\n *\n * When scheduling a message, the deduplication happens before the schedule is created.\n *\n * @default false\n */\n contentBasedDeduplication?: boolean;\n\n /**\n * In case your destination server is unavaialble or returns a status code outside of the 200-299\n * range, we will retry the request after a certain amount of time.\n *\n * Configure how many times you would like the delivery to be retried\n *\n * @default The maximum retry quota associated with your account.\n */\n retries?: number;\n\n /**\n * Use a callback url to forward the response of your destination server to your callback url.\n *\n * The callback url must be publicly accessible\n *\n * @default undefined\n */\n callback?: string;\n\n /**\n * Use a failure callback url to handle messages that could not be delivered.\n *\n * The failure callback url must be publicly accessible\n *\n * @default undefined\n */\n failureCallback?: string;\n\n /**\n * The method to use when sending a request to your API\n *\n * @default `POST`\n */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n} & (\n | {\n /**\n * The url where the message should be sent to.\n */\n url: string;\n topic?: never;\n }\n | {\n url?: never;\n /**\n * The url where the message should be sent to.\n */\n topic: string;\n }\n);\n\nexport type PublishJsonRequest = Omit<PublishRequest, \"body\"> & {\n /**\n * The message to send.\n * This can be anything as long as it can be serialized to JSON.\n */\n body: unknown;\n};\n\nexport type EventsRequest = {\n cursor?: number;\n};\n\nexport type GetEventsResponse = {\n cursor?: number;\n events: Event[];\n};\n\nexport class Client {\n public http: Requester;\n\n public constructor(config: ClientConfig) {\n this.http = new HttpClient({\n retry: config.retry,\n baseUrl: config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"https://qstash.upstash.io\",\n authorization: `Bearer ${config.token}`,\n });\n }\n\n /**\n * Access the topic API.\n *\n * Create, read, update or delete topics.\n */\n public get topics(): Topics {\n return new Topics(this.http);\n }\n\n /**\n * Access the dlq API.\n *\n * List or remove messages from the DLQ.\n */\n public get dlq(): DLQ {\n return new DLQ(this.http);\n }\n\n /**\n * Access the message API.\n *\n * Read or cancel messages.\n */\n public get messages(): Messages {\n return new Messages(this.http);\n }\n\n /**\n * Access the schedule API.\n *\n * Create, read or delete schedules.\n */\n public get schedules(): Schedules {\n return new Schedules(this.http);\n }\n public async publish<TRequest extends PublishRequest>(\n req: TRequest,\n ): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n\n headers.set(\"Upstash-Method\", req.method ?? \"POST\");\n\n if (typeof req.delay !== \"undefined\") {\n headers.set(\"Upstash-Delay\", `${req.delay.toFixed()}s`);\n }\n\n if (typeof req.notBefore !== \"undefined\") {\n headers.set(\"Upstash-Not-Before\", req.notBefore.toFixed());\n }\n\n if (typeof req.deduplicationId !== \"undefined\") {\n headers.set(\"Upstash-Deduplication-Id\", req.deduplicationId);\n }\n\n if (typeof req.contentBasedDeduplication !== \"undefined\") {\n headers.set(\"Upstash-Content-Based-Deduplication\", \"true\");\n }\n\n if (typeof req.retries !== \"undefined\") {\n headers.set(\"Upstash-Retries\", req.retries.toFixed());\n }\n\n if (typeof req.callback !== \"undefined\") {\n headers.set(\"Upstash-Callback\", req.callback);\n }\n\n if (typeof req.failureCallback !== \"undefined\") {\n headers.set(\"Upstash-Failure-Callback\", req.failureCallback);\n }\n\n const res = await this.http.request<PublishResponse<TRequest>>({\n path: [\"v2\", \"publish\", req.url ?? req.topic],\n body: req.body,\n headers,\n method: \"POST\",\n });\n return res;\n }\n\n /**\n * publishJSON is a utility wrapper around `publish` that automatically serializes the body\n * and sets the `Content-Type` header to `application/json`.\n */\n public async publishJSON<\n TBody = unknown,\n TRequest extends PublishRequest<TBody> = PublishRequest<TBody>,\n >(req: TRequest): Promise<PublishResponse<TRequest>> {\n const headers = new Headers(req.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n // @ts-ignore it's just internal\n const res = await this.publish<TRequest>({\n ...req,\n headers,\n body: JSON.stringify(req.body),\n } as PublishRequest);\n return res;\n }\n\n /**\n * Retrieve your logs.\n *\n * The logs endpoint is paginated and returns only 100 logs at a time.\n * If you want to receive more logs, you can use the cursor to paginate.\n *\n * The cursor is a unix timestamp with millisecond precision\n *\n * @example\n * ```ts\n * let cursor = Date.now()\n * const logs: Log[] = []\n * while (cursor > 0) {\n * const res = await qstash.logs({ cursor })\n * logs.push(...res.logs)\n * cursor = res.cursor ?? 0\n * }\n * ```\n */\n public async events(req?: EventsRequest): Promise<GetEventsResponse> {\n const query: Record<string, number> = {};\n if (req?.cursor && req.cursor > 0) {\n query.cursor = req.cursor;\n }\n const res = await this.http.request<GetEventsResponse>({\n path: [\"v2\", \"events\"],\n method: \"GET\",\n query,\n });\n return res;\n }\n}\ntype PublishToUrlResponse = {\n messageId: string;\n url: string;\n deduplicated?: boolean;\n};\n\ntype PublishToTopicResponse = PublishToUrlResponse[];\n\ntype PublishResponse<R> = R extends { url: string } ? PublishToUrlResponse : PublishToTopicResponse;\n"],"mappings":"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","names":[]}
|