two-stroke 5.3.2 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,7 +48,7 @@ app.get(
48
48
  return {
49
49
  body: { message: "Hello, World!" },
50
50
  };
51
- }
51
+ },
52
52
  );
53
53
 
54
54
  // Define a route with path parameters
@@ -60,7 +60,7 @@ app.get(
60
60
  return {
61
61
  body: { user: { id: params.userId, name: "John Doe" } },
62
62
  };
63
- }
63
+ },
64
64
  );
65
65
 
66
66
  // Define a POST route with request validation
@@ -73,7 +73,7 @@ app.post(
73
73
  return {
74
74
  body: { id: "msg_123" },
75
75
  };
76
- }
76
+ },
77
77
  );
78
78
 
79
79
  // Export the worker handlers
@@ -95,7 +95,7 @@ app.get(
95
95
  app.pbkdf("API_KEY"),
96
96
  "/protected",
97
97
  z.object({ message: z.string() }),
98
- async () => ({ body: { message: "Protected endpoint" } })
98
+ async () => ({ body: { message: "Protected endpoint" } }),
99
99
  );
100
100
 
101
101
  // JWT authentication
@@ -103,7 +103,7 @@ app.get(
103
103
  app.jwt<{ userId: string }>("JWT_SECRET", "JWT_AUDIENCE"),
104
104
  "/user-data",
105
105
  z.object({ userId: z.string() }),
106
- async ({ claims }) => ({ body: { userId: claims.userId } })
106
+ async ({ claims }) => ({ body: { userId: claims.userId } }),
107
107
  );
108
108
  ```
109
109
 
@@ -121,7 +121,7 @@ app.queueHandler(
121
121
  console.log(`Processing message: ${data.id}`);
122
122
  }
123
123
  }
124
- }
124
+ },
125
125
  );
126
126
 
127
127
  // Add to queue with retry logic
@@ -133,7 +133,7 @@ await addToQueue(
133
133
  {
134
134
  retries: 3,
135
135
  backoffFactor: 2,
136
- }
136
+ },
137
137
  );
138
138
  ```
139
139
 
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import openapiTS from "openapi-typescript";
5
+ import prettier from "prettier";
6
+ import ts from "typescript";
7
+
8
+ const services = process.argv[2].split(",");
9
+
10
+ const UUID = ts.factory.createTypeReferenceNode(
11
+ ts.factory.createIdentifier("UUID"),
12
+ );
13
+ const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull());
14
+
15
+ await Promise.all(
16
+ services.map(async (service) => {
17
+ const output = await openapiTS(`https://${service}.changeengine.com/doc`, {
18
+ transform(schemaObject) {
19
+ if ("format" in schemaObject && schemaObject.format === "uuid") {
20
+ return schemaObject.nullable
21
+ ? ts.factory.createUnionTypeNode([UUID, NULL])
22
+ : UUID;
23
+ }
24
+ },
25
+ });
26
+ const printer = ts.createPrinter({});
27
+ const resultFile = ts.createSourceFile(
28
+ `src/__definitions__/${service}-definitions.ts`,
29
+ "",
30
+ ts.ScriptTarget.Latest,
31
+ );
32
+ const result = printer.printNode(
33
+ ts.EmitHint.Unspecified,
34
+ output[0],
35
+ resultFile,
36
+ );
37
+ fs.writeFileSync(
38
+ `src/__definitions__/${service}-definitions.ts`,
39
+ await prettier.format(
40
+ `// Autogenerated by two-stroke
41
+
42
+ ${fs.readFileSync("src/__definitions__/type-definitions.ts", "utf-8")}
43
+
44
+ ${result}`,
45
+ { parser: "typescript", printWidth: 100 },
46
+ ),
47
+ );
48
+ }),
49
+ );
package/bin/bulk.mjs CHANGED
@@ -8,7 +8,10 @@ import mime from "mime";
8
8
  const entryOrRest = process.argv[2];
9
9
  const entry = process.argv[3];
10
10
 
11
- const ents = await fs.promises.readdir("dist", { withFileTypes: true, recursive: true });
11
+ const ents = await fs.promises.readdir("dist", {
12
+ withFileTypes: true,
13
+ recursive: true,
14
+ });
12
15
  const files = await Promise.all(
13
16
  ents
14
17
  .filter((ent) => ent.isFile())
@@ -20,9 +23,9 @@ const files = await Promise.all(
20
23
  const key = `${ent.parentPath.substring(4)}/${ent.name}`;
21
24
  return (async () => ({
22
25
  key: ent.name === entry ? `${process.env.DOMAIN}${key}` : key,
23
- value: (await fs.promises.readFile(`${ent.parentPath}/${ent.name}`)).toString(
24
- "base64",
25
- ),
26
+ value: (
27
+ await fs.promises.readFile(`${ent.parentPath}/${ent.name}`)
28
+ ).toString("base64"),
26
29
  base64: true,
27
30
  metadata: {
28
31
  "Content-Type":
package/package.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "bin": {
3
+ "api-types": "./bin/api-types.mjs",
3
4
  "bulk": "./bin/bulk.mjs",
4
5
  "deploy": "./bin/deploy.mjs",
5
6
  "dev": "./bin/dev.mjs",
@@ -9,25 +10,25 @@
9
10
  "type-check": "./bin/type-check.mjs"
10
11
  },
11
12
  "dependencies": {
12
- "@cloudflare/vitest-pool-workers": "^0.8.56",
13
- "@cloudflare/workers-types": "^4.20250723.0",
13
+ "@cloudflare/vitest-pool-workers": "^0.8.57",
14
+ "@cloudflare/workers-types": "^4.20250726.0",
14
15
  "@sentry/cli": "^2.50.2",
15
16
  "@types/node": "^24.1.0",
16
17
  "@typescript-eslint/eslint-plugin": "^8.38.0",
17
18
  "@typescript-eslint/parser": "^8.38.0",
18
19
  "@vitest/coverage-istanbul": "^3.2.4",
19
20
  "eslint-config-prettier": "^10.1.8",
20
- "eslint-config-two-stroke": "^1.2.2",
21
+ "eslint-config-two-stroke": "^1.2.3",
21
22
  "eslint-config-typescript": "^3.0.0",
22
23
  "jose": "^6.0.12",
23
24
  "jwk-subtle": "^1.0.7",
24
25
  "mime": "^4.0.7",
25
- "miniflare": "^4.20250712.1",
26
+ "miniflare": "^4.20250712.2",
26
27
  "openapi-fetch": "^0.14.0",
27
28
  "openapi-typescript": "^7.8.0",
28
29
  "pbkdf-subtle": "^1.0.0",
29
30
  "toucan-js": "^4.1.1",
30
- "zod": "^4.0.5"
31
+ "zod": "^4.0.10"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "@sentry/cli": ">=2",
@@ -51,10 +52,10 @@
51
52
  "name": "two-stroke",
52
53
  "packageManager": "yarn@4.6.0",
53
54
  "type": "module",
54
- "version": "5.3.2",
55
+ "version": "5.5.0",
55
56
  "devDependencies": {
56
57
  "@types/eslint": "^9.6.1",
57
- "eslint": "^9.31.0",
58
+ "eslint": "^9.32.0",
58
59
  "prettier": "^3.6.2",
59
60
  "typescript": "^5.8.3",
60
61
  "vitest": "^3.2.4"
package/src/test.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { JWTPayload, SignJWT, exportJWK, generateKeyPair } from "jose";
2
2
  import { fetchMock, SELF, env } from "cloudflare:test";
3
3
  import createClient from "openapi-fetch";
4
- import consumers from "stream/consumers";
5
4
 
6
5
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/require-await
7
6
  export const setupTests = async <Paths extends {}>() => {
@@ -116,11 +115,9 @@ export function recordRequest(
116
115
  headers: Record<string, string | string[] | undefined>;
117
116
  },
118
117
  ) {
119
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
- return ({ body }: any) => {
121
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
122
- void consumers.json(body).then(cb);
123
- return { statusCode, data, responseOptions };
118
+ return ({ body }: { body?: BodyInit }) => {
119
+ cb(JSON.parse((body?.valueOf() as string) ?? ""));
120
+ return { statusCode, data, responseOptions: responseOptions ?? {} };
124
121
  };
125
122
  }
126
123
 
@@ -133,17 +130,13 @@ export function recordFormRequest(
133
130
  headers: Record<string, string | string[] | undefined>;
134
131
  },
135
132
  ) {
136
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
- return ({ body }: any) => {
138
- void consumers
139
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
140
- .text(body)
141
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-shadow
142
- .then((data: any) =>
143
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
144
- cb(Object.fromEntries(new URLSearchParams(data).entries())),
145
- );
146
- return { statusCode, data, responseOptions };
133
+ return ({ body }: { body?: BodyInit }) => {
134
+ cb(
135
+ Object.fromEntries(
136
+ new URLSearchParams((body?.valueOf() as string) ?? "").entries(),
137
+ ),
138
+ );
139
+ return { statusCode, data, responseOptions: responseOptions ?? {} };
147
140
  };
148
141
  }
149
142
 
@@ -156,13 +149,14 @@ export function recordFirehoseRequest(
156
149
  headers: Record<string, string | string[] | undefined>;
157
150
  },
158
151
  ) {
159
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
- return ({ body }: any) => {
161
- void consumers
162
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
163
- .json(body)
164
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-shadow, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
165
- .then((data: any) => cb(JSON.parse(atob(data["Record"]["Data"]))));
166
- return { statusCode, data, responseOptions };
152
+ return ({ body }: { body?: BodyInit }) => {
153
+ cb(JSON.parse((body?.valueOf() as string) ?? ""));
154
+ cb(
155
+ JSON.parse(
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
157
+ atob(JSON.parse((body?.valueOf() as string) ?? "")["Record"]["Data"]),
158
+ ),
159
+ );
160
+ return { statusCode, data, responseOptions: responseOptions ?? {} };
167
161
  };
168
162
  }