create-esmx 3.0.0-rc.45 → 3.0.0-rc.47

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 (38) hide show
  1. package/dist/cli.integration.test.mjs +11 -7
  2. package/dist/cli.mjs +19 -18
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.mjs +1 -0
  5. package/dist/project.mjs +2 -2
  6. package/dist/project.test.mjs +21 -43
  7. package/dist/types.d.ts +1 -0
  8. package/dist/utils/project-name.d.ts +32 -14
  9. package/dist/utils/project-name.mjs +36 -11
  10. package/dist/utils/project-name.test.d.ts +0 -3
  11. package/dist/utils/project-name.test.mjs +251 -105
  12. package/package.json +5 -4
  13. package/src/cli.integration.test.ts +11 -7
  14. package/src/cli.ts +23 -19
  15. package/src/index.ts +2 -0
  16. package/src/project.test.ts +21 -46
  17. package/src/project.ts +6 -3
  18. package/src/types.ts +1 -0
  19. package/src/utils/project-name.test.ts +299 -203
  20. package/src/utils/project-name.ts +73 -27
  21. package/template/vue2-csr/README.md +80 -0
  22. package/template/vue2-csr/package.json +26 -0
  23. package/template/vue2-csr/src/components/hello-world.vue +77 -0
  24. package/template/vue2-csr/src/entry.node.ts +32 -0
  25. package/template/vue2-csr/src/entry.server.ts +26 -0
  26. package/template/{vue2 → vue2-ssr}/package.json +1 -1
  27. package/template/vue2-ssr/src/app.vue +127 -0
  28. package/template/vue2-ssr/src/create-app.ts +11 -0
  29. package/template/vue2-ssr/src/entry.client.ts +5 -0
  30. package/template/{vue2 → vue2-ssr}/src/entry.node.ts +1 -1
  31. package/template/vue2-ssr/tsconfig.json +26 -0
  32. /package/template/{vue2 → vue2-csr}/src/app.vue +0 -0
  33. /package/template/{vue2 → vue2-csr}/src/create-app.ts +0 -0
  34. /package/template/{vue2 → vue2-csr}/src/entry.client.ts +0 -0
  35. /package/template/{vue2 → vue2-csr}/tsconfig.json +0 -0
  36. /package/template/{vue2 → vue2-ssr}/README.md +0 -0
  37. /package/template/{vue2 → vue2-ssr}/src/components/hello-world.vue +0 -0
  38. /package/template/{vue2 → vue2-ssr}/src/entry.server.ts +0 -0
@@ -1,186 +1,332 @@
1
- import { basename } from "node:path";
2
1
  import { describe, expect, it } from "vitest";
3
2
  import { formatProjectName } from "./project-name.mjs";
3
+ const isWindows = process.platform === "win32";
4
+ const isUnix = !isWindows;
4
5
  describe("project-name utilities", () => {
5
6
  describe("formatProjectName", () => {
6
7
  it("should handle simple project name", () => {
7
8
  const input = "foo";
8
- const result = formatProjectName(input);
9
- expect(result.targetDir).toBe("foo");
10
- expect(result.packageName).toBe("foo");
9
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
10
+ const result = formatProjectName(input, cwd);
11
+ expect(result.name).toBe("foo");
12
+ if (isWindows) {
13
+ expect(result.root).toBe("C:\\workspace\\foo");
14
+ } else {
15
+ expect(result.root).toBe("/home/user/foo");
16
+ }
11
17
  });
12
18
  it("should handle nested path project name", () => {
13
- const input = "foo/bar";
14
- const result = formatProjectName(input);
15
- expect(result.targetDir).toBe("foo/bar");
16
- expect(result.packageName).toBe("bar");
19
+ const input = isWindows ? "foo\\bar" : "foo/bar";
20
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
21
+ const result = formatProjectName(input, cwd);
22
+ expect(result.name).toBe("bar");
23
+ if (isWindows) {
24
+ expect(result.root).toBe("C:\\workspace\\foo\\bar");
25
+ } else {
26
+ expect(result.root).toBe("/home/user/foo/bar");
27
+ }
17
28
  });
18
29
  it("should handle scoped package name", () => {
19
30
  const input = "@scope/foo";
20
- const result = formatProjectName(input);
21
- expect(result.targetDir).toBe("@scope/foo");
22
- expect(result.packageName).toBe("@scope/foo");
31
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
32
+ const result = formatProjectName(input, cwd);
33
+ expect(result.name).toBe("@scope/foo");
34
+ if (isWindows) {
35
+ expect(result.root).toBe("C:\\workspace\\@scope\\foo");
36
+ } else {
37
+ expect(result.root).toBe("/home/user/@scope/foo");
38
+ }
23
39
  });
24
40
  it("should handle relative path project name", () => {
25
- const input = "./foo/bar";
26
- const result = formatProjectName(input);
27
- expect(result.targetDir).toBe("./foo/bar");
28
- expect(result.packageName).toBe("bar");
41
+ const input = isWindows ? ".\\foo\\bar" : "./foo/bar";
42
+ const cwd = isWindows ? "C:\\workspace\\current" : "/home/user/current";
43
+ const result = formatProjectName(input, cwd);
44
+ expect(result.name).toBe("bar");
45
+ if (isWindows) {
46
+ expect(result.root).toBe("C:\\workspace\\current\\foo\\bar");
47
+ } else {
48
+ expect(result.root).toBe("/home/user/current/foo/bar");
49
+ }
29
50
  });
30
51
  it("should handle absolute path project name", () => {
31
- const input = "/root/path/to/foo";
32
- const result = formatProjectName(input);
33
- expect(result.targetDir).toBe("/root/path/to/foo");
34
- expect(result.packageName).toBe("foo");
52
+ const input = isWindows ? "C:\\projects\\my-app" : "/root/path/to/foo";
53
+ const cwd = isWindows ? "D:\\workspace" : "/home/user";
54
+ const result = formatProjectName(input, cwd);
55
+ if (isWindows) {
56
+ expect(result.name).toBe("my-app");
57
+ expect(result.root).toBe("C:\\projects\\my-app");
58
+ } else {
59
+ expect(result.name).toBe("foo");
60
+ expect(result.root).toBe("/root/path/to/foo");
61
+ }
35
62
  });
36
63
  it("should handle current directory", () => {
37
64
  const input = ".";
38
- const expectedPackageName = basename(process.cwd());
39
- const result = formatProjectName(input);
40
- expect(result.targetDir).toBe(".");
41
- expect(result.packageName).toBe(expectedPackageName);
65
+ const cwd = isWindows ? "C:\\Users\\Developer\\Projects\\WindowsApp" : "/home/user/projects/my-app";
66
+ const result = formatProjectName(input, cwd);
67
+ if (isWindows) {
68
+ expect(result.name).toBe("WindowsApp");
69
+ expect(result.root).toBe(
70
+ "C:\\Users\\Developer\\Projects\\WindowsApp"
71
+ );
72
+ } else {
73
+ expect(result.name).toBe("my-app");
74
+ expect(result.root).toBe("/home/user/projects/my-app");
75
+ }
42
76
  });
43
77
  it("should handle project name with trailing slashes", () => {
44
- const input = "foo/bar///";
45
- const result = formatProjectName(input);
46
- expect(result.targetDir).toBe("foo/bar");
47
- expect(result.packageName).toBe("bar");
78
+ const input = isWindows ? "foo\\" : "foo/";
79
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
80
+ const result = formatProjectName(input, cwd);
81
+ expect(result.name).toBe("foo");
82
+ if (isWindows) {
83
+ expect(result.root).toBe("C:\\workspace\\foo");
84
+ } else {
85
+ expect(result.root).toBe("/home/user/foo");
86
+ }
48
87
  });
49
88
  it("should handle project name with multiple trailing slashes", () => {
50
- const input = "my-project/////";
51
- const result = formatProjectName(input);
52
- expect(result.targetDir).toBe("my-project");
53
- expect(result.packageName).toBe("my-project");
89
+ const input = isWindows ? "foo\\\\\\" : "foo///";
90
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
91
+ const result = formatProjectName(input, cwd);
92
+ expect(result.name).toBe("foo");
93
+ if (isWindows) {
94
+ expect(result.root).toBe("C:\\workspace\\foo");
95
+ } else {
96
+ expect(result.root).toBe("/home/user/foo");
97
+ }
54
98
  });
55
99
  it("should handle deep nested path", () => {
56
- const input = "projects/web/frontend/my-app";
57
- const result = formatProjectName(input);
58
- expect(result.targetDir).toBe("projects/web/frontend/my-app");
59
- expect(result.packageName).toBe("my-app");
100
+ const input = isWindows ? "path\\to\\nested\\project" : "path/to/nested/project";
101
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
102
+ const result = formatProjectName(input, cwd);
103
+ expect(result.name).toBe("project");
104
+ if (isWindows) {
105
+ expect(result.root).toBe(
106
+ "C:\\workspace\\path\\to\\nested\\project"
107
+ );
108
+ } else {
109
+ expect(result.root).toBe("/home/user/path/to/nested/project");
110
+ }
60
111
  });
61
112
  it("should handle scoped package with nested path", () => {
62
- const input = "org/@scope/package-name";
63
- const result = formatProjectName(input);
64
- expect(result.targetDir).toBe("org/@scope/package-name");
65
- expect(result.packageName).toBe("package-name");
113
+ const input = isWindows ? "@company\\ui\\library" : "@company/ui/library";
114
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
115
+ const result = formatProjectName(input, cwd);
116
+ expect(result.name).toBe(input);
117
+ if (isWindows) {
118
+ expect(result.root).toBe(
119
+ "C:\\workspace\\@company\\ui\\library"
120
+ );
121
+ } else {
122
+ expect(result.root).toBe("/home/user/@company/ui/library");
123
+ }
66
124
  });
67
125
  it("should handle scoped package starting with @", () => {
68
- const input = "@company/ui-library";
69
- const result = formatProjectName(input);
70
- expect(result.targetDir).toBe("@company/ui-library");
71
- expect(result.packageName).toBe("@company/ui-library");
126
+ const input = "@my-org/my-package";
127
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
128
+ const result = formatProjectName(input, cwd);
129
+ expect(result.name).toBe("@my-org/my-package");
130
+ if (isWindows) {
131
+ expect(result.root).toBe("C:\\workspace\\@my-org\\my-package");
132
+ } else {
133
+ expect(result.root).toBe("/home/user/@my-org/my-package");
134
+ }
72
135
  });
73
136
  it("should handle empty path segment", () => {
74
- const input = "foo//bar";
75
- const result = formatProjectName(input);
76
- expect(result.targetDir).toBe("foo//bar");
77
- expect(result.packageName).toBe("bar");
137
+ const input = isWindows ? "path\\\\with\\\\segments" : "path//with//segments";
138
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
139
+ const result = formatProjectName(input, cwd);
140
+ expect(result.name).toBe("segments");
141
+ if (isWindows) {
142
+ expect(result.root).toBe("C:\\workspace\\path\\with\\segments");
143
+ } else {
144
+ expect(result.root).toBe("/home/user/path/with/segments");
145
+ }
78
146
  });
79
147
  it("should handle single character project name", () => {
80
148
  const input = "a";
81
- const result = formatProjectName(input);
82
- expect(result.targetDir).toBe("a");
83
- expect(result.packageName).toBe("a");
149
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
150
+ const result = formatProjectName(input, cwd);
151
+ expect(result.name).toBe("a");
152
+ if (isWindows) {
153
+ expect(result.root).toBe("C:\\workspace\\a");
154
+ } else {
155
+ expect(result.root).toBe("/home/user/a");
156
+ }
84
157
  });
85
158
  it("should handle project name with numbers and hyphens", () => {
86
- const input = "my-project-v2";
87
- const result = formatProjectName(input);
88
- expect(result.targetDir).toBe("my-project-v2");
89
- expect(result.packageName).toBe("my-project-v2");
159
+ const input = "my-project-123";
160
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
161
+ const result = formatProjectName(input, cwd);
162
+ expect(result.name).toBe("my-project-123");
163
+ if (isWindows) {
164
+ expect(result.root).toBe("C:\\workspace\\my-project-123");
165
+ } else {
166
+ expect(result.root).toBe("/home/user/my-project-123");
167
+ }
90
168
  });
91
169
  it("should handle project name ending with slash", () => {
92
- const input = "path/to/project/";
93
- const result = formatProjectName(input);
94
- expect(result.targetDir).toBe("path/to/project");
95
- expect(result.packageName).toBe("project");
170
+ const input = isWindows ? "my-project\\" : "my-project/";
171
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
172
+ const result = formatProjectName(input, cwd);
173
+ expect(result.name).toBe("my-project");
174
+ if (isWindows) {
175
+ expect(result.root).toBe("C:\\workspace\\my-project");
176
+ } else {
177
+ expect(result.root).toBe("/home/user/my-project");
178
+ }
96
179
  });
97
180
  it("should fall back to default name when path ends with slash and no name", () => {
98
181
  const input = "/";
99
- const result = formatProjectName(input);
100
- expect(result.targetDir).toBe("");
101
- expect(result.packageName).toBe("esmx-project");
182
+ const cwd = isWindows ? "C:\\workspace" : "/home/user";
183
+ const result = formatProjectName(input, cwd);
184
+ expect(result.root).toBe("/");
185
+ expect(result.name).toBe("esmx-project");
102
186
  });
103
- it("should handle Windows-style paths", () => {
104
- const input = "C:\\projects\\my-app";
105
- const result = formatProjectName(input);
106
- expect(result.targetDir).toBe("C:\\projects\\my-app");
107
- expect(result.packageName).toBe("C:\\projects\\my-app");
187
+ it.runIf(isWindows)(
188
+ "should handle Windows-style absolute paths",
189
+ () => {
190
+ const input = "C:\\projects\\my-app";
191
+ const cwd = "D:\\workspace";
192
+ const result = formatProjectName(input, cwd);
193
+ expect(result.name).toBe("my-app");
194
+ expect(result.root).toMatch(/projects[\\\/]my-app/);
195
+ }
196
+ );
197
+ it.runIf(isWindows)("should handle Windows UNC paths", () => {
198
+ const input = "\\\\server\\share\\project";
199
+ const cwd = "C:\\workspace";
200
+ const result = formatProjectName(input, cwd);
201
+ expect(result.name).toBe("project");
202
+ expect(result.root).toMatch(/project$/);
108
203
  });
109
- it("should handle mixed path separators", () => {
110
- const input = "path\\to/project";
111
- const result = formatProjectName(input);
112
- expect(result.targetDir).toBe("path\\to/project");
113
- expect(result.packageName).toBe("project");
204
+ it.runIf(isUnix)("should handle mixed path separators on Unix", () => {
205
+ const input = "path\\to/mixed/separators";
206
+ const cwd = "/home/user";
207
+ const result = formatProjectName(input, cwd);
208
+ expect(result.name).toBe("separators");
209
+ expect(result.root).toBe("/home/user/path\\to/mixed/separators");
114
210
  });
211
+ it.runIf(isWindows)(
212
+ "should handle Windows-style relative paths",
213
+ () => {
214
+ const input = "foo\\bar";
215
+ const cwd = "C:\\workspace";
216
+ const result = formatProjectName(input, cwd);
217
+ expect(result.name).toBe("bar");
218
+ expect(result.root).toMatch(/workspace[\\\/]foo[\\\/]bar/);
219
+ }
220
+ );
221
+ it.runIf(isWindows)(
222
+ "should handle Windows-style trailing backslashes",
223
+ () => {
224
+ const input = "foo\\bar\\\\\\";
225
+ const cwd = "C:\\workspace";
226
+ const result = formatProjectName(input, cwd);
227
+ expect(result.name).toBe("bar");
228
+ expect(result.root).toMatch(/workspace[\\\/]foo[\\\/]bar/);
229
+ }
230
+ );
115
231
  });
116
232
  describe("formatProjectName with cwd parameter", () => {
117
233
  it('should use custom cwd when input is "."', () => {
118
234
  const input = ".";
119
- const customCwd = "/custom/working/directory";
235
+ const customCwd = isWindows ? "C:\\custom\\path\\to\\project" : "/custom/path/to/project";
120
236
  const result = formatProjectName(
121
237
  input,
122
238
  customCwd
123
239
  );
124
- expect(result.targetDir).toBe(".");
125
- expect(result.packageName).toBe("directory");
240
+ expect(result.name).toBe("project");
241
+ expect(result.root).toBe(customCwd);
126
242
  });
127
243
  it("should fallback to process.cwd() when cwd is not provided", () => {
128
- const input = ".";
129
- const expectedPackageName = basename(process.cwd());
244
+ const input = "test-project";
130
245
  const result = formatProjectName(input);
131
- expect(result.targetDir).toBe(".");
132
- expect(result.packageName).toBe(expectedPackageName);
246
+ expect(result.name).toBe("test-project");
247
+ expect(result.root).toMatch(/test-project$/);
133
248
  });
134
249
  it('should ignore cwd parameter when input is not "."', () => {
135
250
  const input = "my-project";
136
- const customCwd = "/custom/working/directory";
251
+ const customCwd = isWindows ? "C:\\custom\\path" : "/custom/path";
137
252
  const result = formatProjectName(
138
253
  input,
139
254
  customCwd
140
255
  );
141
- expect(result.targetDir).toBe("my-project");
142
- expect(result.packageName).toBe("my-project");
256
+ expect(result.name).toBe("my-project");
257
+ if (isWindows) {
258
+ expect(result.root).toBe("C:\\custom\\path\\my-project");
259
+ } else {
260
+ expect(result.root).toBe("/custom/path/my-project");
261
+ }
143
262
  });
144
263
  it("should handle scoped packages with custom cwd", () => {
145
- const input = "@scope/package";
146
- const customCwd = "/any/directory";
264
+ const input = "@scope/foo";
265
+ const customCwd = isWindows ? "C:\\custom\\workspace" : "/custom/workspace";
147
266
  const result = formatProjectName(
148
267
  input,
149
268
  customCwd
150
269
  );
151
- expect(result.targetDir).toBe("@scope/package");
152
- expect(result.packageName).toBe("@scope/package");
270
+ expect(result.name).toBe("@scope/foo");
271
+ if (isWindows) {
272
+ expect(result.root).toBe("C:\\custom\\workspace\\@scope\\foo");
273
+ } else {
274
+ expect(result.root).toBe("/custom/workspace/@scope/foo");
275
+ }
153
276
  });
154
277
  it("should handle nested paths with custom cwd", () => {
155
- const input = "org/team/project";
156
- const customCwd = "/any/directory";
278
+ const input = isWindows ? "foo\\bar" : "foo/bar";
279
+ const customCwd = isWindows ? "C:\\custom\\workspace" : "/custom/workspace";
157
280
  const result = formatProjectName(
158
281
  input,
159
282
  customCwd
160
283
  );
161
- expect(result.targetDir).toBe("org/team/project");
162
- expect(result.packageName).toBe("project");
284
+ expect(result.name).toBe("bar");
285
+ if (isWindows) {
286
+ expect(result.root).toBe("C:\\custom\\workspace\\foo\\bar");
287
+ } else {
288
+ expect(result.root).toBe("/custom/workspace/foo/bar");
289
+ }
163
290
  });
164
- it("should handle Unix-style absolute paths in cwd", () => {
165
- const input = ".";
166
- const customCwd = "/home/user/projects/my-awesome-app";
167
- const result = formatProjectName(
168
- input,
169
- customCwd
170
- );
171
- expect(result.targetDir).toBe(".");
172
- expect(result.packageName).toBe("my-awesome-app");
173
- });
174
- it("should handle Windows-style absolute paths in cwd", () => {
175
- const input = ".";
176
- const customCwd = "C:\\Users\\Developer\\Projects\\WindowsApp";
291
+ it.runIf(isUnix)(
292
+ "should handle Unix-style absolute paths in cwd",
293
+ () => {
294
+ const input = "/root/path/to/foo";
295
+ const customCwd = "/this/should/be/ignored";
296
+ const result = formatProjectName(
297
+ input,
298
+ customCwd
299
+ );
300
+ expect(result.name).toBe("foo");
301
+ expect(result.root).toBe("/root/path/to/foo");
302
+ }
303
+ );
304
+ it.runIf(isWindows)(
305
+ "should handle Windows-style absolute paths in cwd",
306
+ () => {
307
+ const input = "C:\\projects\\my-app";
308
+ const customCwd = "D:\\this\\should\\be\\ignored";
309
+ const result = formatProjectName(
310
+ input,
311
+ customCwd
312
+ );
313
+ expect(result.name).toBe("my-app");
314
+ expect(result.root).toBe("C:\\projects\\my-app");
315
+ }
316
+ );
317
+ it("should handle absolute input paths and ignore cwd", () => {
318
+ const input = isWindows ? "C:\\projects\\absolute-project" : "/projects/absolute-project";
319
+ const customCwd = isWindows ? "D:\\ignored" : "/ignored";
177
320
  const result = formatProjectName(
178
321
  input,
179
322
  customCwd
180
323
  );
181
- expect(result.targetDir).toBe(".");
182
- const expectedPackageName = basename(customCwd);
183
- expect(result.packageName).toBe(expectedPackageName);
324
+ expect(result.name).toBe("absolute-project");
325
+ if (isWindows) {
326
+ expect(result.root).toBe("C:\\projects\\absolute-project");
327
+ } else {
328
+ expect(result.root).toBe("/projects/absolute-project");
329
+ }
184
330
  });
185
331
  });
186
332
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-esmx",
3
- "version": "3.0.0-rc.45",
3
+ "version": "3.0.0-rc.47",
4
4
  "description": "A scaffold tool for creating Esmx projects",
5
5
  "type": "module",
6
6
  "private": false,
@@ -14,7 +14,8 @@
14
14
  "test": "vitest run --pass-with-no-tests",
15
15
  "coverage": "vitest run --coverage --pass-with-no-tests",
16
16
  "lint:js": "biome check --write --no-errors-on-unmatched",
17
- "build": "unbuild"
17
+ "build": "unbuild",
18
+ "postbuild": "node build/postbuild.mjs"
18
19
  },
19
20
  "dependencies": {
20
21
  "@clack/prompts": "^0.7.0",
@@ -23,7 +24,7 @@
23
24
  },
24
25
  "devDependencies": {
25
26
  "@biomejs/biome": "1.9.4",
26
- "@esmx/lint": "3.0.0-rc.45",
27
+ "@esmx/lint": "3.0.0-rc.47",
27
28
  "@types/minimist": "^1.2.5",
28
29
  "@types/node": "^24.0.0",
29
30
  "@vitest/coverage-v8": "3.2.4",
@@ -68,5 +69,5 @@
68
69
  "url": "https://github.com/esmnext/esmx/issues"
69
70
  },
70
71
  "homepage": "https://github.com/esmnext/esmx#readme",
71
- "gitHead": "c1e2c9bf24c9321b06e63a08e8bfc4953c834aef"
72
+ "gitHead": "3e55424b9029d259537a802032f3a1f54b6fb1e8"
72
73
  }
@@ -133,7 +133,7 @@ describe('create-esmx CLI integration tests', () => {
133
133
  const projectPath = join(tmpDir, 'test-project');
134
134
 
135
135
  await cli({
136
- argv: ['test-project', '--template', 'vue2'],
136
+ argv: ['test-project', '--template', 'vue2-csr'],
137
137
  cwd: tmpDir,
138
138
  userAgent: 'npm/test'
139
139
  });
@@ -141,7 +141,7 @@ describe('create-esmx CLI integration tests', () => {
141
141
  expect(existsSync(join(projectPath, 'package.json'))).toBe(true);
142
142
 
143
143
  await cli({
144
- argv: ['test-project', '--template', 'vue2', '--force'],
144
+ argv: ['test-project', '--template', 'vue2-csr', '--force'],
145
145
  cwd: tmpDir,
146
146
  userAgent: 'npm/test'
147
147
  });
@@ -202,7 +202,11 @@ describe('create-esmx CLI integration tests', () => {
202
202
  const projectPath = join(tmpDir, 'non-existent-parent', 'test-project');
203
203
 
204
204
  await cli({
205
- argv: ['non-existent-parent/test-project', '--template', 'vue2'],
205
+ argv: [
206
+ 'non-existent-parent/test-project',
207
+ '--template',
208
+ 'vue2-csr'
209
+ ],
206
210
  cwd: tmpDir,
207
211
  userAgent: 'npm/test'
208
212
  });
@@ -222,7 +226,7 @@ describe('create-esmx CLI integration tests', () => {
222
226
  );
223
227
 
224
228
  await cli({
225
- argv: ['test-project', '--template', 'vue2', '--force'],
229
+ argv: ['test-project', '--template', 'vue2-csr', '--force'],
226
230
  cwd: tmpDir,
227
231
  userAgent: 'npm/test'
228
232
  });
@@ -236,7 +240,7 @@ describe('create-esmx CLI integration tests', () => {
236
240
  await writeFile(testFile, 'existing content');
237
241
 
238
242
  await cli({
239
- argv: ['.', '--template', 'vue2', '--force'],
243
+ argv: ['.', '--template', 'vue2-csr', '--force'],
240
244
  cwd: tmpDir,
241
245
  userAgent: 'npm/test'
242
246
  });
@@ -248,7 +252,7 @@ describe('create-esmx CLI integration tests', () => {
248
252
 
249
253
  it('should create project in current directory when target is "."', async () => {
250
254
  await cli({
251
- argv: ['.', '--template', 'vue2'],
255
+ argv: ['.', '--template', 'vue2-csr'],
252
256
  cwd: tmpDir,
253
257
  userAgent: 'npm/test'
254
258
  });
@@ -269,7 +273,7 @@ describe('create-esmx CLI integration tests', () => {
269
273
  const projectPath = join(tmpDir, projectName);
270
274
 
271
275
  await cli({
272
- argv: [projectName, '--template', 'vue2'],
276
+ argv: [projectName, '--template', 'vue2-csr'],
273
277
  cwd: tmpDir,
274
278
  userAgent: 'npm/test'
275
279
  });
package/src/cli.ts CHANGED
@@ -28,7 +28,7 @@ ${color.bold('Usage:')}
28
28
  ${createCmd} [project-name] [options]
29
29
 
30
30
  ${color.bold('Options:')}
31
- -t, --template <template> Template to use (default: vue2)
31
+ -t, --template <template> Template to use (default: vue2-csr)
32
32
  -n, --name <name> Project name or path
33
33
  -f, --force Force overwrite existing directory
34
34
  -h, --help Show help information
@@ -36,9 +36,9 @@ ${color.bold('Options:')}
36
36
 
37
37
  ${color.bold('Examples:')}
38
38
  ${createCmd} my-project
39
- ${createCmd} my-project -t vue2
39
+ ${createCmd} my-project -t vue2-csr
40
40
  ${createCmd} my-project --force
41
- ${createCmd} . -f -t vue2
41
+ ${createCmd} . -f -t vue2-csr
42
42
 
43
43
  ${color.bold('Available Templates:')}
44
44
  ${getAvailableTemplates()
@@ -80,7 +80,7 @@ async function getProjectName(
80
80
  /**
81
81
  * Get template type from arguments or prompt user
82
82
  */
83
- async function getTemplateType(argTemplate?: string): Promise<string | symbol> {
83
+ async function getTemplateType(argTemplate?: string): Promise<string> {
84
84
  const availableTemplates = getAvailableTemplates();
85
85
 
86
86
  if (
@@ -101,14 +101,14 @@ async function getTemplateType(argTemplate?: string): Promise<string | symbol> {
101
101
  options: options
102
102
  });
103
103
 
104
- return template as string | symbol;
104
+ return String(template);
105
105
  }
106
106
 
107
107
  /**
108
108
  * Main function to create a project
109
109
  */
110
110
  export async function cli(options: CliOptions = {}): Promise<void> {
111
- const { argv, cwd, userAgent } = options;
111
+ const { argv, cwd, userAgent, version } = options;
112
112
  const commandLineArgs = argv || process.argv.slice(2);
113
113
  const workingDir = cwd || process.cwd();
114
114
 
@@ -150,10 +150,7 @@ export async function cli(options: CliOptions = {}): Promise<void> {
150
150
  return;
151
151
  }
152
152
 
153
- const { packageName, targetDir } = formatProjectName(
154
- projectNameInput,
155
- workingDir
156
- );
153
+ const { name, root } = formatProjectName(projectNameInput, workingDir);
157
154
 
158
155
  const templateType = await getTemplateType(parsedArgs.template);
159
156
  if (isCancel(templateType)) {
@@ -169,13 +166,13 @@ export async function cli(options: CliOptions = {}): Promise<void> {
169
166
  const lintTypeCommand = getCommand('lint:type', userAgent);
170
167
 
171
168
  await createProjectFromTemplate(
172
- targetDir,
169
+ root,
173
170
  templateType,
174
171
  workingDir,
175
172
  parsedArgs.force,
176
173
  {
177
- projectName: packageName,
178
- esmxVersion: getEsmxVersion(),
174
+ projectName: name,
175
+ esmxVersion: version || getEsmxVersion(),
179
176
  installCommand,
180
177
  devCommand,
181
178
  buildCommand,
@@ -187,12 +184,19 @@ export async function cli(options: CliOptions = {}): Promise<void> {
187
184
  const installCmd = installCommand;
188
185
  const devCmd = devCommand;
189
186
 
190
- const nextSteps = [
191
- color.reset(`1. ${color.cyan(`cd ${targetDir}`)}`),
192
- color.reset(`2. ${color.cyan(installCmd)}`),
193
- color.reset(`3. ${color.cyan('git init')} ${color.gray('(optional)')}`),
194
- color.reset(`4. ${color.cyan(devCmd)}`)
195
- ];
187
+ const targetDirForDisplay =
188
+ projectNameInput === '.' ? '.' : projectNameInput;
189
+
190
+ const steps = [
191
+ projectNameInput !== '.' ? `cd ${targetDirForDisplay}` : null,
192
+ installCmd,
193
+ `git init ${color.gray('(optional)')}`,
194
+ devCmd
195
+ ].filter(Boolean);
196
+
197
+ const nextSteps = steps.map((step, index) => {
198
+ return color.reset(`${index + 1}. ${color.cyan(step)}`);
199
+ });
196
200
 
197
201
  note(nextSteps.join('\n'), 'Next steps');
198
202
 
package/src/index.ts CHANGED
@@ -1 +1,3 @@
1
1
  export { cli } from './cli';
2
+ export { getAvailableTemplates } from './template';
3
+ export type { TemplateInfo } from './types';