create-esmx 3.0.0-rc.104

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/README.zh-CN.md +52 -0
  4. package/dist/cli.d.ts +5 -0
  5. package/dist/cli.integration.test.d.ts +1 -0
  6. package/dist/cli.integration.test.mjs +238 -0
  7. package/dist/cli.mjs +166 -0
  8. package/dist/create.d.ts +2 -0
  9. package/dist/create.mjs +6 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.mjs +2 -0
  12. package/dist/project.d.ts +5 -0
  13. package/dist/project.mjs +46 -0
  14. package/dist/project.test.d.ts +1 -0
  15. package/dist/project.test.mjs +155 -0
  16. package/dist/template.d.ts +17 -0
  17. package/dist/template.mjs +76 -0
  18. package/dist/template.test.d.ts +1 -0
  19. package/dist/template.test.mjs +106 -0
  20. package/dist/types.d.ts +30 -0
  21. package/dist/types.mjs +0 -0
  22. package/dist/utils/index.d.ts +3 -0
  23. package/dist/utils/index.mjs +7 -0
  24. package/dist/utils/package-manager.d.ts +10 -0
  25. package/dist/utils/package-manager.mjs +49 -0
  26. package/dist/utils/package-manager.test.d.ts +4 -0
  27. package/dist/utils/package-manager.test.mjs +275 -0
  28. package/dist/utils/project-name.d.ts +48 -0
  29. package/dist/utils/project-name.mjs +42 -0
  30. package/dist/utils/project-name.test.d.ts +1 -0
  31. package/dist/utils/project-name.test.mjs +332 -0
  32. package/dist/utils/template.d.ts +19 -0
  33. package/dist/utils/template.mjs +8 -0
  34. package/dist/utils/template.test.d.ts +4 -0
  35. package/dist/utils/template.test.mjs +150 -0
  36. package/package.json +75 -0
  37. package/src/cli.integration.test.ts +289 -0
  38. package/src/cli.ts +214 -0
  39. package/src/create.ts +8 -0
  40. package/src/index.ts +3 -0
  41. package/src/project.test.ts +200 -0
  42. package/src/project.ts +75 -0
  43. package/src/template.test.ts +135 -0
  44. package/src/template.ts +117 -0
  45. package/src/types.ts +32 -0
  46. package/src/utils/index.ts +11 -0
  47. package/src/utils/package-manager.test.ts +540 -0
  48. package/src/utils/package-manager.ts +92 -0
  49. package/src/utils/project-name.test.ts +441 -0
  50. package/src/utils/project-name.ts +101 -0
  51. package/src/utils/template.test.ts +234 -0
  52. package/src/utils/template.ts +34 -0
  53. package/template/react-csr/README.md +81 -0
  54. package/template/react-csr/package.json +29 -0
  55. package/template/react-csr/src/app.css +98 -0
  56. package/template/react-csr/src/app.tsx +26 -0
  57. package/template/react-csr/src/components/hello-world.css +48 -0
  58. package/template/react-csr/src/components/hello-world.tsx +29 -0
  59. package/template/react-csr/src/create-app.tsx +9 -0
  60. package/template/react-csr/src/entry.client.ts +13 -0
  61. package/template/react-csr/src/entry.node.ts +35 -0
  62. package/template/react-csr/src/entry.server.tsx +27 -0
  63. package/template/react-csr/tsconfig.json +27 -0
  64. package/template/react-ssr/README.md +81 -0
  65. package/template/react-ssr/package.json +29 -0
  66. package/template/react-ssr/src/app.css +98 -0
  67. package/template/react-ssr/src/app.tsx +26 -0
  68. package/template/react-ssr/src/components/hello-world.css +48 -0
  69. package/template/react-ssr/src/components/hello-world.tsx +29 -0
  70. package/template/react-ssr/src/create-app.tsx +9 -0
  71. package/template/react-ssr/src/entry.client.ts +13 -0
  72. package/template/react-ssr/src/entry.node.ts +32 -0
  73. package/template/react-ssr/src/entry.server.tsx +36 -0
  74. package/template/react-ssr/tsconfig.json +27 -0
  75. package/template/shared-modules/README.md +85 -0
  76. package/template/shared-modules/package.json +28 -0
  77. package/template/shared-modules/src/entry.client.ts +50 -0
  78. package/template/shared-modules/src/entry.node.ts +67 -0
  79. package/template/shared-modules/src/entry.server.ts +299 -0
  80. package/template/shared-modules/src/index.ts +3 -0
  81. package/template/shared-modules/src/vue/index.ts +1 -0
  82. package/template/shared-modules/src/vue2/index.ts +1 -0
  83. package/template/shared-modules/tsconfig.json +26 -0
  84. package/template/vue-csr/README.md +80 -0
  85. package/template/vue-csr/package.json +26 -0
  86. package/template/vue-csr/src/app.vue +127 -0
  87. package/template/vue-csr/src/components/hello-world.vue +77 -0
  88. package/template/vue-csr/src/create-app.ts +9 -0
  89. package/template/vue-csr/src/entry.client.ts +5 -0
  90. package/template/vue-csr/src/entry.node.ts +35 -0
  91. package/template/vue-csr/src/entry.server.ts +26 -0
  92. package/template/vue-csr/tsconfig.json +26 -0
  93. package/template/vue-ssr/README.md +80 -0
  94. package/template/vue-ssr/package.json +27 -0
  95. package/template/vue-ssr/src/app.vue +127 -0
  96. package/template/vue-ssr/src/components/hello-world.vue +77 -0
  97. package/template/vue-ssr/src/create-app.ts +9 -0
  98. package/template/vue-ssr/src/entry.client.ts +5 -0
  99. package/template/vue-ssr/src/entry.node.ts +37 -0
  100. package/template/vue-ssr/src/entry.server.ts +30 -0
  101. package/template/vue-ssr/tsconfig.json +26 -0
  102. package/template/vue2-csr/README.md +80 -0
  103. package/template/vue2-csr/package.json +26 -0
  104. package/template/vue2-csr/src/app.vue +127 -0
  105. package/template/vue2-csr/src/components/hello-world.vue +77 -0
  106. package/template/vue2-csr/src/create-app.ts +11 -0
  107. package/template/vue2-csr/src/entry.client.ts +5 -0
  108. package/template/vue2-csr/src/entry.node.ts +35 -0
  109. package/template/vue2-csr/src/entry.server.ts +26 -0
  110. package/template/vue2-csr/tsconfig.json +26 -0
  111. package/template/vue2-ssr/README.md +80 -0
  112. package/template/vue2-ssr/package.json +27 -0
  113. package/template/vue2-ssr/src/app.vue +127 -0
  114. package/template/vue2-ssr/src/components/hello-world.vue +77 -0
  115. package/template/vue2-ssr/src/create-app.ts +11 -0
  116. package/template/vue2-ssr/src/entry.client.ts +5 -0
  117. package/template/vue2-ssr/src/entry.node.ts +32 -0
  118. package/template/vue2-ssr/src/entry.server.ts +37 -0
  119. package/template/vue2-ssr/tsconfig.json +26 -0
@@ -0,0 +1,155 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
+ import { createProjectFromTemplate } from "./project.mjs";
7
+ import { getEsmxVersion } from "./template.mjs";
8
+ import { formatProjectName } from "./utils/index.mjs";
9
+ async function createTempDir(prefix = "esmx-unit-test-") {
10
+ return mkdtemp(join(tmpdir(), prefix));
11
+ }
12
+ async function cleanupTempDir(tmpDir) {
13
+ await rm(tmpDir, { recursive: true, force: true });
14
+ }
15
+ describe("project unit tests", () => {
16
+ let tmpDir;
17
+ beforeEach(async () => {
18
+ tmpDir = await createTempDir();
19
+ });
20
+ afterEach(async () => {
21
+ await cleanupTempDir(tmpDir);
22
+ });
23
+ it("should handle isDirectoryEmpty edge cases", async () => {
24
+ const hiddenFilesDir = join(tmpDir, "hidden-files-dir");
25
+ await mkdir(hiddenFilesDir, { recursive: true });
26
+ await writeFile(join(hiddenFilesDir, ".hidden-file"), "hidden content");
27
+ await writeFile(join(hiddenFilesDir, ".gitignore"), "node_modules/");
28
+ const projectNameInput = "hidden-files-dir";
29
+ const { name, root } = formatProjectName(projectNameInput, tmpDir);
30
+ await createProjectFromTemplate(root, "vue2-csr", tmpDir, false, {
31
+ projectName: name,
32
+ esmxVersion: getEsmxVersion(),
33
+ installCommand: "npm install",
34
+ devCommand: "npm run dev",
35
+ buildCommand: "npm run build",
36
+ startCommand: "npm start",
37
+ buildTypeCommand: "npm run build:type",
38
+ lintTypeCommand: "npm run lint:type"
39
+ });
40
+ expect(existsSync(join(hiddenFilesDir, "package.json"))).toBe(true);
41
+ });
42
+ it("should handle directory creation for nested paths", async () => {
43
+ const deepPath = join(
44
+ tmpDir,
45
+ "very",
46
+ "deep",
47
+ "nested",
48
+ "path",
49
+ "project"
50
+ );
51
+ const projectNameInput = "very/deep/nested/path/project";
52
+ const { name, root } = formatProjectName(projectNameInput, tmpDir);
53
+ await createProjectFromTemplate(root, "vue2-csr", tmpDir, false, {
54
+ projectName: name,
55
+ esmxVersion: getEsmxVersion(),
56
+ installCommand: "npm install",
57
+ devCommand: "npm run dev",
58
+ buildCommand: "npm run build",
59
+ startCommand: "npm start",
60
+ buildTypeCommand: "npm run build:type",
61
+ lintTypeCommand: "npm run lint:type"
62
+ });
63
+ expect(existsSync(deepPath)).toBe(true);
64
+ expect(existsSync(join(deepPath, "package.json"))).toBe(true);
65
+ });
66
+ it("should handle file copy with template variable replacement", async () => {
67
+ const projectPath = join(tmpDir, "variable-test");
68
+ const projectNameInput = "variable-test";
69
+ const { name, root } = formatProjectName(projectNameInput, tmpDir);
70
+ await createProjectFromTemplate(root, "vue2-csr", tmpDir, false, {
71
+ projectName: name,
72
+ esmxVersion: getEsmxVersion(),
73
+ installCommand: "npm install",
74
+ devCommand: "npm run dev",
75
+ buildCommand: "npm run build",
76
+ startCommand: "npm start",
77
+ buildTypeCommand: "npm run build:type",
78
+ lintTypeCommand: "npm run lint:type"
79
+ });
80
+ const packageJsonPath = join(projectPath, "package.json");
81
+ expect(existsSync(packageJsonPath)).toBe(true);
82
+ const packageContent = require("node:fs").readFileSync(
83
+ packageJsonPath,
84
+ "utf-8"
85
+ );
86
+ const packageJson = JSON.parse(packageContent);
87
+ expect(packageJson.name).toBe("variable-test");
88
+ });
89
+ it("should handle empty directory detection correctly", async () => {
90
+ const emptyDir = join(tmpDir, "empty-dir");
91
+ await mkdir(emptyDir, { recursive: true });
92
+ const projectNameInput = "empty-dir";
93
+ const { name, root } = formatProjectName(projectNameInput, tmpDir);
94
+ await createProjectFromTemplate(root, "vue2-csr", tmpDir, false, {
95
+ projectName: name,
96
+ esmxVersion: getEsmxVersion(),
97
+ installCommand: "npm install",
98
+ devCommand: "npm run dev",
99
+ buildCommand: "npm run build",
100
+ startCommand: "npm start",
101
+ buildTypeCommand: "npm run build:type",
102
+ lintTypeCommand: "npm run lint:type"
103
+ });
104
+ expect(existsSync(join(emptyDir, "package.json"))).toBe(true);
105
+ });
106
+ it("should handle mixed file types in directory", async () => {
107
+ const mixedDir = join(tmpDir, "mixed-dir");
108
+ await mkdir(mixedDir, { recursive: true });
109
+ await writeFile(join(mixedDir, ".dotfile"), "hidden");
110
+ await writeFile(join(mixedDir, "regular-file.txt"), "visible");
111
+ const projectNameInput = "mixed-dir";
112
+ const { name, root } = formatProjectName(projectNameInput, tmpDir);
113
+ await createProjectFromTemplate(
114
+ root,
115
+ "vue2-csr",
116
+ tmpDir,
117
+ true,
118
+ // force flag
119
+ {
120
+ projectName: name,
121
+ esmxVersion: getEsmxVersion(),
122
+ installCommand: "npm install",
123
+ devCommand: "npm run dev",
124
+ buildCommand: "npm run build",
125
+ startCommand: "npm start",
126
+ buildTypeCommand: "npm run build:type",
127
+ lintTypeCommand: "npm run lint:type"
128
+ }
129
+ );
130
+ expect(existsSync(join(mixedDir, "package.json"))).toBe(true);
131
+ });
132
+ it("should handle special characters in project names", async () => {
133
+ const specialNames = [
134
+ "project-with-dashes",
135
+ "project_with_underscores",
136
+ "project.with.dots"
137
+ ];
138
+ for (const projectName of specialNames) {
139
+ const projectPath = join(tmpDir, projectName);
140
+ const { name, root } = formatProjectName(projectName, tmpDir);
141
+ await createProjectFromTemplate(root, "vue2-csr", tmpDir, false, {
142
+ projectName: name,
143
+ esmxVersion: getEsmxVersion(),
144
+ installCommand: "npm install",
145
+ devCommand: "npm run dev",
146
+ buildCommand: "npm run build",
147
+ startCommand: "npm start",
148
+ buildTypeCommand: "npm run build:type",
149
+ lintTypeCommand: "npm run lint:type"
150
+ });
151
+ expect(existsSync(projectPath)).toBe(true);
152
+ expect(existsSync(join(projectPath, "package.json"))).toBe(true);
153
+ }
154
+ });
155
+ });
@@ -0,0 +1,17 @@
1
+ import type { TemplateInfo, TemplateVariables } from './types';
2
+ /**
3
+ * Get version of esmx from package.json
4
+ */
5
+ export declare function getEsmxVersion(): string;
6
+ /**
7
+ * Get list of available templates
8
+ */
9
+ export declare function getAvailableTemplates(): TemplateInfo[];
10
+ /**
11
+ * Check if directory is empty (ignoring hidden files)
12
+ */
13
+ export declare function isDirectoryEmpty(dirPath: string): boolean;
14
+ /**
15
+ * Copy template files to target directory with variable replacement
16
+ */
17
+ export declare function copyTemplateFiles(templatePath: string, targetPath: string, variables: TemplateVariables): void;
@@ -0,0 +1,76 @@
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ readdirSync,
5
+ readFileSync,
6
+ statSync,
7
+ writeFileSync
8
+ } from "node:fs";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ import { replaceTemplateVariables } from "./utils/index.mjs";
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ export function getEsmxVersion() {
14
+ try {
15
+ const packageJsonPath = resolve(__dirname, "../package.json");
16
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
17
+ return packageJson.version || "latest";
18
+ } catch (error) {
19
+ console.warn("Failed to read esmx version, using latest version");
20
+ return "latest";
21
+ }
22
+ }
23
+ export function getAvailableTemplates() {
24
+ const templateDir = resolve(__dirname, "../template");
25
+ const templates = [];
26
+ const templateFolders = readdirSync(templateDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
27
+ for (const folder of templateFolders) {
28
+ const name = folder;
29
+ const packageJsonPath = resolve(templateDir, folder, "package.json");
30
+ let description = `${name} template`;
31
+ if (existsSync(packageJsonPath)) {
32
+ try {
33
+ const packageJson = JSON.parse(
34
+ readFileSync(packageJsonPath, "utf-8")
35
+ );
36
+ if (packageJson.description) {
37
+ description = packageJson.description;
38
+ }
39
+ templates.push({
40
+ folder,
41
+ name,
42
+ description
43
+ });
44
+ } catch (error) {
45
+ console.warn(
46
+ `Warning: Failed to parse package.json for template '${folder}', skipping.`
47
+ );
48
+ }
49
+ }
50
+ }
51
+ return templates.sort((a, b) => a.name.localeCompare(b.name));
52
+ }
53
+ export function isDirectoryEmpty(dirPath) {
54
+ if (!existsSync(dirPath)) {
55
+ return true;
56
+ }
57
+ const files = readdirSync(dirPath);
58
+ const nonHiddenFiles = files.filter((file) => !file.startsWith("."));
59
+ return nonHiddenFiles.length === 0;
60
+ }
61
+ export function copyTemplateFiles(templatePath, targetPath, variables) {
62
+ const files = readdirSync(templatePath);
63
+ for (const file of files) {
64
+ const filePath = join(templatePath, file);
65
+ const targetFilePath = join(targetPath, file);
66
+ const stat = statSync(filePath);
67
+ if (stat.isDirectory()) {
68
+ mkdirSync(targetFilePath, { recursive: true });
69
+ copyTemplateFiles(filePath, targetFilePath, variables);
70
+ } else {
71
+ let content = readFileSync(filePath, "utf-8");
72
+ content = replaceTemplateVariables(content, variables);
73
+ writeFileSync(targetFilePath, content);
74
+ }
75
+ }
76
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { mkdir, mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
+ import {
7
+ copyTemplateFiles,
8
+ getAvailableTemplates,
9
+ getEsmxVersion,
10
+ isDirectoryEmpty
11
+ } from "./template.mjs";
12
+ async function createTempDir(prefix = "esmx-template-test-") {
13
+ return mkdtemp(join(tmpdir(), prefix));
14
+ }
15
+ async function cleanupTempDir(tempDir) {
16
+ try {
17
+ await rm(tempDir, { recursive: true, force: true });
18
+ } catch (error) {
19
+ console.warn(`Failed to cleanup temp directory: ${tempDir}`, error);
20
+ }
21
+ }
22
+ describe("template unit tests", () => {
23
+ let tmpDir;
24
+ beforeEach(async () => {
25
+ tmpDir = await createTempDir();
26
+ });
27
+ afterEach(async () => {
28
+ await cleanupTempDir(tmpDir);
29
+ });
30
+ it("should get Esmx version from package.json", () => {
31
+ const version = getEsmxVersion();
32
+ expect(typeof version).toBe("string");
33
+ expect(version.length).toBeGreaterThan(0);
34
+ });
35
+ it("should get available templates", () => {
36
+ const templates = getAvailableTemplates();
37
+ expect(templates.length).toBeGreaterThan(0);
38
+ expect(templates[0]).toHaveProperty("folder");
39
+ expect(templates[0]).toHaveProperty("name");
40
+ expect(templates[0]).toHaveProperty("description");
41
+ });
42
+ it("should detect empty directory", async () => {
43
+ const emptyDir = join(tmpDir, "empty");
44
+ await mkdir(emptyDir);
45
+ expect(isDirectoryEmpty(emptyDir)).toBe(true);
46
+ const hiddenDir = join(tmpDir, "hidden");
47
+ await mkdir(hiddenDir);
48
+ writeFileSync(join(hiddenDir, ".hiddenfile"), "hidden");
49
+ expect(isDirectoryEmpty(hiddenDir)).toBe(true);
50
+ const nonEmptyDir = join(tmpDir, "non-empty");
51
+ await mkdir(nonEmptyDir);
52
+ writeFileSync(join(nonEmptyDir, "visible.txt"), "visible");
53
+ expect(isDirectoryEmpty(nonEmptyDir)).toBe(false);
54
+ });
55
+ it("should copy template files with variable replacement", () => {
56
+ const templateDir = join(tmpDir, "template");
57
+ const targetDir = join(tmpDir, "target");
58
+ mkdirSync(templateDir, { recursive: true });
59
+ mkdirSync(join(templateDir, "src"), { recursive: true });
60
+ mkdirSync(targetDir, { recursive: true });
61
+ writeFileSync(
62
+ join(templateDir, "package.json"),
63
+ JSON.stringify({
64
+ name: "{{projectName}}",
65
+ version: "1.0.0",
66
+ dependencies: {
67
+ esmx: "{{esmxVersion}}"
68
+ },
69
+ scripts: {
70
+ dev: "{{devCommand}}",
71
+ build: "{{buildCommand}}"
72
+ }
73
+ })
74
+ );
75
+ writeFileSync(
76
+ join(templateDir, "src", "index.ts"),
77
+ 'console.log("Welcome to {{projectName}}!");'
78
+ );
79
+ copyTemplateFiles(templateDir, targetDir, {
80
+ projectName: "test-project",
81
+ esmxVersion: "1.2.3",
82
+ devCommand: "npm run dev",
83
+ buildCommand: "npm run build",
84
+ installCommand: "npm install",
85
+ startCommand: "npm start",
86
+ buildTypeCommand: "npm run build:type",
87
+ lintTypeCommand: "npm run lint:type"
88
+ });
89
+ expect(existsSync(join(targetDir, "package.json"))).toBe(true);
90
+ expect(existsSync(join(targetDir, "src", "index.ts"))).toBe(true);
91
+ const packageJson = JSON.parse(
92
+ require("node:fs").readFileSync(
93
+ join(targetDir, "package.json"),
94
+ "utf-8"
95
+ )
96
+ );
97
+ expect(packageJson.name).toBe("test-project");
98
+ expect(packageJson.dependencies.esmx).toBe("1.2.3");
99
+ expect(packageJson.scripts.dev).toBe("npm run dev");
100
+ const indexContent = require("node:fs").readFileSync(
101
+ join(targetDir, "src", "index.ts"),
102
+ "utf-8"
103
+ );
104
+ expect(indexContent).toBe('console.log("Welcome to test-project!");');
105
+ });
106
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Options for project creation
3
+ */
4
+ export interface CliOptions {
5
+ argv?: string[];
6
+ cwd?: string;
7
+ userAgent?: string;
8
+ version?: string;
9
+ }
10
+ /**
11
+ * Template information structure
12
+ */
13
+ export interface TemplateInfo {
14
+ folder: string;
15
+ name: string;
16
+ description: string;
17
+ }
18
+ /**
19
+ * Variables used in templates for replacement
20
+ */
21
+ export interface TemplateVariables extends Record<string, string> {
22
+ projectName: string;
23
+ esmxVersion: string;
24
+ installCommand: string;
25
+ devCommand: string;
26
+ buildCommand: string;
27
+ startCommand: string;
28
+ buildTypeCommand: string;
29
+ lintTypeCommand: string;
30
+ }
package/dist/types.mjs ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ export { type CommandType, getCommand } from './package-manager';
2
+ export { formatProjectName, type ProjectNameResult } from './project-name';
3
+ export { replaceTemplateVariables } from './template';
@@ -0,0 +1,7 @@
1
+ export {
2
+ getCommand
3
+ } from "./package-manager.mjs";
4
+ export {
5
+ formatProjectName
6
+ } from "./project-name.mjs";
7
+ export { replaceTemplateVariables } from "./template.mjs";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Package manager detection and command generation utilities
3
+ */
4
+ export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
5
+ export type CommandType = 'install' | 'dev' | 'build' | 'start' | 'create' | 'build:type' | 'lint:type';
6
+ /**
7
+ * Get a specific command for the detected package manager
8
+ * Business logic only needs to specify what command to execute
9
+ */
10
+ export declare function getCommand(commandType: CommandType, userAgent?: string): string;
@@ -0,0 +1,49 @@
1
+ const PACKAGE_MANAGER_CONFIG = {
2
+ npm: {
3
+ install: "npm install",
4
+ dev: "npm run dev",
5
+ build: "npm run build",
6
+ start: "npm start",
7
+ create: "npm create esmx@latest",
8
+ "build:type": "npm run build:type",
9
+ "lint:type": "npm run lint:type"
10
+ },
11
+ yarn: {
12
+ install: "yarn install",
13
+ dev: "yarn dev",
14
+ build: "yarn build",
15
+ start: "yarn start",
16
+ create: "yarn create esmx",
17
+ "build:type": "yarn build:type",
18
+ "lint:type": "yarn lint:type"
19
+ },
20
+ pnpm: {
21
+ install: "pnpm install",
22
+ dev: "pnpm dev",
23
+ build: "pnpm build",
24
+ start: "pnpm start",
25
+ create: "pnpm create esmx",
26
+ "build:type": "pnpm build:type",
27
+ "lint:type": "pnpm lint:type"
28
+ },
29
+ bun: {
30
+ install: "bun install",
31
+ dev: "bun dev",
32
+ build: "bun run build",
33
+ start: "bun start",
34
+ create: "bun create esmx",
35
+ "build:type": "bun run build:type",
36
+ "lint:type": "bun run lint:type"
37
+ }
38
+ };
39
+ function detectPackageManager(userAgent) {
40
+ const agent = userAgent || process.env.npm_config_user_agent || "";
41
+ if (agent.includes("pnpm")) return "pnpm";
42
+ if (agent.includes("yarn")) return "yarn";
43
+ if (agent.includes("bun")) return "bun";
44
+ return "npm";
45
+ }
46
+ export function getCommand(commandType, userAgent) {
47
+ const packageManager = detectPackageManager(userAgent);
48
+ return PACKAGE_MANAGER_CONFIG[packageManager][commandType];
49
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Unit tests for package-manager utilities
3
+ */
4
+ export {};