Skip to content

Commit 6c1d393

Browse files
committed
chore: zod checking add-ons and starters
1 parent e1dd57b commit 6c1d393

File tree

21 files changed

+290
-153
lines changed

21 files changed

+290
-153
lines changed

CONTRIBUTING.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,19 @@
1919
- Run `pnpm dev` at that top level to build everything in watch mode
2020
- Run `pnpm build` and `pnpm test` to make sure the changes work
2121
- Check your work and PR
22+
23+
# Testing Add-ons and Starters
24+
25+
Create the add-on or starter using the CLI. Then serve it locally from the project directory using `npx static-server`.
26+
27+
Then, when creating apps with add-ons:
28+
29+
```bash
30+
node [root of the monorepo]/cli/create-tsrouter-app/dist/index.js app-js --add-ons http://localhost:9080/add-on.json
31+
```
32+
33+
And when creating apps with a starter:
34+
35+
```bash
36+
node [root of the monorepo]/cli/create-tsrouter-app/dist/index.js app-js --starter http://localhost:9080/starter.json
37+
```

examples/legend-state-add-on/.add-on/info.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"link": "https://github.com/jane-smith/legend-state-add-on-add-on",
99
"shadcnComponents": [],
1010
"framework": "react-cra",
11-
"modes": ["file-router"],
11+
"modes": [
12+
"file-router"
13+
],
1214
"routes": [
1315
{
1416
"url": "/demo/legend-state",
@@ -26,4 +28,4 @@
2628
}
2729
},
2830
"dependsOn": []
29-
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ThemeProvider, createTheme } from '@mui/material/styles'
2+
3+
const theme = createTheme({
4+
palette: {
5+
primary: {
6+
main: '#000000',
7+
},
8+
},
9+
})
10+
11+
export default function MuiProvider({
12+
children,
13+
}: {
14+
children: React.ReactNode
15+
}) {
16+
return <ThemeProvider theme={theme}>{children}</ThemeProvider>
17+
}

examples/mui-add-on/.add-on/assets/src/routes/demo.mui.tsx.ejs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
import Button from "@mui/material/Button";
2-
import Box from "@mui/material/Box";
3-
import { createFileRoute } from "@tanstack/react-router";
1+
import { <% if (fileRouter) { %>createFileRoute<% } else { %>createRoute<% } %> } from '@tanstack/react-router'
2+
3+
import Button from '@mui/material/Button'
4+
import Box from '@mui/material/Box'
45

56
<% if (codeRouter) { %>
67
import type { RootRoute } from '@tanstack/react-router'
78
<% } else { %>
89
export const Route = createFileRoute('/demo/mui')({
910
component: MUIDemo,
1011
})
11-
<% } %>;
12+
<% } %>
1213

1314
function MUIDemo() {
1415
return (
1516
<Box sx={{ px: 2, py: 4 }}>
1617
<Button variant="contained">Hello world</Button>
1718
</Box>
18-
);
19+
)
1920
}
2021

2122
<% if (codeRouter) { %>

examples/mui-add-on/.add-on/info.json

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
{
2-
"name": "mui-add-on",
2+
"id": "mui-add-on-add-on",
3+
"name": "mui-add-on-add-on",
34
"version": "0.0.1",
45
"description": "Add-on",
56
"author": "Jane Smith <[email protected]>",
67
"license": "MIT",
78
"link": "https://github.com/jane-smith/mui-add-on-add-on",
8-
"command": {},
99
"shadcnComponents": [],
10-
"modes": ["file-router", "code-router"],
10+
"framework": "react-cra",
11+
"modes": ["file-router"],
1112
"routes": [
1213
{
1314
"url": "/demo/mui",
14-
"name": "mui"
15+
"name": "mui",
16+
"jsName": "Mui",
17+
"path": "./src/routes/demo.mui.tsx"
18+
}
19+
],
20+
"integrations": [
21+
{
22+
"type": "provider",
23+
"jsName": "MuiProvider",
24+
"path": "./src/components/mui-provider.tsx"
1525
}
1626
],
1727
"warning": "",
18-
"variables": {},
1928
"phase": "add-on",
2029
"type": "add-on",
21-
"framework": "react-cra",
2230
"packageAdditions": {
23-
"scripts": {},
2431
"dependencies": {
2532
"@emotion/styled": "^11.14.0",
2633
"@fontsource/roboto": "^5.2.5",
2734
"@mui/icons-material": "^7.0.1",
2835
"@mui/material": "^7.0.1",
2936
"@mui/styled-engine-sc": "^7.0.1",
3037
"styled-components": "^6.1.16"
31-
},
32-
"devDependencies": {}
33-
}
38+
}
39+
},
40+
"dependsOn": []
3441
}

examples/mui-add-on/.cta.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"framework": "react",
2+
"framework": "react-cra",
33
"projectName": "mui-add-on",
44
"typescript": true,
55
"tailwind": true,
@@ -10,4 +10,4 @@
1010
"variableValues": {},
1111
"version": 1,
1212
"existingAddOns": []
13-
}
13+
}

examples/mui-add-on/add-on.json

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,48 @@
11
{
2-
"name": "mui-add-on",
2+
"id": "mui-add-on-add-on",
3+
"name": "mui-add-on-add-on",
34
"version": "0.0.1",
45
"description": "Add-on",
56
"author": "Jane Smith <[email protected]>",
67
"license": "MIT",
78
"link": "https://github.com/jane-smith/mui-add-on-add-on",
8-
"command": {},
99
"shadcnComponents": [],
10-
"templates": [
11-
"file-router",
12-
"code-router"
10+
"framework": "react-cra",
11+
"modes": [
12+
"file-router"
1313
],
1414
"routes": [
1515
{
1616
"url": "/demo/mui",
17-
"name": "mui"
17+
"name": "mui",
18+
"jsName": "Mui",
19+
"path": "./src/routes/demo.mui.tsx"
20+
}
21+
],
22+
"integrations": [
23+
{
24+
"type": "provider",
25+
"jsName": "MuiProvider",
26+
"path": "./src/components/mui-provider.tsx"
1827
}
1928
],
2029
"warning": "",
21-
"variables": {},
2230
"phase": "add-on",
2331
"type": "add-on",
24-
"framework": "react",
2532
"packageAdditions": {
26-
"scripts": {},
2733
"dependencies": {
2834
"@emotion/styled": "^11.14.0",
2935
"@fontsource/roboto": "^5.2.5",
3036
"@mui/icons-material": "^7.0.1",
3137
"@mui/material": "^7.0.1",
3238
"@mui/styled-engine-sc": "^7.0.1",
3339
"styled-components": "^6.1.16"
34-
},
35-
"devDependencies": {}
40+
}
3641
},
42+
"dependsOn": [],
3743
"files": {
38-
"./src/routes/demo.mui.tsx.ejs": "import Button from \"@mui/material/Button\";\nimport Box from \"@mui/material/Box\";\nimport { createFileRoute } from \"@tanstack/react-router\";\n\n<% if (codeRouter) { %>\nimport type { RootRoute } from '@tanstack/react-router'\n<% } else { %>\nexport const Route = createFileRoute('/demo/mui')({\n component: MUIDemo,\n})\n<% } %>;\n\nfunction MUIDemo() {\n return (\n <Box sx={{ px: 2, py: 4 }}>\n <Button variant=\"contained\">Hello world</Button>\n </Box>\n );\n}\n\n<% if (codeRouter) { %>\nexport default (parentRoute: RootRoute) => createRoute({\n path: '/demo/mui',\n \n component: MUIDemo,\n\n getParentRoute: () => parentRoute,\n})\n<% } %>\n"
44+
"./src/components/mui-provider.tsx": "import { ThemeProvider, createTheme } from '@mui/material/styles'\n\nconst theme = createTheme({\n palette: {\n primary: {\n main: '#000000',\n },\n },\n})\n\nexport default function MuiProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n return <ThemeProvider theme={theme}>{children}</ThemeProvider>\n}\n",
45+
"./src/routes/demo.mui.tsx.ejs": "import { <% if (fileRouter) { %>createFileRoute<% } else { %>createRoute<% } %> } from '@tanstack/react-router'\n\nimport Button from '@mui/material/Button'\nimport Box from '@mui/material/Box'\n\n<% if (codeRouter) { %>\nimport type { RootRoute } from '@tanstack/react-router'\n<% } else { %>\nexport const Route = createFileRoute('/demo/mui')({\n component: MUIDemo,\n})\n<% } %>\n\nfunction MUIDemo() {\n return (\n <Box sx={{ px: 2, py: 4 }}>\n <Button variant=\"contained\">Hello world</Button>\n </Box>\n )\n}\n\n<% if (codeRouter) { %>\nexport default (parentRoute: RootRoute) => createRoute({\n path: '/demo/mui',\n \n component: MUIDemo,\n\n getParentRoute: () => parentRoute,\n})\n<% } %>\n"
3946
},
40-
"addDependencies": []
47+
"deletedFiles": []
4148
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ThemeProvider, createTheme } from '@mui/material/styles'
2+
3+
const theme = createTheme({
4+
palette: {
5+
primary: {
6+
main: '#000000',
7+
},
8+
},
9+
})
10+
11+
export default function MuiProvider({
12+
children,
13+
}: {
14+
children: React.ReactNode
15+
}) {
16+
return <ThemeProvider theme={theme}>{children}</ThemeProvider>
17+
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import Button from "@mui/material/Button";
2-
import Box from "@mui/material/Box";
3-
import { createFileRoute } from "@tanstack/react-router";
1+
import { createFileRoute } from '@tanstack/react-router'
42

5-
export const Route = createFileRoute("/demo/mui")({
3+
import Button from '@mui/material/Button'
4+
import Box from '@mui/material/Box'
5+
6+
export const Route = createFileRoute('/demo/mui')({
67
component: MUIDemo,
7-
});
8+
})
89

910
function MUIDemo() {
1011
return (
1112
<Box sx={{ px: 2, py: 4 }}>
1213
<Button variant="contained">Hello world</Button>
1314
</Box>
14-
);
15+
)
1516
}

packages/cta-cli/src/command-line.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,10 @@ import {
77
finalizeAddOns,
88
getFrameworkById,
99
getPackageManager,
10-
loadRemoteAddOn,
10+
loadStarter,
1111
} from '@tanstack/cta-engine'
1212

13-
import type {
14-
AddOn,
15-
Mode,
16-
Options,
17-
StarterCompiled,
18-
} from '@tanstack/cta-engine'
13+
import type { Mode, Options } from '@tanstack/cta-engine'
1914

2015
import type { CliOptions } from './types.js'
2116

@@ -40,19 +35,19 @@ export async function normalizeOptions(
4035
}
4136

4237
let mode: typeof FILE_ROUTER | typeof CODE_ROUTER =
43-
cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER
38+
forcedMode || cliOptions.template === 'file-router'
39+
? FILE_ROUTER
40+
: CODE_ROUTER
4441

4542
const starter = cliOptions.starter
46-
? ((await loadRemoteAddOn(
47-
cliOptions.starter,
48-
)) as unknown as StarterCompiled)
43+
? await loadStarter(cliOptions.starter)
4944
: undefined
5045

5146
if (starter) {
5247
tailwind = starter.tailwind
5348
typescript = starter.typescript
5449
cliOptions.framework = starter.framework
55-
mode = starter.mode
50+
mode = starter.mode as Mode
5651
}
5752

5853
const framework = getFrameworkById(cliOptions.framework || 'react-cra')!
@@ -111,6 +106,6 @@ export async function normalizeOptions(
111106
DEFAULT_PACKAGE_MANAGER,
112107
git: !!cliOptions.git,
113108
chosenAddOns,
114-
starter: starter as unknown as AddOn,
109+
starter: starter,
115110
}
116111
}

packages/cta-cli/tests/command-line.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,21 @@ describe('normalizeOptions', () => {
6262
__testRegisterFramework({
6363
id: 'solid',
6464
name: 'Solid',
65+
getAddOns: () => [],
6566
})
6667
fetch.mockResponseOnce(
6768
JSON.stringify({
69+
id: 'https://github.com/cta-dev/cta-starter-solid',
6870
tailwind: true,
6971
typescript: false,
7072
framework: 'solid',
7173
mode: 'file-router',
74+
type: 'starter',
75+
description: 'A starter for Solid',
76+
name: 'My Solid Starter',
77+
dependsOn: [],
78+
files: {},
79+
deletedFiles: [],
7280
}),
7381
)
7482

@@ -108,6 +116,7 @@ describe('normalizeOptions', () => {
108116
const options = await normalizeOptions(
109117
{
110118
projectName: 'test',
119+
framework: 'react-cra',
111120
},
112121
'file-router',
113122
['foo'],
@@ -136,6 +145,8 @@ describe('normalizeOptions', () => {
136145
{
137146
projectName: 'test',
138147
addOns: ['baz'],
148+
framework: 'react-cra',
149+
template: 'file-router',
139150
},
140151
'file-router',
141152
['foo'],

packages/cta-engine/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"ignore": "^7.0.3",
3636
"memfs": "^4.17.0",
3737
"parse-gitignore": "^2.0.0",
38-
"prettier": "^3.5.0"
38+
"prettier": "^3.5.0",
39+
"zod": "^3.24.2"
3940
},
4041
"devDependencies": {
4142
"@tanstack/config": "^0.16.2",

packages/cta-engine/src/add-ons.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { loadRemoteAddOn } from './custom-add-ons/add-on.js'
2+
13
import type { AddOn, Framework, Mode } from './types.js'
24

35
export function getAllAddOns(framework: Framework, mode: Mode): Array<AddOn> {
@@ -45,15 +47,3 @@ export async function finalizeAddOns(
4547
function loadAddOn(addOn: AddOn): AddOn {
4648
return addOn
4749
}
48-
49-
export async function loadRemoteAddOn(url: string): Promise<AddOn> {
50-
const response = await fetch(url)
51-
const fileContent = await response.json()
52-
fileContent.id = url
53-
return {
54-
...fileContent,
55-
getFiles: () => Promise.resolve(Object.keys(fileContent.files)),
56-
getFileContents: (path: string) => Promise.resolve(fileContent.files[path]),
57-
getDeletedFiles: () => Promise.resolve(fileContent.deletedFiles),
58-
}
59-
}

0 commit comments

Comments
 (0)