@stackframe/init-stack 2.5.6 → 2.5.8
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 +8 -0
- package/index.mjs +238 -133
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/index.mjs
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import inquirer from
|
|
4
|
-
import * as fs from
|
|
5
|
-
import * as child_process from
|
|
6
|
-
import * as path from
|
|
7
|
-
import open from
|
|
8
|
-
|
|
9
|
-
const jsLikeFileExtensions = [
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as child_process from "child_process";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import open from "open";
|
|
8
|
+
|
|
9
|
+
const jsLikeFileExtensions = [
|
|
10
|
+
"mtsx",
|
|
11
|
+
"ctsx",
|
|
12
|
+
"tsx",
|
|
13
|
+
"mts",
|
|
14
|
+
"cts",
|
|
15
|
+
"ts",
|
|
16
|
+
"mjsx",
|
|
17
|
+
"cjsx",
|
|
18
|
+
"jsx",
|
|
19
|
+
"mjs",
|
|
20
|
+
"cjs",
|
|
21
|
+
"js",
|
|
22
|
+
];
|
|
10
23
|
|
|
11
24
|
class UserError extends Error {
|
|
12
25
|
constructor(message) {
|
|
13
26
|
super(message);
|
|
14
|
-
this.name =
|
|
27
|
+
this.name = "UserError";
|
|
15
28
|
}
|
|
16
29
|
}
|
|
17
30
|
|
|
@@ -25,68 +38,103 @@ async function main() {
|
|
|
25
38
|
throw new UserError(`The project path ${projectPath} does not exist`);
|
|
26
39
|
}
|
|
27
40
|
|
|
28
|
-
const packageJsonPath = path.join(projectPath,
|
|
41
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
29
42
|
if (!fs.existsSync(packageJsonPath)) {
|
|
30
|
-
throw new UserError(
|
|
43
|
+
throw new UserError(
|
|
44
|
+
`The package.json file does not exist in the project path ${projectPath}. You must initialize a new project first before installing Stack.`
|
|
45
|
+
);
|
|
31
46
|
}
|
|
32
47
|
|
|
33
|
-
const nextConfigPathWithoutExtension = path.join(projectPath,
|
|
34
|
-
const nextConfigFileExtension = await findJsExtension(
|
|
35
|
-
|
|
48
|
+
const nextConfigPathWithoutExtension = path.join(projectPath, "next.config");
|
|
49
|
+
const nextConfigFileExtension = await findJsExtension(
|
|
50
|
+
nextConfigPathWithoutExtension
|
|
51
|
+
);
|
|
52
|
+
const nextConfigPath =
|
|
53
|
+
nextConfigPathWithoutExtension + "." + (nextConfigFileExtension ?? "js");
|
|
36
54
|
if (!fs.existsSync(nextConfigPath)) {
|
|
37
|
-
throw new UserError(
|
|
55
|
+
throw new UserError(
|
|
56
|
+
`Expected file at ${nextConfigPath}. Only Next.js projects are currently supported.`
|
|
57
|
+
);
|
|
38
58
|
}
|
|
39
59
|
|
|
40
|
-
const envPath = path.join(projectPath,
|
|
41
|
-
const envDevelopmentPath = path.join(projectPath,
|
|
42
|
-
const envDefaultPath = path.join(projectPath,
|
|
43
|
-
const envDefaultsPath = path.join(projectPath,
|
|
44
|
-
const envExamplePath = path.join(projectPath,
|
|
45
|
-
const envLocalPath = path.join(projectPath,
|
|
46
|
-
const potentialEnvLocations = [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
const envPath = path.join(projectPath, ".env");
|
|
61
|
+
const envDevelopmentPath = path.join(projectPath, ".env.development");
|
|
62
|
+
const envDefaultPath = path.join(projectPath, ".env.default");
|
|
63
|
+
const envDefaultsPath = path.join(projectPath, ".env.defaults");
|
|
64
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
65
|
+
const envLocalPath = path.join(projectPath, ".env.local");
|
|
66
|
+
const potentialEnvLocations = [
|
|
67
|
+
envPath,
|
|
68
|
+
envDevelopmentPath,
|
|
69
|
+
envDefaultPath,
|
|
70
|
+
envDefaultsPath,
|
|
71
|
+
envExamplePath,
|
|
72
|
+
envLocalPath,
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const hasSrcAppFolder = fs.existsSync(path.join(projectPath, "src/app"));
|
|
76
|
+
const srcPath = path.join(projectPath, hasSrcAppFolder ? "src" : "");
|
|
77
|
+
const appPath = path.join(srcPath, "app");
|
|
51
78
|
if (!fs.existsSync(appPath)) {
|
|
52
|
-
throw new UserError(
|
|
79
|
+
throw new UserError(
|
|
80
|
+
`The app path ${appPath} does not exist. Only the Next.js app router is supported.`
|
|
81
|
+
);
|
|
53
82
|
}
|
|
54
83
|
|
|
55
|
-
const layoutPathWithoutExtension = path.join(appPath,
|
|
56
|
-
const layoutFileExtension =
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
const
|
|
84
|
+
const layoutPathWithoutExtension = path.join(appPath, "layout");
|
|
85
|
+
const layoutFileExtension =
|
|
86
|
+
(await findJsExtension(layoutPathWithoutExtension)) ?? "jsx";
|
|
87
|
+
const layoutPath = layoutPathWithoutExtension + "." + layoutFileExtension;
|
|
88
|
+
const layoutContent =
|
|
89
|
+
(await readFile(layoutPath)) ??
|
|
90
|
+
throwErr(
|
|
91
|
+
`The layout file at ${layoutPath} does not exist. Stack requires a layout file to be present in the /app folder.`
|
|
92
|
+
);
|
|
93
|
+
const updatedLayoutResult =
|
|
94
|
+
(await getUpdatedLayout(layoutContent)) ??
|
|
95
|
+
throwErr(
|
|
96
|
+
"Unable to parse root layout file. Make sure it contains a <body> tag. If it still doesn't work, you may need to manually install Stack. See: https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#root-layout-required"
|
|
97
|
+
);
|
|
60
98
|
const updatedLayoutContent = updatedLayoutResult.content;
|
|
61
99
|
|
|
62
100
|
const defaultExtension = layoutFileExtension;
|
|
63
101
|
const ind = updatedLayoutResult.indentation;
|
|
64
102
|
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
const stackAppPath =
|
|
103
|
+
const stackAppPathWithoutExtension = path.join(srcPath, "stack");
|
|
104
|
+
const stackAppFileExtension =
|
|
105
|
+
(await findJsExtension(stackAppPathWithoutExtension)) ?? defaultExtension;
|
|
106
|
+
const stackAppPath =
|
|
107
|
+
stackAppPathWithoutExtension + "." + stackAppFileExtension;
|
|
69
108
|
const stackAppContent = await readFile(stackAppPath);
|
|
70
109
|
if (stackAppContent) {
|
|
71
110
|
if (!stackAppContent.includes("@stackframe/stack")) {
|
|
72
|
-
throw new UserError(
|
|
111
|
+
throw new UserError(
|
|
112
|
+
`A file at the path ${stackAppPath} already exists. Stack uses the /src/stack-app file to initialize the Stack SDK. Please remove the existing file and try again.`
|
|
113
|
+
);
|
|
73
114
|
}
|
|
74
|
-
throw new UserError(
|
|
115
|
+
throw new UserError(
|
|
116
|
+
`It seems that you've already installed Stack in this project.`
|
|
117
|
+
);
|
|
75
118
|
}
|
|
76
119
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
120
|
+
const handlerPathWithoutExtension = path.join(
|
|
121
|
+
appPath,
|
|
122
|
+
"handler/[...stack]/page"
|
|
123
|
+
);
|
|
124
|
+
const handlerFileExtension =
|
|
125
|
+
(await findJsExtension(handlerPathWithoutExtension)) ?? defaultExtension;
|
|
126
|
+
const handlerPath = handlerPathWithoutExtension + "." + handlerFileExtension;
|
|
81
127
|
const handlerContent = await readFile(handlerPath);
|
|
82
128
|
if (handlerContent && !handlerContent.includes("@stackframe/stack")) {
|
|
83
|
-
throw new UserError(
|
|
129
|
+
throw new UserError(
|
|
130
|
+
`A file at the path ${handlerPath} already exists. Stack uses the /handler path to handle incoming requests. Please remove the existing file and try again.`
|
|
131
|
+
);
|
|
84
132
|
}
|
|
85
133
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const loadingPath = loadingPathWithoutExtension +
|
|
134
|
+
let loadingPathWithoutExtension = path.join(appPath, "loading");
|
|
135
|
+
const loadingFileExtension =
|
|
136
|
+
(await findJsExtension(loadingPathWithoutExtension)) ?? defaultExtension;
|
|
137
|
+
const loadingPath = loadingPathWithoutExtension + "." + loadingFileExtension;
|
|
90
138
|
|
|
91
139
|
console.log();
|
|
92
140
|
console.log("Found supported project at:", projectPath);
|
|
@@ -94,85 +142,118 @@ async function main() {
|
|
|
94
142
|
|
|
95
143
|
const packageManager = await getPackageManager();
|
|
96
144
|
const versionCommand = `${packageManager} --version`;
|
|
97
|
-
const installCommand =
|
|
145
|
+
const installCommand =
|
|
146
|
+
packageManager === "yarn" ? "yarn add" : `${packageManager} install`;
|
|
98
147
|
|
|
99
148
|
process.stdout.write("\nChecking package manager version... ");
|
|
100
149
|
try {
|
|
101
150
|
await shellNicelyFormatted(versionCommand, { shell: true });
|
|
102
151
|
} catch (err) {
|
|
103
|
-
throw new UserError(
|
|
152
|
+
throw new UserError(
|
|
153
|
+
`Could not run the package manager command ${versionCommand}. Please make sure ${packageManager} is installed on your system.`
|
|
154
|
+
);
|
|
104
155
|
}
|
|
105
156
|
|
|
106
157
|
console.log();
|
|
107
158
|
console.log("Installing dependencies...");
|
|
108
|
-
await shellNicelyFormatted(`${installCommand} @stackframe/stack`, {
|
|
109
|
-
|
|
159
|
+
await shellNicelyFormatted(`${installCommand} @stackframe/stack`, {
|
|
160
|
+
shell: true,
|
|
161
|
+
cwd: projectPath,
|
|
162
|
+
});
|
|
163
|
+
|
|
110
164
|
console.log();
|
|
111
165
|
console.log("Writing files...");
|
|
112
166
|
if (potentialEnvLocations.every((p) => !fs.existsSync(p))) {
|
|
113
|
-
await writeFile(
|
|
167
|
+
await writeFile(
|
|
168
|
+
envLocalPath,
|
|
169
|
+
"# Stack Auth keys\n# Get these variables by creating a project on https://app.stack-auth.com.\nNEXT_PUBLIC_STACK_PROJECT_ID=\nNEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=\nSTACK_SECRET_SERVER_KEY=\n"
|
|
170
|
+
);
|
|
114
171
|
}
|
|
115
|
-
await writeFileIfNotExists(
|
|
116
|
-
|
|
117
|
-
|
|
172
|
+
await writeFileIfNotExists(
|
|
173
|
+
loadingPath,
|
|
174
|
+
`export default function Loading() {\n${ind}// Stack uses React Suspense, which will render this page while user data is being fetched.\n${ind}// See: https://nextjs.org/docs/app/api-reference/file-conventions/loading\n${ind}return <></>;\n}\n`
|
|
175
|
+
);
|
|
176
|
+
await writeFileIfNotExists(
|
|
177
|
+
handlerPath,
|
|
178
|
+
`import { StackHandler } from "@stackframe/stack";\nimport { stackServerApp } from "../../../stack";\n\nexport default function Handler(props${handlerFileExtension.includes("ts") ? ": any" : ""}) {\n${ind}return <StackHandler fullPage app={stackServerApp} {...props} />;\n}\n`
|
|
179
|
+
);
|
|
180
|
+
await writeFileIfNotExists(
|
|
181
|
+
stackAppPath,
|
|
182
|
+
`import "server-only";\n\nimport { StackServerApp } from "@stackframe/stack";\n\nexport const stackServerApp = new StackServerApp({\n${ind}tokenStore: "nextjs-cookie",\n});\n`
|
|
183
|
+
);
|
|
118
184
|
await writeFile(layoutPath, updatedLayoutContent);
|
|
119
185
|
console.log("Files written successfully!");
|
|
120
186
|
}
|
|
121
|
-
main()
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
console.error(
|
|
149
|
-
|
|
150
|
-
console.error(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
187
|
+
main()
|
|
188
|
+
.then(async () => {
|
|
189
|
+
console.log();
|
|
190
|
+
console.log();
|
|
191
|
+
console.log();
|
|
192
|
+
console.log();
|
|
193
|
+
console.log("===============================================");
|
|
194
|
+
console.log();
|
|
195
|
+
console.log("Successfully installed Stack! 🚀🚀🚀");
|
|
196
|
+
console.log();
|
|
197
|
+
console.log(
|
|
198
|
+
"Next up, please create an account on https://app.stack-auth.com to create a new project, and copy the Next.js environment variables from a new API key into your .env.local file."
|
|
199
|
+
);
|
|
200
|
+
console.log();
|
|
201
|
+
console.log(
|
|
202
|
+
"Then, you will be able to access your sign-in page on http://your-website.example.com/handler/sign-in. Congratulations!"
|
|
203
|
+
);
|
|
204
|
+
console.log();
|
|
205
|
+
console.log(
|
|
206
|
+
"For more information, please visit https://docs.stack-auth.com/docs/getting-started/setup"
|
|
207
|
+
);
|
|
208
|
+
console.log();
|
|
209
|
+
console.log("===============================================");
|
|
210
|
+
console.log();
|
|
211
|
+
await open("https://app.stack-auth.com/wizard-congrats");
|
|
212
|
+
})
|
|
213
|
+
.catch((err) => {
|
|
214
|
+
console.error(err);
|
|
215
|
+
console.error();
|
|
216
|
+
console.error();
|
|
217
|
+
console.error();
|
|
218
|
+
console.error();
|
|
219
|
+
console.error("===============================================");
|
|
220
|
+
console.error();
|
|
221
|
+
if (err instanceof UserError) {
|
|
222
|
+
console.error("[ERR] Error: " + err.message);
|
|
223
|
+
} else {
|
|
224
|
+
console.error(
|
|
225
|
+
"[ERR] An error occurred during the initialization process."
|
|
226
|
+
);
|
|
227
|
+
}
|
|
155
228
|
console.error("[ERR]");
|
|
156
|
-
console.error(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
229
|
+
console.error(
|
|
230
|
+
"[ERR] If you need assistance, please try installing Slack manually as described in https://docs.stack-auth.com/docs/getting-started/setup or join our Discord where we're happy to help: https://discord.stack-auth.com"
|
|
231
|
+
);
|
|
232
|
+
if (!(err instanceof UserError)) {
|
|
233
|
+
console.error("[ERR]");
|
|
234
|
+
console.error(`[ERR] Error message: ${err.message}`);
|
|
235
|
+
}
|
|
236
|
+
console.error();
|
|
237
|
+
console.error("===============================================");
|
|
238
|
+
console.error();
|
|
239
|
+
process.exit(1);
|
|
240
|
+
});
|
|
163
241
|
|
|
164
242
|
async function getUpdatedLayout(originalLayout) {
|
|
165
243
|
let layout = originalLayout;
|
|
166
244
|
const indentation = guessIndentation(originalLayout);
|
|
167
245
|
|
|
168
|
-
const firstImportLocationM1 =
|
|
246
|
+
const firstImportLocationM1 = /\simport\s/.exec(layout)?.index;
|
|
169
247
|
const hasStringAsFirstLine = layout.startsWith('"') || layout.startsWith("'");
|
|
170
|
-
const importInsertLocationM1 =
|
|
248
|
+
const importInsertLocationM1 =
|
|
249
|
+
firstImportLocationM1 ?? (hasStringAsFirstLine ? layout.indexOf("\n") : -1);
|
|
171
250
|
const importInsertLocation = importInsertLocationM1 + 1;
|
|
172
251
|
const importStatement = `import { StackProvider, StackTheme } from "@stackframe/stack";\nimport { stackServerApp } from "../stack";\n`;
|
|
173
|
-
layout =
|
|
252
|
+
layout =
|
|
253
|
+
layout.slice(0, importInsertLocation) +
|
|
254
|
+
importStatement +
|
|
255
|
+
layout.slice(importInsertLocation);
|
|
174
256
|
|
|
175
|
-
|
|
176
257
|
const bodyOpenTag = /<\s*body[^>]*>/.exec(layout);
|
|
177
258
|
const bodyCloseTag = /<\s*\/\s*body[^>]*>/.exec(layout);
|
|
178
259
|
if (!bodyOpenTag || !bodyCloseTag) {
|
|
@@ -184,15 +265,27 @@ async function getUpdatedLayout(originalLayout) {
|
|
|
184
265
|
return undefined;
|
|
185
266
|
}
|
|
186
267
|
|
|
187
|
-
const lines = layout.split(
|
|
188
|
-
const [bodyOpenEndLine, bodyOpenEndIndexInLine] = getLineIndex(
|
|
189
|
-
|
|
268
|
+
const lines = layout.split("\n");
|
|
269
|
+
const [bodyOpenEndLine, bodyOpenEndIndexInLine] = getLineIndex(
|
|
270
|
+
lines,
|
|
271
|
+
bodyOpenEndIndex
|
|
272
|
+
);
|
|
273
|
+
const [bodyCloseStartLine, bodyCloseStartIndexInLine] = getLineIndex(
|
|
274
|
+
lines,
|
|
275
|
+
bodyCloseStartIndex
|
|
276
|
+
);
|
|
190
277
|
|
|
191
278
|
const insertOpen = "<StackProvider app={stackServerApp}><StackTheme>";
|
|
192
279
|
const insertClose = "</StackTheme></StackProvider>";
|
|
193
280
|
|
|
194
|
-
layout =
|
|
195
|
-
|
|
281
|
+
layout =
|
|
282
|
+
layout.slice(0, bodyCloseStartIndex) +
|
|
283
|
+
insertClose +
|
|
284
|
+
layout.slice(bodyCloseStartIndex);
|
|
285
|
+
layout =
|
|
286
|
+
layout.slice(0, bodyOpenEndIndex) +
|
|
287
|
+
insertOpen +
|
|
288
|
+
layout.slice(bodyOpenEndIndex);
|
|
196
289
|
|
|
197
290
|
return {
|
|
198
291
|
content: `${layout}`,
|
|
@@ -201,13 +294,19 @@ async function getUpdatedLayout(originalLayout) {
|
|
|
201
294
|
}
|
|
202
295
|
|
|
203
296
|
function guessIndentation(str) {
|
|
204
|
-
const lines = str.split(
|
|
205
|
-
const linesLeadingWhitespaces = lines
|
|
206
|
-
|
|
297
|
+
const lines = str.split("\n");
|
|
298
|
+
const linesLeadingWhitespaces = lines
|
|
299
|
+
.map((line) => line.match(/^\s*/)[0])
|
|
300
|
+
.filter((ws) => ws.length > 0);
|
|
301
|
+
const isMostlyTabs =
|
|
302
|
+
linesLeadingWhitespaces.filter((ws) => ws.includes("\t")).length >=
|
|
303
|
+
(linesLeadingWhitespaces.length * 2) / 3;
|
|
207
304
|
if (isMostlyTabs) return "\t";
|
|
208
|
-
const linesLeadingWhitespacesCount = linesLeadingWhitespaces.map(
|
|
305
|
+
const linesLeadingWhitespacesCount = linesLeadingWhitespaces.map(
|
|
306
|
+
(ws) => ws.length
|
|
307
|
+
);
|
|
209
308
|
const min = Math.min(Infinity, ...linesLeadingWhitespacesCount);
|
|
210
|
-
return Number.isFinite(min) ?
|
|
309
|
+
return Number.isFinite(min) ? " ".repeat(Math.max(2, min)) : " ";
|
|
211
310
|
}
|
|
212
311
|
|
|
213
312
|
function getLineIndex(lines, stringIndex) {
|
|
@@ -219,23 +318,29 @@ function getLineIndex(lines, stringIndex) {
|
|
|
219
318
|
}
|
|
220
319
|
lineIndex += line.length + 1;
|
|
221
320
|
}
|
|
222
|
-
throw new Error(
|
|
321
|
+
throw new Error(
|
|
322
|
+
`Index ${stringIndex} is out of bounds for lines ${JSON.stringify(lines)}`
|
|
323
|
+
);
|
|
223
324
|
}
|
|
224
325
|
|
|
225
326
|
async function getProjectPath() {
|
|
226
327
|
if (savedProjectPath === undefined) {
|
|
227
328
|
savedProjectPath = process.cwd();
|
|
228
329
|
|
|
229
|
-
const askForPathModification = !fs.existsSync(
|
|
330
|
+
const askForPathModification = !fs.existsSync(
|
|
331
|
+
path.join(savedProjectPath, "package.json")
|
|
332
|
+
);
|
|
230
333
|
if (askForPathModification) {
|
|
231
|
-
savedProjectPath = (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
334
|
+
savedProjectPath = (
|
|
335
|
+
await inquirer.prompt([
|
|
336
|
+
{
|
|
337
|
+
type: "input",
|
|
338
|
+
name: "newPath",
|
|
339
|
+
message: "Please enter the path to your project:",
|
|
340
|
+
default: ".",
|
|
341
|
+
},
|
|
342
|
+
])
|
|
343
|
+
).newPath;
|
|
239
344
|
}
|
|
240
345
|
}
|
|
241
346
|
return savedProjectPath;
|
|
@@ -243,7 +348,7 @@ async function getProjectPath() {
|
|
|
243
348
|
|
|
244
349
|
async function findJsExtension(fullPathWithoutExtension) {
|
|
245
350
|
for (const ext of jsLikeFileExtensions) {
|
|
246
|
-
const fullPath = fullPathWithoutExtension +
|
|
351
|
+
const fullPath = fullPathWithoutExtension + "." + ext;
|
|
247
352
|
if (fs.existsSync(fullPath)) {
|
|
248
353
|
return ext;
|
|
249
354
|
}
|
|
@@ -253,24 +358,24 @@ async function findJsExtension(fullPathWithoutExtension) {
|
|
|
253
358
|
|
|
254
359
|
async function getPackageManager() {
|
|
255
360
|
const projectPath = await getProjectPath();
|
|
256
|
-
const yarnLock = fs.existsSync(path.join(projectPath,
|
|
257
|
-
const pnpmLock = fs.existsSync(path.join(projectPath,
|
|
258
|
-
const npmLock = fs.existsSync(path.join(projectPath,
|
|
361
|
+
const yarnLock = fs.existsSync(path.join(projectPath, "yarn.lock"));
|
|
362
|
+
const pnpmLock = fs.existsSync(path.join(projectPath, "pnpm-lock.yaml"));
|
|
363
|
+
const npmLock = fs.existsSync(path.join(projectPath, "package-lock.json"));
|
|
259
364
|
|
|
260
365
|
if (yarnLock && !pnpmLock && !npmLock) {
|
|
261
|
-
return
|
|
366
|
+
return "yarn";
|
|
262
367
|
} else if (!yarnLock && pnpmLock && !npmLock) {
|
|
263
|
-
return
|
|
368
|
+
return "pnpm";
|
|
264
369
|
} else if (!yarnLock && !pnpmLock && npmLock) {
|
|
265
|
-
return
|
|
370
|
+
return "npm";
|
|
266
371
|
}
|
|
267
372
|
|
|
268
373
|
const answers = await inquirer.prompt([
|
|
269
374
|
{
|
|
270
|
-
type:
|
|
271
|
-
name:
|
|
272
|
-
message:
|
|
273
|
-
choices: [
|
|
375
|
+
type: "list",
|
|
376
|
+
name: "packageManager",
|
|
377
|
+
message: "Which package manager are you using for this project?",
|
|
378
|
+
choices: ["npm", "yarn", "pnpm"],
|
|
274
379
|
},
|
|
275
380
|
]);
|
|
276
381
|
return answers.packageManager;
|
|
@@ -285,7 +390,7 @@ async function shellNicelyFormatted(command, options) {
|
|
|
285
390
|
child.stderr.pipe(ui.log);
|
|
286
391
|
|
|
287
392
|
await new Promise((resolve, reject) => {
|
|
288
|
-
child.on(
|
|
393
|
+
child.on("exit", (code) => {
|
|
289
394
|
if (code === 0) {
|
|
290
395
|
resolve();
|
|
291
396
|
} else {
|
|
@@ -300,9 +405,9 @@ async function shellNicelyFormatted(command, options) {
|
|
|
300
405
|
|
|
301
406
|
async function readFile(fullPath) {
|
|
302
407
|
try {
|
|
303
|
-
return fs.readFileSync(fullPath,
|
|
408
|
+
return fs.readFileSync(fullPath, "utf-8");
|
|
304
409
|
} catch (err) {
|
|
305
|
-
if (err.code ===
|
|
410
|
+
if (err.code === "ENOENT") {
|
|
306
411
|
return null;
|
|
307
412
|
}
|
|
308
413
|
throw err;
|