two-stroke 1.0.16 → 1.0.18

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/package.json CHANGED
@@ -10,24 +10,24 @@
10
10
  "dependencies": {
11
11
  "@anatine/zod-openapi": "^2.2.5",
12
12
  "@asteasolutions/zod-to-openapi": "^7.0.0",
13
- "@cloudflare/workers-types": "^4.20240405.0",
13
+ "@cloudflare/workers-types": "^4.20240423.0",
14
14
  "@sentry/cli": "^2.31.0",
15
- "@typescript-eslint/eslint-plugin": "^7.7.0",
16
- "@typescript-eslint/parser": "^7.7.0",
17
- "@vitest/coverage-v8": "^1.5.0",
15
+ "@typescript-eslint/eslint-plugin": "^7.8.0",
16
+ "@typescript-eslint/parser": "^7.8.0",
17
+ "@vitest/coverage-v8": "^1.5.3",
18
18
  "eslint-config-prettier": "^9.1.0",
19
- "eslint-config-two-stroke": "^1.0.1",
19
+ "eslint-config-two-stroke": "^1.0.2",
20
20
  "eslint-config-typescript": "^3.0.0",
21
21
  "jose": "^5.2.4",
22
22
  "jwk-subtle": "^1.0.7",
23
- "miniflare": "^3.20240405.1",
24
- "openapi-fetch": "^0.9.3",
23
+ "miniflare": "^3.20240419.0",
24
+ "openapi-fetch": "^0.9.5",
25
25
  "openapi-typescript": "^6.7.5",
26
26
  "openapi3-ts": "^4.3.1",
27
27
  "pbkdf-subtle": "^1.0.0",
28
28
  "toml": "^3.0.0",
29
- "toucan-js": "^3.3.1",
30
- "zod": "^3.22.4"
29
+ "toucan-js": "^3.4.0",
30
+ "zod": "^3.23.5"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@sentry/cli": ">=2",
@@ -51,13 +51,13 @@
51
51
  "name": "two-stroke",
52
52
  "packageManager": "yarn@4.1.0",
53
53
  "type": "module",
54
- "version": "1.0.16",
54
+ "version": "1.0.18",
55
55
  "devDependencies": {
56
- "@types/eslint": "^8.56.9",
56
+ "@types/eslint": "^8.56.10",
57
57
  "@types/node": "^20.12.7",
58
58
  "eslint": "^8.57.0",
59
59
  "prettier": "^3.2.5",
60
60
  "typescript": "^5.4.5",
61
- "vitest": "^1.5.0"
61
+ "vitest": "^1.5.3"
62
62
  }
63
63
  }
package/src/cmd.mjs CHANGED
@@ -1,13 +1,16 @@
1
1
  import { spawnSync } from "child_process";
2
2
 
3
- export function cmd(cmd, args = []) {
3
+ export function cmd(program, args = []) {
4
4
  const { error, status } = spawnSync(
5
- cmd.split(" ")[0],
6
- [...cmd.split(" ").slice(1), ...args],
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
6
+ program.split(" ")[0],
7
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
8
+ [...program.split(" ").slice(1), ...args],
7
9
  {
8
10
  stdio: "inherit",
9
11
  },
10
12
  );
13
+ // eslint-disable-next-line no-process-exit
11
14
  if (status) process.exit(status);
12
15
  if (error) throw error;
13
16
  }
package/src/index.ts CHANGED
@@ -3,8 +3,9 @@ import { ZodObject, ZodSchema, z } from "zod";
3
3
  import { verify as pbkdfVerify } from "pbkdf-subtle";
4
4
  import { verify as jwkVerify } from "jwk-subtle";
5
5
  import { Env, Handler, Route } from "./types";
6
- import { openAPI } from "./openAPI";
6
+ import { openAPI } from "./open-api";
7
7
 
8
+ // eslint-disable-next-line @typescript-eslint/require-await
8
9
  const noAuth = async () => null;
9
10
 
10
11
  const escapeRegex = (str: string) =>
@@ -54,7 +55,7 @@ export function twoStroke<T extends Env>(title: string, release: string) {
54
55
  release,
55
56
  });
56
57
  try {
57
- if (req.method == "OPTIONS") {
58
+ if (req.method === "OPTIONS") {
58
59
  return new Response("", {
59
60
  status: 204,
60
61
  headers: {
@@ -72,6 +73,7 @@ export function twoStroke<T extends Env>(title: string, release: string) {
72
73
  const params = pathname.match(route.matcher)?.groups ?? {};
73
74
  let claims;
74
75
  try {
76
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
75
77
  claims = await route.auth({ req, env });
76
78
  } catch (err) {
77
79
  console.warn(err);
@@ -95,7 +97,9 @@ export function twoStroke<T extends Env>(title: string, release: string) {
95
97
  response = await route.handler({
96
98
  req,
97
99
  env,
100
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
98
101
  body: body.data,
102
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
99
103
  claims,
100
104
  params,
101
105
  searchParams: new URL(req.url).searchParams,
@@ -124,6 +128,7 @@ export function twoStroke<T extends Env>(title: string, release: string) {
124
128
  response = await route.handler({
125
129
  req,
126
130
  env,
131
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
127
132
  claims,
128
133
  body: undefined,
129
134
  params,
@@ -131,12 +136,13 @@ export function twoStroke<T extends Env>(title: string, release: string) {
131
136
  sentry,
132
137
  });
133
138
  }
134
- if (response.status === undefined || response.status == 200) {
139
+ if (response.status === undefined || response.status === 200) {
135
140
  const output = route.output.safeParse(response.body);
136
141
  if (!output.success) {
137
142
  console.error({
138
143
  message: "Response body schema invalid",
139
144
  error: output.error,
145
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
140
146
  body: response.body,
141
147
  });
142
148
  }
@@ -147,7 +153,8 @@ export function twoStroke<T extends Env>(title: string, release: string) {
147
153
  response.headers["Access-Control-Allow-Origin"] =
148
154
  response.headers["Access-Control-Allow-Origin"] ?? "*";
149
155
  return new Response(
150
- response.headers["Content-Type"] == "application/json"
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
157
+ response.headers["Content-Type"] === "application/json"
151
158
  ? JSON.stringify(response.body)
152
159
  : response.body,
153
160
  response,
@@ -160,6 +167,7 @@ export function twoStroke<T extends Env>(title: string, release: string) {
160
167
  });
161
168
  } catch (err) {
162
169
  console.warn(err);
170
+ // eslint-disable-next-line deprecation/deprecation
163
171
  sentry.captureException(err);
164
172
  return new Response("", {
165
173
  status: 500,
@@ -255,7 +263,7 @@ export function twoStroke<T extends Env>(title: string, release: string) {
255
263
  const [scheme, token] = (req.headers.get("Authorization") ?? " ").split(
256
264
  " ",
257
265
  );
258
- if (scheme == "Bearer") {
266
+ if (scheme === "Bearer") {
259
267
  const claims = await jwkVerify<J>(
260
268
  token ?? "",
261
269
  env[k] as string,
@@ -380,3 +388,30 @@ export function twoStroke<T extends Env>(title: string, release: string) {
380
388
  },
381
389
  };
382
390
  }
391
+
392
+ type AddToQueueConfig = QueueSendOptions & {
393
+ retries?: number;
394
+ backoffFactor?: number;
395
+ };
396
+
397
+ export async function addToQueue<T>(
398
+ queue: Queue<T>,
399
+ message: T,
400
+ config: AddToQueueConfig = {},
401
+ ) {
402
+ const { retries, backoffFactor, ...options } = config;
403
+
404
+ for (let i = 0; i < (retries ?? 5); i++) {
405
+ try {
406
+ await queue.send(message, options);
407
+ return;
408
+ } catch (err) {
409
+ const backoff = (backoffFactor ?? 2) ** i;
410
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
411
+ console.log(`Error adding to queue: ${err}`);
412
+ console.log(`Retrying in ${backoff} seconds`);
413
+ await new Promise((resolve) => setTimeout(resolve, backoff * 1000));
414
+ }
415
+ }
416
+ throw new Error("Failed to add to queue");
417
+ }
@@ -38,6 +38,7 @@ export const openAPI =
38
38
  noAuth: () => A,
39
39
  routes: Route<T, A>[],
40
40
  ) =>
41
+ // eslint-disable-next-line @typescript-eslint/require-await
41
42
  async () => {
42
43
  const openAPIRegistry = new OpenAPIRegistry();
43
44
  openAPIRegistry.registerComponent("securitySchemes", "auth", {
package/src/test.ts CHANGED
@@ -14,6 +14,7 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
14
14
  const fetchMock = createFetchMock();
15
15
  fetchMock.disableNetConnect();
16
16
 
17
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
17
18
  const config = toml.parse(fs.readFileSync("wrangler.toml", "utf8"));
18
19
 
19
20
  const miniflare = new Miniflare({
@@ -24,10 +25,12 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
24
25
  "djAxlhzT1IU9QIP3UKdipECQPAGGoPQK86/GnTBcbHLtPC3ni6JkTQ/iIeF0KG0y1CZ+J+9W",
25
26
  ...bindings,
26
27
  },
28
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
27
29
  queueConsumers: (config.queues?.consumers ?? []).map(
28
30
  ({ queue }: { queue: string }) => queue,
29
31
  ),
30
32
  queueProducers: Object.fromEntries(
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
31
34
  (config.queues?.producers ?? []).map(
32
35
  ({ binding, queue }: { queue: string; binding: string }) => [
33
36
  binding,
@@ -35,16 +38,20 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
35
38
  ],
36
39
  ),
37
40
  ),
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
38
42
  r2Buckets: (config.r2_buckets ?? []).map(
39
43
  ({ binding }: { binding: string }) => binding,
40
44
  ),
45
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
41
46
  kvNamespaces: (config.kv_namespaces ?? []).map(
42
47
  ({ binding }: { binding: string }) => binding,
43
48
  ),
49
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
44
50
  d1Databases: (config.d1_databases ?? []).map(
45
51
  ({ binding }: { binding: string }) => binding,
46
52
  ),
47
53
  serviceBindings: Object.fromEntries(
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
48
55
  (config.services ?? []).map(
49
56
  ({ binding, service }: { binding: string; service: string }) => [
50
57
  binding,
@@ -60,6 +67,7 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
60
67
  // Hack until miniflare supports auto running D1 migrations.
61
68
  // Note: Each migration file can contain only a single statement.
62
69
  await Promise.all(
70
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
63
71
  (config.d1_databases ?? []).map(
64
72
  async ({ binding }: { binding: string }) => {
65
73
  const d1 = await miniflare.getD1Database(binding);
@@ -111,6 +119,7 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
111
119
  const orig = console.log;
112
120
  console.log = function (message) {
113
121
  orig(message);
122
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
114
123
  log.push(message);
115
124
  };
116
125
  await trigger();
@@ -128,6 +137,7 @@ export const setupTests = async <Paths extends {}>(bindings: Env) => {
128
137
  .reply(
129
138
  200,
130
139
  {
140
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
131
141
  jwks_uri: `${bindings[issuer]}/.well-known/jwks`,
132
142
  },
133
143
  {
@@ -185,7 +195,8 @@ export function recordRequest(
185
195
  ) {
186
196
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
197
  return ({ body }: any) => {
188
- consumers.json(body).then(cb);
198
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
199
+ void consumers.json(body).then(cb);
189
200
  return { statusCode, data, responseOptions };
190
201
  };
191
202
  }
@@ -201,10 +212,12 @@ export function recordFormRequest(
201
212
  ) {
202
213
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
203
214
  return ({ body }: any) => {
204
- consumers
215
+ void consumers
216
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
205
217
  .text(body)
206
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-shadow
207
219
  .then((data: any) =>
220
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
208
221
  cb(Object.fromEntries(new URLSearchParams(data).entries())),
209
222
  );
210
223
  return { statusCode, data, responseOptions };
@@ -222,9 +235,10 @@ export function recordFirehoseRequest(
222
235
  ) {
223
236
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
237
  return ({ body }: any) => {
225
- consumers
238
+ void consumers
239
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
226
240
  .json(body)
227
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-shadow, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
228
242
  .then((data: any) => cb(JSON.parse(atob(data["Record"]["Data"]))));
229
243
  return { statusCode, data, responseOptions };
230
244
  };