diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 000000000..0b53ae443 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,42 @@ +name: 💅 Format + +on: + push: + branches: + - main + - 1.x + - dev + - release-* + tags-ignore: + - v* + + pull_request: + branches: + - main + - 1.x + - dev + - release-* + +jobs: + format: + name: "💅 Check formatting" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - name: Use Node.js from .nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: 💅 Check formatting + run: pnpm format:check diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index 66d7a943f..c64afa9c2 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -1,4 +1,4 @@ -name: 'Close issues' +name: "Close issues" on: issues: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a882e9714..63c1662aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,14 +62,14 @@ Once the PR is there, **create an issue** and link the PR (mention the PR as you - If what you'd like to change needs e2e testing (i.e. you need a working build to test your feature), use playwright (see the `/app/tests/e2e` directory for examples). - If what you'd like to change is specific to a component, function (i.e. you need a unit test), use Vitest. You can find examples in the `/app/tests/` directory, look for the .tests.ts/.test.tsx files. - - Note: Vitest is also set-up to test individual components - have a look at `/app/tests/routes/(basic).browser.test.tsx` for an example. + - Note: Vitest is also set-up to test individual components - have a look at `/app/tests/routes/(basic).browser.test.tsx` for an example. #### Testing conventions: - For e2e test, simply place them in the `apps/tests/e2e` directory. The project is configured to run anything found in that directory via playwright as an e2e test. - For unit tests, co-locate them in the same place as the component or function they test: - - E.g. If you're testing `/app/tests/MyComponent.tsx`, create a file named `/app/tests/MyComponent.test.browser.tsx` in the same directory. Note the `.browser` part - that's important to tell Vitest that this test should run in a browser environment. - - For server-side unit tests, use the same placement conventions as described for components, but create a file named `/app/tests/myfeature.test.server.ts` in the same directory. Using `.server` in the filename tells Vitest that this test should run in a node environment. + - E.g. If you're testing `/app/tests/MyComponent.tsx`, create a file named `/app/tests/MyComponent.test.browser.tsx` in the same directory. Note the `.browser` part - that's important to tell Vitest that this test should run in a browser environment. + - For server-side unit tests, use the same placement conventions as described for components, but create a file named `/app/tests/myfeature.test.server.ts` in the same directory. Using `.server` in the filename tells Vitest that this test should run in a node environment. > [!IMPORTANT] > Mark the **allow edit by the maintainers** so we can more easily investigate the failing test and propose a fix. Otherwise we may need to close your PR and cherry-pick your commit. @@ -78,6 +78,8 @@ Once the PR is there, **create an issue** and link the PR (mention the PR as you We have a set of rules defined in the `.editorconfig` and `.oxfmtrc.json` files. Please format your code before opening a PR, so that we keep the codebase consistent. Regardless of what editor you use, running `pnpm format` will format your code according to our rules. +CI runs `pnpm format:check` on every PR and fails if anything is unformatted, so run `pnpm format` before pushing. + --- If you have read all the way here, you're already a champ! 🏆 diff --git a/README.md b/README.md index 18c644e35..6f42faf1b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ > [!IMPORTANT] > This is the branch for the SolidStart 2.0.0-alpha that is currently under heavy development. -> +> > Current SolidStart is maintained at [`1.x`](https://github.com/solidjs/solid-start/tree/1.x). ## Prerequisites diff --git a/apps/fixtures/bare/src/app.css b/apps/fixtures/bare/src/app.css index a4d2e55c4..fc2a7727e 100644 --- a/apps/fixtures/bare/src/app.css +++ b/apps/fixtures/bare/src/app.css @@ -1,5 +1,6 @@ body { - font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-family: + Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } a { diff --git a/apps/fixtures/bare/tsconfig.json b/apps/fixtures/bare/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/bare/tsconfig.json +++ b/apps/fixtures/bare/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/fixtures/basic/src/app.css b/apps/fixtures/basic/src/app.css index 8596998a4..7329129ac 100644 --- a/apps/fixtures/basic/src/app.css +++ b/apps/fixtures/basic/src/app.css @@ -1,5 +1,6 @@ body { - font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-family: + Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } a { diff --git a/apps/fixtures/basic/src/components/Counter.css b/apps/fixtures/basic/src/components/Counter.css index 220e17946..308965720 100644 --- a/apps/fixtures/basic/src/components/Counter.css +++ b/apps/fixtures/basic/src/components/Counter.css @@ -18,4 +18,4 @@ .increment:active { background-color: rgba(68, 107, 158, 0.2); -} \ No newline at end of file +} diff --git a/apps/fixtures/basic/tsconfig.json b/apps/fixtures/basic/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/basic/tsconfig.json +++ b/apps/fixtures/basic/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/fixtures/css/tsconfig.json b/apps/fixtures/css/tsconfig.json index e4bb71b1e..1fd1e25c8 100644 --- a/apps/fixtures/css/tsconfig.json +++ b/apps/fixtures/css/tsconfig.json @@ -12,8 +12,8 @@ "noEmit": true, "isolatedModules": true, "paths": { - "~/*": ["./src/*"], + "~/*": ["./src/*"] }, - "types": ["@solidjs/start/env"], - }, + "types": ["@solidjs/start/env"] + } } diff --git a/apps/fixtures/experiments/src/app.css b/apps/fixtures/experiments/src/app.css index 8596998a4..7329129ac 100644 --- a/apps/fixtures/experiments/src/app.css +++ b/apps/fixtures/experiments/src/app.css @@ -1,5 +1,6 @@ body { - font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-family: + Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } a { diff --git a/apps/fixtures/experiments/src/components/Counter.css b/apps/fixtures/experiments/src/components/Counter.css index 220e17946..308965720 100644 --- a/apps/fixtures/experiments/src/components/Counter.css +++ b/apps/fixtures/experiments/src/components/Counter.css @@ -18,4 +18,4 @@ .increment:active { background-color: rgba(68, 107, 158, 0.2); -} \ No newline at end of file +} diff --git a/apps/fixtures/experiments/tsconfig.json b/apps/fixtures/experiments/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/experiments/tsconfig.json +++ b/apps/fixtures/experiments/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/fixtures/hackernews/package.json b/apps/fixtures/hackernews/package.json index 16844102c..da305b422 100644 --- a/apps/fixtures/hackernews/package.json +++ b/apps/fixtures/hackernews/package.json @@ -1,7 +1,7 @@ { "name": "fixture-hackernews", - "type": "module", "private": true, + "type": "module", "scripts": { "dev": "vite dev", "preview": "vite preview", diff --git a/apps/fixtures/hackernews/src/app.css b/apps/fixtures/hackernews/src/app.css index 1db56b0a5..2bf246440 100644 --- a/apps/fixtures/hackernews/src/app.css +++ b/apps/fixtures/hackernews/src/app.css @@ -1,5 +1,7 @@ body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", + "Droid Sans", "Helvetica Neue", sans-serif; font-size: 15px; background-color: #f2f3f5; margin: 0; @@ -98,7 +100,8 @@ a { padding-top: 45px; } -.news-list, .news-list-nav { +.news-list, +.news-list-nav { background-color: #fff; border-radius: 2px; } @@ -160,17 +163,20 @@ a { margin-top: -10px; } -.news-item .host, .news-item .meta { +.news-item .host, +.news-item .meta { font-size: 0.85em; color: #626262; } -.news-item .host a, .news-item .meta a { +.news-item .host a, +.news-item .meta a { color: #626262; text-decoration: underline; } -.news-item .host a:hover, .news-item .meta a:hover { +.news-item .host a:hover, +.news-item .meta a:hover { color: #335d92; } @@ -187,7 +193,9 @@ a { margin-right: 0.5em; } -.item-view-header .host, .item-view-header .meta, .item-view-header .meta a { +.item-view-header .host, +.item-view-header .meta, +.item-view-header .meta a { color: #626262; } @@ -234,7 +242,9 @@ a { position: relative; } -.comment .by, .comment .text, .comment .toggle { +.comment .by, +.comment .text, +.comment .toggle { font-size: 0.9em; margin: 1em 0; } diff --git a/apps/fixtures/hackernews/tsconfig.json b/apps/fixtures/hackernews/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/hackernews/tsconfig.json +++ b/apps/fixtures/hackernews/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/fixtures/notes/src/app.css b/apps/fixtures/notes/src/app.css index 7607d990d..a03f7aa50 100644 --- a/apps/fixtures/notes/src/app.css +++ b/apps/fixtures/notes/src/app.css @@ -17,7 +17,9 @@ ol[class] { z-index: 1; } -solid-island, solid-children, outlet-wrapper { +solid-island, +solid-children, +outlet-wrapper { display: contents; } @@ -119,10 +121,9 @@ select { --outline-box-shadow-contrast: 0 0 0 2px var(--navy-blue); /* Fonts */ - --sans-serif: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, - Ubuntu, Helvetica, sans-serif; - --monospace: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, - monospace; + --sans-serif: + -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Helvetica, sans-serif; + --monospace: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; } html { @@ -246,7 +247,7 @@ hr { border-radius: 100px; letter-spacing: 0.12em; text-transform: uppercase; - padding: 6px 20px ; + padding: 6px 20px; cursor: pointer; font-weight: 700; outline-style: none; @@ -298,7 +299,9 @@ ul.notes-list { } .sidebar { - box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.1), 0px 2px 2px rgba(0, 0, 0, 0.1); + box-shadow: + 0px 8px 24px rgba(0, 0, 0, 0.1), + 0px 2px 2px rgba(0, 0, 0, 0.1); overflow-y: scroll; z-index: 1000; flex-shrink: 0; @@ -310,7 +313,7 @@ ul.notes-list { background: var(--white); } .dark .sidebar { - background:#151d28; + background: #151d28; } .sidebar-header { letter-spacing: 0.15em; @@ -402,7 +405,9 @@ ul.notes-list { visibility: hidden; opacity: 0; cursor: default; - transition: visibility 0s linear 20ms, opacity 300ms; + transition: + visibility 0s linear 20ms, + opacity 300ms; outline-style: none; } .sidebar-note-toggle-expand:focus { @@ -414,7 +419,9 @@ ul.notes-list { .sidebar-note-toggle-expand:focus { visibility: visible; opacity: 1; - transition: visibility 0s linear 0s, opacity 300ms; + transition: + visibility 0s linear 0s, + opacity 300ms; } .sidebar-note-toggle-expand img { width: 10px; @@ -435,7 +442,7 @@ ul.notes-list { .dark > .sidebar-note-excerpt { color: var(--secondary-text-dark); -} +} .search input { padding: 0 16px; @@ -461,7 +468,9 @@ ul.notes-list { } .note { background: var(--white); - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1), 0px 0px 1px rgba(0, 0, 0, 0.1); + box-shadow: + 0px 0px 5px rgba(0, 0, 0, 0.1), + 0px 0px 1px rgba(0, 0, 0, 0.1); border-radius: 8px; height: 95%; width: 95%; @@ -652,7 +661,7 @@ ul.notes-list { } .skeleton::after { - content: 'Loading...'; + content: "Loading..."; } .skeleton { height: 100%; diff --git a/apps/fixtures/notes/tsconfig.json b/apps/fixtures/notes/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/notes/tsconfig.json +++ b/apps/fixtures/notes/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/fixtures/todomvc/tsconfig.json b/apps/fixtures/todomvc/tsconfig.json index 411ce3ba8..5bd3d2200 100644 --- a/apps/fixtures/todomvc/tsconfig.json +++ b/apps/fixtures/todomvc/tsconfig.json @@ -13,7 +13,7 @@ "isolatedModules": true, "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/landing-page/src/components/ui/button.tsx b/apps/landing-page/src/components/ui/button.tsx index 7f27af5a1..b8816ab66 100644 --- a/apps/landing-page/src/components/ui/button.tsx +++ b/apps/landing-page/src/components/ui/button.tsx @@ -33,8 +33,7 @@ const buttonVariants = cva( ); export interface ButtonProps - extends ComponentProps<"button">, - VariantProps {} + extends ComponentProps<"button">, VariantProps {} const Button: Component = props => { const [, rest] = splitProps(props, ["variant", "size", "class"]); diff --git a/apps/landing-page/src/root.css b/apps/landing-page/src/root.css index 4dde9d51b..9ea9add8e 100644 --- a/apps/landing-page/src/root.css +++ b/apps/landing-page/src/root.css @@ -1,4 +1,4 @@ -@import 'tailwindcss'; +@import "tailwindcss"; @plugin 'tailwindcss-animate'; @@ -126,7 +126,7 @@ overflow: hidden; &::before { - content: ''; + content: ""; position: absolute; top: 0; left: -150%; @@ -144,11 +144,7 @@ } @utility sonar { - background: radial-gradient( - circle, - rgba(255, 255, 255, 0.25), - rgba(255, 255, 255, 0) - ); + background: radial-gradient(circle, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0)); animation: sonarEffect 4s infinite cubic-bezier(0.36, 0.85, 0.57, 0.88); } @@ -250,7 +246,9 @@ } body { @apply bg-background text-foreground; - font-feature-settings: "rlig" 1, "calt" 1; + font-feature-settings: + "rlig" 1, + "calt" 1; } @media (max-width: 640px) { @@ -275,37 +273,37 @@ @keyframes earthquake { 0% { - transform: translate(.5px, .5px) rotate(0deg); + transform: translate(0.5px, 0.5px) rotate(0deg); } 10% { - transform: translate(-.5px, -1px) rotate(-.5deg); + transform: translate(-0.5px, -1px) rotate(-0.5deg); } 20% { - transform: translate(-1.5px, 0px) rotate(.5deg); + transform: translate(-1.5px, 0px) rotate(0.5deg); } 30% { transform: translate(1.5px, 1px) rotate(0deg); } 40% { - transform: translate(.5px, -.5px) rotate(.5deg); + transform: translate(0.5px, -0.5px) rotate(0.5deg); } 50% { - transform: translate(-.5px, 1px) rotate(-.5deg); + transform: translate(-0.5px, 1px) rotate(-0.5deg); } 60% { - transform: translate(-1.5px, .5px) rotate(0deg); + transform: translate(-1.5px, 0.5px) rotate(0deg); } 70% { - transform: translate(1.5px, .5px) rotate(-.5deg); + transform: translate(1.5px, 0.5px) rotate(-0.5deg); } 80% { - transform: translate(-.5px, -.5px) rotate(.5deg); + transform: translate(-0.5px, -0.5px) rotate(0.5deg); } 90% { - transform: translate(.5px, 1px) rotate(0deg); + transform: translate(0.5px, 1px) rotate(0deg); } 100% { - transform: translate(.5px, -1px) rotate(-.5deg); + transform: translate(0.5px, -1px) rotate(-0.5deg); } } @@ -327,7 +325,7 @@ opacity: 1; } 45% { - opacity: .5; + opacity: 0.5; } 70% { transform: scale(6); diff --git a/apps/landing-page/tsconfig.json b/apps/landing-page/tsconfig.json index c95b9e538..5e0aef176 100644 --- a/apps/landing-page/tsconfig.json +++ b/apps/landing-page/tsconfig.json @@ -10,7 +10,7 @@ "baseUrl": "./", "types": ["@solidjs/start/env"], "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/apps/landing-page/ui.config.json b/apps/landing-page/ui.config.json index c93a491c0..63903a66e 100644 --- a/apps/landing-page/ui.config.json +++ b/apps/landing-page/ui.config.json @@ -8,4 +8,4 @@ "aliases": { "path": "~/*" } -} \ No newline at end of file +} diff --git a/apps/tests/src/app.css b/apps/tests/src/app.css index a4d2e55c4..fc2a7727e 100644 --- a/apps/tests/src/app.css +++ b/apps/tests/src/app.css @@ -1,5 +1,6 @@ body { - font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-family: + Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } a { diff --git a/apps/tests/src/e2e/server-function.test.ts b/apps/tests/src/e2e/server-function.test.ts index d7615a17e..b87aff9a7 100644 --- a/apps/tests/src/e2e/server-function.test.ts +++ b/apps/tests/src/e2e/server-function.test.ts @@ -81,9 +81,11 @@ test.describe("server-function", () => { await page.goto("http://localhost:3000/server-function-blob"); await expect(page.locator("#server-fn-test")).toContainText('{"result":true}'); }); - test("should remove exports for non-function values when top-level use server is used", async ({ page }) => { + test("should remove exports for non-function values when top-level use server is used", async ({ + page, + }) => { await page.goto("http://localhost:3000/server-function-query-toplevel"); - await expect(page.locator("#server-fn-test")).toContainText('false'); + await expect(page.locator("#server-fn-test")).toContainText("false"); }); // TODO not sure if this is the correct place diff --git a/apps/tests/src/functions/solid-router-query.ts b/apps/tests/src/functions/solid-router-query.ts index 011338e76..5008b0c84 100644 --- a/apps/tests/src/functions/solid-router-query.ts +++ b/apps/tests/src/functions/solid-router-query.ts @@ -3,5 +3,4 @@ import { query } from "@solidjs/router"; import { isServer } from "solid-js/web"; -export const testQuery = query(() => isServer, 'testQuery'); - +export const testQuery = query(() => isServer, "testQuery"); diff --git a/apps/tests/src/functions/use-is-server.ts b/apps/tests/src/functions/use-is-server.ts index f5831307a..a82a8343b 100644 --- a/apps/tests/src/functions/use-is-server.ts +++ b/apps/tests/src/functions/use-is-server.ts @@ -5,7 +5,6 @@ import { keepAlive } from "~/utils/keep-alive-util"; const serverSecret = "MyServerSuperSecretUniqueString2"; - export function serverFnWithIsServer() { keepAlive(serverSecret); return isServer; diff --git a/apps/tests/src/routes/server-function-file.tsx b/apps/tests/src/routes/server-function-file.tsx index da0a369f0..605bf6dc1 100644 --- a/apps/tests/src/routes/server-function-file.tsx +++ b/apps/tests/src/routes/server-function-file.tsx @@ -9,7 +9,7 @@ export default function App() { const [output, setOutput] = createSignal<{ result?: boolean }>({}); createEffect(async () => { - const file = new File(['Hello, World!'], 'hello-world.txt'); + const file = new File(["Hello, World!"], "hello-world.txt"); const result = await ping(file); const value = await file.text(); setOutput(prev => ({ ...prev, result: value === result })); diff --git a/apps/tests/src/routes/server-function-iterator.tsx b/apps/tests/src/routes/server-function-iterator.tsx index 9beb1a34d..ea8e423da 100644 --- a/apps/tests/src/routes/server-function-iterator.tsx +++ b/apps/tests/src/routes/server-function-iterator.tsx @@ -6,13 +6,13 @@ async function ping(value: Date) { const current = [ value, { - name: 'example', + name: "example", *[Symbol.iterator]() { - yield 'foo'; - yield 'bar'; - yield 'baz'; - } - } + yield "foo"; + yield "bar"; + yield "baz"; + }, + }, ]; return current; @@ -24,7 +24,7 @@ export default function App() { createEffect(async () => { const value = new Date(); const result = await ping(value); - setOutput((prev) => ({ ...prev, result: value.toString() === result[0].toString() })); + setOutput(prev => ({ ...prev, result: value.toString() === result[0].toString() })); }); return ( diff --git a/apps/tests/src/routes/server-function-ping.tsx b/apps/tests/src/routes/server-function-ping.tsx index 677a35340..6744ed15e 100644 --- a/apps/tests/src/routes/server-function-ping.tsx +++ b/apps/tests/src/routes/server-function-ping.tsx @@ -1,9 +1,9 @@ import { createEffect, createSignal } from "solid-js"; async function sleep(value: unknown, ms: number) { - return new Promise((res) => { + return new Promise(res => { setTimeout(res, ms, value); - }) + }); } async function ping(value: Date) { @@ -12,13 +12,13 @@ async function ping(value: Date) { const current = [ value, { - name: 'example', + name: "example", async *[Symbol.asyncIterator]() { - yield sleep('foo', 5000); - yield sleep('bar', 5000); - yield sleep('baz', 5000); - } - } + yield sleep("foo", 5000); + yield sleep("bar", 5000); + yield sleep("baz", 5000); + }, + }, ]; return current; @@ -32,7 +32,7 @@ export default function App() { const result = await ping(value); await ping(value); console.log(result); - setOutput((prev) => ({ ...prev, result: value.toString() === result[0].toString() })); + setOutput(prev => ({ ...prev, result: value.toString() === result[0].toString() })); }); return ( diff --git a/apps/tests/src/routes/server-function-plugin.tsx b/apps/tests/src/routes/server-function-plugin.tsx index e9b8d4b2b..a43c1935d 100644 --- a/apps/tests/src/routes/server-function-plugin.tsx +++ b/apps/tests/src/routes/server-function-plugin.tsx @@ -1,19 +1,15 @@ import { createEffect, createSignal } from "solid-js"; async function sleep(value: unknown, ms: number) { - return new Promise((res) => { + return new Promise(res => { setTimeout(res, ms, value); - }) + }); } async function ping(value: URLSearchParams, clone: URLSearchParams) { "use server"; - const current = [ - value.toString() === clone.toString(), - value, - clone, - ] as const; + const current = [value.toString() === clone.toString(), value, clone] as const; return current; } @@ -23,11 +19,11 @@ export default function App() { createEffect(async () => { const value = new URLSearchParams([ - ['foo', 'bar'], - ['hello', 'world'], + ["foo", "bar"], + ["hello", "world"], ]); const result = await ping(value, value); - setOutput((prev) => ({ ...prev, result: result[0] })); + setOutput(prev => ({ ...prev, result: result[0] })); }); return ( diff --git a/apps/tests/src/routes/server-function-query-toplevel.tsx b/apps/tests/src/routes/server-function-query-toplevel.tsx index 2d55e3532..21383adb3 100644 --- a/apps/tests/src/routes/server-function-query-toplevel.tsx +++ b/apps/tests/src/routes/server-function-query-toplevel.tsx @@ -5,7 +5,7 @@ export default function App() { const [output, setOutput] = createSignal(); createEffect(() => { - setOutput('testQuery' in testModule); + setOutput("testQuery" in testModule); }); return ( diff --git a/apps/tests/src/routes/server-function-readable-stream.tsx b/apps/tests/src/routes/server-function-readable-stream.tsx index 53d39dcf0..05fce7b42 100644 --- a/apps/tests/src/routes/server-function-readable-stream.tsx +++ b/apps/tests/src/routes/server-function-readable-stream.tsx @@ -1,9 +1,9 @@ import { createEffect, createSignal } from "solid-js"; async function sleep(value: T, ms: number) { - return new Promise((res) => { + return new Promise(res => { setTimeout(res, ms, value); - }) + }); } async function ping(value: ReadableStream) { @@ -18,17 +18,17 @@ export default function App() { const result = await ping( new ReadableStream({ async start(controller) { - controller.enqueue(await sleep('foo', 100)); - controller.enqueue(await sleep('bar', 100)); - controller.enqueue(await sleep('baz', 100)); + controller.enqueue(await sleep("foo", 100)); + controller.enqueue(await sleep("bar", 100)); + controller.enqueue(await sleep("baz", 100)); controller.close(); }, - }) + }), ); const reader = result.getReader(); const first = await reader.read(); - setOutput((prev) => ({ ...prev, result: first.value === 'foo' })); + setOutput(prev => ({ ...prev, result: first.value === "foo" })); }); return ( diff --git a/apps/tests/tsconfig.json b/apps/tests/tsconfig.json index 376a974e4..53bd387e8 100644 --- a/apps/tests/tsconfig.json +++ b/apps/tests/tsconfig.json @@ -13,7 +13,7 @@ "types": ["vitest/globals", "@testing-library/jest-dom", "@solidjs/start/env"], "isolatedModules": true, "paths": { - "~/*": ["./src/*"], - }, - }, + "~/*": ["./src/*"] + } + } } diff --git a/package.json b/package.json index 5d235c36b..a3aed91a5 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "solid-start-monorepo", - "description": "monorepo for the SolidStart ecosystem", "version": "0.2.0", - "author": "Ryan Carniato", - "type": "module", + "private": true, + "description": "monorepo for the SolidStart ecosystem", "license": "MIT", + "author": "Ryan Carniato", "repository": { "type": "git", "url": "https://github.com/solidjs/solid-start" }, - "private": true, + "type": "module", "scripts": { "bump": "node scripts/bump.js", "build": "pnpm run packages:build", @@ -25,7 +25,8 @@ "packages:clean": "pnpx rimraf ./packages/*/node_modules/ ./packages/*/dist/", "clean:test": "pnpx rimraf .tmp", "release": "pnpm build && changeset publish", - "format": "pnpm oxfmt", + "format": "oxfmt --write", + "format:check": "oxfmt --check", "rewrite-exports": "pnpm --filter='./packages/*' -c exec \"echo \\$(cat package.json | jq '.exports = .publishConfig.exports') > package.json\"", "vite-ecosystem-ci:build": "pnpm run build:all && pnpm --filter fixture-basic build", "vite-ecosystem-ci:before-test": "pnpm --filter tests exec playwright install chromium", @@ -40,8 +41,8 @@ "typescript": "^7.0.2" }, "engines": { - "pnpm": "^11.17.0", - "node": ">=24" + "node": ">=24", + "pnpm": "^11.17.0" }, "packageManager": "pnpm@11.17.0" } diff --git a/packages/start/package.json b/packages/start/package.json index c7c6c0854..41121ad74 100644 --- a/packages/start/package.json +++ b/packages/start/package.json @@ -1,26 +1,17 @@ { "name": "@solidjs/start", "version": "2.0.0-rc.3", - "type": "module", - "files": [ - "dist", - "env.d.ts", - "CHANGELOG.md" - ], "repository": { "type": "git", "url": "git+https://github.com/solidjs/solid-start.git", "directory": "packages/start" }, - "scripts": { - "build": "pnpm validate-imports && tsc && node scripts/build.js", - "dev": "tsc --watch", - "test": "vitest", - "test:ci": "vitest run", - "typecheck": "tsc --noEmit", - "typecheck:dist": "pnpm build && pnpx @arethetypeswrong/cli --pack . --profile esm-only", - "validate-imports": "node scripts/validate-imports.js" - }, + "files": [ + "dist", + "env.d.ts", + "CHANGELOG.md" + ], + "type": "module", "exports": { ".": "./src/index.tsx", "./config": "./dist/config/index.js", @@ -36,7 +27,6 @@ "./fns/client": "./src/fns/client.ts" }, "publishConfig": { - "access": "public", "exports": { ".": "./dist/index.jsx", "./config": "./dist/config/index.js", @@ -50,7 +40,17 @@ "./env": "./env.d.ts", "./fns/server": "./dist/fns/server.js", "./fns/client": "./dist/fns/client.js" - } + }, + "access": "public" + }, + "scripts": { + "build": "pnpm validate-imports && tsc && node scripts/build.js", + "dev": "tsc --watch", + "test": "vitest", + "test:ci": "vitest run", + "typecheck": "tsc --noEmit", + "typecheck:dist": "pnpm build && pnpx @arethetypeswrong/cli --pack . --profile esm-only", + "validate-imports": "node scripts/validate-imports.js" }, "dependencies": { "@babel/core": "^7.29.7", @@ -79,9 +79,6 @@ "terracotta": "^1.1.1", "vite-plugin-solid": "^2.11.13" }, - "engines": { - "node": ">=24" - }, "devDependencies": { "@types/babel__core": "^7.20.5", "@types/node": "^26.1.1", @@ -90,5 +87,8 @@ }, "peerDependencies": { "vite": "^8 || ^9" + }, + "engines": { + "node": ">=24" } } diff --git a/packages/start/src/client/mount.ts b/packages/start/src/client/mount.ts index 7e17df7c7..6836790bf 100644 --- a/packages/start/src/client/mount.ts +++ b/packages/start/src/client/mount.ts @@ -1 +1 @@ -export { hydrate as mount } from "solid-js/web" +export { hydrate as mount } from "solid-js/web"; diff --git a/packages/start/src/config/boundary-modules.spec.ts b/packages/start/src/config/boundary-modules.spec.ts index 830eb99a9..ca62366d5 100644 --- a/packages/start/src/config/boundary-modules.spec.ts +++ b/packages/start/src/config/boundary-modules.spec.ts @@ -42,9 +42,7 @@ describe("boundaryModules", () => { it("marks Start's server-only entry points with server-only", () => { for (const entry of ["http/index.ts", "middleware/index.ts"]) { const source = readFileSync(join(import.meta.dirname, "..", entry), "utf-8"); - expect(source, `src/${entry} must import "server-only"`).toMatch( - /^import "server-only";$/m, - ); + expect(source, `src/${entry} must import "server-only"`).toMatch(/^import "server-only";$/m); } }); }); diff --git a/packages/start/src/config/env.ts b/packages/start/src/config/env.ts index aa6057dcd..f6d763de8 100644 --- a/packages/start/src/config/env.ts +++ b/packages/start/src/config/env.ts @@ -82,13 +82,13 @@ export function envPlugin(options?: EnvPluginOptions): Plugin { } const vars = currentOptions.server?.load ? currentOptions.server.load(env) - : loadEnv(env, '.', serverPrefix); + : loadEnv(env, ".", serverPrefix); return convertObjectToModule(vars); } if (filename === CLIENT_ENV) { const vars = currentOptions.client?.load ? currentOptions.client.load(env) - : loadEnv(env, '.', clientPrefix); + : loadEnv(env, ".", clientPrefix); return convertObjectToModule(vars); } if (filename === SERVER_RUNTIME_LOADER) { diff --git a/packages/start/src/config/manifest.ts b/packages/start/src/config/manifest.ts index e8c942fb2..be532924e 100644 --- a/packages/start/src/config/manifest.ts +++ b/packages/start/src/config/manifest.ts @@ -49,28 +49,35 @@ export function manifest(start: SolidStartOptions): PluginOption { if (!entry) throw new Error("No client entry found"); let rawManifest: string | undefined; - const viteMajor = parseInt(viteVersion.split('.')[0]!, 10); + const viteMajor = parseInt(viteVersion.split(".")[0]!, 10); - const manifestKey = Object.keys(globalThis.START_CLIENT_BUNDLE).find(k => k.endsWith("manifest.json")); + const manifestKey = Object.keys(globalThis.START_CLIENT_BUNDLE).find(k => + k.endsWith("manifest.json"), + ); if (manifestKey && viteMajor < 8) { const manifestAsset = globalThis.START_CLIENT_BUNDLE[manifestKey] as any; rawManifest = manifestAsset.source as string; } else { - try { - const appRoot = (start as any).appRoot || "./src"; - let outDir = ".solid-start/client"; - if (devServer?.environments?.client?.config?.build?.outDir) { - outDir = devServer.environments.client.config.build.outDir; - } else if (this.environment?.config?.build?.outDir && this.environment?.config?.consumer === "client") { - outDir = this.environment.config.build.outDir; - } else if ((globalThis as any).START_CLIENT_OUT_DIR) { - outDir = (globalThis as any).START_CLIENT_OUT_DIR; - } - const manifestPath = path.resolve(appRoot, "..", outDir, ".vite/manifest.json"); - rawManifest = fs.readFileSync(manifestPath, "utf-8"); - } catch (e) { - throw new Error(`Manifest asset not found in bundle and could not be read from disk. Keys: ${Object.keys(globalThis.START_CLIENT_BUNDLE).join(", ")}. Error: ${e}`); - } + try { + const appRoot = (start as any).appRoot || "./src"; + let outDir = ".solid-start/client"; + if (devServer?.environments?.client?.config?.build?.outDir) { + outDir = devServer.environments.client.config.build.outDir; + } else if ( + this.environment?.config?.build?.outDir && + this.environment?.config?.consumer === "client" + ) { + outDir = this.environment.config.build.outDir; + } else if ((globalThis as any).START_CLIENT_OUT_DIR) { + outDir = (globalThis as any).START_CLIENT_OUT_DIR; + } + const manifestPath = path.resolve(appRoot, "..", outDir, ".vite/manifest.json"); + rawManifest = fs.readFileSync(manifestPath, "utf-8"); + } catch (e) { + throw new Error( + `Manifest asset not found in bundle and could not be read from disk. Keys: ${Object.keys(globalThis.START_CLIENT_BUNDLE).join(", ")}. Error: ${e}`, + ); + } } if (!rawManifest) { diff --git a/packages/start/src/directives/remove-unused-variables.ts b/packages/start/src/directives/remove-unused-variables.ts index bc7bfdcc0..312901d53 100644 --- a/packages/start/src/directives/remove-unused-variables.ts +++ b/packages/start/src/directives/remove-unused-variables.ts @@ -11,7 +11,7 @@ function isInvalidForRemoval(path: babel.NodePath) { // This one is for destructured variables let target = path; if (isPathValid(path, t.isVariableDeclarator)) { - target = path.get('id'); + target = path.get("id"); } return isPathValid(target, t.isObjectPattern) || isPathValid(target, t.isArrayPattern); } @@ -38,7 +38,7 @@ export function removeUnusedVariables(program: babel.NodePath) { case "hoisted": case "module": if (binding.references === 0 && !binding.path.removed) { - const parent = binding.path.parentPath; + const parent = binding.path.parentPath; if (isPathValid(parent, t.isImportDeclaration)) { if (parent.node.specifiers.length === 1) { parent.remove(); @@ -46,7 +46,7 @@ export function removeUnusedVariables(program: babel.NodePath) { binding.path.remove(); } dirty = true; - } else if (!(isInvalidForRemoval(binding.path))) { + } else if (!isInvalidForRemoval(binding.path)) { binding.path.remove(); dirty = true; } diff --git a/packages/start/src/directives/xxhash32.ts b/packages/start/src/directives/xxhash32.ts index 21b1ef0d5..0cae220f3 100644 --- a/packages/start/src/directives/xxhash32.ts +++ b/packages/start/src/directives/xxhash32.ts @@ -20,8 +20,7 @@ function toUtf8(text: string): Uint8Array { } else if (c < 0xd800 || c >= 0xe000) { bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); } else { - const cp = - 0x10000 + (((c & 0x3ff) << 10) | (text.charCodeAt(++i) & 0x3ff)); + const cp = 0x10000 + (((c & 0x3ff) << 10) | (text.charCodeAt(++i) & 0x3ff)); bytes.push( 0xf0 | ((cp >> 18) & 0x7), 0x80 | ((cp >> 12) & 0x3f), @@ -37,11 +36,8 @@ function toUtf8(text: string): Uint8Array { * @param buffer - byte array or string * @param seed - optional seed (32-bit unsigned); */ -export default function xxHash32( - buffer: Uint8Array | string, - seed = 0, -): number { - buffer = typeof buffer === 'string' ? toUtf8(buffer) : buffer; +export default function xxHash32(buffer: Uint8Array | string, seed = 0): number { + buffer = typeof buffer === "string" ? toUtf8(buffer) : buffer; const b = buffer; /* @@ -160,9 +156,7 @@ export default function xxHash32( const laneP = laneN0 * PRIME32_3 + ((laneN1 * PRIME32_3) << 16); acc = (acc + laneP) & 0xffffffff; acc = (acc << 17) | (acc >>> 15); - acc = - ((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) & - 0xffffffff; + acc = ((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) & 0xffffffff; } /* @@ -180,9 +174,7 @@ export default function xxHash32( const lane = b[offset]; acc += lane * PRIME32_5; acc = (acc << 11) | (acc >>> 21); - acc = - ((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) & - 0xffffffff; + acc = ((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) & 0xffffffff; } /* @@ -200,15 +192,11 @@ export default function xxHash32( */ acc ^= acc >>> 15; - acc = - (((acc & 0xffff) * PRIME32_2) & 0xffffffff) + - (((acc >>> 16) * PRIME32_2) << 16); + acc = (((acc & 0xffff) * PRIME32_2) & 0xffffffff) + (((acc >>> 16) * PRIME32_2) << 16); acc ^= acc >>> 13; - acc = - (((acc & 0xffff) * PRIME32_3) & 0xffffffff) + - (((acc >>> 16) * PRIME32_3) << 16); + acc = (((acc & 0xffff) * PRIME32_3) & 0xffffffff) + (((acc >>> 16) * PRIME32_3) << 16); acc ^= acc >>> 16; // turn any negatives back into a positive number; return acc < 0 ? acc + 4294967296 : acc; -} \ No newline at end of file +} diff --git a/packages/start/src/fns/handler.spec.ts b/packages/start/src/fns/handler.spec.ts index 7f310f241..29dad2f25 100644 --- a/packages/start/src/fns/handler.spec.ts +++ b/packages/start/src/fns/handler.spec.ts @@ -59,7 +59,7 @@ describe("createSingleFlightHeaders", () => { it("should not mutate the original request headers", () => { const originalHeaders = new Headers({ "content-type": "application/json", - "cookie": "session=abc123", + cookie: "session=abc123", "cf-ray": "abc123", "cf-cache-status": "HIT", }); diff --git a/packages/start/src/fns/handler.ts b/packages/start/src/fns/handler.ts index e78aa35d6..7c308edb2 100644 --- a/packages/start/src/fns/handler.ts +++ b/packages/start/src/fns/handler.ts @@ -133,18 +133,14 @@ export async function handleServerFunction(h3Event: H3Event) { // forward headers if ((x as any).headers) mergeResponseHeaders(h3Event, (x as any).headers); // forward non-redirect statuses - if ( - (x as any).status && - (!instance || (x as any).status < 300 || (x as any).status >= 400) - ) + if ((x as any).status && (!instance || (x as any).status < 300 || (x as any).status >= 400)) h3Event.res.status = (x as any).status; if ((x as any).customBody) { x = await (x as any).customBody(); } else if ((x as any).body == null) x = null; h3Event.res.headers.set("X-Error", "true"); } else if (instance) { - const error = - x instanceof Error ? x.message : typeof x === "string" ? x : "true"; + const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true"; h3Event.res.headers.set("X-Error", toHeaderValue(error)); } else { @@ -194,10 +190,7 @@ function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boole if (result.headers.has("Location")) { headers.set( `Location`, - new URL( - result.headers.get("Location")!, - url.origin + import.meta.env.BASE_URL, - ).toString(), + new URL(result.headers.get("Location")!, url.origin + import.meta.env.BASE_URL).toString(), ); statusCode = getExpectedRedirectStatus(result); } @@ -214,10 +207,7 @@ function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boole result: isError ? result.message : result, thrown: thrown, error: isError, - input: [ - ...parsed.slice(0, -1), - [...parsed[parsed.length - 1].entries()], - ], + input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]], }), )}; Secure; HttpOnly;`, ); @@ -243,7 +233,7 @@ export function createSingleFlightHeaders(sourceEvent: FetchEvent) { // useH3Internals = true; // sourceEvent.nativeEvent.node.req.headers.cookie = ""; // } - SetCookies.forEach((cookie) => { + SetCookies.forEach(cookie => { if (!cookie) return; // `parseSetCookie` returns undefined for forbidden cookie names and for // cookies with an empty name and value. @@ -268,10 +258,7 @@ export function createSingleFlightHeaders(sourceEvent: FetchEvent) { return headers; } -async function handleSingleFlight( - sourceEvent: FetchEvent, - result: any, -): Promise { +async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise { let revalidate: string[]; let url = new URL(sourceEvent.request.headers.get("referer")!).toString(); if (result instanceof Response) { diff --git a/packages/start/src/server/assets/render.tsx b/packages/start/src/server/assets/render.tsx index 63aa2a07f..70a81fa4f 100644 --- a/packages/start/src/server/assets/render.tsx +++ b/packages/start/src/server/assets/render.tsx @@ -22,11 +22,7 @@ const assetMap = { }; export function renderAsset(asset: Asset, nonce?: string) { - let { - tag, - attrs: { key, ...attrs } = { key: undefined }, - children, - } = asset as any; + let { tag, attrs: { key, ...attrs } = { key: undefined }, children } = asset as any; return (assetMap as any)[tag]({ attrs: { ...attrs, nonce }, key, children }); } diff --git a/packages/start/src/shared/clientOnly.ts b/packages/start/src/shared/clientOnly.ts index 899a1d545..e482815ce 100644 --- a/packages/start/src/shared/clientOnly.ts +++ b/packages/start/src/shared/clientOnly.ts @@ -28,7 +28,9 @@ export default function clientOnly>( onMount(() => setMounted(true)); return createMemo( () => ( - (Comp = comp()), (m = mounted()), untrack(() => (Comp && m ? Comp(rest) : props.fallback)) + (Comp = comp()), + (m = mounted()), + untrack(() => (Comp && m ? Comp(rest) : props.fallback)) ), ); }; diff --git a/packages/start/src/shared/dev-toolbar/error-viewer/CodeView.tsx b/packages/start/src/shared/dev-toolbar/error-viewer/CodeView.tsx index 83673540e..2d1289d20 100644 --- a/packages/start/src/shared/dev-toolbar/error-viewer/CodeView.tsx +++ b/packages/start/src/shared/dev-toolbar/error-viewer/CodeView.tsx @@ -72,7 +72,7 @@ export function CodeView(props: CodeViewProps): JSX.Element | null { for (let i = 0, len = lines.length; i < len; i++) { const el = lines[i] as HTMLElement; if (props.line - minLine() - 1 === i) { - el.dataset.startErrorViewerErrorLine = ''; + el.dataset.startErrorViewerErrorLine = ""; } } } diff --git a/packages/start/src/shared/dev-toolbar/functions/BlobViewer.css b/packages/start/src/shared/dev-toolbar/functions/BlobViewer.css index b440887f3..01ff66a87 100644 --- a/packages/start/src/shared/dev-toolbar/functions/BlobViewer.css +++ b/packages/start/src/shared/dev-toolbar/functions/BlobViewer.css @@ -1,4 +1,4 @@ [data-start-blob-viewer] svg { width: 1rem; height: 1rem; -} \ No newline at end of file +} diff --git a/packages/start/src/shared/dev-toolbar/functions/BlobViewer.tsx b/packages/start/src/shared/dev-toolbar/functions/BlobViewer.tsx index 890698a58..2a1bd2f03 100644 --- a/packages/start/src/shared/dev-toolbar/functions/BlobViewer.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/BlobViewer.tsx @@ -1,14 +1,11 @@ -import { createMemo, createResource, type JSX, onCleanup, Show, Suspense } from 'solid-js'; +import { createMemo, createResource, type JSX, onCleanup, Show, Suspense } from "solid-js"; import { Badge } from "../../ui/Badge.tsx"; import Button from "../../ui/Button.tsx"; -import './BlobViewer.css'; +import "./BlobViewer.css"; - -function DocumentIcon( - props: JSX.IntrinsicElements["svg"] & { title: string }, -): JSX.Element { +function DocumentIcon(props: JSX.IntrinsicElements["svg"] & { title: string }): JSX.Element { return ( {props.title} - + ); } @@ -46,33 +47,28 @@ function BlobViewerInner(props: BlobViewerInnerProps): JSX.Element { return ( - ) + ); } - export interface BlobViewerProps { source: Blob | File | Promise; } - export function BlobViewer(props: BlobViewerProps): JSX.Element { const [data] = createResource(() => props.source); return ( - - {(current) => } - + {current => } ); } diff --git a/packages/start/src/shared/dev-toolbar/functions/FormDataViewer.tsx b/packages/start/src/shared/dev-toolbar/functions/FormDataViewer.tsx index a896bbac7..3334561e6 100644 --- a/packages/start/src/shared/dev-toolbar/functions/FormDataViewer.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/FormDataViewer.tsx @@ -1,7 +1,7 @@ -import { createResource, For, type JSX, Show, Suspense } from 'solid-js'; -import { Section } from '../../ui/Section.tsx'; -import { BlobViewer } from './BlobViewer.tsx'; -import { PropertySeparator, SerovalValue } from './SerovalValue.tsx'; +import { createResource, For, type JSX, Show, Suspense } from "solid-js"; +import { Section } from "../../ui/Section.tsx"; +import { BlobViewer } from "./BlobViewer.tsx"; +import { PropertySeparator, SerovalValue } from "./SerovalValue.tsx"; interface FormDataViewerInnerProps { source: FormData; @@ -9,16 +9,18 @@ interface FormDataViewerInnerProps { function FormDataViewerInner(props: FormDataViewerInnerProps): JSX.Element { return ( -
+
{([key, value]) => (
- {typeof value === 'string' - ? - : } + {typeof value === "string" ? ( + + ) : ( + + )}
)}
@@ -36,9 +38,7 @@ export function FormDataViewer(props: FormDataViewerProps) { return ( - - {(current) => } - + {current => } ); -} \ No newline at end of file +} diff --git a/packages/start/src/shared/dev-toolbar/functions/HeadersViewer.tsx b/packages/start/src/shared/dev-toolbar/functions/HeadersViewer.tsx index d0109b65d..a8712b702 100644 --- a/packages/start/src/shared/dev-toolbar/functions/HeadersViewer.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/HeadersViewer.tsx @@ -1,7 +1,7 @@ import { For } from "solid-js"; import { PropertySeparator, SerovalValue } from "./SerovalValue.tsx"; -import './HeadersViewer.css'; +import "./HeadersViewer.css"; import { Text } from "../../ui/Text.tsx"; interface HeadersViewerProps { @@ -14,12 +14,12 @@ export function HeadersViewer(props: HeadersViewerProps) { {([key, value]) => (
- {key} + {key}
)}
-
+ ); } diff --git a/packages/start/src/shared/dev-toolbar/functions/HexViewer.tsx b/packages/start/src/shared/dev-toolbar/functions/HexViewer.tsx index 29bf21f87..020e6fe69 100644 --- a/packages/start/src/shared/dev-toolbar/functions/HexViewer.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/HexViewer.tsx @@ -1,25 +1,23 @@ import { createMemo, createResource, For, type JSX, Show, Suspense } from "solid-js"; import { Text } from "../../ui/Text.tsx"; -import './HexViewer.css'; - +import "./HexViewer.css"; function toHex(num: number, digits = 2): string { - return num.toString(16).padStart(digits, '0').toUpperCase(); + return num.toString(16).padStart(digits, "0").toUpperCase(); } function HexChunk(props: HexViewerInnerProps) { - const content = createMemo(() => { const byte1 = props.bytes[0] || 0; const byte2 = props.bytes[1] || 0; const byte3 = props.bytes[2] || 0; const byte4 = props.bytes[3] || 0; - return `${toHex(byte1)} ${toHex(byte2)} ${toHex(byte3)} ${toHex(byte4)}` + return `${toHex(byte1)} ${toHex(byte2)} ${toHex(byte3)} ${toHex(byte4)}`; }); return ( - + {content()} ); @@ -58,9 +56,7 @@ function HexText(props: HexViewerInnerProps) { return (
- - {text()} - + {text()}
); } @@ -81,14 +77,10 @@ export function HexViewerInner(props: HexViewerInnerProps): JSX.Element { return (
- - {(current) => } - + {current => }
- - {(current) => } - + {current => }
); @@ -103,9 +95,7 @@ export function HexViewer(props: HexViewerProps): JSX.Element { return ( - - {(current) => } - + {current => } ); } diff --git a/packages/start/src/shared/dev-toolbar/functions/SerovalValue.css b/packages/start/src/shared/dev-toolbar/functions/SerovalValue.css index b38afc019..17a44b954 100644 --- a/packages/start/src/shared/dev-toolbar/functions/SerovalValue.css +++ b/packages/start/src/shared/dev-toolbar/functions/SerovalValue.css @@ -1,5 +1,3 @@ - - [data-start-seroval-value] { display: flex; gap: 0.25rem; diff --git a/packages/start/src/shared/dev-toolbar/functions/SerovalValue.tsx b/packages/start/src/shared/dev-toolbar/functions/SerovalValue.tsx index a8b420a92..4685a97ea 100644 --- a/packages/start/src/shared/dev-toolbar/functions/SerovalValue.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/SerovalValue.tsx @@ -1,5 +1,5 @@ import { Text } from "../../ui/Text.tsx"; -import './SerovalValue.css'; +import "./SerovalValue.css"; interface SerovalValueProps { value: string | number | boolean | undefined | null; @@ -7,12 +7,12 @@ interface SerovalValueProps { export function SerovalValue(props: SerovalValueProps) { return ( - + {`${props.value}`} ); } export function PropertySeparator() { - return :; + return :; } diff --git a/packages/start/src/shared/dev-toolbar/functions/SerovalViewer.css b/packages/start/src/shared/dev-toolbar/functions/SerovalViewer.css index 2bcb7df04..f893feded 100644 --- a/packages/start/src/shared/dev-toolbar/functions/SerovalViewer.css +++ b/packages/start/src/shared/dev-toolbar/functions/SerovalViewer.css @@ -68,4 +68,3 @@ width: 1rem; height: 1rem; } - diff --git a/packages/start/src/shared/dev-toolbar/functions/URLSearchParamsViewer.tsx b/packages/start/src/shared/dev-toolbar/functions/URLSearchParamsViewer.tsx index 6d45ce585..1b2a0046a 100644 --- a/packages/start/src/shared/dev-toolbar/functions/URLSearchParamsViewer.tsx +++ b/packages/start/src/shared/dev-toolbar/functions/URLSearchParamsViewer.tsx @@ -1,6 +1,6 @@ -import { createResource, For, type JSX, Show, Suspense } from 'solid-js'; -import { Section } from '../../ui/Section.tsx'; -import { PropertySeparator, SerovalValue } from './SerovalValue.tsx'; +import { createResource, For, type JSX, Show, Suspense } from "solid-js"; +import { Section } from "../../ui/Section.tsx"; +import { PropertySeparator, SerovalValue } from "./SerovalValue.tsx"; interface URLSearchParamsViewerInnerProps { source: URLSearchParams; @@ -8,7 +8,7 @@ interface URLSearchParamsViewerInnerProps { function URLSearchParamsViewerInner(props: URLSearchParamsViewerInnerProps): JSX.Element { return ( -
+
{([key, value]) => ( @@ -33,9 +33,7 @@ export function URLSearchParamsViewer(props: URLSearchParamsViewerProps) { return ( - - {(current) => } - + {current => } ); -} \ No newline at end of file +} diff --git a/packages/start/src/shared/dev-toolbar/functions/styles.css b/packages/start/src/shared/dev-toolbar/functions/styles.css index 854f9d1bc..ae3bfe46a 100644 --- a/packages/start/src/shared/dev-toolbar/functions/styles.css +++ b/packages/start/src/shared/dev-toolbar/functions/styles.css @@ -101,7 +101,6 @@ } [data-start-function-instance-viewer-content] { - height: 100%; } diff --git a/packages/start/src/shared/dev-toolbar/functions/tracker.ts b/packages/start/src/shared/dev-toolbar/functions/tracker.ts index 2fd56f264..bf1d9471a 100644 --- a/packages/start/src/shared/dev-toolbar/functions/tracker.ts +++ b/packages/start/src/shared/dev-toolbar/functions/tracker.ts @@ -19,18 +19,12 @@ export type ServerFunctionCallListener = (event: ServerFunctionCall) => void; const LISTENERS = new Set(); -export function captureServerFunctionCall( - listener: ServerFunctionCallListener, -): () => void { +export function captureServerFunctionCall(listener: ServerFunctionCallListener): () => void { LISTENERS.add(listener); return () => LISTENERS.delete(listener); } -export function pushRequest( - id: string, - instance: string, - source: Request, -): void { +export function pushRequest(id: string, instance: string, source: Request): void { const event: ServerFunctionCall = { type: "request", id, @@ -43,11 +37,7 @@ export function pushRequest( } } -export function pushResponse( - id: string, - instance: string, - source: Response, -): void { +export function pushResponse(id: string, instance: string, source: Response): void { const event: ServerFunctionCall = { type: "response", id, diff --git a/packages/start/src/shared/ui/Badge.css b/packages/start/src/shared/ui/Badge.css index cee81bcf5..845eb3e40 100644 --- a/packages/start/src/shared/ui/Badge.css +++ b/packages/start/src/shared/ui/Badge.css @@ -27,7 +27,6 @@ --foreground: oklch(47.6% 0.114 61.907); } - [data-start-badge="info"] { --background: oklch(97% 0.014 254.604); --foreground: oklch(48.8% 0.243 264.376); diff --git a/packages/start/src/shared/ui/Badge.tsx b/packages/start/src/shared/ui/Badge.tsx index 5de35361e..d75b6d352 100644 --- a/packages/start/src/shared/ui/Badge.tsx +++ b/packages/start/src/shared/ui/Badge.tsx @@ -1,16 +1,18 @@ -import type { JSX } from 'solid-js'; -import './Badge.css'; -import { Text } from './Text.tsx'; - +import type { JSX } from "solid-js"; +import "./Badge.css"; +import { Text } from "./Text.tsx"; export interface BadgeProps { - type: 'info' | 'success' | 'failure' | 'warning'; + type: "info" | "success" | "failure" | "warning"; children: JSX.Element; } export function Badge(props: BadgeProps): JSX.Element { return ( - + {props.children} ); diff --git a/packages/start/src/shared/ui/Button.tsx b/packages/start/src/shared/ui/Button.tsx index a32756439..4468aebf8 100644 --- a/packages/start/src/shared/ui/Button.tsx +++ b/packages/start/src/shared/ui/Button.tsx @@ -1,8 +1,8 @@ import { Button as BaseButton } from "terracotta"; import "./Button.css"; -const Button: typeof BaseButton = (props) => ( - +const Button: typeof BaseButton = props => ( + ); export default Button; diff --git a/packages/start/src/shared/ui/Cascade.tsx b/packages/start/src/shared/ui/Cascade.tsx index 459b2af25..5bfd5f8a2 100644 --- a/packages/start/src/shared/ui/Cascade.tsx +++ b/packages/start/src/shared/ui/Cascade.tsx @@ -1,13 +1,8 @@ -import { - Select as BaseSelect, - SelectOption as BaseSelectOption, -} from "terracotta"; +import { Select as BaseSelect, SelectOption as BaseSelectOption } from "terracotta"; import "./Cascade.css"; -export const Cascade: typeof BaseSelect = (props) => ( - -); -export const CascadeOption: typeof BaseSelectOption = (props) => ( +export const Cascade: typeof BaseSelect = props => ; +export const CascadeOption: typeof BaseSelectOption = props => ( ); diff --git a/packages/start/src/shared/ui/Dialog.css b/packages/start/src/shared/ui/Dialog.css index 198f22735..8bfff92f5 100644 --- a/packages/start/src/shared/ui/Dialog.css +++ b/packages/start/src/shared/ui/Dialog.css @@ -5,8 +5,7 @@ overflow-y: auto; } - -[data-start-dialog]>div { +[data-start-dialog] > div { position: relative; display: flex; align-items: center; diff --git a/packages/start/src/shared/ui/Dialog.tsx b/packages/start/src/shared/ui/Dialog.tsx index 1e765a05b..23078dc4e 100644 --- a/packages/start/src/shared/ui/Dialog.tsx +++ b/packages/start/src/shared/ui/Dialog.tsx @@ -6,12 +6,10 @@ import { import "./Dialog.css"; -export const Dialog: typeof BaseDialog = (props) => ( - -); -export const DialogOverlay: typeof BaseDialogOverlay = (props) => ( +export const Dialog: typeof BaseDialog = props => ; +export const DialogOverlay: typeof BaseDialogOverlay = props => ( ); -export const DialogPanel: typeof BaseDialogPanel = (props) => ( +export const DialogPanel: typeof BaseDialogPanel = props => ( ); diff --git a/packages/start/src/shared/ui/IconButton.tsx b/packages/start/src/shared/ui/IconButton.tsx index 57417f601..7b0117367 100644 --- a/packages/start/src/shared/ui/IconButton.tsx +++ b/packages/start/src/shared/ui/IconButton.tsx @@ -1,8 +1,8 @@ import { Button as BaseButton } from "terracotta"; import "./IconButton.css"; -const IconButton: typeof BaseButton = (props) => ( - +const IconButton: typeof BaseButton = props => ( + ); export default IconButton; diff --git a/packages/start/src/shared/ui/Placeholder.css b/packages/start/src/shared/ui/Placeholder.css index 178046658..cf51a4bf2 100644 --- a/packages/start/src/shared/ui/Placeholder.css +++ b/packages/start/src/shared/ui/Placeholder.css @@ -9,4 +9,4 @@ [data-start-placeholder] > span { text-align: center; -} \ No newline at end of file +} diff --git a/packages/start/src/shared/ui/Placeholder.tsx b/packages/start/src/shared/ui/Placeholder.tsx index b2c28be66..9b746fa74 100644 --- a/packages/start/src/shared/ui/Placeholder.tsx +++ b/packages/start/src/shared/ui/Placeholder.tsx @@ -1,14 +1,10 @@ -import type { JSX } from 'solid-js'; -import './Placeholder.css'; +import type { JSX } from "solid-js"; +import "./Placeholder.css"; export interface PlaceholderProps { children?: JSX.Element; } export default function Placeholder(props: PlaceholderProps): JSX.Element { - return ( -
- {props.children} -
- ); -} \ No newline at end of file + return
{props.children}
; +} diff --git a/packages/start/src/shared/ui/Section.css b/packages/start/src/shared/ui/Section.css index 67b6878b0..fb573550f 100644 --- a/packages/start/src/shared/ui/Section.css +++ b/packages/start/src/shared/ui/Section.css @@ -7,7 +7,6 @@ text-transform: uppercase; } - [data-start-section-content] { margin-left: 0.5rem; padding-left: 0.5rem; diff --git a/packages/start/src/shared/ui/Section.tsx b/packages/start/src/shared/ui/Section.tsx index 0524ed4f0..3cbb54216 100644 --- a/packages/start/src/shared/ui/Section.tsx +++ b/packages/start/src/shared/ui/Section.tsx @@ -1,23 +1,21 @@ import type { JSX } from "solid-js"; import { Text, type TextProps } from "./Text.tsx"; -import './Section.css'; +import "./Section.css"; export interface SectionProps { title: string; - options?: TextProps<'span'>['options']; + options?: TextProps<"span">["options"]; children: JSX.Element; } export function Section(props: SectionProps): JSX.Element { return (
- + {props.title} -
- {props.children} -
+
{props.children}
); } diff --git a/packages/start/src/shared/ui/Select.tsx b/packages/start/src/shared/ui/Select.tsx index 2d648832a..90ba5cd76 100644 --- a/packages/start/src/shared/ui/Select.tsx +++ b/packages/start/src/shared/ui/Select.tsx @@ -1,13 +1,8 @@ -import { - Select as BaseSelect, - SelectOption as BaseSelectOption, -} from "terracotta"; +import { Select as BaseSelect, SelectOption as BaseSelectOption } from "terracotta"; import "./Select.css"; -export const Select: typeof BaseSelect = (props) => ( - -); -export const SelectOption: typeof BaseSelectOption = (props) => ( - +export const Select: typeof BaseSelect = props => ; +export const SelectOption: typeof BaseSelectOption = props => ( + ); diff --git a/packages/start/src/shared/ui/Table.tsx b/packages/start/src/shared/ui/Table.tsx index 87eeb18f0..5609f174f 100644 --- a/packages/start/src/shared/ui/Table.tsx +++ b/packages/start/src/shared/ui/Table.tsx @@ -1,35 +1,27 @@ -import type { ComponentProps, JSX } from 'solid-js'; +import type { ComponentProps, JSX } from "solid-js"; -import './Table.css'; +import "./Table.css"; -type TableProps = ComponentProps<'div'>; +type TableProps = ComponentProps<"div">; export function Table(props: TableProps): JSX.Element { - return ( -
- ); + return
; } -type TableHeaderProps = ComponentProps<'div'>; +type TableHeaderProps = ComponentProps<"div">; export function TableHeader(props: TableHeaderProps): JSX.Element { - return ( -
- ); + return
; } -type TableRowProps = ComponentProps<'div'>; +type TableRowProps = ComponentProps<"div">; export function TableRow(props: TableRowProps): JSX.Element { - return ( -
- ); + return
; } -type TableCellProps = ComponentProps<'div'>; +type TableCellProps = ComponentProps<"div">; export function TableCell(props: TableCellProps): JSX.Element { - return ( -
- ); + return
; } diff --git a/packages/start/src/shared/ui/Tabs.tsx b/packages/start/src/shared/ui/Tabs.tsx index 1ef39f24e..1e9eaeb42 100644 --- a/packages/start/src/shared/ui/Tabs.tsx +++ b/packages/start/src/shared/ui/Tabs.tsx @@ -7,16 +7,11 @@ import { import "./Tabs.css"; -export const Tab: typeof BaseTab = (props) => ( - -); -export const TabGroup: typeof BaseTabGroup = (props) => ( +export const Tab: typeof BaseTab = props => ; +export const TabGroup: typeof BaseTabGroup = props => ( ); -export const TabPanel: typeof BaseTabPanel = (props) => ( +export const TabPanel: typeof BaseTabPanel = props => ( ); -export const TabList: typeof BaseTabList = (props) => ( - -); - +export const TabList: typeof BaseTabList = props => ; diff --git a/packages/start/src/shared/ui/Text.css b/packages/start/src/shared/ui/Text.css index a67b817da..c5c8e1daa 100644 --- a/packages/start/src/shared/ui/Text.css +++ b/packages/start/src/shared/ui/Text.css @@ -24,13 +24,17 @@ } [data-start-text-font="sans"] { - font-family: system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + font-family: + system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; } [data-start-text-font="serif"] { - font-family: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; + font-family: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; } [data-start-text-font="mono"] { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + font-family: + ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", + monospace; } [data-start-text-weight="thin"] { diff --git a/packages/start/src/shared/ui/Text.tsx b/packages/start/src/shared/ui/Text.tsx index 44bad1b2d..b33fd9400 100644 --- a/packages/start/src/shared/ui/Text.tsx +++ b/packages/start/src/shared/ui/Text.tsx @@ -1,37 +1,49 @@ -import { type ComponentProps, createMemo, type JSX, splitProps } from 'solid-js'; -import { Dynamic } from 'solid-js/web'; +import { type ComponentProps, createMemo, type JSX, splitProps } from "solid-js"; +import { Dynamic } from "solid-js/web"; -import './Text.css'; +import "./Text.css"; -export type TextProps = ComponentProps & { +export type TextProps = ComponentProps & { options?: { as?: T; - size?: 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl'; - font?: 'sans' | 'serif' | 'mono'; - weight?: 'thin' | 'extralight' | 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold'; - wrap?: 'wrap' | 'nowrap'; + size?: "xs" | "sm" | "base" | "lg" | "xl" | "2xl"; + font?: "sans" | "serif" | "mono"; + weight?: + | "thin" + | "extralight" + | "light" + | "normal" + | "medium" + | "semibold" + | "bold" + | "extrabold"; + wrap?: "wrap" | "nowrap"; }; }; -export function Text(props: TextProps): JSX.Element { - const [current, rest] = splitProps(props, ['options']); +export function Text( + props: TextProps, +): JSX.Element { + const [current, rest] = splitProps(props, ["options"]); const customization = createMemo>(() => { - const options = Object.assign({}, { - size: 'base', - font: 'mono', - weight: 'normal', - wrap: 'wrap', - }, current.options); + const options = Object.assign( + {}, + { + size: "base", + font: "mono", + weight: "normal", + wrap: "wrap", + }, + current.options, + ); const entries = Object.entries(options); - return Object.fromEntries(entries.map(([key, value]) => [`data-start-text-${key}`, value])) as TextProps; + return Object.fromEntries( + entries.map(([key, value]) => [`data-start-text-${key}`, value]), + ) as TextProps; }); return ( - + ); } diff --git a/packages/start/src/utils/debounce.ts b/packages/start/src/utils/debounce.ts index 09ac249b5..fc1656936 100644 --- a/packages/start/src/utils/debounce.ts +++ b/packages/start/src/utils/debounce.ts @@ -5,6 +5,6 @@ export const debounce = void>(cb: T, debounceMs: let timeout: NodeJS.Timeout | undefined; return (...args: Parameters) => { clearTimeout(timeout); - timeout = setTimeout(() => cb(...args), debounceMs) - } -} + timeout = setTimeout(() => cb(...args), debounceMs); + }; +}; diff --git a/packages/start/tsconfig.json b/packages/start/tsconfig.json index e2ce74e9d..7d1e2f82d 100644 --- a/packages/start/tsconfig.json +++ b/packages/start/tsconfig.json @@ -17,7 +17,7 @@ "types": ["vite/client"], "allowImportingTsExtensions": true, "rewriteRelativeImportExtensions": true, - "rootDir": "./src", + "rootDir": "./src" }, "include": ["env.d.ts", "./src", "./src/env.d.ts"], "exclude": ["**/*.spec.ts"] diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f5da12500..e4a9cc9bf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,15 +2,15 @@ packages: - packages/* - apps/* - apps/fixtures/* - - '!**/.tmp/**' + - "!**/.tmp/**" allowBuilds: - '@parcel/watcher': true + "@parcel/watcher": true esbuild: true ignoredBuiltDependencies: - - '@prisma/client' - - '@prisma/engines' + - "@prisma/client" + - "@prisma/engines" - better-sqlite3 - msw - prisma @@ -20,6 +20,6 @@ minimumReleaseAgeExclude: - h3@2.0.1-rc.26 onlyBuiltDependencies: - - '@parcel/watcher' + - "@parcel/watcher" - cypress - esbuild