@upstash/qstash 0.0.2 → 0.0.3

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/esm/client.js CHANGED
@@ -18,27 +18,106 @@ export class Client {
18
18
  authorization: config.authorization,
19
19
  });
20
20
  }
21
+ /**
22
+ * Access the topic API.
23
+ *
24
+ * Create, read, update or delete topics.
25
+ */
21
26
  get topics() {
22
27
  return new Topics(this.http);
23
28
  }
29
+ /**
30
+ * Access the endpoint API.
31
+ *
32
+ * Create, read, update or delete endpoints.
33
+ */
24
34
  get endpoints() {
25
35
  return new Endpoints(this.http);
26
36
  }
37
+ /**
38
+ * Access the message API.
39
+ *
40
+ * Read or cancel messages.
41
+ */
27
42
  get messages() {
28
43
  return new Messages(this.http);
29
44
  }
45
+ /**
46
+ * Access the schedule API.
47
+ *
48
+ * Read or delete schedules.
49
+ */
30
50
  get schedules() {
31
51
  return new Schedules(this.http);
32
52
  }
33
53
  async publish(req) {
54
+ const destination = req.url ?? req.topic;
55
+ if (!destination) {
56
+ throw new Error("Either url or topic must be set");
57
+ }
58
+ const headers = new Headers(req.headers);
59
+ if (req.delay) {
60
+ headers.set("Upstash-Delay", req.delay.toFixed());
61
+ }
62
+ if (req.notBefore) {
63
+ headers.set("Upstash-Not-Before", req.notBefore.toFixed());
64
+ }
65
+ if (req.deadline) {
66
+ headers.set("Upstash-Deadline", req.deadline.toFixed());
67
+ }
68
+ if (req.deduplicationID) {
69
+ headers.set("Upstash-Deduplication-ID", req.deduplicationID);
70
+ }
71
+ if (req.contentBasedDeduplication) {
72
+ headers.set("Upstash-Content-Based-Deduplication", "true");
73
+ }
74
+ if (req.retries) {
75
+ headers.set("Upstash-Retries", req.retries.toFixed());
76
+ }
77
+ if (req.cron) {
78
+ headers.set("Upstash-Cron", req.cron);
79
+ }
34
80
  const res = await this.http.request({
35
- path: ["v1", "publish", req.destination],
36
- body: req.cron,
37
- headers: req.headers,
81
+ path: ["v1", "publish", destination],
82
+ body: req.body,
83
+ headers,
38
84
  method: "POST",
39
85
  });
40
86
  return res;
41
87
  }
88
+ /**
89
+ * publishJSON is a utility wrapper around `publish` that automatically serializes the body
90
+ * and sets the `Content-Type` header to `application/json`.
91
+ */
92
+ async publishJSON(req) {
93
+ const headers = new Headers(req.headers);
94
+ headers.set("Content-Type", "application/json");
95
+ const res = await this.publish({
96
+ ...req,
97
+ headers,
98
+ body: JSON.stringify(req.body),
99
+ });
100
+ return res;
101
+ }
102
+ /**
103
+ * Retrieve your logs.
104
+ *
105
+ * The logs endpoint is paginated and returns only 100 logs at a time.
106
+ * If you want to receive more logs, you can use the cursor to paginate.
107
+ *
108
+ * The cursor is a unix timestamp with millisecond precision
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * let cursor = Date.now()
113
+ * const logs: Log[] = []
114
+ * while (cursor > 0) {
115
+ * const res = await qstash.logs({ cursor })
116
+ * logs.push(...res.logs)
117
+ * cursor = res.cursor ?? 0
118
+ * }
119
+ * ```
120
+ */
42
121
  async logs(req) {
43
122
  const query = {};
44
123
  if (req?.cursor && req.cursor > 0) {
package/esm/http.js CHANGED
@@ -42,10 +42,8 @@ export class HttpClient {
42
42
  }
43
43
  }
44
44
  async request(req) {
45
- const headers = new Headers({
46
- ...req.headers,
47
- "Upstash-Authorization": `Bearer ${this.authorization}`,
48
- });
45
+ const headers = new Headers(req.headers);
46
+ headers.set("Upstash-Authorization", `Bearer ${this.authorization}`);
49
47
  const requestOptions = {
50
48
  method: req.method,
51
49
  headers,
@@ -75,10 +73,9 @@ export class HttpClient {
75
73
  if (!res) {
76
74
  throw error ?? new Error("Exhausted all retries");
77
75
  }
78
- const body = (await res.json());
79
76
  if (res.status < 200 || res.status >= 300) {
80
- throw new QstashError(body.error ?? res.statusText);
77
+ throw new QstashError(await res.text() ?? res.statusText);
81
78
  }
82
- return body;
79
+ return (await res.json());
83
80
  }
84
81
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "./script/platforms/nodejs.js",
4
4
  "types": "./types/platforms/nodejs.d.ts",
5
5
  "name": "@upstash/qstash",
6
- "version": "v0.0.2",
6
+ "version": "v0.0.3",
7
7
  "description": "Official Deno/Typescript client for qStash",
8
8
  "repository": {
9
9
  "type": "git",
package/script/client.js CHANGED
@@ -21,27 +21,106 @@ class Client {
21
21
  authorization: config.authorization,
22
22
  });
23
23
  }
24
+ /**
25
+ * Access the topic API.
26
+ *
27
+ * Create, read, update or delete topics.
28
+ */
24
29
  get topics() {
25
30
  return new topics_js_1.Topics(this.http);
26
31
  }
32
+ /**
33
+ * Access the endpoint API.
34
+ *
35
+ * Create, read, update or delete endpoints.
36
+ */
27
37
  get endpoints() {
28
38
  return new endpoints_js_1.Endpoints(this.http);
29
39
  }
40
+ /**
41
+ * Access the message API.
42
+ *
43
+ * Read or cancel messages.
44
+ */
30
45
  get messages() {
31
46
  return new messages_js_1.Messages(this.http);
32
47
  }
48
+ /**
49
+ * Access the schedule API.
50
+ *
51
+ * Read or delete schedules.
52
+ */
33
53
  get schedules() {
34
54
  return new schedules_js_1.Schedules(this.http);
35
55
  }
36
56
  async publish(req) {
57
+ const destination = req.url ?? req.topic;
58
+ if (!destination) {
59
+ throw new Error("Either url or topic must be set");
60
+ }
61
+ const headers = new Headers(req.headers);
62
+ if (req.delay) {
63
+ headers.set("Upstash-Delay", req.delay.toFixed());
64
+ }
65
+ if (req.notBefore) {
66
+ headers.set("Upstash-Not-Before", req.notBefore.toFixed());
67
+ }
68
+ if (req.deadline) {
69
+ headers.set("Upstash-Deadline", req.deadline.toFixed());
70
+ }
71
+ if (req.deduplicationID) {
72
+ headers.set("Upstash-Deduplication-ID", req.deduplicationID);
73
+ }
74
+ if (req.contentBasedDeduplication) {
75
+ headers.set("Upstash-Content-Based-Deduplication", "true");
76
+ }
77
+ if (req.retries) {
78
+ headers.set("Upstash-Retries", req.retries.toFixed());
79
+ }
80
+ if (req.cron) {
81
+ headers.set("Upstash-Cron", req.cron);
82
+ }
37
83
  const res = await this.http.request({
38
- path: ["v1", "publish", req.destination],
39
- body: req.cron,
40
- headers: req.headers,
84
+ path: ["v1", "publish", destination],
85
+ body: req.body,
86
+ headers,
41
87
  method: "POST",
42
88
  });
43
89
  return res;
44
90
  }
91
+ /**
92
+ * publishJSON is a utility wrapper around `publish` that automatically serializes the body
93
+ * and sets the `Content-Type` header to `application/json`.
94
+ */
95
+ async publishJSON(req) {
96
+ const headers = new Headers(req.headers);
97
+ headers.set("Content-Type", "application/json");
98
+ const res = await this.publish({
99
+ ...req,
100
+ headers,
101
+ body: JSON.stringify(req.body),
102
+ });
103
+ return res;
104
+ }
105
+ /**
106
+ * Retrieve your logs.
107
+ *
108
+ * The logs endpoint is paginated and returns only 100 logs at a time.
109
+ * If you want to receive more logs, you can use the cursor to paginate.
110
+ *
111
+ * The cursor is a unix timestamp with millisecond precision
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * let cursor = Date.now()
116
+ * const logs: Log[] = []
117
+ * while (cursor > 0) {
118
+ * const res = await qstash.logs({ cursor })
119
+ * logs.push(...res.logs)
120
+ * cursor = res.cursor ?? 0
121
+ * }
122
+ * ```
123
+ */
45
124
  async logs(req) {
46
125
  const query = {};
47
126
  if (req?.cursor && req.cursor > 0) {
package/script/http.js CHANGED
@@ -45,10 +45,8 @@ class HttpClient {
45
45
  }
46
46
  }
47
47
  async request(req) {
48
- const headers = new Headers({
49
- ...req.headers,
50
- "Upstash-Authorization": `Bearer ${this.authorization}`,
51
- });
48
+ const headers = new Headers(req.headers);
49
+ headers.set("Upstash-Authorization", `Bearer ${this.authorization}`);
52
50
  const requestOptions = {
53
51
  method: req.method,
54
52
  headers,
@@ -78,11 +76,10 @@ class HttpClient {
78
76
  if (!res) {
79
77
  throw error ?? new Error("Exhausted all retries");
80
78
  }
81
- const body = (await res.json());
82
79
  if (res.status < 200 || res.status >= 300) {
83
- throw new error_js_1.QstashError(body.error ?? res.statusText);
80
+ throw new error_js_1.QstashError(await res.text() ?? res.statusText);
84
81
  }
85
- return body;
82
+ return (await res.json());
86
83
  }
87
84
  }
88
85
  exports.HttpClient = HttpClient;
package/types/client.d.ts CHANGED
@@ -16,14 +16,21 @@ export declare type ClientConfig = {
16
16
  */
17
17
  authorization: string;
18
18
  };
19
- declare type PublishRequest = {
19
+ declare type Destination = {
20
20
  /**
21
21
  * The url of a publicly accessible server where you want to send this message to.
22
22
  * The url must have a valid scheme (http or https).
23
- *
24
- * Alternatively, you can specify a topic name or id instead of a url to publish to a topic.
25
23
  */
26
- destination: string;
24
+ url: string;
25
+ topic?: never;
26
+ } | {
27
+ url?: never;
28
+ /**
29
+ * Either the name or id of a topic to send this message to.
30
+ */
31
+ topic: string;
32
+ };
33
+ export declare type PublishRequest = Destination & {
27
34
  /**
28
35
  * The message to send.
29
36
  *
@@ -32,12 +39,6 @@ declare type PublishRequest = {
32
39
  * You can leave this empty if you want to send a message with no body.
33
40
  */
34
41
  body?: BodyInit;
35
- /**
36
- * Optionally specify a cron expression to repeatedly send this message to the destination.
37
- *
38
- * @default undefined
39
- */
40
- cron?: string;
41
42
  /**
42
43
  * Optionally send along headers with the message.
43
44
  * These headers will be sent to your destination.
@@ -109,6 +110,22 @@ declare type PublishRequest = {
109
110
  * @default The maximum retry quota associated with your account.
110
111
  */
111
112
  retries?: number;
113
+ } & ({
114
+ /**
115
+ * Optionally specify a cron expression to repeatedly send this message to the destination.
116
+ *
117
+ * @default undefined
118
+ */
119
+ cron: string;
120
+ } | {
121
+ cron?: never;
122
+ });
123
+ export declare type PublishJsonRequest = Omit<PublishRequest, "body"> & {
124
+ /**
125
+ * The message to send.
126
+ * This can be anything as long as it can be serialized to JSON.
127
+ */
128
+ body: unknown;
112
129
  };
113
130
  export declare type LogsRequest = {
114
131
  cursor?: number;
@@ -120,11 +137,55 @@ export declare type GetLogsRespone = {
120
137
  export declare class Client {
121
138
  http: Requester;
122
139
  constructor(config: ClientConfig);
140
+ /**
141
+ * Access the topic API.
142
+ *
143
+ * Create, read, update or delete topics.
144
+ */
123
145
  get topics(): Topics;
146
+ /**
147
+ * Access the endpoint API.
148
+ *
149
+ * Create, read, update or delete endpoints.
150
+ */
124
151
  get endpoints(): Endpoints;
152
+ /**
153
+ * Access the message API.
154
+ *
155
+ * Read or cancel messages.
156
+ */
125
157
  get messages(): Messages;
158
+ /**
159
+ * Access the schedule API.
160
+ *
161
+ * Read or delete schedules.
162
+ */
126
163
  get schedules(): Schedules;
127
- publish<R extends PublishRequest = PublishRequest>(req: R): Promise<PublishResponse<R>>;
164
+ publish<R extends PublishRequest>(req: R): Promise<PublishResponse<R>>;
165
+ /**
166
+ * publishJSON is a utility wrapper around `publish` that automatically serializes the body
167
+ * and sets the `Content-Type` header to `application/json`.
168
+ */
169
+ publishJSON<R extends PublishJsonRequest = PublishJsonRequest>(req: R): Promise<PublishResponse<R>>;
170
+ /**
171
+ * Retrieve your logs.
172
+ *
173
+ * The logs endpoint is paginated and returns only 100 logs at a time.
174
+ * If you want to receive more logs, you can use the cursor to paginate.
175
+ *
176
+ * The cursor is a unix timestamp with millisecond precision
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * let cursor = Date.now()
181
+ * const logs: Log[] = []
182
+ * while (cursor > 0) {
183
+ * const res = await qstash.logs({ cursor })
184
+ * logs.push(...res.logs)
185
+ * cursor = res.cursor ?? 0
186
+ * }
187
+ * ```
188
+ */
128
189
  logs(req?: LogsRequest): Promise<GetLogsRespone>;
129
190
  }
130
191
  declare type PublishResponse<PublishRequest> = PublishRequest extends {