Skip to content

Commit 9f33c8e

Browse files
committed
fix: registry fixes
1 parent b41ac67 commit 9f33c8e

File tree

4 files changed

+43
-31
lines changed

4 files changed

+43
-31
lines changed

examples/react-cra/registry-with-add-ons.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
"description": "A starter project for React with CRA",
66
"url": "./ecommerce-starter/starter.json",
77
"banner": "./ecommerce-starter/.starter/banner.png",
8-
"modes": "file-router",
8+
"mode": "file-router",
99
"framework": "react-cra"
1010
},
1111
{
1212
"name": "Blog",
1313
"description": "A blog starter for Tanstack React Start",
1414
"url": "./blog-starter/starter.json",
1515
"banner": "./blog-starter/.starter/banner.png",
16-
"modes": "file-router",
16+
"mode": "file-router",
1717
"framework": "react-cra"
1818
},
1919
{
2020
"name": "Resume",
2121
"description": "A resume starter for Tanstack React Start",
2222
"url": "./resume-starter/starter.json",
2323
"banner": "./resume-starter/.starter/banner.png",
24-
"modes": "file-router",
24+
"mode": "file-router",
2525
"framework": "react-cra"
2626
}
2727
],

examples/react-cra/registry.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
"description": "A starter project for React with CRA",
66
"url": "./ecommerce-starter/starter.json",
77
"banner": "./ecommerce-starter/.starter/banner.png",
8-
"modes": "file-router",
8+
"mode": "file-router",
99
"framework": "react-cra"
1010
},
1111
{
1212
"name": "Blog",
1313
"description": "A blog starter for Tanstack React Start",
1414
"url": "./blog-starter/starter.json",
1515
"banner": "./blog-starter/.starter/banner.png",
16-
"modes": "file-router",
16+
"mode": "file-router",
1717
"framework": "react-cra"
1818
},
1919
{
2020
"name": "Resume",
2121
"description": "A resume starter for Tanstack React Start",
2222
"url": "./resume-starter/starter.json",
2323
"banner": "./resume-starter/.starter/banner.png",
24-
"modes": "file-router",
24+
"mode": "file-router",
2525
"framework": "react-cra"
2626
}
2727
]

packages/cta-engine/src/registry.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
1+
import { z } from 'zod'
12
import { loadRemoteAddOn } from './custom-add-ons/add-on.js'
23
import { loadStarter } from './custom-add-ons/starter.js'
34

4-
import type { AddOn, Mode, Starter } from './types'
5+
import type { AddOn, Starter } from './types'
56

6-
export type Registry = {
7-
starters: Array<{
8-
name: string
9-
description: string
10-
url: string
11-
banner?: string
12-
mode: Mode
13-
framework: string
14-
}>
15-
'add-ons': Array<{
16-
name: string
17-
description: string
18-
url: string
19-
modes: Array<Mode>
20-
framework: string
21-
}>
22-
}
7+
const registrySchema = z.object({
8+
starters: z
9+
.array(
10+
z.object({
11+
name: z.string(),
12+
description: z.string(),
13+
url: z.string(),
14+
banner: z.string().optional(),
15+
mode: z.enum(['code-router', 'file-router']),
16+
framework: z.string(),
17+
}),
18+
)
19+
.optional(),
20+
'add-ons': z
21+
.array(
22+
z.object({
23+
name: z.string(),
24+
description: z.string(),
25+
url: z.string(),
26+
modes: z.array(z.enum(['code-router', 'file-router'])),
27+
framework: z.string(),
28+
}),
29+
)
30+
.optional(),
31+
})
32+
33+
export type Registry = z.infer<typeof registrySchema>
2334

2435
function absolutizeUrl(originalUrl: string, relativeUrl: string) {
2536
if (relativeUrl.startsWith('http') || relativeUrl.startsWith('https')) {
@@ -35,22 +46,23 @@ export async function getRawRegistry(
3546
const regUrl = registryUrl || process.env.CTA_REGISTRY
3647
if (regUrl) {
3748
const registry = (await fetch(regUrl).then((res) => res.json())) as Registry
38-
for (const addOn of registry['add-ons']) {
49+
const parsedRegistry = registrySchema.parse(registry)
50+
for (const addOn of parsedRegistry['add-ons'] || []) {
3951
addOn.url = absolutizeUrl(regUrl, addOn.url)
4052
}
41-
for (const starter of registry.starters) {
53+
for (const starter of parsedRegistry.starters || []) {
4254
starter.url = absolutizeUrl(regUrl, starter.url)
4355
if (starter.banner) {
4456
starter.banner = absolutizeUrl(regUrl, starter.banner)
4557
}
4658
}
47-
return registry
59+
return parsedRegistry
4860
}
4961
}
5062

5163
async function getAddOns(registry: Registry): Promise<Array<AddOn>> {
5264
const addOns: Array<AddOn> = []
53-
for (const addOnInfo of registry['add-ons']) {
65+
for (const addOnInfo of registry['add-ons'] || []) {
5466
const addOn = await loadRemoteAddOn(addOnInfo.url)
5567
addOns.push(addOn)
5668
}
@@ -66,7 +78,7 @@ export async function getRegistryAddOns(
6678

6779
async function getStarters(registry: Registry): Promise<Array<Starter>> {
6880
const starters: Array<Starter> = []
69-
for (const starterInfo of registry.starters) {
81+
for (const starterInfo of registry.starters || []) {
7082
const starter = await loadStarter(starterInfo.url)
7183
starters.push(starter)
7284
}

packages/cta-ui/lib/engine-handling/generate-initial-payload.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ export async function generateInitialPayload() {
9595
convertAddOnToAddOnInfo,
9696
)
9797

98-
for (const addOnInfo of registryAddOns || []) {
99-
const addOnFramework = rawRegistry?.['add-ons'].find(
98+
for (const addOnInfo of registryAddOns) {
99+
const addOnFramework = rawRegistry?.['add-ons']?.find(
100100
(addOn) => addOn.url === addOnInfo.id,
101101
)
102102
if (addOnFramework?.framework === serializedOptions.framework) {

0 commit comments

Comments
 (0)