create-medusa-app 2.11.2 → 2.11.3-preview-20251031150158
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +0 -1
- package/CHANGELOG.md +8 -0
- package/dist/index.js +0 -0
- package/package.json +11 -11
- package/dist/commands/create-refactoring.js +0 -387
package/.turbo/turbo-build.log
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-medusa-app",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.3-preview-20251031150158",
|
|
4
4
|
"description": "Create a Medusa project using a single command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./dist/index.js",
|
|
7
7
|
"bin": "dist/index.js",
|
|
8
8
|
"license": "MIT",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "node --loader ts-node/esm src/index.ts",
|
|
11
|
+
"start": "node dist/index.js",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"watch": "tsc --watch"
|
|
14
|
+
},
|
|
9
15
|
"dependencies": {
|
|
10
|
-
"@medusajs/deps": "2.11.
|
|
11
|
-
"@medusajs/telemetry": "2.11.
|
|
16
|
+
"@medusajs/deps": "2.11.3-preview-20251031150158",
|
|
17
|
+
"@medusajs/telemetry": "2.11.3-preview-20251031150158",
|
|
12
18
|
"boxen": "^5",
|
|
13
19
|
"chalk": "^5.2.0",
|
|
14
20
|
"commander": "^10.0.1",
|
|
@@ -57,11 +63,5 @@
|
|
|
57
63
|
"publishConfig": {
|
|
58
64
|
"access": "public"
|
|
59
65
|
},
|
|
60
|
-
"gitHead": "41a5425405aea5045a26def95c0dc00cf4a5a44d"
|
|
61
|
-
|
|
62
|
-
"dev": "node --loader ts-node/esm src/index.ts",
|
|
63
|
-
"start": "node dist/index.js",
|
|
64
|
-
"build": "tsc",
|
|
65
|
-
"watch": "tsc --watch"
|
|
66
|
-
}
|
|
67
|
-
}
|
|
66
|
+
"gitHead": "41a5425405aea5045a26def95c0dc00cf4a5a44d"
|
|
67
|
+
}
|
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import inquirer from "inquirer";
|
|
2
|
-
import slugifyType from "slugify";
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { getDbClientAndCredentials, runCreateDb } from "../utils/create-db.js";
|
|
5
|
-
import prepareProject from "../utils/prepare-project.js";
|
|
6
|
-
import startMedusa from "../utils/start-medusa.js";
|
|
7
|
-
import open from "open";
|
|
8
|
-
import waitOn from "wait-on";
|
|
9
|
-
import ora from "ora";
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
import path from "path";
|
|
12
|
-
import logMessage from "../utils/log-message.js";
|
|
13
|
-
import createAbortController, { isAbortError, } from "../utils/create-abort-controller.js";
|
|
14
|
-
import { track } from "@medusajs/telemetry";
|
|
15
|
-
import boxen from "boxen";
|
|
16
|
-
import { emojify } from "node-emoji";
|
|
17
|
-
import ProcessManager from "../utils/process-manager.js";
|
|
18
|
-
import { displayFactBox } from "../utils/facts.js";
|
|
19
|
-
import { EOL } from "os";
|
|
20
|
-
import { runCloneRepo } from "../utils/clone-repo.js";
|
|
21
|
-
import { askForNextjsStarter, installNextjsStarter, startNextjsStarter, } from "../utils/nextjs-utils.js";
|
|
22
|
-
import { getNodeVersion, MIN_SUPPORTED_NODE_VERSION, } from "../utils/node-version.js";
|
|
23
|
-
const slugify = slugifyType.default;
|
|
24
|
-
// Base class for common project functionality
|
|
25
|
-
class BaseProjectCreator {
|
|
26
|
-
options;
|
|
27
|
-
args;
|
|
28
|
-
spinner;
|
|
29
|
-
processManager;
|
|
30
|
-
abortController;
|
|
31
|
-
factBoxOptions;
|
|
32
|
-
projectName;
|
|
33
|
-
projectPath;
|
|
34
|
-
isProjectCreated = false;
|
|
35
|
-
printedMessage = false;
|
|
36
|
-
constructor(projectName, options, args) {
|
|
37
|
-
this.options = options;
|
|
38
|
-
this.args = args;
|
|
39
|
-
this.spinner = ora();
|
|
40
|
-
this.processManager = new ProcessManager();
|
|
41
|
-
this.abortController = createAbortController(this.processManager);
|
|
42
|
-
this.projectName = projectName;
|
|
43
|
-
const basePath = typeof options.directoryPath === "string" ? options.directoryPath : "";
|
|
44
|
-
this.projectPath = path.join(basePath, projectName);
|
|
45
|
-
this.factBoxOptions = {
|
|
46
|
-
interval: null,
|
|
47
|
-
spinner: this.spinner,
|
|
48
|
-
processManager: this.processManager,
|
|
49
|
-
message: "",
|
|
50
|
-
title: "",
|
|
51
|
-
verbose: options.verbose || false,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
getProjectPath(projectName) {
|
|
55
|
-
return path.join(this.options.directoryPath ?? "", projectName);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// Plugin Project Creator
|
|
59
|
-
class PluginProjectCreator extends BaseProjectCreator {
|
|
60
|
-
constructor(projectName, options, args) {
|
|
61
|
-
super(projectName, options, args);
|
|
62
|
-
this.setupProcessManager();
|
|
63
|
-
}
|
|
64
|
-
async create() {
|
|
65
|
-
track("CREATE_CLI_CMP");
|
|
66
|
-
logMessage({
|
|
67
|
-
message: `${emojify(":rocket:")} Starting plugin setup, this may take a few minutes.`,
|
|
68
|
-
});
|
|
69
|
-
this.spinner.start();
|
|
70
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
71
|
-
...this.factBoxOptions,
|
|
72
|
-
title: "Setting up plugin...",
|
|
73
|
-
});
|
|
74
|
-
try {
|
|
75
|
-
await this.cloneAndPreparePlugin();
|
|
76
|
-
this.spinner.succeed(chalk.green("Plugin Prepared"));
|
|
77
|
-
this.showSuccessMessage();
|
|
78
|
-
}
|
|
79
|
-
catch (e) {
|
|
80
|
-
this.handleError(e);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async cloneAndPreparePlugin() {
|
|
84
|
-
await runCloneRepo({
|
|
85
|
-
projectName: this.projectPath,
|
|
86
|
-
repoUrl: this.options.repoUrl ?? "",
|
|
87
|
-
abortController: this.abortController,
|
|
88
|
-
spinner: this.spinner,
|
|
89
|
-
verbose: this.options.verbose,
|
|
90
|
-
});
|
|
91
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
92
|
-
...this.factBoxOptions,
|
|
93
|
-
message: "Created plugin directory",
|
|
94
|
-
});
|
|
95
|
-
await prepareProject({
|
|
96
|
-
isPlugin: true,
|
|
97
|
-
directory: this.projectPath,
|
|
98
|
-
projectName: this.projectName,
|
|
99
|
-
spinner: this.spinner,
|
|
100
|
-
processManager: this.processManager,
|
|
101
|
-
abortController: this.abortController,
|
|
102
|
-
verbose: this.options.verbose,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
handleError(e) {
|
|
106
|
-
if (isAbortError(e)) {
|
|
107
|
-
process.exit();
|
|
108
|
-
}
|
|
109
|
-
this.spinner.stop();
|
|
110
|
-
logMessage({
|
|
111
|
-
message: `An error occurred while preparing plugin: ${e}`,
|
|
112
|
-
type: "error",
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
showSuccessMessage() {
|
|
116
|
-
logMessage({
|
|
117
|
-
message: boxen(chalk.green(`Change to the \`${this.projectName}\` directory to explore your Medusa plugin.${EOL}${EOL}Check out the Medusa plugin documentation to start your development:${EOL}${EOL}https://docs.medusajs.com/${EOL}${EOL}Star us on GitHub if you like what we're building:${EOL}${EOL}https://github.com/medusajs/medusa/stargazers`), {
|
|
118
|
-
titleAlignment: "center",
|
|
119
|
-
textAlignment: "center",
|
|
120
|
-
padding: 1,
|
|
121
|
-
margin: 1,
|
|
122
|
-
float: "center",
|
|
123
|
-
}),
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
setupProcessManager() {
|
|
127
|
-
this.processManager.onTerminated(async () => {
|
|
128
|
-
this.spinner.stop();
|
|
129
|
-
if (!this.printedMessage && this.isProjectCreated) {
|
|
130
|
-
this.printedMessage = true;
|
|
131
|
-
this.showSuccessMessage();
|
|
132
|
-
}
|
|
133
|
-
return;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// Medusa Project Creator
|
|
138
|
-
class MedusaProjectCreator extends BaseProjectCreator {
|
|
139
|
-
client = null;
|
|
140
|
-
dbConnectionString = "";
|
|
141
|
-
isDbInitialized = false;
|
|
142
|
-
nextjsDirectory = "";
|
|
143
|
-
inviteToken;
|
|
144
|
-
constructor(projectName, options, args) {
|
|
145
|
-
super(projectName, options, args);
|
|
146
|
-
this.setupProcessManager();
|
|
147
|
-
}
|
|
148
|
-
async create() {
|
|
149
|
-
track("CREATE_CLI_CMA");
|
|
150
|
-
try {
|
|
151
|
-
await this.initializeProject();
|
|
152
|
-
await this.setupProject();
|
|
153
|
-
await this.startServices();
|
|
154
|
-
}
|
|
155
|
-
catch (e) {
|
|
156
|
-
this.handleError(e);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
async initializeProject() {
|
|
160
|
-
const installNextjs = this.options.withNextjsStarter || (await askForNextjsStarter());
|
|
161
|
-
if (!this.options.skipDb) {
|
|
162
|
-
await this.setupDatabase();
|
|
163
|
-
}
|
|
164
|
-
logMessage({
|
|
165
|
-
message: `${emojify(":rocket:")} Starting project setup, this may take a few minutes.`,
|
|
166
|
-
});
|
|
167
|
-
this.spinner.start();
|
|
168
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
169
|
-
...this.factBoxOptions,
|
|
170
|
-
title: "Setting up project...",
|
|
171
|
-
});
|
|
172
|
-
try {
|
|
173
|
-
await runCloneRepo({
|
|
174
|
-
projectName: this.projectPath,
|
|
175
|
-
repoUrl: this.options.repoUrl ?? "",
|
|
176
|
-
abortController: this.abortController,
|
|
177
|
-
spinner: this.spinner,
|
|
178
|
-
verbose: this.options.verbose,
|
|
179
|
-
});
|
|
180
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
181
|
-
...this.factBoxOptions,
|
|
182
|
-
message: "Created project directory",
|
|
183
|
-
});
|
|
184
|
-
if (installNextjs) {
|
|
185
|
-
this.nextjsDirectory = await installNextjsStarter({
|
|
186
|
-
directoryName: this.projectPath,
|
|
187
|
-
abortController: this.abortController,
|
|
188
|
-
factBoxOptions: this.factBoxOptions,
|
|
189
|
-
verbose: this.options.verbose,
|
|
190
|
-
processManager: this.processManager,
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
catch (e) {
|
|
195
|
-
throw e;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
async setupDatabase() {
|
|
199
|
-
const dbName = `medusa-${slugify(this.projectName)}`;
|
|
200
|
-
const { client, dbConnectionString, ...rest } = await getDbClientAndCredentials({
|
|
201
|
-
dbName,
|
|
202
|
-
dbUrl: this.options.dbUrl,
|
|
203
|
-
verbose: this.options.verbose,
|
|
204
|
-
});
|
|
205
|
-
this.client = client;
|
|
206
|
-
this.dbConnectionString = dbConnectionString;
|
|
207
|
-
this.isDbInitialized = true;
|
|
208
|
-
if (!this.options.dbUrl) {
|
|
209
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
210
|
-
...this.factBoxOptions,
|
|
211
|
-
title: "Creating database...",
|
|
212
|
-
});
|
|
213
|
-
this.client = await runCreateDb({
|
|
214
|
-
client: this.client,
|
|
215
|
-
dbName,
|
|
216
|
-
spinner: this.spinner,
|
|
217
|
-
});
|
|
218
|
-
this.factBoxOptions.interval = displayFactBox({
|
|
219
|
-
...this.factBoxOptions,
|
|
220
|
-
message: `Database ${dbName} created`,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
async setupProject() {
|
|
225
|
-
try {
|
|
226
|
-
this.inviteToken = await prepareProject({
|
|
227
|
-
isPlugin: false,
|
|
228
|
-
directory: this.projectPath,
|
|
229
|
-
dbConnectionString: this.dbConnectionString,
|
|
230
|
-
seed: this.options.seed,
|
|
231
|
-
spinner: this.spinner,
|
|
232
|
-
processManager: this.processManager,
|
|
233
|
-
abortController: this.abortController,
|
|
234
|
-
skipDb: this.options.skipDb,
|
|
235
|
-
migrations: this.options.migrations,
|
|
236
|
-
onboardingType: this.nextjsDirectory ? "nextjs" : "default",
|
|
237
|
-
nextjsDirectory: this.nextjsDirectory,
|
|
238
|
-
client: this.client,
|
|
239
|
-
verbose: this.options.verbose,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
finally {
|
|
243
|
-
await this.client?.end();
|
|
244
|
-
}
|
|
245
|
-
this.spinner.succeed(chalk.green("Project Prepared"));
|
|
246
|
-
}
|
|
247
|
-
async startServices() {
|
|
248
|
-
if (this.options.skipDb || !this.options.browser) {
|
|
249
|
-
this.showSuccessMessage();
|
|
250
|
-
process.exit();
|
|
251
|
-
}
|
|
252
|
-
logMessage({
|
|
253
|
-
message: "Starting Medusa...",
|
|
254
|
-
});
|
|
255
|
-
startMedusa({
|
|
256
|
-
directory: this.projectPath,
|
|
257
|
-
abortController: this.abortController,
|
|
258
|
-
});
|
|
259
|
-
if (this.nextjsDirectory) {
|
|
260
|
-
startNextjsStarter({
|
|
261
|
-
directory: this.nextjsDirectory,
|
|
262
|
-
abortController: this.abortController,
|
|
263
|
-
verbose: this.options.verbose,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
this.isProjectCreated = true;
|
|
267
|
-
await this.openBrowser();
|
|
268
|
-
}
|
|
269
|
-
async openBrowser() {
|
|
270
|
-
await waitOn({
|
|
271
|
-
resources: ["http://localhost:9000/health"],
|
|
272
|
-
}).then(async () => {
|
|
273
|
-
open(this.inviteToken
|
|
274
|
-
? `http://localhost:9000/app/invite?token=${this.inviteToken}&first_run=true`
|
|
275
|
-
: "http://localhost:9000/app");
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
handleError(e) {
|
|
279
|
-
if (isAbortError(e)) {
|
|
280
|
-
process.exit();
|
|
281
|
-
}
|
|
282
|
-
this.spinner.stop();
|
|
283
|
-
logMessage({
|
|
284
|
-
message: `An error occurred: ${e}`,
|
|
285
|
-
type: "error",
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
showSuccessMessage() {
|
|
289
|
-
logMessage({
|
|
290
|
-
message: boxen(chalk.green(`Change to the \`${this.projectName}\` directory to explore your Medusa project.${EOL}${EOL}Start your Medusa app again with the following command:${EOL}${EOL}yarn dev${EOL}${EOL}${this.inviteToken
|
|
291
|
-
? `After you start the Medusa app, you can set a password for your admin user with the URL http://localhost:7001/invite?token=${this.inviteToken}&first_run=true${EOL}${EOL}`
|
|
292
|
-
: ""}${this.nextjsDirectory?.length
|
|
293
|
-
? `The Next.js Starter storefront was installed in the \`${this.nextjsDirectory}\` directory. Change to that directory and start it with the following command:${EOL}${EOL}npm run dev${EOL}${EOL}`
|
|
294
|
-
: ""}Check out the Medusa documentation to start your development:${EOL}${EOL}https://docs.medusajs.com/${EOL}${EOL}Star us on GitHub if you like what we're building:${EOL}${EOL}https://github.com/medusajs/medusa/stargazers`), {
|
|
295
|
-
titleAlignment: "center",
|
|
296
|
-
textAlignment: "center",
|
|
297
|
-
padding: 1,
|
|
298
|
-
margin: 1,
|
|
299
|
-
float: "center",
|
|
300
|
-
}),
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
setupProcessManager() {
|
|
304
|
-
this.processManager.onTerminated(async () => {
|
|
305
|
-
this.spinner.stop();
|
|
306
|
-
// prevent an error from occurring if
|
|
307
|
-
// client hasn't been declared yet
|
|
308
|
-
if (this.isDbInitialized && this.client) {
|
|
309
|
-
await this.client.end();
|
|
310
|
-
}
|
|
311
|
-
if (!this.printedMessage && this.isProjectCreated) {
|
|
312
|
-
this.printedMessage = true;
|
|
313
|
-
this.showSuccessMessage();
|
|
314
|
-
}
|
|
315
|
-
return;
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
// Project Factory
|
|
320
|
-
class ProjectCreatorFactory {
|
|
321
|
-
static async create(args, options) {
|
|
322
|
-
const isPlugin = args.indexOf("--plugin") !== -1;
|
|
323
|
-
if (isPlugin) {
|
|
324
|
-
args.splice(args.indexOf("--plugin"), 1);
|
|
325
|
-
}
|
|
326
|
-
ProjectCreatorFactory.validateNodeVersion();
|
|
327
|
-
const projectName = await ProjectCreatorFactory.getProjectName(args, options.directoryPath, isPlugin);
|
|
328
|
-
return isPlugin
|
|
329
|
-
? new PluginProjectCreator(projectName, options, args)
|
|
330
|
-
: new MedusaProjectCreator(projectName, options, args);
|
|
331
|
-
}
|
|
332
|
-
static validateNodeVersion() {
|
|
333
|
-
const nodeVersion = getNodeVersion();
|
|
334
|
-
if (nodeVersion < MIN_SUPPORTED_NODE_VERSION) {
|
|
335
|
-
logMessage({
|
|
336
|
-
message: `Medusa requires at least v20 of Node.js. You're using v${nodeVersion}. Please install at least v20 and try again: https://nodejs.org/en/download`,
|
|
337
|
-
type: "error",
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
static async getProjectName(args, directoryPath, isPlugin) {
|
|
342
|
-
let askProjectName = args.length === 0;
|
|
343
|
-
if (args.length > 0) {
|
|
344
|
-
const projectPath = path.join(directoryPath || "", args[0]);
|
|
345
|
-
if (fs.existsSync(projectPath) &&
|
|
346
|
-
fs.lstatSync(projectPath).isDirectory()) {
|
|
347
|
-
logMessage({
|
|
348
|
-
message: `A directory already exists with the name ${args[0]}. Please enter a different ${isPlugin ? "plugin" : "project"} name.`,
|
|
349
|
-
type: "warn",
|
|
350
|
-
});
|
|
351
|
-
askProjectName = true;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return askProjectName
|
|
355
|
-
? await askForProjectName(directoryPath, isPlugin)
|
|
356
|
-
: args[0];
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
async function askForProjectName(directoryPath, isPlugin) {
|
|
360
|
-
const { projectName } = await inquirer.prompt([
|
|
361
|
-
{
|
|
362
|
-
type: "input",
|
|
363
|
-
name: "projectName",
|
|
364
|
-
message: `What's the name of your ${isPlugin ? "plugin" : "project"}?`,
|
|
365
|
-
default: "my-medusa-store",
|
|
366
|
-
filter: (input) => {
|
|
367
|
-
return slugify(input).toLowerCase();
|
|
368
|
-
},
|
|
369
|
-
validate: (input) => {
|
|
370
|
-
if (!input.length) {
|
|
371
|
-
return `Please enter a ${isPlugin ? "plugin" : "project"} name`;
|
|
372
|
-
}
|
|
373
|
-
const projectPath = path.join(directoryPath || "", input);
|
|
374
|
-
return fs.existsSync(projectPath) &&
|
|
375
|
-
fs.lstatSync(projectPath).isDirectory()
|
|
376
|
-
? `A directory already exists with the same name. Please enter a different ${isPlugin ? "plugin" : "project"} name.`
|
|
377
|
-
: true;
|
|
378
|
-
},
|
|
379
|
-
},
|
|
380
|
-
]);
|
|
381
|
-
return projectName;
|
|
382
|
-
}
|
|
383
|
-
// Main entry point
|
|
384
|
-
export default async (args, options) => {
|
|
385
|
-
const projectCreator = await ProjectCreatorFactory.create(args, options);
|
|
386
|
-
await projectCreator.create();
|
|
387
|
-
};
|