@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.
Files changed (83) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/edge-add-ons.js +106 -0
  3. package/dist/edge-config-file.js +15 -0
  4. package/dist/edge-create-app.js +438 -0
  5. package/dist/edge-environment.js +141 -0
  6. package/dist/edge-file-helpers.js +88 -0
  7. package/dist/edge-frameworks.js +33 -0
  8. package/dist/edge-package-json.js +146 -0
  9. package/dist/edge-path.js +62 -0
  10. package/dist/edge-render.js +31 -0
  11. package/dist/edge-template-file.js +141 -0
  12. package/dist/edge.js +7 -0
  13. package/dist/frameworks/react/add-ons/storybook/info.json +5 -10
  14. package/dist/generated/create-manifest.js +4683 -0
  15. package/dist/manifest-types.js +1 -0
  16. package/dist/manifest.js +1 -0
  17. package/dist/types/custom-add-ons/add-on.d.ts +5 -3
  18. package/dist/types/edge-add-ons.d.ts +5 -0
  19. package/dist/types/edge-config-file.d.ts +8 -0
  20. package/dist/types/edge-create-app.d.ts +2 -0
  21. package/dist/types/edge-environment.d.ts +19 -0
  22. package/dist/types/edge-file-helpers.d.ts +7 -0
  23. package/dist/types/edge-frameworks.d.ts +7 -0
  24. package/dist/types/edge-package-json.d.ts +3 -0
  25. package/dist/types/edge-path.d.ts +5 -0
  26. package/dist/types/edge-render.d.ts +1 -0
  27. package/dist/types/edge-template-file.d.ts +2 -0
  28. package/dist/types/edge.d.ts +9 -0
  29. package/dist/types/generated/create-manifest.d.ts +36 -0
  30. package/dist/types/manifest-types.d.ts +4 -0
  31. package/dist/types/manifest.d.ts +1 -0
  32. package/dist/types/types.d.ts +96 -56
  33. package/dist/types.js +5 -3
  34. package/package.json +25 -5
  35. package/scripts/generate-manifest.mjs +407 -0
  36. package/src/edge-add-ons.ts +138 -0
  37. package/src/edge-config-file.ts +35 -0
  38. package/src/edge-create-app.ts +594 -0
  39. package/src/edge-environment.ts +175 -0
  40. package/src/edge-file-helpers.ts +112 -0
  41. package/src/edge-frameworks.ts +54 -0
  42. package/src/edge-package-json.ts +212 -0
  43. package/src/edge-path.ts +77 -0
  44. package/src/edge-render.ts +32 -0
  45. package/src/edge-template-file.ts +204 -0
  46. package/src/edge.ts +43 -0
  47. package/src/frameworks/react/add-ons/storybook/info.json +5 -10
  48. package/src/generated/create-manifest.ts +6490 -0
  49. package/src/manifest-types.ts +8 -0
  50. package/src/manifest.ts +1 -0
  51. package/src/types.ts +5 -3
  52. package/tests/edge-import.test.ts +31 -0
  53. package/tests/edge-manifest.test.ts +168 -0
  54. package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.ts +0 -17
  55. package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.ts +0 -15
  56. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.ts +0 -67
  57. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +0 -47
  58. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.stories.tsx +0 -92
  59. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +0 -29
  60. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.ts +0 -14
  61. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.ts +0 -43
  62. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +0 -39
  63. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.ts +0 -53
  64. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +0 -52
  65. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.ts +0 -55
  66. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +0 -57
  67. package/dist/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +0 -93
  68. package/dist/frameworks/react/add-ons/storybook/package.json +0 -10
  69. package/src/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.ts +0 -17
  70. package/src/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.ts +0 -15
  71. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.ts +0 -67
  72. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +0 -47
  73. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.stories.tsx +0 -92
  74. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +0 -29
  75. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.ts +0 -14
  76. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.ts +0 -43
  77. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +0 -39
  78. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.ts +0 -53
  79. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +0 -52
  80. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.ts +0 -55
  81. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +0 -57
  82. package/src/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +0 -93
  83. 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": 18,
11
- "routes": [
12
- {
13
- "icon": "BookOpen",
14
- "url": "/demo/storybook",
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
  }