@tanstack/cli 0.0.7 → 0.48.2

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/dist/bin.js +7 -0
  2. package/dist/cli.js +481 -0
  3. package/dist/command-line.js +174 -0
  4. package/dist/dev-watch.js +290 -0
  5. package/dist/file-syncer.js +148 -0
  6. package/dist/index.js +1 -0
  7. package/dist/mcp/api.js +31 -0
  8. package/dist/mcp/tools.js +250 -0
  9. package/dist/mcp/types.js +37 -0
  10. package/dist/mcp.js +121 -0
  11. package/dist/options.js +162 -0
  12. package/dist/types/bin.d.ts +2 -0
  13. package/dist/types/cli.d.ts +16 -0
  14. package/dist/types/command-line.d.ts +10 -0
  15. package/dist/types/dev-watch.d.ts +27 -0
  16. package/dist/types/file-syncer.d.ts +18 -0
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/mcp/api.d.ts +4 -0
  19. package/dist/types/mcp/tools.d.ts +2 -0
  20. package/dist/types/mcp/types.d.ts +217 -0
  21. package/dist/types/mcp.d.ts +6 -0
  22. package/dist/types/options.d.ts +8 -0
  23. package/dist/types/types.d.ts +25 -0
  24. package/dist/types/ui-environment.d.ts +2 -0
  25. package/dist/types/ui-prompts.d.ts +12 -0
  26. package/dist/types/utils.d.ts +8 -0
  27. package/dist/types.js +1 -0
  28. package/dist/ui-environment.js +52 -0
  29. package/dist/ui-prompts.js +244 -0
  30. package/dist/utils.js +30 -0
  31. package/package.json +46 -46
  32. package/src/bin.ts +6 -93
  33. package/src/cli.ts +692 -0
  34. package/src/command-line.ts +236 -0
  35. package/src/dev-watch.ts +430 -0
  36. package/src/file-syncer.ts +205 -0
  37. package/src/index.ts +1 -85
  38. package/src/mcp.ts +190 -0
  39. package/src/options.ts +260 -0
  40. package/src/types.ts +27 -0
  41. package/src/ui-environment.ts +74 -0
  42. package/src/ui-prompts.ts +322 -0
  43. package/src/utils.ts +38 -0
  44. package/tests/command-line.test.ts +304 -0
  45. package/tests/index.test.ts +9 -0
  46. package/tests/mcp.test.ts +225 -0
  47. package/tests/options.test.ts +304 -0
  48. package/tests/setupVitest.ts +6 -0
  49. package/tests/ui-environment.test.ts +97 -0
  50. package/tests/ui-prompts.test.ts +238 -0
  51. package/tsconfig.json +17 -0
  52. package/vitest.config.js +7 -0
  53. package/dist/bin.cjs +0 -761
  54. package/dist/bin.d.cts +0 -1
  55. package/dist/bin.d.mts +0 -1
  56. package/dist/bin.mjs +0 -760
  57. package/dist/index.cjs +0 -36
  58. package/dist/index.d.cts +0 -1172
  59. package/dist/index.d.mts +0 -1172
  60. package/dist/index.mjs +0 -3
  61. package/dist/template-CkAkdP8n.mjs +0 -2545
  62. package/dist/template-Cup47s9h.cjs +0 -2783
  63. package/src/api/fetch.test.ts +0 -114
  64. package/src/api/fetch.ts +0 -249
  65. package/src/cache/index.ts +0 -89
  66. package/src/commands/create.ts +0 -463
  67. package/src/commands/mcp.test.ts +0 -152
  68. package/src/commands/mcp.ts +0 -203
  69. package/src/engine/compile-with-addons.test.ts +0 -302
  70. package/src/engine/compile.test.ts +0 -404
  71. package/src/engine/compile.ts +0 -551
  72. package/src/engine/config-file.test.ts +0 -118
  73. package/src/engine/config-file.ts +0 -61
  74. package/src/engine/custom-addons/integration.ts +0 -323
  75. package/src/engine/custom-addons/shared.test.ts +0 -98
  76. package/src/engine/custom-addons/shared.ts +0 -281
  77. package/src/engine/custom-addons/template.test.ts +0 -288
  78. package/src/engine/custom-addons/template.ts +0 -124
  79. package/src/engine/template.test.ts +0 -256
  80. package/src/engine/template.ts +0 -269
  81. package/src/engine/types.ts +0 -336
  82. package/src/parse-gitignore.d.ts +0 -5
  83. package/src/templates/base.ts +0 -891
@@ -0,0 +1,217 @@
1
+ import { z } from 'zod';
2
+ export declare const LibrarySchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ name: z.ZodString;
5
+ tagline: z.ZodString;
6
+ description: z.ZodOptional<z.ZodString>;
7
+ frameworks: z.ZodArray<z.ZodString, "many">;
8
+ latestVersion: z.ZodString;
9
+ latestBranch: z.ZodOptional<z.ZodString>;
10
+ availableVersions: z.ZodArray<z.ZodString, "many">;
11
+ repo: z.ZodString;
12
+ docsRoot: z.ZodOptional<z.ZodString>;
13
+ defaultDocs: z.ZodOptional<z.ZodString>;
14
+ docsUrl: z.ZodOptional<z.ZodString>;
15
+ githubUrl: z.ZodOptional<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ id: string;
18
+ name: string;
19
+ tagline: string;
20
+ frameworks: string[];
21
+ latestVersion: string;
22
+ availableVersions: string[];
23
+ repo: string;
24
+ description?: string | undefined;
25
+ latestBranch?: string | undefined;
26
+ docsRoot?: string | undefined;
27
+ defaultDocs?: string | undefined;
28
+ docsUrl?: string | undefined;
29
+ githubUrl?: string | undefined;
30
+ }, {
31
+ id: string;
32
+ name: string;
33
+ tagline: string;
34
+ frameworks: string[];
35
+ latestVersion: string;
36
+ availableVersions: string[];
37
+ repo: string;
38
+ description?: string | undefined;
39
+ latestBranch?: string | undefined;
40
+ docsRoot?: string | undefined;
41
+ defaultDocs?: string | undefined;
42
+ docsUrl?: string | undefined;
43
+ githubUrl?: string | undefined;
44
+ }>;
45
+ export declare const LibrariesResponseSchema: z.ZodObject<{
46
+ libraries: z.ZodArray<z.ZodObject<{
47
+ id: z.ZodString;
48
+ name: z.ZodString;
49
+ tagline: z.ZodString;
50
+ description: z.ZodOptional<z.ZodString>;
51
+ frameworks: z.ZodArray<z.ZodString, "many">;
52
+ latestVersion: z.ZodString;
53
+ latestBranch: z.ZodOptional<z.ZodString>;
54
+ availableVersions: z.ZodArray<z.ZodString, "many">;
55
+ repo: z.ZodString;
56
+ docsRoot: z.ZodOptional<z.ZodString>;
57
+ defaultDocs: z.ZodOptional<z.ZodString>;
58
+ docsUrl: z.ZodOptional<z.ZodString>;
59
+ githubUrl: z.ZodOptional<z.ZodString>;
60
+ }, "strip", z.ZodTypeAny, {
61
+ id: string;
62
+ name: string;
63
+ tagline: string;
64
+ frameworks: string[];
65
+ latestVersion: string;
66
+ availableVersions: string[];
67
+ repo: string;
68
+ description?: string | undefined;
69
+ latestBranch?: string | undefined;
70
+ docsRoot?: string | undefined;
71
+ defaultDocs?: string | undefined;
72
+ docsUrl?: string | undefined;
73
+ githubUrl?: string | undefined;
74
+ }, {
75
+ id: string;
76
+ name: string;
77
+ tagline: string;
78
+ frameworks: string[];
79
+ latestVersion: string;
80
+ availableVersions: string[];
81
+ repo: string;
82
+ description?: string | undefined;
83
+ latestBranch?: string | undefined;
84
+ docsRoot?: string | undefined;
85
+ defaultDocs?: string | undefined;
86
+ docsUrl?: string | undefined;
87
+ githubUrl?: string | undefined;
88
+ }>, "many">;
89
+ groups: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>;
90
+ groupNames: z.ZodRecord<z.ZodString, z.ZodString>;
91
+ }, "strip", z.ZodTypeAny, {
92
+ libraries: {
93
+ id: string;
94
+ name: string;
95
+ tagline: string;
96
+ frameworks: string[];
97
+ latestVersion: string;
98
+ availableVersions: string[];
99
+ repo: string;
100
+ description?: string | undefined;
101
+ latestBranch?: string | undefined;
102
+ docsRoot?: string | undefined;
103
+ defaultDocs?: string | undefined;
104
+ docsUrl?: string | undefined;
105
+ githubUrl?: string | undefined;
106
+ }[];
107
+ groups: Record<string, string[]>;
108
+ groupNames: Record<string, string>;
109
+ }, {
110
+ libraries: {
111
+ id: string;
112
+ name: string;
113
+ tagline: string;
114
+ frameworks: string[];
115
+ latestVersion: string;
116
+ availableVersions: string[];
117
+ repo: string;
118
+ description?: string | undefined;
119
+ latestBranch?: string | undefined;
120
+ docsRoot?: string | undefined;
121
+ defaultDocs?: string | undefined;
122
+ docsUrl?: string | undefined;
123
+ githubUrl?: string | undefined;
124
+ }[];
125
+ groups: Record<string, string[]>;
126
+ groupNames: Record<string, string>;
127
+ }>;
128
+ export declare const PartnerSchema: z.ZodObject<{
129
+ id: z.ZodString;
130
+ name: z.ZodString;
131
+ tagline: z.ZodOptional<z.ZodString>;
132
+ description: z.ZodString;
133
+ category: z.ZodString;
134
+ categoryLabel: z.ZodString;
135
+ libraries: z.ZodArray<z.ZodString, "many">;
136
+ url: z.ZodString;
137
+ }, "strip", z.ZodTypeAny, {
138
+ id: string;
139
+ name: string;
140
+ description: string;
141
+ libraries: string[];
142
+ category: string;
143
+ categoryLabel: string;
144
+ url: string;
145
+ tagline?: string | undefined;
146
+ }, {
147
+ id: string;
148
+ name: string;
149
+ description: string;
150
+ libraries: string[];
151
+ category: string;
152
+ categoryLabel: string;
153
+ url: string;
154
+ tagline?: string | undefined;
155
+ }>;
156
+ export declare const PartnersResponseSchema: z.ZodObject<{
157
+ partners: z.ZodArray<z.ZodObject<{
158
+ id: z.ZodString;
159
+ name: z.ZodString;
160
+ tagline: z.ZodOptional<z.ZodString>;
161
+ description: z.ZodString;
162
+ category: z.ZodString;
163
+ categoryLabel: z.ZodString;
164
+ libraries: z.ZodArray<z.ZodString, "many">;
165
+ url: z.ZodString;
166
+ }, "strip", z.ZodTypeAny, {
167
+ id: string;
168
+ name: string;
169
+ description: string;
170
+ libraries: string[];
171
+ category: string;
172
+ categoryLabel: string;
173
+ url: string;
174
+ tagline?: string | undefined;
175
+ }, {
176
+ id: string;
177
+ name: string;
178
+ description: string;
179
+ libraries: string[];
180
+ category: string;
181
+ categoryLabel: string;
182
+ url: string;
183
+ tagline?: string | undefined;
184
+ }>, "many">;
185
+ categories: z.ZodArray<z.ZodString, "many">;
186
+ categoryLabels: z.ZodRecord<z.ZodString, z.ZodString>;
187
+ }, "strip", z.ZodTypeAny, {
188
+ partners: {
189
+ id: string;
190
+ name: string;
191
+ description: string;
192
+ libraries: string[];
193
+ category: string;
194
+ categoryLabel: string;
195
+ url: string;
196
+ tagline?: string | undefined;
197
+ }[];
198
+ categories: string[];
199
+ categoryLabels: Record<string, string>;
200
+ }, {
201
+ partners: {
202
+ id: string;
203
+ name: string;
204
+ description: string;
205
+ libraries: string[];
206
+ category: string;
207
+ categoryLabel: string;
208
+ url: string;
209
+ tagline?: string | undefined;
210
+ }[];
211
+ categories: string[];
212
+ categoryLabels: Record<string, string>;
213
+ }>;
214
+ export type Library = z.infer<typeof LibrarySchema>;
215
+ export type LibrariesResponse = z.infer<typeof LibrariesResponseSchema>;
216
+ export type Partner = z.infer<typeof PartnerSchema>;
217
+ export type PartnersResponse = z.infer<typeof PartnersResponseSchema>;
@@ -0,0 +1,6 @@
1
+ export declare function runMCPServer(sse: boolean, { forcedAddOns, appName, name, }: {
2
+ forcedMode?: string;
3
+ forcedAddOns?: Array<string>;
4
+ appName?: string;
5
+ name?: string;
6
+ }): Promise<void>;
@@ -0,0 +1,8 @@
1
+ import type { Options } from '@tanstack/create';
2
+ import type { CliOptions } from './types.js';
3
+ export declare function promptForCreateOptions(cliOptions: CliOptions, { forcedAddOns, forcedMode, showDeploymentOptions, }: {
4
+ forcedAddOns?: Array<string>;
5
+ forcedMode?: string;
6
+ showDeploymentOptions?: boolean;
7
+ }): Promise<Required<Options> | undefined>;
8
+ export declare function promptForAddOns(): Promise<Array<string>>;
@@ -0,0 +1,25 @@
1
+ import type { PackageManager } from '@tanstack/create';
2
+ export type TemplateOptions = 'typescript' | 'javascript' | 'file-router';
3
+ export interface CliOptions {
4
+ template?: TemplateOptions;
5
+ framework?: string;
6
+ tailwind?: boolean;
7
+ packageManager?: PackageManager;
8
+ toolchain?: string | false;
9
+ deployment?: string;
10
+ projectName?: string;
11
+ git?: boolean;
12
+ addOns?: Array<string> | boolean;
13
+ listAddOns?: boolean;
14
+ addonDetails?: string;
15
+ mcp?: boolean;
16
+ mcpSse?: boolean;
17
+ starter?: string;
18
+ targetDir?: string;
19
+ interactive?: boolean;
20
+ ui?: boolean;
21
+ devWatch?: string;
22
+ install?: boolean;
23
+ addOnConfig?: string;
24
+ force?: boolean;
25
+ }
@@ -0,0 +1,2 @@
1
+ import type { Environment } from '@tanstack/create';
2
+ export declare function createUIEnvironment(appName: string, silent: boolean): Environment;
@@ -0,0 +1,12 @@
1
+ import type { PackageManager } from '@tanstack/create';
2
+ import type { Framework } from '@tanstack/create/dist/types/types.js';
3
+ export declare function getProjectName(): Promise<string>;
4
+ export declare function selectRouterType(): Promise<string>;
5
+ export declare function selectTypescript(): Promise<boolean>;
6
+ export declare function selectTailwind(): Promise<boolean>;
7
+ export declare function selectPackageManager(): Promise<PackageManager>;
8
+ export declare function selectAddOns(framework: Framework, mode: string, type: string, message: string, forcedAddOns?: Array<string>, allowMultiple?: boolean): Promise<Array<string>>;
9
+ export declare function selectGit(): Promise<boolean>;
10
+ export declare function selectToolchain(framework: Framework, toolchain?: string | false): Promise<string | undefined>;
11
+ export declare function promptForAddOnOptions(addOnIds: Array<string>, framework: Framework): Promise<Record<string, Record<string, any>>>;
12
+ export declare function selectDeployment(framework: Framework, deployment?: string): Promise<string | undefined>;
@@ -0,0 +1,8 @@
1
+ import type { TemplateOptions } from './types.js';
2
+ export declare function convertTemplateToMode(template: TemplateOptions): string;
3
+ export declare function sanitizePackageName(name: string): string;
4
+ export declare function getCurrentDirectoryName(): string;
5
+ export declare function validateProjectName(name: string): {
6
+ valid: boolean;
7
+ error: string;
8
+ };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ import { cancel, confirm, intro, isCancel, log, outro, spinner, } from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { createDefaultEnvironment } from '@tanstack/create';
4
+ export function createUIEnvironment(appName, silent) {
5
+ const defaultEnvironment = createDefaultEnvironment();
6
+ let newEnvironment = {
7
+ ...defaultEnvironment,
8
+ appName,
9
+ };
10
+ if (!silent) {
11
+ newEnvironment = {
12
+ ...newEnvironment,
13
+ intro: (message) => {
14
+ intro(message);
15
+ },
16
+ outro: (message) => {
17
+ outro(message);
18
+ },
19
+ info: (title, message) => {
20
+ log.info(`${title ? chalk.red(title) : ''}${message ? '\n' + chalk.green(message) : ''}`);
21
+ },
22
+ error: (title, message) => {
23
+ log.error(`${title ? `${title}: ` : ''}${message ? '\n' + message : ''}`);
24
+ },
25
+ warn: (title, message) => {
26
+ log.warn(`${title ? `${title}: ` : ''}${message ? '\n' + message : ''}`);
27
+ },
28
+ confirm: async (message) => {
29
+ const shouldContinue = await confirm({
30
+ message,
31
+ });
32
+ if (isCancel(shouldContinue)) {
33
+ cancel('Operation cancelled.');
34
+ process.exit(0);
35
+ }
36
+ return shouldContinue;
37
+ },
38
+ spinner: () => {
39
+ const s = spinner();
40
+ return {
41
+ start: (message) => {
42
+ s.start(message);
43
+ },
44
+ stop: (message) => {
45
+ s.stop(message);
46
+ },
47
+ };
48
+ },
49
+ };
50
+ }
51
+ return newEnvironment;
52
+ }
@@ -0,0 +1,244 @@
1
+ import { cancel, confirm, isCancel, multiselect, note, select, text, } from '@clack/prompts';
2
+ import { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getAllAddOns, } from '@tanstack/create';
3
+ import { validateProjectName } from './utils.js';
4
+ export async function getProjectName() {
5
+ const value = await text({
6
+ message: 'What would you like to name your project?',
7
+ defaultValue: 'my-app',
8
+ validate(value) {
9
+ if (!value) {
10
+ return 'Please enter a name';
11
+ }
12
+ const { valid, error } = validateProjectName(value);
13
+ if (!valid) {
14
+ return error;
15
+ }
16
+ },
17
+ });
18
+ if (isCancel(value)) {
19
+ cancel('Operation cancelled.');
20
+ process.exit(0);
21
+ }
22
+ return value;
23
+ }
24
+ export async function selectRouterType() {
25
+ const routerType = await select({
26
+ message: 'Select the router type:',
27
+ options: [
28
+ {
29
+ value: 'file-router',
30
+ label: 'File Router - File-based routing structure',
31
+ },
32
+ {
33
+ value: 'code-router',
34
+ label: 'Code Router - Traditional code-based routing',
35
+ },
36
+ ],
37
+ initialValue: 'file-router',
38
+ });
39
+ if (isCancel(routerType)) {
40
+ cancel('Operation cancelled.');
41
+ process.exit(0);
42
+ }
43
+ return routerType;
44
+ }
45
+ export async function selectTypescript() {
46
+ const typescriptEnable = await confirm({
47
+ message: 'Would you like to use TypeScript?',
48
+ initialValue: true,
49
+ });
50
+ if (isCancel(typescriptEnable)) {
51
+ cancel('Operation cancelled.');
52
+ process.exit(0);
53
+ }
54
+ return typescriptEnable;
55
+ }
56
+ export async function selectTailwind() {
57
+ const tailwind = await confirm({
58
+ message: 'Would you like to use Tailwind CSS?',
59
+ initialValue: true,
60
+ });
61
+ if (isCancel(tailwind)) {
62
+ cancel('Operation cancelled.');
63
+ process.exit(0);
64
+ }
65
+ return tailwind;
66
+ }
67
+ export async function selectPackageManager() {
68
+ const packageManager = await select({
69
+ message: 'Select package manager:',
70
+ options: SUPPORTED_PACKAGE_MANAGERS.map((pm) => ({
71
+ value: pm,
72
+ label: pm,
73
+ })),
74
+ initialValue: DEFAULT_PACKAGE_MANAGER,
75
+ });
76
+ if (isCancel(packageManager)) {
77
+ cancel('Operation cancelled.');
78
+ process.exit(0);
79
+ }
80
+ return packageManager;
81
+ }
82
+ // Track if we've shown the multiselect help text
83
+ let hasShownMultiselectHelp = false;
84
+ export async function selectAddOns(framework, mode, type, message, forcedAddOns = [], allowMultiple = true) {
85
+ const allAddOns = await getAllAddOns(framework, mode);
86
+ const addOns = allAddOns.filter((addOn) => addOn.type === type);
87
+ if (addOns.length === 0) {
88
+ return [];
89
+ }
90
+ // Show help text only once
91
+ if (!hasShownMultiselectHelp) {
92
+ note('Use ↑/↓ to navigate • Space to select/deselect • Enter to confirm', 'Keyboard Shortcuts');
93
+ hasShownMultiselectHelp = true;
94
+ }
95
+ if (allowMultiple) {
96
+ const value = await multiselect({
97
+ message,
98
+ options: addOns
99
+ .filter((addOn) => !forcedAddOns.includes(addOn.id))
100
+ .map((addOn) => ({
101
+ value: addOn.id,
102
+ label: addOn.name,
103
+ hint: addOn.description,
104
+ })),
105
+ required: false,
106
+ });
107
+ if (isCancel(value)) {
108
+ cancel('Operation cancelled.');
109
+ process.exit(0);
110
+ }
111
+ return value;
112
+ }
113
+ else {
114
+ const value = await select({
115
+ message,
116
+ options: [
117
+ {
118
+ value: 'none',
119
+ label: 'None',
120
+ },
121
+ ...addOns
122
+ .filter((addOn) => !forcedAddOns.includes(addOn.id))
123
+ .map((addOn) => ({
124
+ value: addOn.id,
125
+ label: addOn.name,
126
+ hint: addOn.description,
127
+ })),
128
+ ],
129
+ initialValue: 'none',
130
+ });
131
+ if (isCancel(value)) {
132
+ cancel('Operation cancelled.');
133
+ process.exit(0);
134
+ }
135
+ return value === 'none' ? [] : [value];
136
+ }
137
+ }
138
+ export async function selectGit() {
139
+ const git = await confirm({
140
+ message: 'Would you like to initialize a new git repository?',
141
+ initialValue: true,
142
+ });
143
+ if (isCancel(git)) {
144
+ cancel('Operation cancelled.');
145
+ process.exit(0);
146
+ }
147
+ return git;
148
+ }
149
+ export async function selectToolchain(framework, toolchain) {
150
+ if (toolchain === false) {
151
+ return undefined;
152
+ }
153
+ const toolchains = new Set();
154
+ for (const addOn of framework.getAddOns()) {
155
+ if (addOn.type === 'toolchain') {
156
+ toolchains.add(addOn);
157
+ if (toolchain && addOn.id === toolchain) {
158
+ return toolchain;
159
+ }
160
+ }
161
+ }
162
+ const tc = await select({
163
+ message: 'Select toolchain',
164
+ options: [
165
+ {
166
+ value: undefined,
167
+ label: 'None',
168
+ },
169
+ ...Array.from(toolchains).map((tc) => ({
170
+ value: tc.id,
171
+ label: tc.name,
172
+ })),
173
+ ],
174
+ initialValue: undefined,
175
+ });
176
+ if (isCancel(tc)) {
177
+ cancel('Operation cancelled.');
178
+ process.exit(0);
179
+ }
180
+ return tc;
181
+ }
182
+ export async function promptForAddOnOptions(addOnIds, framework) {
183
+ const addOnOptions = {};
184
+ for (const addOnId of addOnIds) {
185
+ const addOn = framework.getAddOns().find((a) => a.id === addOnId);
186
+ if (!addOn || !addOn.options)
187
+ continue;
188
+ addOnOptions[addOnId] = {};
189
+ for (const [optionName, option] of Object.entries(addOn.options)) {
190
+ if (option && typeof option === 'object' && 'type' in option) {
191
+ if (option.type === 'select') {
192
+ const selectOption = option;
193
+ const value = await select({
194
+ message: `${addOn.name}: ${selectOption.label}`,
195
+ options: selectOption.options.map((opt) => ({
196
+ value: opt.value,
197
+ label: opt.label,
198
+ })),
199
+ initialValue: selectOption.default,
200
+ });
201
+ if (isCancel(value)) {
202
+ cancel('Operation cancelled.');
203
+ process.exit(0);
204
+ }
205
+ addOnOptions[addOnId][optionName] = value;
206
+ }
207
+ // Future option types can be added here
208
+ }
209
+ }
210
+ }
211
+ return addOnOptions;
212
+ }
213
+ export async function selectDeployment(framework, deployment) {
214
+ const deployments = new Set();
215
+ let initialValue = undefined;
216
+ for (const addOn of framework
217
+ .getAddOns()
218
+ .sort((a, b) => a.name.localeCompare(b.name))) {
219
+ if (addOn.type === 'deployment') {
220
+ deployments.add(addOn);
221
+ if (deployment && addOn.id === deployment) {
222
+ return deployment;
223
+ }
224
+ if (addOn.default) {
225
+ initialValue = addOn.id;
226
+ }
227
+ }
228
+ }
229
+ const dp = await select({
230
+ message: 'Select deployment adapter',
231
+ options: [
232
+ ...Array.from(deployments).map((d) => ({
233
+ value: d.id,
234
+ label: d.name,
235
+ })),
236
+ ],
237
+ initialValue: initialValue,
238
+ });
239
+ if (isCancel(dp)) {
240
+ cancel('Operation cancelled.');
241
+ process.exit(0);
242
+ }
243
+ return dp;
244
+ }
package/dist/utils.js ADDED
@@ -0,0 +1,30 @@
1
+ import { basename } from 'node:path';
2
+ import validatePackageName from 'validate-npm-package-name';
3
+ export function convertTemplateToMode(template) {
4
+ if (template === 'typescript' || template === 'javascript') {
5
+ return 'code-router';
6
+ }
7
+ return 'file-router';
8
+ }
9
+ export function sanitizePackageName(name) {
10
+ return name
11
+ .toLowerCase()
12
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
13
+ .replace(/_/g, '-') // Replace underscores with hyphens
14
+ .replace(/[^a-z0-9-]/g, '') // Remove invalid characters
15
+ .replace(/^[^a-z]+/, '') // Ensure it starts with a letter
16
+ .replace(/-+/g, '-') // Collapse multiple hyphens
17
+ .replace(/-$/, ''); // Remove trailing hyphen
18
+ }
19
+ export function getCurrentDirectoryName() {
20
+ return basename(process.cwd());
21
+ }
22
+ export function validateProjectName(name) {
23
+ const { validForNewPackages, validForOldPackages, errors, warnings } = validatePackageName(name);
24
+ const error = errors?.[0] || warnings?.[0];
25
+ return {
26
+ valid: validForNewPackages && validForOldPackages,
27
+ error: error?.replace(/name/g, 'Project name') ||
28
+ 'Project name does not meet npm package naming requirements',
29
+ };
30
+ }