two-stroke 6.0.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +12 -12
  2. package/src/index.ts +26 -24
  3. package/src/types.ts +1 -0
package/package.json CHANGED
@@ -10,25 +10,25 @@
10
10
  "type-check": "./bin/type-check.mjs"
11
11
  },
12
12
  "dependencies": {
13
- "@cloudflare/vitest-pool-workers": "^0.8.70",
14
- "@cloudflare/workers-types": "^4.20250906.0",
15
- "@sentry/cli": "^2.53.0",
16
- "@types/node": "^24.3.1",
17
- "@typescript-eslint/eslint-plugin": "^8.43.0",
18
- "@typescript-eslint/parser": "^8.43.0",
13
+ "@cloudflare/vitest-pool-workers": "^0.9.8",
14
+ "@cloudflare/workers-types": "^4.20250927.0",
15
+ "@sentry/cli": "^2.56.0",
16
+ "@types/node": "^24.6.0",
17
+ "@typescript-eslint/eslint-plugin": "^8.45.0",
18
+ "@typescript-eslint/parser": "^8.45.0",
19
19
  "@vitest/coverage-istanbul": "^3.2.4",
20
20
  "eslint-config-prettier": "^10.1.8",
21
- "eslint-config-two-stroke": "^1.2.8",
21
+ "eslint-config-two-stroke": "^1.2.11",
22
22
  "eslint-config-typescript": "^3.0.0",
23
23
  "jose": "^6.1.0",
24
24
  "jwk-subtle": "^1.0.7",
25
- "mime": "^4.0.7",
26
- "miniflare": "^4.20250902.0",
25
+ "mime": "^4.1.0",
26
+ "miniflare": "^4.20250927.0",
27
27
  "openapi-fetch": "^0.14.0",
28
28
  "openapi-typescript": "^7.9.1",
29
29
  "pbkdf-subtle": "^1.0.0",
30
30
  "toucan-js": "^4.1.1",
31
- "zod": "^4.1.5"
31
+ "zod": "^4.1.11"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@sentry/cli": ">=2",
@@ -52,10 +52,10 @@
52
52
  "name": "two-stroke",
53
53
  "packageManager": "yarn@4.6.0",
54
54
  "type": "module",
55
- "version": "6.0.1",
55
+ "version": "6.1.0",
56
56
  "devDependencies": {
57
57
  "@types/eslint": "^9.6.1",
58
- "eslint": "^9.35.0",
58
+ "eslint": "^9.36.0",
59
59
  "prettier": "^3.6.2",
60
60
  "typescript": "^5.9.2",
61
61
  "vitest": "^3.2.4"
package/src/index.ts CHANGED
@@ -14,7 +14,7 @@ const escapeRegex = (str: string) =>
14
14
  export function twoStroke<T extends Env>(
15
15
  title: string,
16
16
  release: string,
17
- origin?: (o: string | null) => string,
17
+ origin?: (o: string | null) => string
18
18
  ) {
19
19
  let _queue: (c: {
20
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -47,7 +47,7 @@ export function twoStroke<T extends Env>(
47
47
  readonly SENTRY_DSN: string;
48
48
  readonly SENTRY_ENVIRONMENT: string;
49
49
  },
50
- context: ExecutionContext,
50
+ context: ExecutionContext
51
51
  ): Promise<Response> {
52
52
  const defaultHeaders = {
53
53
  "Access-Control-Allow-Origin": origin
@@ -85,8 +85,8 @@ export function twoStroke<T extends Env>(
85
85
  if (req.method === route.method && route.matcher.test(pathname)) {
86
86
  const params = Object.fromEntries(
87
87
  Object.entries(pathname.match(route.matcher)?.groups ?? {}).map(
88
- ([k, v]) => [k, decodeURIComponent(v)],
89
- ),
88
+ ([k, v]) => [k, decodeURIComponent(v)]
89
+ )
90
90
  );
91
91
  let claims;
92
92
  try {
@@ -125,7 +125,7 @@ export function twoStroke<T extends Env>(
125
125
  {
126
126
  status: 400,
127
127
  headers: defaultHeaders,
128
- },
128
+ }
129
129
  );
130
130
  }
131
131
  const body = route.input
@@ -145,6 +145,7 @@ export function twoStroke<T extends Env>(
145
145
  params,
146
146
  searchParams: new URL(req.url).searchParams,
147
147
  sentry,
148
+ waitUntil: (p: Promise<void>) => context.waitUntil(p),
148
149
  });
149
150
  else {
150
151
  console.error({
@@ -161,7 +162,7 @@ export function twoStroke<T extends Env>(
161
162
  {
162
163
  status: 400,
163
164
  headers: defaultHeaders,
164
- },
165
+ }
165
166
  );
166
167
  }
167
168
  } else {
@@ -174,6 +175,7 @@ export function twoStroke<T extends Env>(
174
175
  params,
175
176
  searchParams: new URL(req.url).searchParams,
176
177
  sentry,
178
+ waitUntil: (p: Promise<void>) => context.waitUntil(p),
177
179
  });
178
180
  }
179
181
  if (response.status === undefined || response.status === 200) {
@@ -211,7 +213,7 @@ export function twoStroke<T extends Env>(
211
213
  "application/json"
212
214
  ? JSON.stringify(response.body)
213
215
  : response.body,
214
- responseWithHeaders,
216
+ responseWithHeaders
215
217
  );
216
218
  }
217
219
  }
@@ -235,7 +237,7 @@ export function twoStroke<T extends Env>(
235
237
  readonly SENTRY_DSN: string;
236
238
  readonly SENTRY_ENVIRONMENT: string;
237
239
  },
238
- context: ExecutionContext,
240
+ context: ExecutionContext
239
241
  ) {
240
242
  const sentry = new Toucan({
241
243
  dsn: env.SENTRY_DSN,
@@ -256,7 +258,7 @@ export function twoStroke<T extends Env>(
256
258
  readonly SENTRY_DSN: string;
257
259
  readonly SENTRY_ENVIRONMENT: string;
258
260
  },
259
- context: ExecutionContext,
261
+ context: ExecutionContext
260
262
  ) {
261
263
  const sentry = new Toucan({
262
264
  dsn: env.SENTRY_DSN,
@@ -281,7 +283,7 @@ export function twoStroke<T extends Env>(
281
283
  readonly SENTRY_DSN: string;
282
284
  readonly SENTRY_ENVIRONMENT: string;
283
285
  },
284
- context: ExecutionContext,
286
+ context: ExecutionContext
285
287
  ) {
286
288
  const sentry = new Toucan({
287
289
  dsn: env.SENTRY_DSN,
@@ -301,13 +303,13 @@ export function twoStroke<T extends Env>(
301
303
  env: T;
302
304
  message: ForwardableEmailMessage;
303
305
  sentry: Toucan;
304
- }) => Promise<void>,
306
+ }) => Promise<void>
305
307
  ) {
306
308
  _email = handler;
307
309
  },
308
310
  schedule(
309
311
  cron: string,
310
- handler: (c: { env: T; sentry: Toucan }) => Promise<void>,
312
+ handler: (c: { env: T; sentry: Toucan }) => Promise<void>
311
313
  ) {
312
314
  crons[cron] = handler;
313
315
  },
@@ -329,13 +331,13 @@ export function twoStroke<T extends Env>(
329
331
  <J>(k: keyof T, ak: keyof T) =>
330
332
  async ({ req, env }: { req: Request; env: T }) => {
331
333
  const [scheme, token] = (req.headers.get("Authorization") ?? " ").split(
332
- " ",
334
+ " "
333
335
  );
334
336
  if (scheme === "Bearer") {
335
337
  const claims = await jwkVerify<J>(
336
338
  token ?? "",
337
339
  env[k] as string,
338
- env[ak] as string,
340
+ env[ak] as string
339
341
  );
340
342
  if (!claims) {
341
343
  throw Error("Invalid");
@@ -351,7 +353,7 @@ export function twoStroke<T extends Env>(
351
353
  batch: MessageBatch<z.input<I>>;
352
354
  sentry: Toucan;
353
355
  parsedBatch: ZodSafeParseResult<z.output<I>>[];
354
- }) => Promise<void>,
356
+ }) => Promise<void>
355
357
  ) {
356
358
  _queue = async ({
357
359
  batch,
@@ -378,14 +380,14 @@ export function twoStroke<T extends Env>(
378
380
  path: P,
379
381
  input: I,
380
382
  output: O,
381
- handler: Handler<T, I, O, A, P>,
383
+ handler: Handler<T, I, O, A, P>
382
384
  ) {
383
385
  routes.push({
384
386
  auth,
385
387
  method: "PUT",
386
388
  path,
387
389
  matcher: new RegExp(
388
- `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`,
390
+ `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`
389
391
  ),
390
392
  input,
391
393
  output,
@@ -406,14 +408,14 @@ export function twoStroke<T extends Env>(
406
408
  input: I,
407
409
  output: O,
408
410
  handler: Handler<T, I, O, A, P>,
409
- params?: PP,
411
+ params?: PP
410
412
  ) {
411
413
  routes.push({
412
414
  auth,
413
415
  method: "POST",
414
416
  path,
415
417
  matcher: new RegExp(
416
- `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`,
418
+ `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`
417
419
  ),
418
420
  input,
419
421
  output,
@@ -433,14 +435,14 @@ export function twoStroke<T extends Env>(
433
435
  path: P,
434
436
  output: O,
435
437
  handler: Handler<T, undefined, O, A, P>,
436
- params?: PP,
438
+ params?: PP
437
439
  ) {
438
440
  routes.push({
439
441
  auth,
440
442
  method: "GET",
441
443
  path,
442
444
  matcher: new RegExp(
443
- `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`,
445
+ `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`
444
446
  ),
445
447
  output,
446
448
  handler,
@@ -458,14 +460,14 @@ export function twoStroke<T extends Env>(
458
460
  path: P,
459
461
  output: O,
460
462
  handler: Handler<T, undefined, O, A, P>,
461
- params?: PP,
463
+ params?: PP
462
464
  ) {
463
465
  routes.push({
464
466
  auth,
465
467
  method: "DELETE",
466
468
  path,
467
469
  matcher: new RegExp(
468
- `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`,
470
+ `^${escapeRegex(path).replaceAll(/\/{([^}]*)}/g, "/(?<$1>[^\\/]*)")}$`
469
471
  ),
470
472
  output,
471
473
  handler,
@@ -483,7 +485,7 @@ type AddToQueueConfig = QueueSendOptions & {
483
485
  export async function addToQueue<T>(
484
486
  queue: Queue<T>,
485
487
  message: T,
486
- config: AddToQueueConfig = {},
488
+ config: AddToQueueConfig = {}
487
489
  ) {
488
490
  const { retries, backoffFactor, ...options } = config;
489
491
 
package/src/types.ts CHANGED
@@ -58,6 +58,7 @@ export type Handler<
58
58
  searchParams: URLSearchParams;
59
59
  claims: A;
60
60
  sentry: Toucan;
61
+ waitUntil: (p: Promise<void>) => void;
61
62
  }) => Promise<
62
63
  | {
63
64
  body: z.infer<O>;