create-acmekit-app 2.13.39 → 2.13.41

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.13.41
4
+
5
+ ### Patch Changes
6
+
7
+ - changes
8
+
9
+ - Updated dependencies []:
10
+ - @acmekit/telemetry@2.13.41
11
+ - @acmekit/deps@2.13.41
12
+
13
+ ## 2.13.40
14
+
15
+ ### Patch Changes
16
+
17
+ - changes
18
+
19
+ - Updated dependencies []:
20
+ - @acmekit/telemetry@2.13.40
21
+ - @acmekit/deps@2.13.40
22
+
3
23
  ## 2.13.39
4
24
 
5
25
  ### Patch Changes
package/dist/index.js CHANGED
@@ -13,7 +13,6 @@ program
13
13
  .option("--no-migrations", "Skips running migrations, creating admin user, and seeding. If used, it's expected that you pass the --db-url option with a url of a database that has all necessary migrations. Otherwise, unexpected errors will occur.", true)
14
14
  .option("--no-browser", "Disables opening the browser at the end of the project creation and only shows success message.", true)
15
15
  .option("--directory-path <path>", "Specify the directory path to install the project in.")
16
- .option("--with-nextjs-starter", "Install the Next.js starter along with the AcmeKit backend", false)
17
16
  .option("--verbose", "Show all logs of underlying commands. Useful for debugging.", false)
18
17
  .addOption(new Option("--use-npm", "Use npm as the package manager").conflicts([
19
18
  "usePnpm",
@@ -10,11 +10,11 @@ const facts = [
10
10
  "Organize customers by customer groups and set special prices for them.",
11
11
  "Specify the inventory of products per location and sales channel.",
12
12
  "Publishable-API Keys allow you to send scoped requests to the server's client API routes.",
13
- "API Routes expose business logic to clients, such as storefronts and admin customizations.",
13
+ "API Routes expose business logic to clients, such as custom frontends and admin customizations.",
14
14
  "Subscribers are asynchronous functions that are executed when an event is emitted.",
15
15
  "Data models represent tables in the database. They are created using AcmeKit's Data Modeling Language (DML).",
16
16
  "AcmeKit's client API routes are prefixed by /client. The admin API routes are prefixed by /admin.",
17
- "The JS SDK allows you to send requests to the AcmeKit server from your storefront or admin customizations.",
17
+ "The JS SDK allows you to send requests to the AcmeKit server from your frontend or admin customizations.",
18
18
  "Modules are reusable packages of functionalities related to a single commerce domain or integration.",
19
19
  "Modules have a main service that provides data-management and integration functionalities.",
20
20
  "Modules allow you to replace an entire functionality with your custom logic.",
@@ -55,7 +55,7 @@ async function preparePlugin({ directory, projectName, spinner, processManager,
55
55
  });
56
56
  displayFactBox({ ...factBoxOptions, message: "Finished Preparation" });
57
57
  }
58
- async function prepareProject({ directory, projectName, dbName, dbConnectionString, seed, spinner, processManager, abortController, skipDb, migrations, onboardingType = "default", nextjsDirectory = "", client, verbose = false, packageManager, version, }) {
58
+ async function prepareProject({ directory, projectName, dbName, dbConnectionString, seed, spinner, processManager, abortController, skipDb, migrations, client, verbose = false, packageManager, version, }) {
59
59
  // initialize execution options
60
60
  const execOptions = {
61
61
  cwd: directory,
@@ -94,7 +94,7 @@ async function prepareProject({ directory, projectName, dbName, dbConnectionStri
94
94
  // initialize the invite token to return
95
95
  let inviteToken = undefined;
96
96
  // add environment variables
97
- let env = `MEDUSA_ADMIN_ONBOARDING_TYPE=${onboardingType}${EOL}CLIENT_CORS=${CLIENT_CORS}${EOL}ADMIN_CORS=${ADMIN_CORS}${EOL}AUTH_CORS=${AUTH_CORS}${EOL}REDIS_URL=${DEFAULT_REDIS_URL}${EOL}JWT_SECRET=supersecret${EOL}COOKIE_SECRET=supersecret`;
97
+ let env = `CLIENT_CORS=${CLIENT_CORS}${EOL}ADMIN_CORS=${ADMIN_CORS}${EOL}AUTH_CORS=${AUTH_CORS}${EOL}REDIS_URL=${DEFAULT_REDIS_URL}${EOL}JWT_SECRET=supersecret${EOL}COOKIE_SECRET=supersecret`;
98
98
  if (!skipDb) {
99
99
  if (dbName) {
100
100
  env += `${EOL}DB_NAME=${dbName}`;
@@ -102,9 +102,6 @@ async function prepareProject({ directory, projectName, dbName, dbConnectionStri
102
102
  }
103
103
  env += `${EOL}DATABASE_URL=${dbConnectionString}`;
104
104
  }
105
- if (nextjsDirectory) {
106
- env += `${EOL}MEDUSA_ADMIN_ONBOARDING_NEXTJS_DIRECTORY=${nextjsDirectory}`;
107
- }
108
105
  fs.appendFileSync(path.join(directory, `.env`), env);
109
106
  factBoxOptions.interval = displayFactBox({
110
107
  ...factBoxOptions,
@@ -176,18 +173,6 @@ async function prepareProject({ directory, projectName, dbName, dbConnectionStri
176
173
  });
177
174
  }
178
175
  }
179
- // if installation includes Next.js, retrieve the publishable API key
180
- // from the backend and add it as an enviornment variable
181
- if (nextjsDirectory && client) {
182
- const apiKeys = await client.query(`SELECT * FROM "api_key" WHERE type = 'publishable'`);
183
- if (apiKeys.rowCount) {
184
- const nextjsEnvPath = path.join(nextjsDirectory, fs.existsSync(path.join(nextjsDirectory, ".env.local"))
185
- ? ".env.local"
186
- : ".env.template");
187
- const originalContent = fs.readFileSync(nextjsEnvPath, "utf-8");
188
- fs.writeFileSync(nextjsEnvPath, originalContent.replace("NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_test", `NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=${apiKeys.rows[0].token}`));
189
- }
190
- }
191
176
  displayFactBox({ ...factBoxOptions, message: "Finished Preparation" });
192
177
  return inviteToken;
193
178
  }
@@ -11,7 +11,6 @@ import { isAbortError } from "../create-abort-controller.js";
11
11
  import { getDbClientAndCredentials, runCreateDb } from "../create-db.js";
12
12
  import { displayFactBox } from "../facts.js";
13
13
  import logMessage from "../log-message.js";
14
- import { askForNextjsStarter, installNextjsStarter, startNextjsStarter, } from "../nextjs-utils.js";
15
14
  import prepareProject from "../prepare-project.js";
16
15
  import startAcmeKit from "../start-acmekit.js";
17
16
  import { BaseProjectCreator, } from "./creator.js";
@@ -22,7 +21,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
22
21
  client = null;
23
22
  dbConnectionString = "";
24
23
  isDbInitialized = false;
25
- nextjsDirectory = "";
26
24
  inviteToken;
27
25
  constructor(projectName, options, args) {
28
26
  super(projectName, options, args);
@@ -40,7 +38,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
40
38
  }
41
39
  }
42
40
  async initializeProject() {
43
- const installNextjs = this.options.withNextjsStarter || (await askForNextjsStarter());
44
41
  if (!this.options.skipDb) {
45
42
  await this.setupDatabase();
46
43
  }
@@ -63,16 +60,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
63
60
  ...this.factBoxOptions,
64
61
  message: "Created project directory",
65
62
  });
66
- if (installNextjs) {
67
- this.nextjsDirectory = await installNextjsStarter({
68
- directoryName: this.projectPath,
69
- abortController: this.abortController,
70
- factBoxOptions: this.factBoxOptions,
71
- verbose: this.options.verbose,
72
- packageManager: this.packageManager,
73
- version: this.options.version,
74
- });
75
- }
76
63
  }
77
64
  async setupDatabase() {
78
65
  let dbName = `acmekit-${slugify(this.projectName)}`;
@@ -114,8 +101,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
114
101
  abortController: this.abortController,
115
102
  skipDb: this.options.skipDb,
116
103
  migrations: this.options.migrations,
117
- onboardingType: this.nextjsDirectory ? "nextjs" : "default",
118
- nextjsDirectory: this.nextjsDirectory,
119
104
  client: this.client,
120
105
  verbose: this.options.verbose,
121
106
  packageManager: this.packageManager,
@@ -140,14 +125,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
140
125
  abortController: this.abortController,
141
126
  packageManager: this.packageManager,
142
127
  });
143
- if (this.nextjsDirectory) {
144
- startNextjsStarter({
145
- directory: this.nextjsDirectory,
146
- abortController: this.abortController,
147
- verbose: this.options.verbose,
148
- packageManager: this.packageManager,
149
- });
150
- }
151
128
  this.isProjectCreated = true;
152
129
  await this.openBrowser();
153
130
  }
@@ -175,8 +152,6 @@ export class AcmeKitProjectCreator extends BaseProjectCreator {
175
152
  logMessage({
176
153
  message: boxen(chalk.green(`Change to the \`${this.projectName}\` directory to explore your AcmeKit project.${EOL}${EOL}Start your AcmeKit application again with the following command:${EOL}${EOL}${commandStr}${EOL}${EOL}${this.inviteToken
177
154
  ? `After you start the AcmeKit application, you can create an admin user with the URL http://localhost:9000/app/invite?token=${this.inviteToken}&first_run=true${EOL}${EOL}`
178
- : ""}${this.nextjsDirectory?.length
179
- ? `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}${commandStr}${EOL}${EOL}`
180
155
  : ""}Check out the AcmeKit ${terminalLink("documentation", "https://docs.acmekit.com/")} to start your development:${EOL}${EOL}Star us on ${terminalLink("GitHub", "https://github.com/acmekit/acmekit/stargazers")} if you like what we're building.`), {
181
156
  titleAlignment: "center",
182
157
  textAlignment: "center",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-acmekit-app",
3
- "version": "2.13.39",
3
+ "version": "2.13.41",
4
4
  "description": "Create a AcmeKit project using a single command.",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -14,8 +14,8 @@
14
14
  "test": "../../../node_modules/.bin/jest --passWithNoTests src"
15
15
  },
16
16
  "dependencies": {
17
- "@acmekit/deps": "2.13.39",
18
- "@acmekit/telemetry": "2.13.39",
17
+ "@acmekit/deps": "2.13.41",
18
+ "@acmekit/telemetry": "2.13.41",
19
19
  "boxen": "^5.0.1",
20
20
  "chalk": "^4.1.2",
21
21
  "commander": "^11.0.0",
package/src/index.ts CHANGED
@@ -32,11 +32,6 @@ program
32
32
  "--directory-path <path>",
33
33
  "Specify the directory path to install the project in."
34
34
  )
35
- .option(
36
- "--with-nextjs-starter",
37
- "Install the Next.js starter along with the AcmeKit backend",
38
- false
39
- )
40
35
  .option(
41
36
  "--verbose",
42
37
  "Show all logs of underlying commands. Useful for debugging.",
@@ -22,11 +22,11 @@ const facts = [
22
22
  "Organize customers by customer groups and set special prices for them.",
23
23
  "Specify the inventory of products per location and sales channel.",
24
24
  "Publishable-API Keys allow you to send scoped requests to the server's client API routes.",
25
- "API Routes expose business logic to clients, such as storefronts and admin customizations.",
25
+ "API Routes expose business logic to clients, such as custom frontends and admin customizations.",
26
26
  "Subscribers are asynchronous functions that are executed when an event is emitted.",
27
27
  "Data models represent tables in the database. They are created using AcmeKit's Data Modeling Language (DML).",
28
28
  "AcmeKit's client API routes are prefixed by /client. The admin API routes are prefixed by /admin.",
29
- "The JS SDK allows you to send requests to the AcmeKit server from your storefront or admin customizations.",
29
+ "The JS SDK allows you to send requests to the AcmeKit server from your frontend or admin customizations.",
30
30
  "Modules are reusable packages of functionalities related to a single commerce domain or integration.",
31
31
  "Modules have a main service that provides data-management and integration functionalities.",
32
32
  "Modules allow you to replace an entire functionality with your custom logic.",
@@ -41,8 +41,6 @@ type PrepareProjectOptions = {
41
41
  abortController?: AbortController
42
42
  skipDb?: boolean
43
43
  migrations?: boolean
44
- onboardingType?: "default" | "nextjs"
45
- nextjsDirectory?: string
46
44
  client: Client | null
47
45
  verbose?: boolean
48
46
  packageManager: PackageManager
@@ -131,8 +129,6 @@ async function prepareProject({
131
129
  abortController,
132
130
  skipDb,
133
131
  migrations,
134
- onboardingType = "default",
135
- nextjsDirectory = "",
136
132
  client,
137
133
  verbose = false,
138
134
  packageManager,
@@ -185,7 +181,7 @@ async function prepareProject({
185
181
  let inviteToken: string | undefined = undefined
186
182
 
187
183
  // add environment variables
188
- let env = `MEDUSA_ADMIN_ONBOARDING_TYPE=${onboardingType}${EOL}CLIENT_CORS=${CLIENT_CORS}${EOL}ADMIN_CORS=${ADMIN_CORS}${EOL}AUTH_CORS=${AUTH_CORS}${EOL}REDIS_URL=${DEFAULT_REDIS_URL}${EOL}JWT_SECRET=supersecret${EOL}COOKIE_SECRET=supersecret`
184
+ let env = `CLIENT_CORS=${CLIENT_CORS}${EOL}ADMIN_CORS=${ADMIN_CORS}${EOL}AUTH_CORS=${AUTH_CORS}${EOL}REDIS_URL=${DEFAULT_REDIS_URL}${EOL}JWT_SECRET=supersecret${EOL}COOKIE_SECRET=supersecret`
189
185
 
190
186
  if (!skipDb) {
191
187
  if (dbName) {
@@ -195,10 +191,6 @@ async function prepareProject({
195
191
  env += `${EOL}DATABASE_URL=${dbConnectionString}`
196
192
  }
197
193
 
198
- if (nextjsDirectory) {
199
- env += `${EOL}MEDUSA_ADMIN_ONBOARDING_NEXTJS_DIRECTORY=${nextjsDirectory}`
200
- }
201
-
202
194
  fs.appendFileSync(path.join(directory, `.env`), env)
203
195
 
204
196
  factBoxOptions.interval = displayFactBox({
@@ -302,33 +294,6 @@ async function prepareProject({
302
294
  }
303
295
  }
304
296
 
305
- // if installation includes Next.js, retrieve the publishable API key
306
- // from the backend and add it as an enviornment variable
307
- if (nextjsDirectory && client) {
308
- const apiKeys = await client.query(
309
- `SELECT * FROM "api_key" WHERE type = 'publishable'`
310
- )
311
-
312
- if (apiKeys.rowCount) {
313
- const nextjsEnvPath = path.join(
314
- nextjsDirectory,
315
- fs.existsSync(path.join(nextjsDirectory, ".env.local"))
316
- ? ".env.local"
317
- : ".env.template"
318
- )
319
-
320
- const originalContent = fs.readFileSync(nextjsEnvPath, "utf-8")
321
-
322
- fs.writeFileSync(
323
- nextjsEnvPath,
324
- originalContent.replace(
325
- "NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_test",
326
- `NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=${apiKeys.rows[0].token}`
327
- )
328
- )
329
- }
330
- }
331
-
332
297
  displayFactBox({ ...factBoxOptions, message: "Finished Preparation" })
333
298
 
334
299
  return inviteToken
@@ -11,11 +11,6 @@ import { isAbortError } from "../create-abort-controller.js"
11
11
  import { getDbClientAndCredentials, runCreateDb } from "../create-db.js"
12
12
  import { displayFactBox } from "../facts.js"
13
13
  import logMessage from "../log-message.js"
14
- import {
15
- askForNextjsStarter,
16
- installNextjsStarter,
17
- startNextjsStarter,
18
- } from "../nextjs-utils.js"
19
14
  import prepareProject from "../prepare-project.js"
20
15
  import startAcmeKit from "../start-acmekit.js"
21
16
  import {
@@ -35,7 +30,6 @@ export class AcmeKitProjectCreator
35
30
  private client: any = null
36
31
  private dbConnectionString: string = ""
37
32
  private isDbInitialized: boolean = false
38
- private nextjsDirectory: string = ""
39
33
  private inviteToken?: string
40
34
 
41
35
  constructor(projectName: string, options: ProjectOptions, args: string[]) {
@@ -56,9 +50,6 @@ export class AcmeKitProjectCreator
56
50
  }
57
51
 
58
52
  private async initializeProject(): Promise<void> {
59
- const installNextjs =
60
- this.options.withNextjsStarter || (await askForNextjsStarter())
61
-
62
53
  if (!this.options.skipDb) {
63
54
  await this.setupDatabase()
64
55
  }
@@ -88,17 +79,6 @@ export class AcmeKitProjectCreator
88
79
  ...this.factBoxOptions,
89
80
  message: "Created project directory",
90
81
  })
91
-
92
- if (installNextjs) {
93
- this.nextjsDirectory = await installNextjsStarter({
94
- directoryName: this.projectPath,
95
- abortController: this.abortController,
96
- factBoxOptions: this.factBoxOptions,
97
- verbose: this.options.verbose,
98
- packageManager: this.packageManager,
99
- version: this.options.version,
100
- })
101
- }
102
82
  }
103
83
 
104
84
  private async setupDatabase(): Promise<void> {
@@ -147,8 +127,6 @@ export class AcmeKitProjectCreator
147
127
  abortController: this.abortController,
148
128
  skipDb: this.options.skipDb,
149
129
  migrations: this.options.migrations,
150
- onboardingType: this.nextjsDirectory ? "nextjs" : "default",
151
- nextjsDirectory: this.nextjsDirectory,
152
130
  client: this.client,
153
131
  verbose: this.options.verbose,
154
132
  packageManager: this.packageManager,
@@ -177,15 +155,6 @@ export class AcmeKitProjectCreator
177
155
  packageManager: this.packageManager,
178
156
  })
179
157
 
180
- if (this.nextjsDirectory) {
181
- startNextjsStarter({
182
- directory: this.nextjsDirectory,
183
- abortController: this.abortController,
184
- verbose: this.options.verbose,
185
- packageManager: this.packageManager,
186
- })
187
- }
188
-
189
158
  this.isProjectCreated = true
190
159
 
191
160
  await this.openBrowser()
@@ -229,10 +198,6 @@ export class AcmeKitProjectCreator
229
198
  this.inviteToken
230
199
  ? `After you start the AcmeKit application, you can create an admin user with the URL http://localhost:9000/app/invite?token=${this.inviteToken}&first_run=true${EOL}${EOL}`
231
200
  : ""
232
- }${
233
- this.nextjsDirectory?.length
234
- ? `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}${commandStr}${EOL}${EOL}`
235
- : ""
236
201
  }Check out the AcmeKit ${terminalLink(
237
202
  "documentation",
238
203
  "https://docs.acmekit.com/"
@@ -13,7 +13,6 @@ export interface ProjectOptions {
13
13
  browser?: boolean
14
14
  migrations?: boolean
15
15
  directoryPath?: string
16
- withNextjsStarter?: boolean
17
16
  verbose?: boolean
18
17
  plugin?: boolean
19
18
  version?: string
@@ -1,139 +0,0 @@
1
- import { exec } from "child_process"
2
- import fs from "fs"
3
- import inquirer from "inquirer"
4
- import { customAlphabet } from "nanoid"
5
- import path from "path"
6
- import { isAbortError } from "./create-abort-controller.js"
7
- import execute from "./execute.js"
8
- import { displayFactBox, FactBoxOptions } from "./facts.js"
9
- import logMessage from "./log-message.js"
10
- import { updatePackageVersions } from "./update-package-versions.js"
11
- import PackageManager from "./package-manager.js"
12
-
13
- const NEXTJS_REPO = "https://github.com/acmekit/nextjs-starter-acmekit"
14
- const NEXTJS_BRANCH = "main"
15
-
16
- export async function askForNextjsStarter(): Promise<boolean> {
17
- const { installNextjs } = await inquirer.prompt([
18
- {
19
- type: "confirm",
20
- name: "installNextjs",
21
- message: `Would you like to install the Next.js Starter Storefront? You can also install it later.`,
22
- default: false,
23
- },
24
- ])
25
-
26
- return installNextjs
27
- }
28
-
29
- type InstallOptions = {
30
- directoryName: string
31
- abortController?: AbortController
32
- factBoxOptions: FactBoxOptions
33
- verbose?: boolean
34
- packageManager: PackageManager
35
- version?: string
36
- }
37
-
38
- export async function installNextjsStarter({
39
- directoryName,
40
- abortController,
41
- factBoxOptions,
42
- verbose = false,
43
- packageManager,
44
- version,
45
- }: InstallOptions): Promise<string> {
46
- factBoxOptions.interval = displayFactBox({
47
- ...factBoxOptions,
48
- title: "Installing Next.js Starter Storefront...",
49
- })
50
-
51
- let nextjsDirectory = `${directoryName}-storefront`
52
-
53
- if (
54
- fs.existsSync(nextjsDirectory) &&
55
- fs.lstatSync(nextjsDirectory).isDirectory()
56
- ) {
57
- // append a random number to the directory name
58
- nextjsDirectory += `-${customAlphabet(
59
- // npm throws an error if the directory name has an uppercase letter
60
- "123456789abcdefghijklmnopqrstuvwxyz",
61
- 4
62
- )()}`
63
- }
64
-
65
- try {
66
- await execute(
67
- [
68
- `git clone ${NEXTJS_REPO} -b ${NEXTJS_BRANCH} ${nextjsDirectory} --depth 1`,
69
- {
70
- signal: abortController?.signal,
71
- env: process.env,
72
- },
73
- ],
74
- { verbose }
75
- )
76
-
77
- if (version) {
78
- const packageJsonPath = path.join(nextjsDirectory, "package.json")
79
- updatePackageVersions(packageJsonPath, version, { applyChanges: true })
80
- }
81
-
82
- const execOptions = {
83
- signal: abortController?.signal,
84
- cwd: nextjsDirectory,
85
- }
86
- await packageManager.installDependencies(execOptions)
87
- } catch (e) {
88
- if (isAbortError(e)) {
89
- process.exit()
90
- }
91
-
92
- logMessage({
93
- message: `An error occurred while installing Next.js Starter Storefront: ${e}`,
94
- type: "error",
95
- })
96
- }
97
-
98
- fs.rmSync(path.join(nextjsDirectory, ".git"), {
99
- recursive: true,
100
- force: true,
101
- })
102
-
103
- fs.renameSync(
104
- path.join(nextjsDirectory, ".env.template"),
105
- path.join(nextjsDirectory, ".env.local")
106
- )
107
-
108
- displayFactBox({
109
- ...factBoxOptions,
110
- message: `Installed Next.js Starter Storefront successfully in the ${nextjsDirectory} directory.`,
111
- })
112
-
113
- return nextjsDirectory
114
- }
115
-
116
- type StartOptions = {
117
- directory: string
118
- abortController?: AbortController
119
- verbose?: boolean
120
- packageManager: PackageManager
121
- }
122
-
123
- export function startNextjsStarter({
124
- directory,
125
- abortController,
126
- verbose = false,
127
- packageManager,
128
- }: StartOptions) {
129
- const command = packageManager.getCommandStr(`dev`)
130
- const childProcess = exec(command, {
131
- cwd: directory,
132
- signal: abortController?.signal,
133
- })
134
-
135
- if (verbose) {
136
- childProcess.stdout?.pipe(process.stdout)
137
- childProcess.stderr?.pipe(process.stderr)
138
- }
139
- }