@tanstack/create 0.68.2 → 0.68.3
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/CHANGELOG.md +6 -0
- package/dist/edge-add-ons.js +106 -0
- package/dist/edge-config-file.js +15 -0
- package/dist/edge-create-app.js +438 -0
- package/dist/edge-environment.js +141 -0
- package/dist/edge-file-helpers.js +88 -0
- package/dist/edge-frameworks.js +33 -0
- package/dist/edge-package-json.js +146 -0
- package/dist/edge-path.js +62 -0
- package/dist/edge-render.js +31 -0
- package/dist/edge-template-file.js +141 -0
- package/dist/edge.js +7 -0
- package/dist/frameworks/react/add-ons/storybook/info.json +5 -10
- package/dist/generated/create-manifest.js +4683 -0
- package/dist/manifest-types.js +1 -0
- package/dist/manifest.js +1 -0
- package/dist/types/custom-add-ons/add-on.d.ts +5 -3
- package/dist/types/edge-add-ons.d.ts +5 -0
- package/dist/types/edge-config-file.d.ts +8 -0
- package/dist/types/edge-create-app.d.ts +2 -0
- package/dist/types/edge-environment.d.ts +19 -0
- package/dist/types/edge-file-helpers.d.ts +7 -0
- package/dist/types/edge-frameworks.d.ts +7 -0
- package/dist/types/edge-package-json.d.ts +3 -0
- package/dist/types/edge-path.d.ts +5 -0
- package/dist/types/edge-render.d.ts +1 -0
- package/dist/types/edge-template-file.d.ts +2 -0
- package/dist/types/edge.d.ts +9 -0
- package/dist/types/generated/create-manifest.d.ts +36 -0
- package/dist/types/manifest-types.d.ts +4 -0
- package/dist/types/manifest.d.ts +1 -0
- package/dist/types/types.d.ts +96 -56
- package/dist/types.js +5 -3
- package/package.json +25 -5
- package/scripts/generate-manifest.mjs +407 -0
- package/src/edge-add-ons.ts +138 -0
- package/src/edge-config-file.ts +35 -0
- package/src/edge-create-app.ts +594 -0
- package/src/edge-environment.ts +175 -0
- package/src/edge-file-helpers.ts +112 -0
- package/src/edge-frameworks.ts +54 -0
- package/src/edge-package-json.ts +212 -0
- package/src/edge-path.ts +77 -0
- package/src/edge-render.ts +32 -0
- package/src/edge-template-file.ts +204 -0
- package/src/edge.ts +43 -0
- package/src/frameworks/react/add-ons/storybook/info.json +5 -10
- package/src/generated/create-manifest.ts +6490 -0
- package/src/manifest-types.ts +8 -0
- package/src/manifest.ts +1 -0
- package/src/types.ts +5 -3
- package/tests/edge-import.test.ts +31 -0
- package/tests/edge-manifest.test.ts +168 -0
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.ts +0 -17
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.ts +0 -15
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.ts +0 -67
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +0 -47
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.stories.tsx +0 -92
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +0 -29
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.ts +0 -14
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.ts +0 -43
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +0 -39
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.ts +0 -53
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +0 -52
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.ts +0 -55
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +0 -57
- package/dist/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +0 -93
- package/dist/frameworks/react/add-ons/storybook/package.json +0 -10
- package/src/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.ts +0 -17
- package/src/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.ts +0 -15
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.ts +0 -67
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +0 -47
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.stories.tsx +0 -92
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +0 -29
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.ts +0 -14
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.ts +0 -43
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +0 -39
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.ts +0 -53
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +0 -52
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.ts +0 -55
- package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +0 -57
- package/src/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +0 -93
- package/src/frameworks/react/add-ons/storybook/package.json +0 -10
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { cleanUpFileArray, cleanUpFiles } from './edge-file-helpers.js';
|
|
2
|
+
import { basenamePath, dirnamePath, joinPaths, normalizePath, } from './edge-path.js';
|
|
3
|
+
function hasDirectory(files, path) {
|
|
4
|
+
const directory = normalizePath(path);
|
|
5
|
+
const prefix = directory.endsWith('/') ? directory : `${directory}/`;
|
|
6
|
+
return Object.keys(files).some((file) => file.startsWith(prefix));
|
|
7
|
+
}
|
|
8
|
+
function createMissingDirectoryError(path) {
|
|
9
|
+
return new Error(`Directory not found: ${path}`);
|
|
10
|
+
}
|
|
11
|
+
export function createMemoryEnvironment(returnPathsRelativeTo = '') {
|
|
12
|
+
const output = {
|
|
13
|
+
files: {},
|
|
14
|
+
commands: [],
|
|
15
|
+
deletedFiles: [],
|
|
16
|
+
};
|
|
17
|
+
const files = {};
|
|
18
|
+
let errors = [];
|
|
19
|
+
const environment = {
|
|
20
|
+
startRun: () => {
|
|
21
|
+
errors = [];
|
|
22
|
+
output.files = {};
|
|
23
|
+
output.commands = [];
|
|
24
|
+
output.deletedFiles = [];
|
|
25
|
+
},
|
|
26
|
+
finishRun: () => {
|
|
27
|
+
output.files = Object.keys(files).reduce((acc, file) => {
|
|
28
|
+
acc[file] = files[file];
|
|
29
|
+
return acc;
|
|
30
|
+
}, {});
|
|
31
|
+
if (returnPathsRelativeTo.length) {
|
|
32
|
+
output.files = cleanUpFiles(output.files, returnPathsRelativeTo);
|
|
33
|
+
output.deletedFiles = cleanUpFileArray(output.deletedFiles, returnPathsRelativeTo);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
getErrors: () => errors,
|
|
37
|
+
appendFile: (path, contents) => {
|
|
38
|
+
const normalized = normalizePath(path);
|
|
39
|
+
files[normalized] = `${files[normalized] ?? ''}${contents}`;
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
},
|
|
42
|
+
copyFile: (from, to) => {
|
|
43
|
+
const normalizedFrom = normalizePath(from);
|
|
44
|
+
const normalizedTo = normalizePath(to);
|
|
45
|
+
if (!(normalizedFrom in files)) {
|
|
46
|
+
throw new Error(`File not found: ${from}`);
|
|
47
|
+
}
|
|
48
|
+
files[normalizedTo] = files[normalizedFrom];
|
|
49
|
+
return Promise.resolve();
|
|
50
|
+
},
|
|
51
|
+
writeFile: (path, contents) => {
|
|
52
|
+
files[normalizePath(path)] = contents;
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
},
|
|
55
|
+
writeFileBase64: (path, base64Contents) => {
|
|
56
|
+
files[normalizePath(path)] = base64Contents;
|
|
57
|
+
return Promise.resolve();
|
|
58
|
+
},
|
|
59
|
+
execute: (command, args) => {
|
|
60
|
+
output.commands.push({
|
|
61
|
+
command,
|
|
62
|
+
args,
|
|
63
|
+
});
|
|
64
|
+
return Promise.resolve({ stdout: '' });
|
|
65
|
+
},
|
|
66
|
+
deleteFile: (path) => {
|
|
67
|
+
const normalized = normalizePath(path);
|
|
68
|
+
output.deletedFiles.push(normalized);
|
|
69
|
+
delete files[normalized];
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
},
|
|
72
|
+
exists: (path) => {
|
|
73
|
+
const normalized = normalizePath(path);
|
|
74
|
+
return normalized in files || hasDirectory(files, normalized);
|
|
75
|
+
},
|
|
76
|
+
isDirectory: (path) => hasDirectory(files, path),
|
|
77
|
+
readFile: (path) => {
|
|
78
|
+
const normalized = normalizePath(path);
|
|
79
|
+
if (!(normalized in files)) {
|
|
80
|
+
throw new Error(`File not found: ${path}`);
|
|
81
|
+
}
|
|
82
|
+
return Promise.resolve(files[normalized]);
|
|
83
|
+
},
|
|
84
|
+
readdir: (path) => {
|
|
85
|
+
const normalized = normalizePath(path);
|
|
86
|
+
const directory = normalized === '.' ? '' : normalized;
|
|
87
|
+
const prefix = directory ? `${directory}/` : '';
|
|
88
|
+
if (directory && !hasDirectory(files, directory)) {
|
|
89
|
+
throw createMissingDirectoryError(path);
|
|
90
|
+
}
|
|
91
|
+
const entries = new Set();
|
|
92
|
+
for (const file of Object.keys(files)) {
|
|
93
|
+
if (!file.startsWith(prefix)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const rest = file.slice(prefix.length);
|
|
97
|
+
const entry = rest.split('/')[0];
|
|
98
|
+
if (entry) {
|
|
99
|
+
entries.add(entry);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return Promise.resolve(Array.from(entries));
|
|
103
|
+
},
|
|
104
|
+
rimraf: (path) => {
|
|
105
|
+
const normalized = normalizePath(path);
|
|
106
|
+
const prefix = normalized.endsWith('/') ? normalized : `${normalized}/`;
|
|
107
|
+
for (const file of Object.keys(files)) {
|
|
108
|
+
if (file === normalized || file.startsWith(prefix)) {
|
|
109
|
+
delete files[file];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return Promise.resolve();
|
|
113
|
+
},
|
|
114
|
+
appName: 'TanStack',
|
|
115
|
+
startStep: () => { },
|
|
116
|
+
finishStep: () => { },
|
|
117
|
+
intro: () => { },
|
|
118
|
+
outro: () => { },
|
|
119
|
+
info: () => { },
|
|
120
|
+
error: (_title, message) => {
|
|
121
|
+
if (message) {
|
|
122
|
+
errors.push(message);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
warn: () => { },
|
|
126
|
+
confirm: () => Promise.resolve(true),
|
|
127
|
+
spinner: () => ({
|
|
128
|
+
start: () => { },
|
|
129
|
+
stop: () => { },
|
|
130
|
+
}),
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
environment,
|
|
134
|
+
output,
|
|
135
|
+
paths: {
|
|
136
|
+
basename: basenamePath,
|
|
137
|
+
dirname: dirnamePath,
|
|
138
|
+
join: joinPaths,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { basenamePath, extnamePath } from './edge-path.js';
|
|
2
|
+
import { hasDrive, stripDrive } from './utils.js';
|
|
3
|
+
const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico'];
|
|
4
|
+
export function isBinaryFile(path) {
|
|
5
|
+
return BINARY_EXTENSIONS.includes(extnamePath(path));
|
|
6
|
+
}
|
|
7
|
+
export function isBase64(content) {
|
|
8
|
+
return content.startsWith('base64::');
|
|
9
|
+
}
|
|
10
|
+
export function toCleanPath(absolutePath, baseDir) {
|
|
11
|
+
const normalizedPath = absolutePath.replace(/\\/g, '/');
|
|
12
|
+
const normalizedBase = baseDir.replace(/\\/g, '/');
|
|
13
|
+
let cleanPath = normalizedPath;
|
|
14
|
+
if (normalizedPath.startsWith(normalizedBase)) {
|
|
15
|
+
cleanPath = normalizedPath.slice(normalizedBase.length);
|
|
16
|
+
}
|
|
17
|
+
else if (hasDrive(normalizedPath) !== hasDrive(normalizedBase)) {
|
|
18
|
+
const pathNoDrive = stripDrive(normalizedPath);
|
|
19
|
+
const baseNoDrive = stripDrive(normalizedBase);
|
|
20
|
+
if (pathNoDrive.startsWith(baseNoDrive)) {
|
|
21
|
+
cleanPath = pathNoDrive.slice(baseNoDrive.length);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (cleanPath.startsWith('/')) {
|
|
25
|
+
cleanPath = cleanPath.slice(1);
|
|
26
|
+
}
|
|
27
|
+
return cleanPath;
|
|
28
|
+
}
|
|
29
|
+
export function relativePath(from, to, stripExtension = false) {
|
|
30
|
+
const normalized = from.replace(/\\/g, '/');
|
|
31
|
+
const cleanedFrom = normalized.startsWith('./')
|
|
32
|
+
? normalized.slice(2)
|
|
33
|
+
: normalized;
|
|
34
|
+
const cleanedTo = to.startsWith('./') ? to.slice(2) : to;
|
|
35
|
+
const fromSegments = cleanedFrom.split('/');
|
|
36
|
+
const toSegments = cleanedTo.split('/');
|
|
37
|
+
fromSegments.pop();
|
|
38
|
+
toSegments.pop();
|
|
39
|
+
let commonIndex = 0;
|
|
40
|
+
while (commonIndex < fromSegments.length &&
|
|
41
|
+
commonIndex < toSegments.length &&
|
|
42
|
+
fromSegments[commonIndex] === toSegments[commonIndex]) {
|
|
43
|
+
commonIndex++;
|
|
44
|
+
}
|
|
45
|
+
const upLevels = fromSegments.length - commonIndex;
|
|
46
|
+
const downLevels = toSegments.slice(commonIndex);
|
|
47
|
+
const target = stripExtension ? to.replace(extnamePath(to), '') : to;
|
|
48
|
+
if (upLevels === 0 && downLevels.length === 0) {
|
|
49
|
+
return `./${basenamePath(target)}`;
|
|
50
|
+
}
|
|
51
|
+
else if (upLevels === 0 && downLevels.length > 0) {
|
|
52
|
+
return `./${downLevels.join('/')}/${basenamePath(target)}`;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const relative = [...Array(upLevels).fill('..'), ...downLevels].join('/');
|
|
56
|
+
return `${relative}/${basenamePath(target)}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function isDemoFilePath(path) {
|
|
60
|
+
if (!path)
|
|
61
|
+
return false;
|
|
62
|
+
const normalized = path.replace(/\\/g, '/');
|
|
63
|
+
if (normalized.includes('/routes/demo/') ||
|
|
64
|
+
normalized.includes('/routes/example/')) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const filename = normalized.split('/').pop() || '';
|
|
68
|
+
return (filename.startsWith('demo.') ||
|
|
69
|
+
filename.startsWith('demo-') ||
|
|
70
|
+
filename.startsWith('example.') ||
|
|
71
|
+
filename.startsWith('example-'));
|
|
72
|
+
}
|
|
73
|
+
export function cleanUpFiles(files, targetDir) {
|
|
74
|
+
return Object.keys(files).reduce((acc, file) => {
|
|
75
|
+
if (basenamePath(file) !== '.cta.json') {
|
|
76
|
+
acc[targetDir ? toCleanPath(file, targetDir) : file] = files[file];
|
|
77
|
+
}
|
|
78
|
+
return acc;
|
|
79
|
+
}, {});
|
|
80
|
+
}
|
|
81
|
+
export function cleanUpFileArray(files, targetDir) {
|
|
82
|
+
return files.reduce((acc, file) => {
|
|
83
|
+
if (basenamePath(file) !== '.cta.json') {
|
|
84
|
+
acc.push(targetDir ? toCleanPath(file, targetDir) : file);
|
|
85
|
+
}
|
|
86
|
+
return acc;
|
|
87
|
+
}, []);
|
|
88
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createManifestFrameworks } from './generated/create-manifest.js';
|
|
2
|
+
function createAddOn(addOn) {
|
|
3
|
+
return {
|
|
4
|
+
...addOn,
|
|
5
|
+
getFiles: () => Promise.resolve(Object.keys(addOn.files)),
|
|
6
|
+
getFileContents: (path) => Promise.resolve(addOn.files[path]),
|
|
7
|
+
getDeletedFiles: () => Promise.resolve(addOn.deletedFiles),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function createFrameworkFromManifest(framework) {
|
|
11
|
+
const addOns = framework.addOns.map(createAddOn);
|
|
12
|
+
const { addOns: _addOns, base, ...rest } = framework;
|
|
13
|
+
return {
|
|
14
|
+
...rest,
|
|
15
|
+
getFiles: () => Promise.resolve(Object.keys(base)),
|
|
16
|
+
getFileContents: (path) => Promise.resolve(base[path]),
|
|
17
|
+
getDeletedFiles: () => Promise.resolve([]),
|
|
18
|
+
getAddOns: () => addOns,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const frameworks = createManifestFrameworks().map(createFrameworkFromManifest);
|
|
22
|
+
export function getFrameworkById(id) {
|
|
23
|
+
if (id === 'react-cra') {
|
|
24
|
+
return frameworks.find((framework) => framework.id === 'react');
|
|
25
|
+
}
|
|
26
|
+
return frameworks.find((framework) => framework.id === id);
|
|
27
|
+
}
|
|
28
|
+
export function getFrameworkByName(name) {
|
|
29
|
+
return frameworks.find((framework) => framework.name.toLowerCase() === name.toLowerCase());
|
|
30
|
+
}
|
|
31
|
+
export function getFrameworks() {
|
|
32
|
+
return frameworks;
|
|
33
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { render } from './edge-render.js';
|
|
2
|
+
import { formatCommand, sortObject } from './utils.js';
|
|
3
|
+
import { getPackageManagerExecuteCommand } from './package-manager.js';
|
|
4
|
+
export function mergePackageJSON(packageJSON, overlayPackageJSON) {
|
|
5
|
+
const packageDependencies = packageJSON.dependencies && typeof packageJSON.dependencies === 'object'
|
|
6
|
+
? packageJSON.dependencies
|
|
7
|
+
: {};
|
|
8
|
+
const overlayDependencies = overlayPackageJSON?.dependencies &&
|
|
9
|
+
typeof overlayPackageJSON.dependencies === 'object'
|
|
10
|
+
? overlayPackageJSON.dependencies
|
|
11
|
+
: {};
|
|
12
|
+
const packageDevDependencies = packageJSON.devDependencies && typeof packageJSON.devDependencies === 'object'
|
|
13
|
+
? packageJSON.devDependencies
|
|
14
|
+
: {};
|
|
15
|
+
const overlayDevDependencies = overlayPackageJSON?.devDependencies &&
|
|
16
|
+
typeof overlayPackageJSON.devDependencies === 'object'
|
|
17
|
+
? overlayPackageJSON.devDependencies
|
|
18
|
+
: {};
|
|
19
|
+
const packageScripts = packageJSON.scripts && typeof packageJSON.scripts === 'object'
|
|
20
|
+
? packageJSON.scripts
|
|
21
|
+
: {};
|
|
22
|
+
const overlayScripts = overlayPackageJSON?.scripts && typeof overlayPackageJSON.scripts === 'object'
|
|
23
|
+
? overlayPackageJSON.scripts
|
|
24
|
+
: {};
|
|
25
|
+
const mergedPackageJSON = {
|
|
26
|
+
...packageJSON,
|
|
27
|
+
...(overlayPackageJSON || {}),
|
|
28
|
+
dependencies: {
|
|
29
|
+
...packageDependencies,
|
|
30
|
+
...overlayDependencies,
|
|
31
|
+
},
|
|
32
|
+
devDependencies: {
|
|
33
|
+
...packageDevDependencies,
|
|
34
|
+
...overlayDevDependencies,
|
|
35
|
+
},
|
|
36
|
+
scripts: {
|
|
37
|
+
...packageScripts,
|
|
38
|
+
...overlayScripts,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const packagePnpm = packageJSON.pnpm && typeof packageJSON.pnpm === 'object'
|
|
42
|
+
? packageJSON.pnpm
|
|
43
|
+
: undefined;
|
|
44
|
+
const overlayPnpm = overlayPackageJSON?.pnpm && typeof overlayPackageJSON.pnpm === 'object'
|
|
45
|
+
? overlayPackageJSON.pnpm
|
|
46
|
+
: undefined;
|
|
47
|
+
const baseOnlyBuiltDependencies = Array.isArray(packagePnpm?.onlyBuiltDependencies)
|
|
48
|
+
? packagePnpm.onlyBuiltDependencies
|
|
49
|
+
: [];
|
|
50
|
+
const overlayOnlyBuiltDependencies = Array.isArray(overlayPnpm?.onlyBuiltDependencies)
|
|
51
|
+
? overlayPnpm.onlyBuiltDependencies
|
|
52
|
+
: [];
|
|
53
|
+
const onlyBuiltDependencies = [
|
|
54
|
+
...new Set([
|
|
55
|
+
...baseOnlyBuiltDependencies,
|
|
56
|
+
...overlayOnlyBuiltDependencies,
|
|
57
|
+
]),
|
|
58
|
+
];
|
|
59
|
+
if (packagePnpm || overlayPnpm) {
|
|
60
|
+
mergedPackageJSON.pnpm = {
|
|
61
|
+
...packagePnpm,
|
|
62
|
+
...overlayPnpm,
|
|
63
|
+
};
|
|
64
|
+
if (onlyBuiltDependencies.length) {
|
|
65
|
+
const mergedPnpm = mergedPackageJSON.pnpm;
|
|
66
|
+
mergedPnpm.onlyBuiltDependencies = onlyBuiltDependencies;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return mergedPackageJSON;
|
|
70
|
+
}
|
|
71
|
+
export function createPackageJSON(options) {
|
|
72
|
+
const packageManager = options.packageManager;
|
|
73
|
+
function getPackageManagerExecuteScript(pkg, args = []) {
|
|
74
|
+
return formatCommand(getPackageManagerExecuteCommand(packageManager, pkg, args));
|
|
75
|
+
}
|
|
76
|
+
let packageJSON = {
|
|
77
|
+
...JSON.parse(JSON.stringify(options.framework.basePackageJSON)),
|
|
78
|
+
name: options.projectName,
|
|
79
|
+
};
|
|
80
|
+
const additions = [
|
|
81
|
+
options.framework.optionalPackages.typescript,
|
|
82
|
+
options.framework.optionalPackages.tailwindcss,
|
|
83
|
+
options.mode ? options.framework.optionalPackages[options.mode] : undefined,
|
|
84
|
+
];
|
|
85
|
+
for (const addition of additions.filter((addition) => Boolean(addition))) {
|
|
86
|
+
packageJSON = mergePackageJSON(packageJSON, addition);
|
|
87
|
+
}
|
|
88
|
+
for (const addOn of options.chosenAddOns) {
|
|
89
|
+
let addOnPackageJSON = addOn.packageAdditions;
|
|
90
|
+
if (addOn.packageTemplate) {
|
|
91
|
+
const templateValues = {
|
|
92
|
+
packageManager: options.packageManager,
|
|
93
|
+
projectName: options.projectName,
|
|
94
|
+
typescript: true,
|
|
95
|
+
tailwind: true,
|
|
96
|
+
js: 'ts',
|
|
97
|
+
jsx: 'tsx',
|
|
98
|
+
fileRouter: options.mode === 'file-router',
|
|
99
|
+
codeRouter: options.mode === 'code-router',
|
|
100
|
+
routerOnly: options.routerOnly === true,
|
|
101
|
+
addOnEnabled: options.chosenAddOns.reduce((acc, addon) => {
|
|
102
|
+
acc[addon.id] = true;
|
|
103
|
+
return acc;
|
|
104
|
+
}, {}),
|
|
105
|
+
addOnOption: options.addOnOptions,
|
|
106
|
+
addOns: options.chosenAddOns,
|
|
107
|
+
getPackageManagerExecuteScript,
|
|
108
|
+
};
|
|
109
|
+
try {
|
|
110
|
+
addOnPackageJSON = JSON.parse(render(addOn.packageTemplate, templateValues));
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(`Error processing package.json.ejs for add-on ${addOn.id}:`, error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
packageJSON = mergePackageJSON(packageJSON, addOnPackageJSON);
|
|
117
|
+
}
|
|
118
|
+
if (options.starter) {
|
|
119
|
+
packageJSON = mergePackageJSON(packageJSON, options.starter.packageAdditions);
|
|
120
|
+
}
|
|
121
|
+
const dependencies = packageJSON.dependencies;
|
|
122
|
+
const devDependencies = packageJSON.devDependencies;
|
|
123
|
+
const scripts = packageJSON.scripts;
|
|
124
|
+
if (options.routerOnly) {
|
|
125
|
+
if (options.framework.id === 'react') {
|
|
126
|
+
delete dependencies?.['@tanstack/react-start'];
|
|
127
|
+
delete dependencies?.['@tanstack/react-router-ssr-query'];
|
|
128
|
+
packageJSON.devDependencies = {
|
|
129
|
+
...(devDependencies ?? {}),
|
|
130
|
+
'@tanstack/router-plugin': devDependencies?.['@tanstack/router-plugin'] ?? 'latest',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (options.framework.id === 'solid') {
|
|
134
|
+
delete dependencies?.['@tanstack/solid-start'];
|
|
135
|
+
delete dependencies?.['@tanstack/solid-router-ssr-query'];
|
|
136
|
+
delete scripts?.start;
|
|
137
|
+
packageJSON.devDependencies = {
|
|
138
|
+
...(devDependencies ?? {}),
|
|
139
|
+
'@tanstack/router-plugin': devDependencies?.['@tanstack/router-plugin'] ?? 'latest',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
packageJSON.dependencies = sortObject((packageJSON.dependencies ?? {}));
|
|
144
|
+
packageJSON.devDependencies = sortObject((packageJSON.devDependencies ?? {}));
|
|
145
|
+
return packageJSON;
|
|
146
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export function normalizePath(path) {
|
|
2
|
+
const normalized = path.replace(/\\/g, '/');
|
|
3
|
+
const isAbsolute = normalized.startsWith('/');
|
|
4
|
+
const parts = [];
|
|
5
|
+
for (const part of normalized.split('/')) {
|
|
6
|
+
if (!part || part === '.') {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
if (part === '..') {
|
|
10
|
+
if (parts.length && parts[parts.length - 1] !== '..') {
|
|
11
|
+
parts.pop();
|
|
12
|
+
}
|
|
13
|
+
else if (!isAbsolute) {
|
|
14
|
+
parts.push(part);
|
|
15
|
+
}
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
parts.push(part);
|
|
19
|
+
}
|
|
20
|
+
const joined = parts.join('/');
|
|
21
|
+
if (isAbsolute) {
|
|
22
|
+
return joined ? `/${joined}` : '/';
|
|
23
|
+
}
|
|
24
|
+
return joined || '.';
|
|
25
|
+
}
|
|
26
|
+
export function joinPaths(...paths) {
|
|
27
|
+
const filtered = paths.filter((path) => typeof path === 'string' && path.length > 0);
|
|
28
|
+
if (!filtered.length) {
|
|
29
|
+
return '.';
|
|
30
|
+
}
|
|
31
|
+
return normalizePath(filtered.join('/'));
|
|
32
|
+
}
|
|
33
|
+
export function basenamePath(path) {
|
|
34
|
+
const normalized = normalizePath(path);
|
|
35
|
+
if (normalized === '/') {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
return normalized.split('/').pop() ?? '';
|
|
39
|
+
}
|
|
40
|
+
export function dirnamePath(path) {
|
|
41
|
+
const normalized = normalizePath(path);
|
|
42
|
+
if (normalized === '/') {
|
|
43
|
+
return '/';
|
|
44
|
+
}
|
|
45
|
+
const parts = normalized.split('/');
|
|
46
|
+
parts.pop();
|
|
47
|
+
if (!parts.length) {
|
|
48
|
+
return '.';
|
|
49
|
+
}
|
|
50
|
+
if (parts.length === 1 && parts[0] === '') {
|
|
51
|
+
return '/';
|
|
52
|
+
}
|
|
53
|
+
return parts.join('/') || '.';
|
|
54
|
+
}
|
|
55
|
+
export function extnamePath(path) {
|
|
56
|
+
const basename = basenamePath(path);
|
|
57
|
+
const index = basename.lastIndexOf('.');
|
|
58
|
+
if (index <= 0) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
return basename.slice(index);
|
|
62
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { renderManifestTemplate } from './generated/create-manifest.js';
|
|
2
|
+
export function render(template, data) {
|
|
3
|
+
return renderManifestTemplate(template, {
|
|
4
|
+
packageManager: undefined,
|
|
5
|
+
projectName: undefined,
|
|
6
|
+
typescript: undefined,
|
|
7
|
+
tailwind: undefined,
|
|
8
|
+
js: undefined,
|
|
9
|
+
jsx: undefined,
|
|
10
|
+
fileRouter: undefined,
|
|
11
|
+
codeRouter: undefined,
|
|
12
|
+
routerOnly: undefined,
|
|
13
|
+
includeExamples: undefined,
|
|
14
|
+
addOnEnabled: {},
|
|
15
|
+
addOnOption: {},
|
|
16
|
+
addOns: [],
|
|
17
|
+
integrations: [],
|
|
18
|
+
routes: [],
|
|
19
|
+
getPackageManagerAddScript: () => '',
|
|
20
|
+
getPackageManagerRunScript: () => '',
|
|
21
|
+
getPackageManagerExecuteScript: () => '',
|
|
22
|
+
relativePath: () => '',
|
|
23
|
+
integrationImportContent: () => '',
|
|
24
|
+
integrationImportCode: () => '',
|
|
25
|
+
renderTemplate: () => '',
|
|
26
|
+
ignoreFile: () => {
|
|
27
|
+
throw new Error('ignoreFile');
|
|
28
|
+
},
|
|
29
|
+
...(data ?? {}),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { render } from './edge-render.js';
|
|
2
|
+
import { relativePath } from './edge-file-helpers.js';
|
|
3
|
+
import { joinPaths } from './edge-path.js';
|
|
4
|
+
import { formatCommand } from './utils.js';
|
|
5
|
+
import { getPackageManagerExecuteCommand, getPackageManagerInstallCommand, getPackageManagerScriptCommand, } from './package-manager.js';
|
|
6
|
+
function convertDotFilesAndPaths(path) {
|
|
7
|
+
return path
|
|
8
|
+
.split('/')
|
|
9
|
+
.map((segment) => segment.replace(/^_dot_/, '.'))
|
|
10
|
+
.join('/');
|
|
11
|
+
}
|
|
12
|
+
function normalizeSourceExtension(target, typescript) {
|
|
13
|
+
if (!typescript) {
|
|
14
|
+
return target;
|
|
15
|
+
}
|
|
16
|
+
const normalizedTarget = target.replace(/\\/g, '/');
|
|
17
|
+
if (!normalizedTarget.startsWith('src/')) {
|
|
18
|
+
return target;
|
|
19
|
+
}
|
|
20
|
+
if (normalizedTarget.endsWith('.js')) {
|
|
21
|
+
return `${target.slice(0, -3)}.ts`;
|
|
22
|
+
}
|
|
23
|
+
if (normalizedTarget.endsWith('.jsx')) {
|
|
24
|
+
return `${target.slice(0, -4)}.tsx`;
|
|
25
|
+
}
|
|
26
|
+
return target;
|
|
27
|
+
}
|
|
28
|
+
export function createTemplateFile(environment, options) {
|
|
29
|
+
function getPackageManagerAddScript(packageName, isDev = false) {
|
|
30
|
+
return formatCommand(getPackageManagerInstallCommand(options.packageManager, packageName, isDev));
|
|
31
|
+
}
|
|
32
|
+
function getPackageManagerRunScript(scriptName, args = []) {
|
|
33
|
+
return formatCommand(getPackageManagerScriptCommand(options.packageManager, [
|
|
34
|
+
scriptName,
|
|
35
|
+
...args,
|
|
36
|
+
]));
|
|
37
|
+
}
|
|
38
|
+
function getPackageManagerExecuteScript(pkg, args = []) {
|
|
39
|
+
return formatCommand(getPackageManagerExecuteCommand(options.packageManager, pkg, args));
|
|
40
|
+
}
|
|
41
|
+
class IgnoreFileError extends Error {
|
|
42
|
+
constructor() {
|
|
43
|
+
super('ignoreFile');
|
|
44
|
+
this.name = 'IgnoreFileError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const integrations = [];
|
|
48
|
+
for (const addOn of options.chosenAddOns) {
|
|
49
|
+
if (addOn.integrations) {
|
|
50
|
+
for (const integration of addOn.integrations) {
|
|
51
|
+
integrations.push({
|
|
52
|
+
...integration,
|
|
53
|
+
_sourceId: addOn.id,
|
|
54
|
+
_sourceName: addOn.name,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const routes = [];
|
|
60
|
+
for (const addOn of options.chosenAddOns) {
|
|
61
|
+
if (addOn.routes) {
|
|
62
|
+
routes.push(...addOn.routes);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const addOnEnabled = options.chosenAddOns.reduce((acc, addOn) => {
|
|
66
|
+
acc[addOn.id] = true;
|
|
67
|
+
return acc;
|
|
68
|
+
}, {});
|
|
69
|
+
return async function templateFile(file, content) {
|
|
70
|
+
const localRelativePath = (path, stripExtension = false) => relativePath(file, path, stripExtension);
|
|
71
|
+
const integrationImportContent = (integration) => integration.import ||
|
|
72
|
+
`import ${integration.jsName} from '${localRelativePath(integration.path || '')}'`;
|
|
73
|
+
const integrationImportCode = (integration) => integration.code || integration.jsName;
|
|
74
|
+
const templateValues = {
|
|
75
|
+
packageManager: options.packageManager,
|
|
76
|
+
projectName: options.projectName,
|
|
77
|
+
typescript: true,
|
|
78
|
+
tailwind: true,
|
|
79
|
+
js: 'ts',
|
|
80
|
+
jsx: 'tsx',
|
|
81
|
+
fileRouter: options.mode === 'file-router',
|
|
82
|
+
codeRouter: options.mode === 'code-router',
|
|
83
|
+
routerOnly: options.routerOnly === true,
|
|
84
|
+
includeExamples: options.includeExamples !== false,
|
|
85
|
+
addOnEnabled,
|
|
86
|
+
addOnOption: options.addOnOptions,
|
|
87
|
+
addOns: options.chosenAddOns,
|
|
88
|
+
integrations,
|
|
89
|
+
routes,
|
|
90
|
+
getPackageManagerAddScript,
|
|
91
|
+
getPackageManagerRunScript,
|
|
92
|
+
getPackageManagerExecuteScript,
|
|
93
|
+
relativePath: (path, stripExtension = false) => relativePath(file, path, stripExtension),
|
|
94
|
+
integrationImportContent,
|
|
95
|
+
integrationImportCode,
|
|
96
|
+
renderTemplate: (templateContent) => {
|
|
97
|
+
return render(templateContent, templateValues);
|
|
98
|
+
},
|
|
99
|
+
ignoreFile: () => {
|
|
100
|
+
throw new IgnoreFileError();
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
let ignoreFile = false;
|
|
104
|
+
if (file.endsWith('.ejs')) {
|
|
105
|
+
try {
|
|
106
|
+
content = render(content, templateValues);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error instanceof IgnoreFileError) {
|
|
110
|
+
ignoreFile = true;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
114
|
+
environment.error(`EJS error in file ${file}`, message);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (ignoreFile) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
let target = convertDotFilesAndPaths(file.replace('.ejs', ''));
|
|
123
|
+
target = normalizeSourceExtension(target, options.typescript);
|
|
124
|
+
const prefixMatch = target.match(/^(.+\/)?__([^_]+)__(.+)$/);
|
|
125
|
+
if (prefixMatch) {
|
|
126
|
+
const [, directory, , filename] = prefixMatch;
|
|
127
|
+
target = (directory || '') + filename;
|
|
128
|
+
}
|
|
129
|
+
let append = false;
|
|
130
|
+
if (target.endsWith('.append')) {
|
|
131
|
+
append = true;
|
|
132
|
+
target = target.replace('.append', '');
|
|
133
|
+
}
|
|
134
|
+
if (append) {
|
|
135
|
+
await environment.appendFile(joinPaths(options.targetDir, target), content);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
await environment.writeFile(joinPaths(options.targetDir, target), content);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
package/dist/edge.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createApp } from './edge-create-app.js';
|
|
2
|
+
export { createMemoryEnvironment, } from './edge-environment.js';
|
|
3
|
+
export { getFrameworkById, getFrameworkByName, getFrameworks, } from './edge-frameworks.js';
|
|
4
|
+
export { finalizeAddOns, getAllAddOns, loadRemoteAddOn, populateAddOnOptionsDefaults, } from './edge-add-ons.js';
|
|
5
|
+
export { createSerializedOptions } from './options.js';
|
|
6
|
+
export { CONFIG_FILE } from './constants.js';
|
|
7
|
+
export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManagerExecuteCommand, getPackageManagerInstallCommand, getPackageManagerScriptCommand, translateExecuteCommand, } from './package-manager.js';
|
|
@@ -7,14 +7,9 @@
|
|
|
7
7
|
"type": "add-on",
|
|
8
8
|
"category": "tooling",
|
|
9
9
|
"color": "#FF4785",
|
|
10
|
-
"priority":
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"name": "Storybook",
|
|
16
|
-
"path": "src/routes/demo.storybook.tsx",
|
|
17
|
-
"jsName": "StorybookDemo"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
10
|
+
"priority": 1,
|
|
11
|
+
"command": {
|
|
12
|
+
"command": "npx",
|
|
13
|
+
"args": ["storybook", "init", "-y", "--no-dev"]
|
|
14
|
+
}
|
|
20
15
|
}
|