@stackframe/init-stack 1.0.7 → 2.4.20
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 +18 -0
- package/index.mjs +53 -23
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @stackframe/init-stack
|
|
2
2
|
|
|
3
|
+
## 2.4.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Support multiple projects on the same domain
|
|
8
|
+
|
|
9
|
+
## 2.4.19
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Sync package versions
|
|
14
|
+
|
|
15
|
+
## 1.0.8
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Improve setup flow
|
|
20
|
+
|
|
3
21
|
## 1.0.7
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/index.mjs
CHANGED
|
@@ -8,33 +8,42 @@ import open from 'open';
|
|
|
8
8
|
|
|
9
9
|
const jsLikeFileExtensions = ['mtsx', 'ctsx', 'tsx', 'mts', 'cts', 'ts', 'mjsx', 'cjsx', 'jsx', 'mjs', 'cjs', 'js'];
|
|
10
10
|
|
|
11
|
+
class UserError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'UserError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let savedProjectPath = process.argv[2] || undefined;
|
|
19
|
+
|
|
11
20
|
async function main() {
|
|
12
21
|
console.log("Welcome to the Stack installation wizard! 🧙♂️");
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
let projectPath = await getProjectPath();
|
|
15
24
|
if (!fs.existsSync(projectPath)) {
|
|
16
|
-
throw new
|
|
25
|
+
throw new UserError(`The project path ${projectPath} does not exist`);
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
20
29
|
if (!fs.existsSync(packageJsonPath)) {
|
|
21
|
-
throw new
|
|
30
|
+
throw new UserError(`The package.json file does not exist in the project path ${projectPath}. You must initialize a new project first before installing Stack.`);
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
const nextConfigPathWithoutExtension = path.join(projectPath, 'next.config');
|
|
25
34
|
const nextConfigFileExtension = await findJsExtension(nextConfigPathWithoutExtension);
|
|
26
|
-
const nextConfigPath = nextConfigPathWithoutExtension + '.' + nextConfigFileExtension;
|
|
35
|
+
const nextConfigPath = nextConfigPathWithoutExtension + '.' + (nextConfigFileExtension ?? "js");
|
|
27
36
|
if (!fs.existsSync(nextConfigPath)) {
|
|
28
|
-
throw new
|
|
37
|
+
throw new UserError(`Expected file at ${nextConfigPath}. Only Next.js projects are currently supported.`);
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
const envLocalPath = path.join(projectPath, '.env.local');
|
|
32
41
|
|
|
33
|
-
const
|
|
34
|
-
const srcPath = path.join(projectPath,
|
|
42
|
+
const hasSrcAppFolder = fs.existsSync(path.join(projectPath, 'src/app'));
|
|
43
|
+
const srcPath = path.join(projectPath, hasSrcAppFolder ? 'src' : '');
|
|
35
44
|
const appPath = path.join(srcPath, 'app');
|
|
36
45
|
if (!fs.existsSync(appPath)) {
|
|
37
|
-
throw new
|
|
46
|
+
throw new UserError(`The app path ${appPath} does not exist. Only the Next.js app router is supported.`);
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
const layoutPathWithoutExtension = path.join(appPath, 'layout');
|
|
@@ -54,9 +63,9 @@ async function main() {
|
|
|
54
63
|
const stackAppContent = await readFile(stackAppPath);
|
|
55
64
|
if (stackAppContent) {
|
|
56
65
|
if (!stackAppContent.includes("@stackframe/stack")) {
|
|
57
|
-
throw new
|
|
66
|
+
throw new UserError(`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.`);
|
|
58
67
|
}
|
|
59
|
-
throw new
|
|
68
|
+
throw new UserError(`It seems that you've already installed Stack in this project.`);
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
|
|
@@ -65,7 +74,7 @@ async function main() {
|
|
|
65
74
|
const handlerPath = handlerPathWithoutExtension + '.' + handlerFileExtension;
|
|
66
75
|
const handlerContent = await readFile(handlerPath);
|
|
67
76
|
if (handlerContent && !handlerContent.includes("@stackframe/stack")) {
|
|
68
|
-
throw new
|
|
77
|
+
throw new UserError(`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.`);
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
|
|
@@ -85,7 +94,7 @@ async function main() {
|
|
|
85
94
|
try {
|
|
86
95
|
await shellNicelyFormatted(versionCommand, { shell: true });
|
|
87
96
|
} catch (err) {
|
|
88
|
-
throw new
|
|
97
|
+
throw new UserError(`Could not run the package manager command ${versionCommand}. Please make sure ${packageManager} is installed on your system.`);
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
console.log();
|
|
@@ -96,7 +105,7 @@ async function main() {
|
|
|
96
105
|
console.log("Writing files...");
|
|
97
106
|
await writeFileIfNotExists(envLocalPath, "NEXT_PUBLIC_STACK_PROJECT_ID=\nNEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=\nSTACK_SECRET_SERVER_KEY=\n");
|
|
98
107
|
await writeFileIfNotExists(loadingPath, `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`);
|
|
99
|
-
await writeFileIfNotExists(handlerPath, `import { StackHandler } from "@stackframe/stack";\nimport { stackServerApp } from "../../../stack";\n\nexport default function Handler(props${handlerFileExtension.includes("ts") ? ": any" : ""}) {\n${ind}return <StackHandler app={stackServerApp} {...props} />;\n}\n`);
|
|
108
|
+
await writeFileIfNotExists(handlerPath, `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`);
|
|
100
109
|
await writeFileIfNotExists(stackAppPath, `import "server-only";\n\nimport { StackServerApp } from "@stackframe/stack";\n\nexport const stackServerApp = new StackServerApp({\n${ind}tokenStore: "nextjs-cookie",\n});\n`);
|
|
101
110
|
await writeFile(layoutPath, updatedLayoutContent);
|
|
102
111
|
console.log("Files written successfully!");
|
|
@@ -127,11 +136,17 @@ main().then(async() => {
|
|
|
127
136
|
console.error();
|
|
128
137
|
console.error("===============================================");
|
|
129
138
|
console.error();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
if (err instanceof UserError) {
|
|
140
|
+
console.error("[ERR] Error: " + err.message);
|
|
141
|
+
} else {
|
|
142
|
+
console.error("[ERR] An error occured during the initialization process.");
|
|
143
|
+
}
|
|
133
144
|
console.error("[ERR]");
|
|
134
|
-
console.error(
|
|
145
|
+
console.error("[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");
|
|
146
|
+
if (!(err instanceof UserError)) {
|
|
147
|
+
console.error("[ERR]");
|
|
148
|
+
console.error(`[ERR] Error message: ${err.message}`);
|
|
149
|
+
}
|
|
135
150
|
console.error();
|
|
136
151
|
console.error("===============================================");
|
|
137
152
|
console.error();
|
|
@@ -199,9 +214,23 @@ function getLineIndex(lines, stringIndex) {
|
|
|
199
214
|
throw new Error(`Index ${stringIndex} is out of bounds for lines ${JSON.stringify(lines)}`);
|
|
200
215
|
}
|
|
201
216
|
|
|
202
|
-
function getProjectPath() {
|
|
203
|
-
|
|
204
|
-
|
|
217
|
+
async function getProjectPath() {
|
|
218
|
+
if (savedProjectPath === undefined) {
|
|
219
|
+
savedProjectPath = process.cwd();
|
|
220
|
+
|
|
221
|
+
const askForPathModification = !fs.existsSync(path.join(savedProjectPath, 'package.json'));
|
|
222
|
+
if (askForPathModification) {
|
|
223
|
+
savedProjectPath = (await inquirer.prompt([
|
|
224
|
+
{
|
|
225
|
+
type: 'input',
|
|
226
|
+
name: 'newPath',
|
|
227
|
+
message: 'Please enter the path to your project:',
|
|
228
|
+
default: ".",
|
|
229
|
+
},
|
|
230
|
+
])).newPath;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return savedProjectPath;
|
|
205
234
|
}
|
|
206
235
|
|
|
207
236
|
async function findJsExtension(fullPathWithoutExtension) {
|
|
@@ -215,9 +244,10 @@ async function findJsExtension(fullPathWithoutExtension) {
|
|
|
215
244
|
}
|
|
216
245
|
|
|
217
246
|
async function getPackageManager() {
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
const
|
|
247
|
+
const projectPath = await getProjectPath();
|
|
248
|
+
const yarnLock = fs.existsSync(path.join(projectPath, 'yarn.lock'));
|
|
249
|
+
const pnpmLock = fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'));
|
|
250
|
+
const npmLock = fs.existsSync(path.join(projectPath, 'package-lock.json'));
|
|
221
251
|
|
|
222
252
|
if (yarnLock && !pnpmLock && !npmLock) {
|
|
223
253
|
return 'yarn';
|