@tanstack/cta-engine 0.10.0-alpha.11 → 0.10.0-alpha.12
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/add-ons.js +3 -2
- package/dist/cli.js +14 -14
- package/dist/create-app.js +7 -1
- package/dist/custom-add-on.js +2 -1
- package/dist/file-helper.js +18 -0
- package/dist/options.js +8 -8
- package/dist/types/file-helper.d.ts +2 -0
- package/package.json +1 -1
- package/src/add-ons.ts +3 -2
- package/src/cli.ts +23 -23
- package/src/create-app.ts +11 -1
- package/src/custom-add-on.ts +2 -3
- package/src/file-helper.ts +20 -0
- package/src/options.ts +12 -7
package/dist/add-ons.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { getTemplatesRoot } from './templates.js';
|
|
6
6
|
import { DEFAULT_FRAMEWORK } from './constants.js';
|
|
7
|
+
import { readFileHelper } from './file-helper.js';
|
|
7
8
|
function isDirectory(path) {
|
|
8
9
|
return statSync(path).isDirectory();
|
|
9
10
|
}
|
|
@@ -15,7 +16,7 @@ function findFilesRecursively(path, files) {
|
|
|
15
16
|
findFilesRecursively(filePath, files);
|
|
16
17
|
}
|
|
17
18
|
else {
|
|
18
|
-
files[filePath] =
|
|
19
|
+
files[filePath] = readFileHelper(filePath);
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
}
|
package/dist/cli.js
CHANGED
|
@@ -30,16 +30,25 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
30
30
|
// .action(async () => {
|
|
31
31
|
// await initAddOn('overlay')
|
|
32
32
|
// })
|
|
33
|
+
program.argument('[project-name]', 'name of the project');
|
|
34
|
+
if (!forcedMode) {
|
|
35
|
+
program.option('--template <type>', 'project template (typescript, javascript, file-router)', (value) => {
|
|
36
|
+
if (value !== 'typescript' &&
|
|
37
|
+
value !== 'javascript' &&
|
|
38
|
+
value !== 'file-router') {
|
|
39
|
+
throw new InvalidArgumentError(`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
33
44
|
program
|
|
34
|
-
.argument('[project-name]', 'name of the project')
|
|
35
|
-
.option('--no-git', 'do not create a git repository')
|
|
36
|
-
.option('--target-dir <path>', 'the directory to create the project in')
|
|
37
45
|
.option('--framework <type>', 'project framework (solid, react)', (value) => {
|
|
38
46
|
if (!SUPPORTED_FRAMEWORKS.includes(value)) {
|
|
39
47
|
throw new InvalidArgumentError(`Invalid framework: ${value}. Only the following are allowed: ${SUPPORTED_FRAMEWORKS.join(', ')}`);
|
|
40
48
|
}
|
|
41
49
|
return value;
|
|
42
50
|
}, DEFAULT_FRAMEWORK)
|
|
51
|
+
// .option('--overlay [url]', 'add an overlay from a URL', false)
|
|
43
52
|
.option(`--package-manager <${SUPPORTED_PACKAGE_MANAGERS.join('|')}>`, `Explicitly tell the CLI to use this package manager`, (value) => {
|
|
44
53
|
if (!SUPPORTED_PACKAGE_MANAGERS.includes(value)) {
|
|
45
54
|
throw new InvalidArgumentError(`Invalid package manager: ${value}. The following are allowed: ${SUPPORTED_PACKAGE_MANAGERS.join(', ')}`);
|
|
@@ -61,19 +70,10 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
61
70
|
return addOns;
|
|
62
71
|
})
|
|
63
72
|
.option('--list-add-ons', 'list all available add-ons', false)
|
|
64
|
-
|
|
73
|
+
.option('--no-git', 'do not create a git repository')
|
|
74
|
+
.option('--target-dir <path>', 'the directory to create the project in')
|
|
65
75
|
.option('--mcp', 'run the MCP server', false)
|
|
66
76
|
.option('--mcp-sse', 'run the MCP server in SSE mode', false);
|
|
67
|
-
if (!forcedMode) {
|
|
68
|
-
program.option('--template <type>', 'project template (typescript, javascript, file-router)', (value) => {
|
|
69
|
-
if (value !== 'typescript' &&
|
|
70
|
-
value !== 'javascript' &&
|
|
71
|
-
value !== 'file-router') {
|
|
72
|
-
throw new InvalidArgumentError(`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`);
|
|
73
|
-
}
|
|
74
|
-
return value;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
77
|
program.action(async (projectName, options) => {
|
|
78
78
|
if (options.listAddOns) {
|
|
79
79
|
await listAddOns(options, {
|
package/dist/create-app.js
CHANGED
|
@@ -8,6 +8,7 @@ import { CODE_ROUTER, FILE_ROUTER } from './constants.js';
|
|
|
8
8
|
import { sortObject } from './utils.js';
|
|
9
9
|
import { writeConfigFile } from './config-file.js';
|
|
10
10
|
import { packageManagerExecute } from './package-manager.js';
|
|
11
|
+
import { getBinaryFile } from './file-helper.js';
|
|
11
12
|
function createCopyFiles(environment, targetDir) {
|
|
12
13
|
return async function copyFiles(templateDir, files,
|
|
13
14
|
// optionally copy files from a folder to the root
|
|
@@ -197,6 +198,11 @@ async function copyAddOnFile(environment, content, target, targetPath, templateF
|
|
|
197
198
|
isAppend = true;
|
|
198
199
|
}
|
|
199
200
|
const finalTargetPath = resolve(dirname(targetPath), targetFile);
|
|
201
|
+
const binaryContent = getBinaryFile(content);
|
|
202
|
+
if (binaryContent) {
|
|
203
|
+
await environment.writeFile(finalTargetPath, binaryContent);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
200
206
|
if (isTemplate) {
|
|
201
207
|
await templateFile(content, finalTargetPath);
|
|
202
208
|
}
|
|
@@ -309,7 +315,7 @@ export async function createApp(options, { silent = false, environment, cwd, app
|
|
|
309
315
|
// Copy all the asset files from the addons
|
|
310
316
|
const s = silent ? null : spinner();
|
|
311
317
|
for (const type of ['add-on', 'example']) {
|
|
312
|
-
for (const phase of ['setup', 'add-on']) {
|
|
318
|
+
for (const phase of ['setup', 'add-on', 'example']) {
|
|
313
319
|
for (const addOn of options.chosenAddOns.filter((addOn) => addOn.phase === phase && addOn.type === type)) {
|
|
314
320
|
s?.start(`Setting up ${addOn.name}...`);
|
|
315
321
|
await runAddOn(addOn);
|
package/dist/custom-add-on.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createMemoryEnvironment } from './environment.js';
|
|
|
6
6
|
import { createApp } from './create-app.js';
|
|
7
7
|
import { readConfigFile } from './config-file.js';
|
|
8
8
|
import { finalizeAddOns } from './add-ons.js';
|
|
9
|
+
import { readFileHelper } from './file-helper.js';
|
|
9
10
|
const INFO_FILE = {
|
|
10
11
|
'add-on': '.add-on/info.json',
|
|
11
12
|
overlay: 'overlay-info.json',
|
|
@@ -98,7 +99,7 @@ async function recursivelyGatherFiles(path, files) {
|
|
|
98
99
|
await recursivelyGatherFiles(resolve(path, file.name), files);
|
|
99
100
|
}
|
|
100
101
|
else {
|
|
101
|
-
files[resolve(path, file.name)] = (
|
|
102
|
+
files[resolve(path, file.name)] = readFileHelper(resolve(path, file.name));
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { extname } from 'node:path';
|
|
3
|
+
const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico'];
|
|
4
|
+
export function readFileHelper(path) {
|
|
5
|
+
if (BINARY_EXTENSIONS.includes(extname(path))) {
|
|
6
|
+
return `base64::${readFileSync(path).toString('base64')}`;
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
return readFileSync(path, 'utf-8').toString();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function getBinaryFile(content) {
|
|
13
|
+
if (content.startsWith('base64::')) {
|
|
14
|
+
const binaryContent = Buffer.from(content.replace('base64::', ''), 'base64');
|
|
15
|
+
return binaryContent;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
package/dist/options.js
CHANGED
|
@@ -13,12 +13,6 @@ export async function normalizeOptions(cliOptions, forcedAddOns) {
|
|
|
13
13
|
if (parseSeparatedArgs.length > 1) {
|
|
14
14
|
cliOptions.addOns = parseSeparatedArgs;
|
|
15
15
|
}
|
|
16
|
-
if (forcedAddOns) {
|
|
17
|
-
cliOptions.addOns = [...cliOptions.addOns, ...forcedAddOns];
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
else if (forcedAddOns) {
|
|
21
|
-
cliOptions.addOns = [...forcedAddOns];
|
|
22
16
|
}
|
|
23
17
|
if (cliOptions.projectName) {
|
|
24
18
|
let typescript = cliOptions.template === 'typescript' ||
|
|
@@ -40,11 +34,17 @@ export async function normalizeOptions(cliOptions, forcedAddOns) {
|
|
|
40
34
|
}
|
|
41
35
|
let addOns = false;
|
|
42
36
|
let chosenAddOns = [];
|
|
43
|
-
if (Array.isArray(cliOptions.addOns) ||
|
|
37
|
+
if (Array.isArray(cliOptions.addOns) ||
|
|
38
|
+
overlay?.dependsOn ||
|
|
39
|
+
forcedAddOns) {
|
|
44
40
|
addOns = true;
|
|
45
41
|
let finalAddOns = [...(overlay?.dependsOn || [])];
|
|
46
42
|
if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
|
|
47
|
-
finalAddOns = [
|
|
43
|
+
finalAddOns = Array.from(new Set([
|
|
44
|
+
...(forcedAddOns || []),
|
|
45
|
+
...finalAddOns,
|
|
46
|
+
...cliOptions.addOns,
|
|
47
|
+
]));
|
|
48
48
|
}
|
|
49
49
|
chosenAddOns = await finalizeAddOns(cliOptions.framework || DEFAULT_FRAMEWORK, cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER, finalAddOns);
|
|
50
50
|
tailwind = true;
|
package/package.json
CHANGED
package/src/add-ons.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
3
3
|
import { resolve } from 'node:path'
|
|
4
4
|
import chalk from 'chalk'
|
|
5
5
|
|
|
6
6
|
import { getTemplatesRoot } from './templates.js'
|
|
7
7
|
import { DEFAULT_FRAMEWORK } from './constants.js'
|
|
8
|
+
import { readFileHelper } from './file-helper.js'
|
|
8
9
|
|
|
9
10
|
import type { AddOn, CliOptions, Framework, TemplateOptions } from './types.js'
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ function findFilesRecursively(path: string, files: Record<string, string>) {
|
|
|
19
20
|
if (isDirectory(filePath)) {
|
|
20
21
|
findFilesRecursively(filePath, files)
|
|
21
22
|
} else {
|
|
22
|
-
files[filePath] =
|
|
23
|
+
files[filePath] = readFileHelper(filePath)
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
}
|
package/src/cli.ts
CHANGED
|
@@ -54,10 +54,27 @@ export function cli({
|
|
|
54
54
|
// await initAddOn('overlay')
|
|
55
55
|
// })
|
|
56
56
|
|
|
57
|
+
program.argument('[project-name]', 'name of the project')
|
|
58
|
+
|
|
59
|
+
if (!forcedMode) {
|
|
60
|
+
program.option<'typescript' | 'javascript' | 'file-router'>(
|
|
61
|
+
'--template <type>',
|
|
62
|
+
'project template (typescript, javascript, file-router)',
|
|
63
|
+
(value) => {
|
|
64
|
+
if (
|
|
65
|
+
value !== 'typescript' &&
|
|
66
|
+
value !== 'javascript' &&
|
|
67
|
+
value !== 'file-router'
|
|
68
|
+
) {
|
|
69
|
+
throw new InvalidArgumentError(
|
|
70
|
+
`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`,
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
return value
|
|
74
|
+
},
|
|
75
|
+
)
|
|
76
|
+
}
|
|
57
77
|
program
|
|
58
|
-
.argument('[project-name]', 'name of the project')
|
|
59
|
-
.option('--no-git', 'do not create a git repository')
|
|
60
|
-
.option('--target-dir <path>', 'the directory to create the project in')
|
|
61
78
|
.option<Framework>(
|
|
62
79
|
'--framework <type>',
|
|
63
80
|
'project framework (solid, react)',
|
|
@@ -73,6 +90,7 @@ export function cli({
|
|
|
73
90
|
},
|
|
74
91
|
DEFAULT_FRAMEWORK,
|
|
75
92
|
)
|
|
93
|
+
// .option('--overlay [url]', 'add an overlay from a URL', false)
|
|
76
94
|
.option<PackageManager>(
|
|
77
95
|
`--package-manager <${SUPPORTED_PACKAGE_MANAGERS.join('|')}>`,
|
|
78
96
|
`Explicitly tell the CLI to use this package manager`,
|
|
@@ -114,29 +132,11 @@ export function cli({
|
|
|
114
132
|
},
|
|
115
133
|
)
|
|
116
134
|
.option('--list-add-ons', 'list all available add-ons', false)
|
|
117
|
-
|
|
135
|
+
.option('--no-git', 'do not create a git repository')
|
|
136
|
+
.option('--target-dir <path>', 'the directory to create the project in')
|
|
118
137
|
.option('--mcp', 'run the MCP server', false)
|
|
119
138
|
.option('--mcp-sse', 'run the MCP server in SSE mode', false)
|
|
120
139
|
|
|
121
|
-
if (!forcedMode) {
|
|
122
|
-
program.option<'typescript' | 'javascript' | 'file-router'>(
|
|
123
|
-
'--template <type>',
|
|
124
|
-
'project template (typescript, javascript, file-router)',
|
|
125
|
-
(value) => {
|
|
126
|
-
if (
|
|
127
|
-
value !== 'typescript' &&
|
|
128
|
-
value !== 'javascript' &&
|
|
129
|
-
value !== 'file-router'
|
|
130
|
-
) {
|
|
131
|
-
throw new InvalidArgumentError(
|
|
132
|
-
`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`,
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
return value
|
|
136
|
-
},
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
140
|
program.action(async (projectName: string, options: CliOptions) => {
|
|
141
141
|
if (options.listAddOns) {
|
|
142
142
|
await listAddOns(options, {
|
package/src/create-app.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { CODE_ROUTER, FILE_ROUTER } from './constants.js'
|
|
|
9
9
|
import { sortObject } from './utils.js'
|
|
10
10
|
import { writeConfigFile } from './config-file.js'
|
|
11
11
|
import { packageManagerExecute } from './package-manager.js'
|
|
12
|
+
import { getBinaryFile } from './file-helper.js'
|
|
12
13
|
|
|
13
14
|
import type { AddOn, Environment, Options } from './types.js'
|
|
14
15
|
|
|
@@ -287,6 +288,15 @@ async function copyAddOnFile(
|
|
|
287
288
|
|
|
288
289
|
const finalTargetPath = resolve(dirname(targetPath), targetFile)
|
|
289
290
|
|
|
291
|
+
const binaryContent = getBinaryFile(content)
|
|
292
|
+
if (binaryContent) {
|
|
293
|
+
await environment.writeFile(
|
|
294
|
+
finalTargetPath,
|
|
295
|
+
binaryContent as unknown as string,
|
|
296
|
+
)
|
|
297
|
+
return
|
|
298
|
+
}
|
|
299
|
+
|
|
290
300
|
if (isTemplate) {
|
|
291
301
|
await templateFile(content, finalTargetPath)
|
|
292
302
|
} else {
|
|
@@ -499,7 +509,7 @@ export async function createApp(
|
|
|
499
509
|
// Copy all the asset files from the addons
|
|
500
510
|
const s = silent ? null : spinner()
|
|
501
511
|
for (const type of ['add-on', 'example']) {
|
|
502
|
-
for (const phase of ['setup', 'add-on']) {
|
|
512
|
+
for (const phase of ['setup', 'add-on', 'example']) {
|
|
503
513
|
for (const addOn of options.chosenAddOns.filter(
|
|
504
514
|
(addOn) => addOn.phase === phase && addOn.type === type,
|
|
505
515
|
)) {
|
package/src/custom-add-on.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { createMemoryEnvironment } from './environment.js'
|
|
|
7
7
|
import { createApp } from './create-app.js'
|
|
8
8
|
import { readConfigFile } from './config-file.js'
|
|
9
9
|
import { finalizeAddOns } from './add-ons.js'
|
|
10
|
+
import { readFileHelper } from './file-helper.js'
|
|
10
11
|
|
|
11
12
|
import type { Framework, Options } from './types.js'
|
|
12
13
|
import type { PersistedOptions } from './config-file.js'
|
|
@@ -134,9 +135,7 @@ async function recursivelyGatherFiles(
|
|
|
134
135
|
if (file.isDirectory()) {
|
|
135
136
|
await recursivelyGatherFiles(resolve(path, file.name), files)
|
|
136
137
|
} else {
|
|
137
|
-
files[resolve(path, file.name)] = (
|
|
138
|
-
await readFile(resolve(path, file.name))
|
|
139
|
-
).toString()
|
|
138
|
+
files[resolve(path, file.name)] = readFileHelper(resolve(path, file.name))
|
|
140
139
|
}
|
|
141
140
|
}
|
|
142
141
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { extname } from 'node:path'
|
|
3
|
+
|
|
4
|
+
const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico']
|
|
5
|
+
|
|
6
|
+
export function readFileHelper(path: string): string {
|
|
7
|
+
if (BINARY_EXTENSIONS.includes(extname(path))) {
|
|
8
|
+
return `base64::${readFileSync(path).toString('base64')}`
|
|
9
|
+
} else {
|
|
10
|
+
return readFileSync(path, 'utf-8').toString()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getBinaryFile(content: string): string | null {
|
|
15
|
+
if (content.startsWith('base64::')) {
|
|
16
|
+
const binaryContent = Buffer.from(content.replace('base64::', ''), 'base64')
|
|
17
|
+
return binaryContent as unknown as string
|
|
18
|
+
}
|
|
19
|
+
return null
|
|
20
|
+
}
|
package/src/options.ts
CHANGED
|
@@ -31,11 +31,6 @@ export async function normalizeOptions(
|
|
|
31
31
|
if (parseSeparatedArgs.length > 1) {
|
|
32
32
|
cliOptions.addOns = parseSeparatedArgs
|
|
33
33
|
}
|
|
34
|
-
if (forcedAddOns) {
|
|
35
|
-
cliOptions.addOns = [...cliOptions.addOns, ...forcedAddOns]
|
|
36
|
-
}
|
|
37
|
-
} else if (forcedAddOns) {
|
|
38
|
-
cliOptions.addOns = [...forcedAddOns]
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
if (cliOptions.projectName) {
|
|
@@ -65,11 +60,21 @@ export async function normalizeOptions(
|
|
|
65
60
|
|
|
66
61
|
let addOns = false
|
|
67
62
|
let chosenAddOns: Array<AddOn> = []
|
|
68
|
-
if (
|
|
63
|
+
if (
|
|
64
|
+
Array.isArray(cliOptions.addOns) ||
|
|
65
|
+
overlay?.dependsOn ||
|
|
66
|
+
forcedAddOns
|
|
67
|
+
) {
|
|
69
68
|
addOns = true
|
|
70
69
|
let finalAddOns = [...(overlay?.dependsOn || [])]
|
|
71
70
|
if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
|
|
72
|
-
finalAddOns =
|
|
71
|
+
finalAddOns = Array.from(
|
|
72
|
+
new Set([
|
|
73
|
+
...(forcedAddOns || []),
|
|
74
|
+
...finalAddOns,
|
|
75
|
+
...cliOptions.addOns,
|
|
76
|
+
]),
|
|
77
|
+
)
|
|
73
78
|
}
|
|
74
79
|
chosenAddOns = await finalizeAddOns(
|
|
75
80
|
cliOptions.framework || DEFAULT_FRAMEWORK,
|