create-stackflow 1.0.4 → 1.0.7
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/README.md +4 -6
- package/cli.js +1 -1
- package/package.json +1 -1
- package/src/commands/create.js +9 -8
- package/src/generators/backend.js +264 -192
- package/src/generators/chat.js +661 -0
- package/src/generators/frontend.js +227 -118
- package/src/generators/root.js +6 -58
- package/src/utils/install.js +42 -0
- package/src/utils/prompts.js +26 -1
package/src/generators/root.js
CHANGED
|
@@ -1,62 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import fs from "fs-extra";
|
|
3
|
-
import { writeTemplate } from "../utils/template.js";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
const frontendName = path.basename(context.frontendDir);
|
|
7
|
-
const backendName = path.basename(context.backendDir);
|
|
8
|
-
|
|
9
|
-
await writeTemplate(
|
|
10
|
-
path.join(context.projectDir, "package.json"),
|
|
11
|
-
`{
|
|
12
|
-
"name": "{{projectName}}",
|
|
13
|
-
"version": "1.0.0",
|
|
14
|
-
"private": true,
|
|
15
|
-
"scripts": {
|
|
16
|
-
"dev": "concurrently \\"npm run dev --workspace {{backendName}}\\" \\"npm run dev --workspace {{frontendName}}\\"",
|
|
17
|
-
"dev:frontend": "npm run dev --workspace {{frontendName}}",
|
|
18
|
-
"dev:backend": "npm run dev --workspace {{backendName}}"
|
|
19
|
-
},
|
|
20
|
-
"workspaces": [
|
|
21
|
-
"{{frontendName}}",
|
|
22
|
-
"{{backendName}}"
|
|
23
|
-
],
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"concurrently": "latest"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
`,
|
|
29
|
-
{ ...context, frontendName, backendName }
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
await writeTemplate(
|
|
33
|
-
path.join(context.projectDir, "README.md"),
|
|
34
|
-
`# {{projectName}}
|
|
35
|
-
|
|
36
|
-
Generated with \`create-stackflow\`.
|
|
37
|
-
|
|
38
|
-
## Development
|
|
39
|
-
|
|
40
|
-
\`\`\`bash
|
|
41
|
-
npm run dev
|
|
42
|
-
\`\`\`
|
|
43
|
-
|
|
44
|
-
Frontend runs on Vite/Next.js. Backend runs on Express at \`http://localhost:5000\`.
|
|
45
|
-
|
|
46
|
-
## Environment
|
|
47
|
-
|
|
48
|
-
MongoDB local connection:
|
|
49
|
-
|
|
50
|
-
\`\`\`
|
|
51
|
-
mongodb://127.0.0.1:27017/{{databaseName}}
|
|
52
|
-
\`\`\`
|
|
53
|
-
`,
|
|
54
|
-
context
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
await fs.outputFile(
|
|
58
|
-
path.join(context.projectDir, ".gitignore"),
|
|
59
|
-
`node_modules
|
|
4
|
+
const GITIGNORE = `node_modules
|
|
60
5
|
.env
|
|
61
6
|
.env.*
|
|
62
7
|
dist
|
|
@@ -65,6 +10,9 @@ build
|
|
|
65
10
|
coverage
|
|
66
11
|
uploads/*
|
|
67
12
|
!uploads/.gitkeep
|
|
68
|
-
|
|
69
|
-
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export async function createRootFiles(context) {
|
|
16
|
+
await fs.outputFile(path.join(context.frontendDir, ".gitignore"), GITIGNORE);
|
|
17
|
+
await fs.outputFile(path.join(context.backendDir, ".gitignore"), GITIGNORE);
|
|
70
18
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { execa } from "execa";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hoist dependencies into project-root/node_modules via a temporary workspace
|
|
7
|
+
* package.json, then remove root package.json and lockfile so only
|
|
8
|
+
* frontend/, backend/, and node_modules/ remain at the project root.
|
|
9
|
+
*/
|
|
10
|
+
export async function installHoistedWorkspace(context) {
|
|
11
|
+
const frontendName = path.basename(context.frontendDir);
|
|
12
|
+
const backendName = path.basename(context.backendDir);
|
|
13
|
+
const rootPkgPath = path.join(context.projectDir, "package.json");
|
|
14
|
+
const rootLockPath = path.join(context.projectDir, "package-lock.json");
|
|
15
|
+
|
|
16
|
+
await fs.writeJson(
|
|
17
|
+
rootPkgPath,
|
|
18
|
+
{
|
|
19
|
+
name: context.projectName,
|
|
20
|
+
private: true,
|
|
21
|
+
workspaces: [frontendName, backendName],
|
|
22
|
+
},
|
|
23
|
+
{ spaces: 2 },
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
await execa("npm", ["install"], { cwd: context.projectDir, stdio: "ignore" });
|
|
27
|
+
|
|
28
|
+
await fs.remove(rootPkgPath);
|
|
29
|
+
if (await fs.pathExists(rootLockPath)) {
|
|
30
|
+
await fs.remove(rootLockPath);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await removeNestedNodeModules(context.frontendDir);
|
|
34
|
+
await removeNestedNodeModules(context.backendDir);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function removeNestedNodeModules(dir) {
|
|
38
|
+
const nested = path.join(dir, "node_modules");
|
|
39
|
+
if (await fs.pathExists(nested)) {
|
|
40
|
+
await fs.remove(nested);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/utils/prompts.js
CHANGED
|
@@ -143,7 +143,6 @@ export async function askQuestions(projectName) {
|
|
|
143
143
|
choices: [
|
|
144
144
|
{ name: "Zod", value: "zod" },
|
|
145
145
|
{ name: "Yup", value: "yup" },
|
|
146
|
-
{ name: "Joi", value: "joi" },
|
|
147
146
|
{ name: "None", value: "none" },
|
|
148
147
|
],
|
|
149
148
|
default: "zod",
|
|
@@ -247,6 +246,16 @@ export async function askQuestions(projectName) {
|
|
|
247
246
|
],
|
|
248
247
|
default: "javascript",
|
|
249
248
|
},
|
|
249
|
+
{
|
|
250
|
+
type: "list",
|
|
251
|
+
name: "backendModule",
|
|
252
|
+
message: "Backend module system?",
|
|
253
|
+
choices: [
|
|
254
|
+
{ name: "ES Modules (import/export)", value: "esm" },
|
|
255
|
+
{ name: "CommonJS (require/module.exports)", value: "cjs" },
|
|
256
|
+
],
|
|
257
|
+
default: "esm",
|
|
258
|
+
},
|
|
250
259
|
{
|
|
251
260
|
type: "list",
|
|
252
261
|
name: "database",
|
|
@@ -311,6 +320,19 @@ export async function askQuestions(projectName) {
|
|
|
311
320
|
{ name: "hpp", value: "hpp" },
|
|
312
321
|
],
|
|
313
322
|
},
|
|
323
|
+
{
|
|
324
|
+
type: "confirm",
|
|
325
|
+
name: "swagger",
|
|
326
|
+
message: "Add Swagger API documentation?",
|
|
327
|
+
default: false,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
type: "confirm",
|
|
331
|
+
name: "socketio",
|
|
332
|
+
message:
|
|
333
|
+
"Add real-time chat (Socket.IO)? Includes WhatsApp-style chat requests + 1:1 messaging",
|
|
334
|
+
default: false,
|
|
335
|
+
},
|
|
314
336
|
{
|
|
315
337
|
type: "confirm",
|
|
316
338
|
name: "runProject",
|
|
@@ -327,6 +349,7 @@ export async function askQuestions(projectName) {
|
|
|
327
349
|
tailwind: frontendAnswers.styling === "tailwind",
|
|
328
350
|
shadcn: frontendAnswers.uiLibrary === "shadcn",
|
|
329
351
|
axios: frontendAnswers.dataFetching === "axios",
|
|
352
|
+
form: frontendAnswers.formLibrary,
|
|
330
353
|
reactHookForm: frontendAnswers.formLibrary === "react-hook-form",
|
|
331
354
|
|
|
332
355
|
helmet: backendAnswers.securityPackages.includes("helmet"),
|
|
@@ -336,6 +359,8 @@ export async function askQuestions(projectName) {
|
|
|
336
359
|
|
|
337
360
|
multer: backendAnswers.fileUpload === "Multer",
|
|
338
361
|
cloudinary: backendAnswers.fileUpload === "Cloudinary",
|
|
362
|
+
swagger: backendAnswers.swagger,
|
|
363
|
+
socketio: backendAnswers.socketio,
|
|
339
364
|
runProject: backendAnswers.runProject,
|
|
340
365
|
};
|
|
341
366
|
}
|