four-stroke 0.0.3 → 0.0.5

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.
@@ -17,4 +17,10 @@ jobs:
17
17
 
18
18
  - uses: ./.github/actions/install
19
19
 
20
- - run: pnpm eslint
20
+ - run: pnpm oxlint
21
+
22
+ - run: pnpm oxfmt --check
23
+
24
+ - run: pnpm tsc --noEmit
25
+
26
+ - run: pnpm knip
package/.knip.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "entry": ["src/**/*.ts", "src/**/*.tsx"]
3
+ }
package/bin/api-types.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import openapiTS from "openapi-typescript";
5
- import prettier from "prettier";
5
+ import { format } from "oxfmt";
6
6
  import ts from "typescript";
7
7
 
8
8
  const services = process.argv[2].split(",");
@@ -17,6 +17,7 @@ await Promise.all(
17
17
  if ("format" in schemaObject && schemaObject.format === "uuid") {
18
18
  return schemaObject.nullable ? ts.factory.createUnionTypeNode([UUID, NULL]) : UUID;
19
19
  }
20
+ return null;
20
21
  },
21
22
  });
22
23
  const printer = ts.createPrinter({});
@@ -28,14 +29,17 @@ await Promise.all(
28
29
  const result = printer.printNode(ts.EmitHint.Unspecified, output[0], resultFile);
29
30
  fs.writeFileSync(
30
31
  `src/__definitions__/${service.replace("https://", "")}-definitions.ts`,
31
- await prettier.format(
32
- `// Autogenerated by four-stroke
32
+ (
33
+ await format(
34
+ `src/__definitions__/${service.replace("https://", "")}-definitions.ts`,
35
+ `// Autogenerated by two-stroke
33
36
 
34
- ${fs.readFileSync("src/__definitions__/type-definitions.ts", "utf-8")}
37
+ ${fs.readFileSync("src/__definitions__/type-definitions.ts", "utf8")}
35
38
 
36
39
  ${result}`,
37
- { parser: "typescript", printWidth: 100 },
38
- ),
40
+ { parser: "typescript", printWidth: 100 },
41
+ )
42
+ ).code,
39
43
  );
40
44
  }),
41
45
  );
package/bin/deploy.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  import fs from "fs";
4
- import { cmd } from "../src/cmd.mjs";
5
4
  import { basename } from "path";
5
+ import { cmd } from "../src/cmd.mjs";
6
6
 
7
7
  const env = process.argv[2];
8
8
  const release = process.argv[3];
package/bin/format.mjs CHANGED
@@ -2,5 +2,5 @@
2
2
  "use strict";
3
3
  import { cmd } from "../src/cmd.mjs";
4
4
 
5
- cmd("eslint --cache --fix");
6
- cmd("prettier --cache --write .");
5
+ cmd("oxfmt");
6
+ cmd("oxlint --fix");
package/bin/lint.mjs CHANGED
@@ -3,24 +3,8 @@
3
3
  import fs from "fs";
4
4
  import { cmd } from "../src/cmd.mjs";
5
5
 
6
- cmd("react-router typegen");
7
6
  if (fs.existsSync("wrangler.jsonc")) {
8
- const devVarsFiles = fs.globSync("**/.dev.vars");
9
- const backed = [];
10
-
11
- for (const file of devVarsFiles) {
12
- const tmp = file + ".bak.bak";
13
- fs.renameSync(file, tmp);
14
- backed.push({ original: file, tmp });
15
- }
16
-
17
- try {
18
- cmd("wrangler types --strict-vars false --check");
19
- } finally {
20
- for (const { original, tmp } of backed) {
21
- fs.renameSync(tmp, original);
22
- }
23
- }
7
+ cmd("wrangler types --env-file /dev/null --strict-vars false --check");
24
8
  }
25
- cmd("eslint --cache --max-warnings=0");
26
- cmd("prettier --cache --check .");
9
+ cmd("oxfmt --check");
10
+ cmd("oxlint");
@@ -4,22 +4,7 @@ import fs from "fs";
4
4
  import { cmd } from "../src/cmd.mjs";
5
5
 
6
6
  if (fs.existsSync("wrangler.jsonc")) {
7
- const devVarsFiles = fs.globSync("**/.dev.vars");
8
- const backed = [];
9
-
10
- for (const file of devVarsFiles) {
11
- const tmp = file + ".bak.bak";
12
- fs.renameSync(file, tmp);
13
- backed.push({ original: file, tmp });
14
- }
15
-
16
- try {
17
- cmd("wrangler types --strict-vars false");
18
- } finally {
19
- for (const { original, tmp } of backed) {
20
- fs.renameSync(tmp, original);
21
- }
22
- }
7
+ cmd("wrangler types --env-file /dev/null --strict-vars false");
23
8
  }
24
9
  cmd("vite build");
25
10
  cmd("tsc --noEmit");
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from "oxfmt";
2
+
3
+ export default defineConfig({
4
+ sortImports: {
5
+ newlinesBetween: false,
6
+ groups: [
7
+ ["value-builtin", "value-external"],
8
+ ["value-internal", "value-parent", "value-sibling", "value-index"],
9
+ { newlinesBetween: true },
10
+ "type-import",
11
+ "unknown",
12
+ ],
13
+ },
14
+ ignorePatterns: ["worker-configuration.d.ts", "wrangler.jsonc"],
15
+ });
@@ -0,0 +1,90 @@
1
+ import { defineConfig } from "oxlint";
2
+
3
+ export default defineConfig({
4
+ plugins: ["eslint", "typescript", "unicorn", "oxc", "import", "promise", "vitest"],
5
+ options: {
6
+ typeAware: true,
7
+ },
8
+ categories: {
9
+ correctness: "error",
10
+ suspicious: "warn",
11
+ perf: "error",
12
+ style: "warn",
13
+ },
14
+ rules: {
15
+ "no-map-spread": "off",
16
+ "no-named-export": "off",
17
+ "no-magic-numbers": "off",
18
+ "consistent-indexed-object-style": "off",
19
+ "id-length": "off",
20
+ "no-await-expression-member": "off",
21
+ "max-nested-calls": "off",
22
+ "sort-keys": "off",
23
+ curly: "off",
24
+ "switch-case-braces": "off",
25
+ "vitest/require-hook": "off",
26
+ "no-ternary": "off",
27
+ "group-exports": "off",
28
+ "exports-last": "off",
29
+ "prefer-default-export": "off",
30
+ "no-null": "off",
31
+ "consistent-type-specifier-style": "off",
32
+ "max-statements": "off",
33
+ "consistent-type-imports": "error",
34
+ "relative-url-style": ["error", "always"],
35
+ "no-namespace": "off",
36
+ "no-duplicate-imports": ["error", { allowSeparateTypeImports: true }],
37
+ "func-style": "off",
38
+ "sort-imports": [
39
+ "error",
40
+ {
41
+ ignoreDeclarationSort: true,
42
+ ignoreMemberSort: false,
43
+ },
44
+ ],
45
+ "new-cap": "off",
46
+ "promise/prefer-await-to-callbacks": "off",
47
+ "promise/avoid-new": "off",
48
+ "prefer-await-to-then": "off",
49
+ "max-params": "off",
50
+ "no-underscore-dangle": "off",
51
+ "no-nested-ternary": "off",
52
+ "unicorn/no-nested-ternary": "off",
53
+ "no-anonymous-default-export": "off",
54
+ "no-continue": "off",
55
+ "init-declarations": "off",
56
+ "prefer-to-be-truthy": "off",
57
+ "vitest/prefer-expect-assertions": "off",
58
+ "vitest/prefer-importing-vitest-globals": "off",
59
+ "vitest/no-importing-vitest-globals": "error",
60
+ "vitest/require-top-level-describe": "off",
61
+ "vitest/max-expects": "off",
62
+ "vitest/no-hooks": "off",
63
+ },
64
+ overrides: [
65
+ {
66
+ files: ["*.test.ts", "*.spec.ts"],
67
+ rules: {
68
+ "@typescript-eslint/no-explicit-any": "off",
69
+ },
70
+ },
71
+ {
72
+ files: ["*-definitions.ts"],
73
+ rules: {
74
+ "no-unused-vars": "off",
75
+ "@typescript-eslint/no-redundant-type-constituents": "off",
76
+ "@typescript-eslint/no-duplicate-type-constituents": "off",
77
+ "group-exports": "off",
78
+ "exports-last": "off",
79
+ "consistent-indexed-object-style": "off",
80
+ },
81
+ },
82
+ {
83
+ files: ["bin/*.mjs", "src/cmd.mjs"],
84
+ rules: {
85
+ "import/no-nodejs-modules": "off",
86
+ "prefer-destructuring": "off",
87
+ },
88
+ },
89
+ ],
90
+ });
package/package.json CHANGED
@@ -1,4 +1,12 @@
1
1
  {
2
+ "name": "four-stroke",
3
+ "version": "0.0.5",
4
+ "description": "Simple Cloudflare Worker SSR SPA framework",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/change-engine/four-stroke"
9
+ },
2
10
  "bin": {
3
11
  "api-types": "./bin/api-types.mjs",
4
12
  "deploy": "./bin/deploy.mjs",
@@ -8,52 +16,31 @@
8
16
  "test": "./bin/test.mjs",
9
17
  "type-check": "./bin/type-check.mjs"
10
18
  },
19
+ "type": "module",
20
+ "main": "src/fake.ts",
11
21
  "dependencies": {
12
- "@cloudflare/vitest-pool-workers": "^0.16.20",
13
- "@sentry/cli": "^3.5.1",
14
- "@types/node": "^26.0.1",
15
22
  "@types/react": "^19.2.17",
16
- "@types/react-dom": "^19.2.3",
17
- "@typescript-eslint/eslint-plugin": "^8.62.0",
18
- "@typescript-eslint/parser": "^8.62.0",
19
- "@vitest/runner": "^4.1.9",
20
- "@vitest/snapshot": "^4.1.9",
21
- "eslint-config-prettier": "^10.1.8",
22
- "eslint-config-two-stroke": "^1.5.6",
23
- "eslint-config-typescript": "^3.0.0",
24
- "openapi-typescript": "^7.13.0",
25
- "react": "^19.2.7",
26
- "react-dom": "^19.2.7"
23
+ "openapi-typescript": "^7.13.0"
24
+ },
25
+ "devDependencies": {
26
+ "@cloudflare/vitest-pool-workers": "^0.18.4",
27
+ "knip": "^6.26.0",
28
+ "oxfmt": "^0.59.0",
29
+ "oxlint": "^1.74.0",
30
+ "oxlint-tsgolint": "^0.24.0",
31
+ "typescript": "^6.0.3",
32
+ "vitest": "^4.1.10"
27
33
  },
28
34
  "peerDependencies": {
29
- "@sentry/cli": ">=2",
30
- "eslint": ">=10",
31
- "prettier": ">=3",
32
- "typescript": ">=5",
35
+ "knip": "^6.26.0",
36
+ "oxfmt": "^0.59.0",
37
+ "oxlint": "^1.74.0",
38
+ "oxlint-tsgolint": "^0.24.0",
39
+ "typescript": "^6.0.3",
33
40
  "vitest": ">=4",
34
41
  "wrangler": ">=3"
35
42
  },
36
- "description": "Simple Cloudflare Worker SSR SPA framework",
37
43
  "engines": {
38
44
  "node": "^24.9.0"
39
- },
40
- "license": "MIT",
41
- "main": "src/index.ts",
42
- "name": "four-stroke",
43
- "prettier": {
44
- "printWidth": 100
45
- },
46
- "repository": {
47
- "type": "git",
48
- "url": "https://github.com/change-engine/four-stroke"
49
- },
50
- "type": "module",
51
- "version": "0.0.3",
52
- "devDependencies": {
53
- "@types/eslint": "^9.6.1",
54
- "eslint": "^10.5.0",
55
- "prettier": "^3.8.4",
56
- "typescript": "^6.0.3",
57
- "vitest": "^4.1.9"
58
45
  }
59
46
  }
@@ -1,9 +1,9 @@
1
1
  import type { Viewer } from "../util/auth";
2
2
 
3
- type ViewerMenuProps = {
3
+ interface ViewerMenuProps {
4
4
  logoutUrl: string;
5
5
  viewer: Viewer;
6
- };
6
+ }
7
7
 
8
8
  export default function ViewerMenu({ logoutUrl, viewer }: ViewerMenuProps): React.ReactNode {
9
9
  return (
package/src/util/auth.ts CHANGED
@@ -1,7 +1,7 @@
1
- export type Viewer = {
1
+ export interface Viewer {
2
2
  name: string;
3
3
  picture: string | null;
4
- };
4
+ }
5
5
 
6
6
  export const getCookieValue = (request: Request, name: string): string | null => {
7
7
  const cookieHeader = request.headers.get("Cookie");
@@ -32,6 +32,7 @@ export const parseViewerFromAccessToken = (accessToken: string): Viewer | null =
32
32
  }
33
33
 
34
34
  try {
35
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
35
36
  const claims = JSON.parse(decodeBase64Url(payload)) as {
36
37
  email?: unknown;
37
38
  name?: unknown;
package/tsconfig.json CHANGED
@@ -14,7 +14,8 @@
14
14
  "types": [
15
15
  "./worker-configuration.d.ts",
16
16
  "vitest/globals",
17
- "@cloudflare/vitest-pool-workers/types"
17
+ "@cloudflare/vitest-pool-workers/types",
18
+ "@types/react"
18
19
  ],
19
20
  "verbatimModuleSyntax": true,
20
21
  "jsx": "react-jsx"
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // Generated by Wrangler by running `wrangler types --strict-vars=false` (hash: f0ebc0bbc8852abc1241a56510ca0186)
2
+ // Generated by Wrangler by running `wrangler types` (hash: f0ebc0bbc8852abc1241a56510ca0186)
3
3
  // Runtime types generated with workerd@1.20260625.1 2025-09-15 disable_nodejs_fs_module,nodejs_compat
4
4
  interface __BaseEnv_Env {
5
5
  }
package/eslint.config.js DELETED
@@ -1,3 +0,0 @@
1
- import config from "eslint-config-two-stroke";
2
-
3
- export default config;