@tanstack/cta-ui 0.10.0-alpha.24 → 0.10.0-alpha.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-D0-fpgzI.js +223 -0
- package/dist/assets/index-D0-fpgzI.js.map +1 -0
- package/dist/assets/index-D5brMzJg.css +1 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.html +13 -0
- package/dist/logo192.png +0 -0
- package/dist/logo512.png +0 -0
- package/dist/manifest.json +25 -0
- package/dist/robots.txt +3 -0
- package/dist/tailwind.svg +1 -0
- package/dist/tanstack.png +0 -0
- package/dist/typescript.svg +1 -0
- package/index.html +12 -0
- package/{src → lib}/engine-handling/add-to-app-wrapper.ts +37 -41
- package/{src → lib}/engine-handling/create-app-wrapper.ts +35 -37
- package/{src → lib}/engine-handling/generate-initial-payload.ts +2 -2
- package/lib/engine-handling/server-environment.ts +37 -0
- package/lib/index.ts +140 -34
- package/lib/types.d.ts +13 -0
- package/lib-dist/engine-handling/add-to-app-wrapper.d.ts +12 -0
- package/lib-dist/engine-handling/add-to-app-wrapper.js +73 -0
- package/lib-dist/engine-handling/create-app-wrapper.d.ts +13 -0
- package/lib-dist/engine-handling/create-app-wrapper.js +68 -0
- package/lib-dist/engine-handling/file-helpers.d.ts +2 -0
- package/lib-dist/engine-handling/file-helpers.js +20 -0
- package/lib-dist/engine-handling/framework-registration.d.ts +1 -0
- package/lib-dist/engine-handling/framework-registration.js +10 -0
- package/lib-dist/engine-handling/generate-initial-payload.d.ts +40 -0
- package/lib-dist/engine-handling/generate-initial-payload.js +93 -0
- package/lib-dist/engine-handling/server-environment.d.ts +17 -0
- package/lib-dist/engine-handling/server-environment.js +18 -0
- package/lib-dist/index.d.ts +3 -7
- package/lib-dist/index.js +119 -18
- package/package.json +10 -12
- package/src/index.tsx +44 -0
- package/src/lib/api.ts +10 -8
- package/src/main.tsx +12 -0
- package/vite.config.ts +16 -0
- package/app.config.js +0 -22
- package/src/api.ts +0 -6
- package/src/client.tsx +0 -8
- package/src/engine-handling/server-environment.ts +0 -30
- package/src/integrations/tanstack-query/layout.tsx +0 -5
- package/src/integrations/tanstack-query/root-provider.tsx +0 -15
- package/src/logo.svg +0 -44
- package/src/routeTree.gen.ts +0 -88
- package/src/router.tsx +0 -32
- package/src/routes/__root.tsx +0 -86
- package/src/routes/api/add-to-app.ts +0 -21
- package/src/routes/api/create-app.ts +0 -21
- package/src/routes/api/dry-run-add-to-app.ts +0 -16
- package/src/routes/api/dry-run-create-app.ts +0 -16
- package/src/routes/api/initial-payload.ts +0 -10
- package/src/routes/api/load-remote-add-on.ts +0 -42
- package/src/routes/api/load-starter.ts +0 -47
- package/src/routes/api/shutdown.ts +0 -11
- package/src/routes/index.tsx +0 -17
- package/src/ssr.tsx +0 -12
- /package/{src → lib}/engine-handling/file-helpers.ts +0 -0
- /package/{src → lib}/engine-handling/framework-registration.ts +0 -0
package/lib/index.ts
CHANGED
|
@@ -1,43 +1,149 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path'
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import express from 'express'
|
|
4
|
+
import cors from 'cors'
|
|
5
|
+
import {
|
|
6
|
+
AddOnCompiledSchema,
|
|
7
|
+
StarterCompiledSchema,
|
|
8
|
+
} from '@tanstack/cta-engine'
|
|
3
9
|
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
process.env.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
if (forcedAddOns) {
|
|
31
|
-
process.env.CTA_FORCED_ADD_ONS = forcedAddOns.join(',')
|
|
10
|
+
import { addToAppWrapper } from './engine-handling/add-to-app-wrapper.js'
|
|
11
|
+
import { createAppWrapper } from './engine-handling/create-app-wrapper.js'
|
|
12
|
+
import { generateInitialPayload } from './engine-handling/generate-initial-payload.js'
|
|
13
|
+
import { setServerEnvironment } from './engine-handling/server-environment.js'
|
|
14
|
+
|
|
15
|
+
import type { ServerEnvironment } from './engine-handling/server-environment.js'
|
|
16
|
+
|
|
17
|
+
export function launchUI(
|
|
18
|
+
options: Partial<ServerEnvironment> & {
|
|
19
|
+
port?: number
|
|
20
|
+
},
|
|
21
|
+
) {
|
|
22
|
+
const { port: requestedPort, ...rest } = options
|
|
23
|
+
setServerEnvironment(rest)
|
|
24
|
+
|
|
25
|
+
const app = express()
|
|
26
|
+
|
|
27
|
+
app.use(cors())
|
|
28
|
+
app.use(express.json())
|
|
29
|
+
app.use(express.urlencoded({ extended: true }))
|
|
30
|
+
|
|
31
|
+
const launchUI = !process.env.CTA_DISABLE_UI
|
|
32
|
+
if (launchUI) {
|
|
33
|
+
const packagePath = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|
34
|
+
app.use(express.static(resolve(packagePath, 'dist')))
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
app.post('/api/add-to-app', async (req, res) => {
|
|
38
|
+
await addToAppWrapper(req.body.addOns, {
|
|
39
|
+
response: res,
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
app.post('/api/create-app', async (req, res) => {
|
|
44
|
+
await createAppWrapper(req.body.options, {
|
|
45
|
+
response: res,
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
app.post('/api/dry-run-add-to-app', async (req, res) => {
|
|
50
|
+
res.send(
|
|
51
|
+
await addToAppWrapper(req.body.addOns, {
|
|
52
|
+
dryRun: true,
|
|
53
|
+
}),
|
|
54
|
+
)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
app.post('/api/dry-run-create-app', async (req, res) => {
|
|
58
|
+
res.send(
|
|
59
|
+
await createAppWrapper(req.body.options, {
|
|
60
|
+
dryRun: true,
|
|
61
|
+
}),
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
app.get('/api/initial-payload', async (_req, res) => {
|
|
66
|
+
res.send(await generateInitialPayload())
|
|
67
|
+
})
|
|
36
68
|
|
|
37
|
-
|
|
69
|
+
app.get('/api/load-remote-add-on', async (req, res) => {
|
|
70
|
+
const { url } = req.query
|
|
71
|
+
if (!url) {
|
|
72
|
+
res.status(400).send('URL is required')
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(url as string)
|
|
77
|
+
const data = await response.json()
|
|
78
|
+
const parsed = AddOnCompiledSchema.safeParse(data)
|
|
79
|
+
if (!parsed.success) {
|
|
80
|
+
res.status(400).json({ error: 'Invalid add-on data' })
|
|
81
|
+
} else {
|
|
82
|
+
res.json({
|
|
83
|
+
id: url,
|
|
84
|
+
name: parsed.data.name,
|
|
85
|
+
description: parsed.data.description,
|
|
86
|
+
version: parsed.data.version,
|
|
87
|
+
author: parsed.data.author,
|
|
88
|
+
license: parsed.data.license,
|
|
89
|
+
link: parsed.data.link,
|
|
90
|
+
smallLogo: parsed.data.smallLogo,
|
|
91
|
+
logo: parsed.data.logo,
|
|
92
|
+
type: parsed.data.type,
|
|
93
|
+
modes: parsed.data.modes,
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
res.status(500).send('Failed to load add-on')
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
app.get('/api/load-starter', async (req, res) => {
|
|
102
|
+
const { url } = req.query
|
|
103
|
+
if (!url) {
|
|
104
|
+
res.status(400).send('URL is required')
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch(url as string)
|
|
109
|
+
const data = await response.json()
|
|
110
|
+
const parsed = StarterCompiledSchema.safeParse(data)
|
|
111
|
+
if (!parsed.success) {
|
|
112
|
+
res.status(400).json({ error: 'Invalid starter data' })
|
|
113
|
+
} else {
|
|
114
|
+
res.json({
|
|
115
|
+
url,
|
|
116
|
+
id: parsed.data.id,
|
|
117
|
+
name: parsed.data.name,
|
|
118
|
+
description: parsed.data.description,
|
|
119
|
+
version: parsed.data.version,
|
|
120
|
+
author: parsed.data.author,
|
|
121
|
+
license: parsed.data.license,
|
|
122
|
+
dependsOn: parsed.data.dependsOn,
|
|
123
|
+
mode: parsed.data.mode,
|
|
124
|
+
typescript: parsed.data.typescript,
|
|
125
|
+
tailwind: parsed.data.tailwind,
|
|
126
|
+
banner: parsed.data.banner
|
|
127
|
+
? (url as string).replace('starter.json', parsed.data.banner)
|
|
128
|
+
: undefined,
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
} catch {
|
|
132
|
+
res.status(500).send('Failed to load starter')
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
app.post('/api/shutdown', (_req, res) => {
|
|
137
|
+
setTimeout(() => {
|
|
138
|
+
process.exit(0)
|
|
139
|
+
}, 50)
|
|
140
|
+
res.send({ shutdown: true })
|
|
141
|
+
})
|
|
38
142
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
143
|
+
const port = requestedPort || process.env.PORT || 8080
|
|
144
|
+
app.listen(port, () => {
|
|
145
|
+
console.log(
|
|
146
|
+
`Create TanStack ${launchUI ? 'App' : 'API'} is running on http://localhost:${port}`,
|
|
147
|
+
)
|
|
42
148
|
})
|
|
43
149
|
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
export declare function addToAppWrapper(addOns: Array<string>, opts: {
|
|
3
|
+
dryRun?: boolean;
|
|
4
|
+
response?: Response;
|
|
5
|
+
}): Promise<{
|
|
6
|
+
files: Record<string, string>;
|
|
7
|
+
deletedFiles: Array<string>;
|
|
8
|
+
commands: Array<{
|
|
9
|
+
command: string;
|
|
10
|
+
args: Array<string>;
|
|
11
|
+
}>;
|
|
12
|
+
} | undefined>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { addToApp, createDefaultEnvironment, createMemoryEnvironment, recursivelyGatherFiles, } from '@tanstack/cta-engine';
|
|
4
|
+
import { cleanUpFileArray, cleanUpFiles } from './file-helpers.js';
|
|
5
|
+
import { getProjectPath } from './server-environment.js';
|
|
6
|
+
import { createAppWrapper } from './create-app-wrapper.js';
|
|
7
|
+
export async function addToAppWrapper(addOns, opts) {
|
|
8
|
+
const projectPath = getProjectPath();
|
|
9
|
+
const persistedOptions = JSON.parse(readFileSync(resolve(projectPath, '.cta.json')).toString());
|
|
10
|
+
persistedOptions.targetDir = projectPath;
|
|
11
|
+
const newAddons = [];
|
|
12
|
+
for (const addOn of addOns) {
|
|
13
|
+
if (!persistedOptions.existingAddOns.includes(addOn)) {
|
|
14
|
+
newAddons.push(addOn);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (newAddons.length === 0) {
|
|
18
|
+
return await createAppWrapper(persistedOptions, opts);
|
|
19
|
+
}
|
|
20
|
+
async function createEnvironment() {
|
|
21
|
+
if (opts.dryRun) {
|
|
22
|
+
const { environment, output } = createMemoryEnvironment(projectPath);
|
|
23
|
+
environment.writeFile(resolve(projectPath, '.cta.json'), JSON.stringify(persistedOptions, null, 2));
|
|
24
|
+
const localFiles = await cleanUpFiles(await recursivelyGatherFiles(projectPath, false));
|
|
25
|
+
for (const file of Object.keys(localFiles)) {
|
|
26
|
+
environment.writeFile(resolve(projectPath, file), localFiles[file]);
|
|
27
|
+
}
|
|
28
|
+
return { environment, output };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
environment: createDefaultEnvironment(),
|
|
32
|
+
output: { files: {}, deletedFiles: [], commands: [] },
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const { environment, output } = await createEnvironment();
|
|
36
|
+
if (opts.response) {
|
|
37
|
+
opts.response.writeHead(200, {
|
|
38
|
+
'Content-Type': 'text/plain',
|
|
39
|
+
'Transfer-Encoding': 'chunked',
|
|
40
|
+
});
|
|
41
|
+
environment.startStep = ({ id, type, message }) => {
|
|
42
|
+
opts.response.write(JSON.stringify({
|
|
43
|
+
msgType: 'start',
|
|
44
|
+
id,
|
|
45
|
+
type,
|
|
46
|
+
message,
|
|
47
|
+
}) + '\n');
|
|
48
|
+
};
|
|
49
|
+
environment.finishStep = (id, message) => {
|
|
50
|
+
opts.response.write(JSON.stringify({
|
|
51
|
+
msgType: 'finish',
|
|
52
|
+
id,
|
|
53
|
+
message,
|
|
54
|
+
}) + '\n');
|
|
55
|
+
};
|
|
56
|
+
environment.startRun();
|
|
57
|
+
await addToApp(environment, newAddons, projectPath, {
|
|
58
|
+
forced: true,
|
|
59
|
+
});
|
|
60
|
+
environment.finishRun();
|
|
61
|
+
opts.response.end();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
environment.startRun();
|
|
65
|
+
await addToApp(environment, newAddons, projectPath, {
|
|
66
|
+
forced: true,
|
|
67
|
+
});
|
|
68
|
+
environment.finishRun();
|
|
69
|
+
output.files = cleanUpFiles(output.files, projectPath);
|
|
70
|
+
output.deletedFiles = cleanUpFileArray(output.deletedFiles, projectPath);
|
|
71
|
+
return output;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SerializedOptions } from '@tanstack/cta-engine';
|
|
2
|
+
import type { Response } from 'express';
|
|
3
|
+
export declare function createAppWrapper(projectOptions: SerializedOptions, opts: {
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
response?: Response;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
files: Record<string, string>;
|
|
8
|
+
deletedFiles: Array<string>;
|
|
9
|
+
commands: Array<{
|
|
10
|
+
command: string;
|
|
11
|
+
args: Array<string>;
|
|
12
|
+
}>;
|
|
13
|
+
} | undefined>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { createApp, createDefaultEnvironment, createMemoryEnvironment, finalizeAddOns, getFrameworkById, loadStarter, } from '@tanstack/cta-engine';
|
|
3
|
+
import { registerFrameworks } from './framework-registration.js';
|
|
4
|
+
import { cleanUpFileArray, cleanUpFiles } from './file-helpers.js';
|
|
5
|
+
import { getApplicationMode, getProjectPath } from './server-environment.js';
|
|
6
|
+
export async function createAppWrapper(projectOptions, opts) {
|
|
7
|
+
registerFrameworks();
|
|
8
|
+
const framework = getFrameworkById(projectOptions.framework);
|
|
9
|
+
let starter;
|
|
10
|
+
const addOns = [...(projectOptions.chosenAddOns || [])];
|
|
11
|
+
if (projectOptions.starter) {
|
|
12
|
+
starter = await loadStarter(projectOptions.starter);
|
|
13
|
+
for (const addOn of starter?.dependsOn ?? []) {
|
|
14
|
+
addOns.push(addOn);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const chosenAddOns = await finalizeAddOns(framework, projectOptions.mode, addOns);
|
|
18
|
+
const projectPath = getProjectPath();
|
|
19
|
+
const targetDir = getApplicationMode() === 'add'
|
|
20
|
+
? projectOptions.targetDir
|
|
21
|
+
: resolve(projectPath, projectOptions.projectName);
|
|
22
|
+
const options = {
|
|
23
|
+
...projectOptions,
|
|
24
|
+
targetDir,
|
|
25
|
+
starter,
|
|
26
|
+
framework,
|
|
27
|
+
chosenAddOns,
|
|
28
|
+
};
|
|
29
|
+
function createEnvironment() {
|
|
30
|
+
if (opts.dryRun) {
|
|
31
|
+
return createMemoryEnvironment(targetDir);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
environment: createDefaultEnvironment(),
|
|
35
|
+
output: { files: {}, deletedFiles: [], commands: [] },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const { environment, output } = createEnvironment();
|
|
39
|
+
if (opts.response) {
|
|
40
|
+
opts.response.writeHead(200, {
|
|
41
|
+
'Content-Type': 'text/plain',
|
|
42
|
+
'Transfer-Encoding': 'chunked',
|
|
43
|
+
});
|
|
44
|
+
environment.startStep = ({ id, type, message }) => {
|
|
45
|
+
opts.response.write(JSON.stringify({
|
|
46
|
+
msgType: 'start',
|
|
47
|
+
id,
|
|
48
|
+
type,
|
|
49
|
+
message,
|
|
50
|
+
}) + '\n');
|
|
51
|
+
};
|
|
52
|
+
environment.finishStep = (id, message) => {
|
|
53
|
+
opts.response.write(JSON.stringify({
|
|
54
|
+
msgType: 'finish',
|
|
55
|
+
id,
|
|
56
|
+
message,
|
|
57
|
+
}) + '\n');
|
|
58
|
+
};
|
|
59
|
+
await createApp(environment, options);
|
|
60
|
+
opts.response.end();
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
await createApp(environment, options);
|
|
64
|
+
output.files = cleanUpFiles(output.files, targetDir);
|
|
65
|
+
output.deletedFiles = cleanUpFileArray(output.deletedFiles, targetDir);
|
|
66
|
+
return output;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
export function cleanUpFiles(files, targetDir) {
|
|
3
|
+
return Object.keys(files).reduce((acc, file) => {
|
|
4
|
+
const content = files[file].startsWith('base64::')
|
|
5
|
+
? '<binary file>'
|
|
6
|
+
: files[file];
|
|
7
|
+
if (basename(file) !== '.cta.json') {
|
|
8
|
+
acc[targetDir ? file.replace(targetDir, '.') : file] = content;
|
|
9
|
+
}
|
|
10
|
+
return acc;
|
|
11
|
+
}, {});
|
|
12
|
+
}
|
|
13
|
+
export function cleanUpFileArray(files, targetDir) {
|
|
14
|
+
return files.reduce((acc, file) => {
|
|
15
|
+
if (basename(file) !== '.cta.json') {
|
|
16
|
+
acc.push(targetDir ? file.replace(targetDir, '.') : file);
|
|
17
|
+
}
|
|
18
|
+
return acc;
|
|
19
|
+
}, []);
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerFrameworks(): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { register as registerReactCra } from '@tanstack/cta-framework-react-cra';
|
|
2
|
+
import { register as registerSolid } from '@tanstack/cta-framework-solid';
|
|
3
|
+
let registered = false;
|
|
4
|
+
export function registerFrameworks() {
|
|
5
|
+
if (registered)
|
|
6
|
+
return;
|
|
7
|
+
registerReactCra();
|
|
8
|
+
registerSolid();
|
|
9
|
+
registered = true;
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SerializedOptions } from '@tanstack/cta-engine';
|
|
2
|
+
import type { Registry } from '../types.js';
|
|
3
|
+
export declare function generateInitialPayload(): Promise<{
|
|
4
|
+
applicationMode: "add" | "setup";
|
|
5
|
+
localFiles: Record<string, string>;
|
|
6
|
+
addOns: {
|
|
7
|
+
'code-router': {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
type: "starter" | "add-on" | "example" | "toolchain";
|
|
12
|
+
smallLogo: string | undefined;
|
|
13
|
+
logo: string | undefined;
|
|
14
|
+
link: string | undefined;
|
|
15
|
+
dependsOn: string[] | undefined;
|
|
16
|
+
}[];
|
|
17
|
+
'file-router': {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
type: "starter" | "add-on" | "example" | "toolchain";
|
|
22
|
+
smallLogo: string | undefined;
|
|
23
|
+
logo: string | undefined;
|
|
24
|
+
link: string | undefined;
|
|
25
|
+
dependsOn: string[] | undefined;
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
28
|
+
options: SerializedOptions;
|
|
29
|
+
output: {
|
|
30
|
+
files: Record<string, string>;
|
|
31
|
+
deletedFiles: Array<string>;
|
|
32
|
+
commands: Array<{
|
|
33
|
+
command: string;
|
|
34
|
+
args: Array<string>;
|
|
35
|
+
}>;
|
|
36
|
+
} | undefined;
|
|
37
|
+
forcedRouterMode: import("@tanstack/cta-engine").Mode | undefined;
|
|
38
|
+
forcedAddOns: string[];
|
|
39
|
+
registry: Registry | undefined;
|
|
40
|
+
}>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, resolve } from 'node:path';
|
|
3
|
+
import { createSerializedOptionsFromPersisted, getAllAddOns, getFrameworkById, recursivelyGatherFiles, } from '@tanstack/cta-engine';
|
|
4
|
+
import { cleanUpFiles } from './file-helpers.js';
|
|
5
|
+
import { createAppWrapper } from './create-app-wrapper.js';
|
|
6
|
+
import { registerFrameworks } from './framework-registration.js';
|
|
7
|
+
import { getApplicationMode, getForcedAddOns, getForcedRouterMode, getProjectOptions, getProjectPath, getRegistry, } from './server-environment.js';
|
|
8
|
+
function absolutizeUrl(originalUrl, relativeUrl) {
|
|
9
|
+
if (relativeUrl.startsWith('http') || relativeUrl.startsWith('https')) {
|
|
10
|
+
return relativeUrl;
|
|
11
|
+
}
|
|
12
|
+
const baseUrl = originalUrl.replace(/registry.json$/, '');
|
|
13
|
+
return `${baseUrl}${relativeUrl.replace(/^\.\//, '')}`;
|
|
14
|
+
}
|
|
15
|
+
export async function generateInitialPayload() {
|
|
16
|
+
registerFrameworks();
|
|
17
|
+
const projectPath = getProjectPath();
|
|
18
|
+
const applicationMode = getApplicationMode();
|
|
19
|
+
const localFiles = applicationMode === 'add'
|
|
20
|
+
? await cleanUpFiles(await recursivelyGatherFiles(projectPath, false))
|
|
21
|
+
: {};
|
|
22
|
+
const forcedRouterMode = getForcedRouterMode();
|
|
23
|
+
function getSerializedOptions() {
|
|
24
|
+
if (applicationMode === 'setup') {
|
|
25
|
+
const projectOptions = getProjectOptions();
|
|
26
|
+
return {
|
|
27
|
+
...projectOptions,
|
|
28
|
+
framework: projectOptions.framework || 'react-cra',
|
|
29
|
+
projectName: projectOptions.projectName || basename(projectPath),
|
|
30
|
+
mode: forcedRouterMode || projectOptions.mode,
|
|
31
|
+
typescript: projectOptions.typescript || true,
|
|
32
|
+
tailwind: projectOptions.tailwind || true,
|
|
33
|
+
git: projectOptions.git || true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const persistedOptions = JSON.parse(readFileSync(resolve(projectPath, '.cta.json')).toString());
|
|
38
|
+
return createSerializedOptionsFromPersisted(persistedOptions);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const registryUrl = getRegistry();
|
|
42
|
+
let registry;
|
|
43
|
+
if (registryUrl) {
|
|
44
|
+
registry = (await fetch(registryUrl).then((res) => res.json()));
|
|
45
|
+
for (const addOn of registry['add-ons']) {
|
|
46
|
+
addOn.url = absolutizeUrl(registryUrl, addOn.url);
|
|
47
|
+
}
|
|
48
|
+
for (const starter of registry.starters) {
|
|
49
|
+
starter.url = absolutizeUrl(registryUrl, starter.url);
|
|
50
|
+
if (starter.banner) {
|
|
51
|
+
starter.banner = absolutizeUrl(registryUrl, starter.banner);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const serializedOptions = getSerializedOptions();
|
|
56
|
+
const output = await createAppWrapper(serializedOptions, {
|
|
57
|
+
dryRun: true,
|
|
58
|
+
});
|
|
59
|
+
const framework = await getFrameworkById(serializedOptions.framework);
|
|
60
|
+
const codeRouter = getAllAddOns(framework, 'code-router').map((addOn) => ({
|
|
61
|
+
id: addOn.id,
|
|
62
|
+
name: addOn.name,
|
|
63
|
+
description: addOn.description,
|
|
64
|
+
type: addOn.type,
|
|
65
|
+
smallLogo: addOn.smallLogo,
|
|
66
|
+
logo: addOn.logo,
|
|
67
|
+
link: addOn.link,
|
|
68
|
+
dependsOn: addOn.dependsOn,
|
|
69
|
+
}));
|
|
70
|
+
const fileRouter = getAllAddOns(framework, 'file-router').map((addOn) => ({
|
|
71
|
+
id: addOn.id,
|
|
72
|
+
name: addOn.name,
|
|
73
|
+
description: addOn.description,
|
|
74
|
+
type: addOn.type,
|
|
75
|
+
smallLogo: addOn.smallLogo,
|
|
76
|
+
logo: addOn.logo,
|
|
77
|
+
link: addOn.link,
|
|
78
|
+
dependsOn: addOn.dependsOn,
|
|
79
|
+
}));
|
|
80
|
+
return {
|
|
81
|
+
applicationMode,
|
|
82
|
+
localFiles,
|
|
83
|
+
addOns: {
|
|
84
|
+
'code-router': codeRouter,
|
|
85
|
+
'file-router': fileRouter,
|
|
86
|
+
},
|
|
87
|
+
options: serializedOptions,
|
|
88
|
+
output,
|
|
89
|
+
forcedRouterMode,
|
|
90
|
+
forcedAddOns: getForcedAddOns(),
|
|
91
|
+
registry,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Mode, SerializedOptions } from '@tanstack/cta-engine';
|
|
2
|
+
export type ServerEnvironment = {
|
|
3
|
+
projectPath: string;
|
|
4
|
+
mode: 'add' | 'setup';
|
|
5
|
+
options?: SerializedOptions;
|
|
6
|
+
addOns?: Array<string>;
|
|
7
|
+
forcedRouterMode?: Mode;
|
|
8
|
+
forcedAddOns?: Array<string>;
|
|
9
|
+
registry?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function setServerEnvironment(options: Partial<ServerEnvironment>): void;
|
|
12
|
+
export declare const getProjectPath: () => string;
|
|
13
|
+
export declare const getApplicationMode: () => "add" | "setup";
|
|
14
|
+
export declare const getProjectOptions: () => SerializedOptions;
|
|
15
|
+
export declare const getForcedRouterMode: () => Mode | undefined;
|
|
16
|
+
export declare const getForcedAddOns: () => string[];
|
|
17
|
+
export declare const getRegistry: () => string | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const serverEnvironment = {
|
|
2
|
+
projectPath: '',
|
|
3
|
+
mode: 'add',
|
|
4
|
+
options: {},
|
|
5
|
+
addOns: [],
|
|
6
|
+
forcedRouterMode: undefined,
|
|
7
|
+
forcedAddOns: undefined,
|
|
8
|
+
registry: undefined,
|
|
9
|
+
};
|
|
10
|
+
export function setServerEnvironment(options) {
|
|
11
|
+
Object.assign(serverEnvironment, options);
|
|
12
|
+
}
|
|
13
|
+
export const getProjectPath = () => serverEnvironment.projectPath;
|
|
14
|
+
export const getApplicationMode = () => serverEnvironment.mode;
|
|
15
|
+
export const getProjectOptions = () => serverEnvironment.options;
|
|
16
|
+
export const getForcedRouterMode = () => serverEnvironment.forcedRouterMode;
|
|
17
|
+
export const getForcedAddOns = () => serverEnvironment.forcedAddOns || [];
|
|
18
|
+
export const getRegistry = () => serverEnvironment.registry;
|
package/lib-dist/index.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function launchUI(
|
|
3
|
-
|
|
4
|
-
addOns?: Array<string>;
|
|
5
|
-
options?: SerializedOptions;
|
|
6
|
-
forcedMode?: Mode;
|
|
7
|
-
forcedAddOns?: Array<string>;
|
|
1
|
+
import type { ServerEnvironment } from './engine-handling/server-environment.js';
|
|
2
|
+
export declare function launchUI(options: Partial<ServerEnvironment> & {
|
|
3
|
+
port?: number;
|
|
8
4
|
}): void;
|