better-ts-stack 1.1.3 → 2.0.0
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 +113 -82
- package/dist/args.d.ts +12 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +90 -0
- package/dist/args.js.map +1 -0
- package/dist/builder/configGenerator.d.ts +1 -0
- package/dist/builder/configGenerator.d.ts.map +1 -1
- package/dist/builder/configGenerator.js +46 -6
- package/dist/builder/configGenerator.js.map +1 -1
- package/dist/builder/dependencyInstaller.d.ts.map +1 -1
- package/dist/builder/dependencyInstaller.js +8 -14
- package/dist/builder/dependencyInstaller.js.map +1 -1
- package/dist/builder/gitInitializer.d.ts.map +1 -1
- package/dist/builder/gitInitializer.js +8 -41
- package/dist/builder/gitInitializer.js.map +1 -1
- package/dist/builder/index.d.ts.map +1 -1
- package/dist/builder/index.js +27 -63
- package/dist/builder/index.js.map +1 -1
- package/dist/builder/moduleSelector.d.ts +1 -4
- package/dist/builder/moduleSelector.d.ts.map +1 -1
- package/dist/builder/moduleSelector.js +11 -15
- package/dist/builder/moduleSelector.js.map +1 -1
- package/dist/builder/templateContext.d.ts +2 -17
- package/dist/builder/templateContext.d.ts.map +1 -1
- package/dist/builder/templateContext.js +6 -5
- package/dist/builder/templateContext.js.map +1 -1
- package/dist/index.js +45 -20
- package/dist/index.js.map +1 -1
- package/dist/output/nextSteps.d.ts +1 -2
- package/dist/output/nextSteps.d.ts.map +1 -1
- package/dist/output/nextSteps.js +10 -19
- package/dist/output/nextSteps.js.map +1 -1
- package/dist/prompts/index.d.ts +3 -3
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +22 -58
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/stack.d.ts +3 -2
- package/dist/prompts/stack.d.ts.map +1 -1
- package/dist/prompts/stack.js +81 -70
- package/dist/prompts/stack.js.map +1 -1
- package/dist/types/index.d.ts +20 -42
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +40 -38
- package/dist/types/index.js.map +1 -1
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +19 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/messages.d.ts +9 -0
- package/dist/ui/messages.d.ts.map +1 -0
- package/dist/ui/messages.js +100 -0
- package/dist/ui/messages.js.map +1 -0
- package/dist/ui/prompts.d.ts +20 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +71 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/theme.d.ts +9 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +24 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/validators/index.d.ts +1 -0
- package/dist/validators/index.d.ts.map +1 -1
- package/dist/validators/index.js +6 -0
- package/dist/validators/index.js.map +1 -1
- package/package.json +70 -66
- package/templates/backend/express/config.json +44 -44
- package/templates/backend/express/eslint.config.mjs +40 -40
- package/templates/backend/express/gitignore +36 -36
- package/templates/backend/express/src/index.ts +76 -76
- package/templates/backend/express/src/routes/health.ts +12 -12
- package/templates/backend/express/tsconfig.json +25 -25
- package/templates/backend/nestjs/.prettierignore +52 -0
- package/templates/backend/nestjs/.prettierrc +16 -0
- package/templates/backend/nestjs/config.json +44 -0
- package/templates/backend/nestjs/eslint.config.mjs +40 -0
- package/templates/backend/nestjs/gitignore +36 -0
- package/templates/backend/nestjs/nest-cli.json +9 -0
- package/templates/backend/nestjs/src/app.module.ts.hbs +34 -0
- package/templates/backend/nestjs/src/health/health.controller.ts +12 -0
- package/templates/backend/nestjs/src/main.ts +23 -0
- package/templates/backend/nestjs/tsconfig.eslint.json +9 -0
- package/templates/backend/nestjs/tsconfig.json +25 -0
- package/templates/frontend/nextjs/app/layout.tsx +13 -13
- package/templates/frontend/nextjs/app/page.tsx.hbs +97 -97
- package/templates/frontend/nextjs/components/ui/button.tsx +51 -51
- package/templates/frontend/nextjs/components/ui/card.tsx +60 -60
- package/templates/frontend/nextjs/components/ui/field.tsx +67 -67
- package/templates/frontend/nextjs/components/ui/input.tsx +18 -18
- package/templates/frontend/nextjs/components.json +19 -19
- package/templates/frontend/nextjs/config.json +38 -38
- package/templates/frontend/nextjs/eslint.config.mjs +11 -11
- package/templates/frontend/nextjs/gitignore +42 -42
- package/templates/frontend/nextjs/lib/utils.ts +6 -6
- package/templates/frontend/nextjs/next.config.ts.hbs +12 -12
- package/templates/frontend/nextjs/proxy.ts.hbs +24 -24
- package/templates/frontend/nextjs/tsconfig.json +34 -34
- package/templates/frontend/tanstack/config.json +48 -48
- package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -68
- package/templates/frontend/tanstack/src/styles/app.css +85 -85
- package/templates/modules/auth/express/config.json +27 -26
- package/templates/modules/auth/express/src/controllers/authController.ts.hbs +116 -130
- package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -26
- package/templates/modules/auth/express/src/services/userStore.ts.hbs +117 -117
- package/templates/modules/auth/nestjs/config.json +24 -0
- package/templates/modules/auth/nestjs/src/auth/auth.controller.ts +46 -0
- package/templates/modules/auth/nestjs/src/auth/auth.guard.ts +36 -0
- package/templates/modules/auth/nestjs/src/auth/auth.module.ts.hbs +22 -0
- package/templates/modules/auth/nestjs/src/auth/auth.schemas.ts +35 -0
- package/templates/modules/auth/nestjs/src/auth/auth.service.ts +70 -0
- package/templates/modules/auth/nestjs/src/auth/jwt.ts +27 -0
- package/templates/modules/auth/nestjs/src/auth/users.service.ts.hbs +144 -0
- package/templates/modules/auth/nestjs/src/auth/zod-validation.pipe.ts +16 -0
- package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -96
- package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -35
- package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -35
- package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -132
- package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -50
- package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -152
- package/templates/modules/auth/nextjs/config.json +31 -31
- package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -39
- package/templates/modules/auth/nextjs/lib/auth.ts.hbs +37 -37
- package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +4 -4
- package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -140
- package/templates/modules/docker/.dockerignore +14 -14
- package/templates/modules/docker/Dockerfile.hbs +137 -130
- package/templates/modules/docker/config.json +19 -19
- package/templates/modules/docker/docker-compose.yml.hbs +9 -9
- package/templates/modules/drizzle/express/config.json +27 -27
- package/templates/modules/drizzle/express/drizzle.config.ts +13 -13
- package/templates/modules/drizzle/express/src/lib/db.ts +13 -13
- package/templates/modules/drizzle/express/src/lib/schema.ts +10 -10
- package/templates/modules/drizzle/nestjs/config.json +27 -0
- package/templates/modules/drizzle/nestjs/drizzle.config.ts +13 -0
- package/templates/modules/drizzle/nestjs/src/database/database.module.ts +30 -0
- package/templates/modules/drizzle/nestjs/src/database/schema.ts +10 -0
- package/templates/modules/drizzle/nextjs/config.json +29 -29
- package/templates/modules/drizzle/nextjs/lib/db.ts +13 -13
- package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
- package/templates/modules/mongoose/express/config.json +16 -16
- package/templates/modules/mongoose/nestjs/config.json +16 -0
- package/templates/modules/mongoose/nestjs/src/users/user.schema.ts +21 -0
- package/templates/modules/mongoose/nextjs/config.json +16 -16
- package/templates/modules/mongoose/nextjs/lib/db.ts +36 -36
- package/templates/modules/mongoose/tanstack/config.json +17 -17
- package/templates/modules/mongoose/tanstack/src/lib/db.ts +37 -37
- package/templates/modules/prisma/express/config.json +28 -28
- package/templates/modules/prisma/express/prisma/schema.prisma +1 -1
- package/templates/modules/prisma/express/prisma.config.ts +12 -12
- package/templates/modules/prisma/express/src/lib/prisma.ts +24 -24
- package/templates/modules/prisma/nestjs/config.json +28 -0
- package/templates/modules/prisma/nestjs/prisma/schema.prisma +23 -0
- package/templates/modules/prisma/nestjs/prisma.config.ts +12 -0
- package/templates/modules/prisma/nestjs/src/prisma/prisma.module.ts +11 -0
- package/templates/modules/prisma/nestjs/src/prisma/prisma.service.ts +17 -0
- package/templates/modules/prisma/nextjs/config.json +29 -29
- package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -91
- package/templates/modules/prisma/tanstack/config.json +5 -5
- package/dist/intro.d.ts +0 -2
- package/dist/intro.d.ts.map +0 -1
- package/dist/intro.js +0 -27
- package/dist/intro.js.map +0 -1
- package/templates/backend/express/.eslintrc.js +0 -24
package/dist/builder/index.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.build = build;
|
|
7
|
-
const consola_1 = __importDefault(require("consola"));
|
|
8
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
8
|
const registry_1 = require("../modules/registry");
|
|
10
9
|
const nextSteps_1 = require("../output/nextSteps");
|
|
@@ -18,104 +17,69 @@ const moduleSelector_1 = require("./moduleSelector");
|
|
|
18
17
|
const templateContext_1 = require("./templateContext");
|
|
19
18
|
// Main function to orchestrate the project construction process
|
|
20
19
|
async function build(config, targetDir) {
|
|
21
|
-
|
|
20
|
+
// 1. Validate target directory
|
|
21
|
+
const validationResult = await (0, validators_1.validateDirectoryEmpty)(targetDir);
|
|
22
|
+
if (validationResult)
|
|
23
|
+
throw (0, types_1.buildError)(validationResult, "DIRECTORY_NOT_EMPTY");
|
|
24
|
+
const didDirectoryExist = await fs_extra_1.default.pathExists(targetDir);
|
|
22
25
|
try {
|
|
23
|
-
// 1. Validate target directory
|
|
24
|
-
consola_1.default.info("Validating target directory...");
|
|
25
|
-
const validationResult = await (0, validators_1.validateDirectoryEmpty)(targetDir);
|
|
26
|
-
if (validationResult)
|
|
27
|
-
throw (0, types_1.buildError)(validationResult, "DIRECTORY_NOT_EMPTY");
|
|
28
26
|
// 2. Create target directory
|
|
29
|
-
consola_1.default.info("Creating project directory...");
|
|
30
27
|
await fs_extra_1.default.ensureDir(targetDir).catch((e) => {
|
|
31
28
|
throw (0, types_1.buildError)(e, "DIRECTORY_CREATE_ERROR", "Failed to create directory");
|
|
32
29
|
});
|
|
33
|
-
// 3. Select modules
|
|
34
|
-
consola_1.default.info("Selecting modules...");
|
|
30
|
+
// 3. Select and load modules
|
|
35
31
|
const selection = (0, moduleSelector_1.selectModules)(config);
|
|
36
|
-
// 4. Load modules
|
|
37
|
-
consola_1.default.info("Loading module configurations...");
|
|
38
32
|
const modules = [];
|
|
39
33
|
try {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
for (const moduleWithFramework of selection.modules) {
|
|
43
|
-
const module = await (0, registry_1.getModule)(moduleWithFramework.id);
|
|
44
|
-
modules.push({ ...module, framework: moduleWithFramework.framework });
|
|
34
|
+
for (const id of [selection.base, ...selection.modules]) {
|
|
35
|
+
modules.push(await (0, registry_1.getModule)(id));
|
|
45
36
|
}
|
|
46
37
|
}
|
|
47
38
|
catch (e) {
|
|
48
39
|
throw (0, types_1.buildError)(e, "MODULE_LOADING_ERROR", "Failed to load modules");
|
|
49
40
|
}
|
|
50
|
-
|
|
51
|
-
// 5. Build template context
|
|
52
|
-
consola_1.default.info("Building template context...");
|
|
41
|
+
// 4. Build template context and merge module configurations
|
|
53
42
|
const templateContext = (0, templateContext_1.buildTemplateContext)(config);
|
|
54
|
-
// 6. Merge configurations
|
|
55
43
|
const mergedConfig = (0, configGenerator_1.mergeConfigurations)(modules.map((m) => m.config), templateContext);
|
|
56
|
-
//
|
|
57
|
-
consola_1.default.info("Copying module files...");
|
|
44
|
+
// 5. Copy module files
|
|
58
45
|
try {
|
|
59
46
|
for (const module of modules) {
|
|
60
|
-
consola_1.default.debug(` - Copying ${module.config.id}...`);
|
|
61
47
|
await (0, fileProcessor_1.copyModuleFiles)(module.path, targetDir);
|
|
62
48
|
}
|
|
63
|
-
consola_1.default.success("Module files copied");
|
|
64
49
|
}
|
|
65
50
|
catch (e) {
|
|
66
51
|
throw (0, types_1.buildError)(e, "FILE_COPY_ERROR", "Failed to copy module files");
|
|
67
52
|
}
|
|
68
|
-
//
|
|
69
|
-
consola_1.default.info("Processing template files...");
|
|
53
|
+
// 6. Process Handlebars templates
|
|
70
54
|
try {
|
|
71
|
-
|
|
72
|
-
if (allTemplateFiles.length > 0) {
|
|
73
|
-
await (0, fileProcessor_1.processTemplateFiles)(targetDir, templateContext, allTemplateFiles);
|
|
74
|
-
consola_1.default.success(`Processed ${allTemplateFiles.length} template file(s)`);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
consola_1.default.info(" No template files to process");
|
|
78
|
-
}
|
|
55
|
+
await (0, fileProcessor_1.processTemplateFiles)(targetDir, templateContext, modules.flatMap((m) => m.config.templateFiles));
|
|
79
56
|
}
|
|
80
57
|
catch (e) {
|
|
81
58
|
throw (0, types_1.buildError)(e, "TEMPLATE_PROCESSING_ERROR", "Failed to process template files");
|
|
82
59
|
}
|
|
83
|
-
//
|
|
84
|
-
consola_1.default.info("Generating package.json...");
|
|
60
|
+
// 7. Generate package.json
|
|
85
61
|
await (0, configGenerator_1.generatePackageJson)(targetDir, mergedConfig, config);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
consola_1.default.info("Generating environment files...");
|
|
89
|
-
await (0, configGenerator_1.generateEnvFile)(targetDir, mergedConfig.envVars);
|
|
90
|
-
consola_1.default.success("Environment files generated");
|
|
91
|
-
// 11. Install dependencies (optional)
|
|
92
|
-
let depsInstalled = false;
|
|
93
|
-
if (config.installDeps) {
|
|
94
|
-
try {
|
|
95
|
-
depsInstalled = (0, dependencyInstaller_1.installDependencies)(config.packageManager, targetDir);
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
consola_1.default.warn("Continuing despite dependency installation issues");
|
|
99
|
-
}
|
|
62
|
+
if (config.packageManager === "pnpm") {
|
|
63
|
+
await (0, configGenerator_1.generatePnpmWorkspace)(targetDir, mergedConfig.overrides);
|
|
100
64
|
}
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
// 13. Done!
|
|
111
|
-
consola_1.default.success("Project building completed successfully!");
|
|
65
|
+
// 8. Generate environment files
|
|
66
|
+
await (0, configGenerator_1.generateEnvFile)(targetDir, mergedConfig.envVars);
|
|
67
|
+
// 9. Install dependencies and initialize git (both optional); a failure
|
|
68
|
+
// in either is reported as a warning and does not fail the build
|
|
69
|
+
const depsInstalled = config.installDeps &&
|
|
70
|
+
(0, dependencyInstaller_1.installDependencies)(config.packageManager, targetDir);
|
|
71
|
+
if (config.initGit)
|
|
72
|
+
(0, gitInitializer_1.initializeGitRepository)(targetDir);
|
|
112
73
|
return {
|
|
113
74
|
success: true,
|
|
114
75
|
projectPath: targetDir,
|
|
115
|
-
nextSteps: (0, nextSteps_1.generateNextSteps)(config, depsInstalled),
|
|
76
|
+
nextSteps: (0, nextSteps_1.generateNextSteps)(config, targetDir, depsInstalled),
|
|
116
77
|
};
|
|
117
78
|
}
|
|
118
79
|
catch (error) {
|
|
80
|
+
// Remove the partial project so a retry is not blocked by a non-empty
|
|
81
|
+
// directory; a directory that already existed is emptied, not deleted
|
|
82
|
+
await (didDirectoryExist ? fs_extra_1.default.emptyDir(targetDir) : fs_extra_1.default.remove(targetDir)).catch(() => undefined);
|
|
119
83
|
throw (0, types_1.buildError)(error, "BUILDING_ERROR", "Building failed");
|
|
120
84
|
}
|
|
121
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builder/index.ts"],"names":[],"mappings":";;;;;AAmBA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builder/index.ts"],"names":[],"mappings":";;;;;AAmBA,sBA8FC;AAjHD,wDAA0B;AAE1B,kDAAgD;AAChD,mDAAwD;AACxD,oCAA0E;AAC1E,8CAAuD;AACvD,uDAK2B;AAC3B,+DAA4D;AAC5D,mDAAwE;AACxE,qDAA2D;AAC3D,qDAAiD;AACjD,uDAAyD;AAEzD,gEAAgE;AACzD,KAAK,UAAU,KAAK,CACzB,MAAqB,EACrB,SAAiB;IAEjB,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,MAAM,IAAA,mCAAsB,EAAC,SAAS,CAAC,CAAC;IAEjE,IAAI,gBAAgB;QAClB,MAAM,IAAA,kBAAU,EAAC,gBAAgB,EAAE,qBAAqB,CAAC,CAAC;IAE5D,MAAM,iBAAiB,GAAG,MAAM,kBAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,6BAA6B;QAC7B,MAAM,kBAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;YACxC,MAAM,IAAA,kBAAU,EACd,CAAC,EACD,wBAAwB,EACxB,4BAA4B,CAC7B,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,SAAS,GAAG,IAAA,8BAAa,EAAC,MAAM,CAAC,CAAC;QACxC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,KAAK,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,MAAM,IAAA,oBAAS,EAAC,EAAE,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAA,kBAAU,EAAC,CAAC,EAAE,sBAAsB,EAAE,wBAAwB,CAAC,CAAC;QACxE,CAAC;QAED,4DAA4D;QAC5D,MAAM,eAAe,GAAG,IAAA,sCAAoB,EAAC,MAAM,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,IAAA,qCAAmB,EACtC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAC5B,eAAe,CAChB,CAAC;QAEF,uBAAuB;QACvB,IAAI,CAAC;YACH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,IAAA,+BAAe,EAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAA,kBAAU,EAAC,CAAC,EAAE,iBAAiB,EAAE,6BAA6B,CAAC,CAAC;QACxE,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC;YACH,MAAM,IAAA,oCAAoB,EACxB,SAAS,EACT,eAAe,EACf,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAC/C,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAA,kBAAU,EACd,CAAC,EACD,2BAA2B,EAC3B,kCAAkC,CACnC,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,MAAM,IAAA,qCAAmB,EAAC,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,IAAA,uCAAqB,EAAC,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC;QAED,gCAAgC;QAChC,MAAM,IAAA,iCAAe,EAAC,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAEvD,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,aAAa,GACjB,MAAM,CAAC,WAAW;YAClB,IAAA,yCAAmB,EAAC,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QAExD,IAAI,MAAM,CAAC,OAAO;YAAE,IAAA,wCAAuB,EAAC,SAAS,CAAC,CAAC;QAEvD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,IAAA,6BAAiB,EAAC,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC;SAC/D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,sEAAsE;QACtE,sEAAsE;QACtE,MAAM,CACJ,iBAAiB,CAAC,CAAC,CAAC,kBAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,kBAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAClE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzB,MAAM,IAAA,kBAAU,EAAC,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moduleSelector.d.ts","sourceRoot":"","sources":["../../src/builder/moduleSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa;;;
|
|
1
|
+
{"version":3,"file":"moduleSelector.d.ts","sourceRoot":"","sources":["../../src/builder/moduleSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa;;;EAmBlD"}
|
|
@@ -3,24 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.selectModules = selectModules;
|
|
4
4
|
// Determines which base and feature modules to include based on user configuration
|
|
5
5
|
function selectModules(config) {
|
|
6
|
-
|
|
7
|
-
const framework = config.framework;
|
|
6
|
+
const { framework } = config;
|
|
8
7
|
// Select base template based on app type
|
|
9
8
|
const base = config.applicationType === "backend"
|
|
10
|
-
? `backend/${
|
|
11
|
-
: `frontend/${
|
|
9
|
+
? `backend/${framework}`
|
|
10
|
+
: `frontend/${framework}`;
|
|
12
11
|
const modules = [];
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (config.useAuth) {
|
|
22
|
-
modules.push({ id: `auth/${framework}`, framework });
|
|
23
|
-
}
|
|
12
|
+
// Database and auth modules have one variant per framework (prisma/express,
|
|
13
|
+
// auth/nextjs, ...); the Docker module is shared
|
|
14
|
+
if (config.database !== "none")
|
|
15
|
+
modules.push(`${config.database}/${framework}`);
|
|
16
|
+
if (config.useDocker)
|
|
17
|
+
modules.push("docker");
|
|
18
|
+
if (config.useAuth)
|
|
19
|
+
modules.push(`auth/${framework}`);
|
|
24
20
|
return { base, modules };
|
|
25
21
|
}
|
|
26
22
|
//# sourceMappingURL=moduleSelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moduleSelector.js","sourceRoot":"","sources":["../../src/builder/moduleSelector.ts"],"names":[],"mappings":";;AAGA,
|
|
1
|
+
{"version":3,"file":"moduleSelector.js","sourceRoot":"","sources":["../../src/builder/moduleSelector.ts"],"names":[],"mappings":";;AAGA,sCAmBC;AApBD,mFAAmF;AACnF,SAAgB,aAAa,CAAC,MAAqB;IACjD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE7B,yCAAyC;IACzC,MAAM,IAAI,GACR,MAAM,CAAC,eAAe,KAAK,SAAS;QAClC,CAAC,CAAC,WAAW,SAAS,EAAE;QACxB,CAAC,CAAC,YAAY,SAAS,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,4EAA4E;IAC5E,iDAAiD;IACjD,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM;QAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,SAAS,EAAE,CAAC,CAAC;IAEtD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
import { ProjectConfig } from "../types";
|
|
1
|
+
import { ProjectConfig, TemplateContext } from "../types";
|
|
2
2
|
export declare function lowercase(str: string): string;
|
|
3
3
|
export declare function uppercase(str: string): string;
|
|
4
4
|
export declare function kebabCase(str: string): string;
|
|
5
|
-
export declare function buildTemplateContext(config: ProjectConfig):
|
|
6
|
-
projectName: string;
|
|
7
|
-
packageManager: import("../types").PackageManager;
|
|
8
|
-
database: import("../types").DatabaseOption;
|
|
9
|
-
framework: import("../types").BackendFramework | import("../types").FrontendFramework;
|
|
10
|
-
port: number;
|
|
11
|
-
useDocker: boolean;
|
|
12
|
-
useAuth: boolean;
|
|
13
|
-
helpers: {
|
|
14
|
-
lowercase: typeof lowercase;
|
|
15
|
-
uppercase: typeof uppercase;
|
|
16
|
-
kebabCase: typeof kebabCase;
|
|
17
|
-
eq: (a: string, b: string) => boolean;
|
|
18
|
-
runner: () => "bun" | "node";
|
|
19
|
-
};
|
|
20
|
-
};
|
|
5
|
+
export declare function buildTemplateContext(config: ProjectConfig): TemplateContext;
|
|
21
6
|
//# sourceMappingURL=templateContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templateContext.d.ts","sourceRoot":"","sources":["../../src/builder/templateContext.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"templateContext.d.ts","sourceRoot":"","sources":["../../src/builder/templateContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAoB3E"}
|
|
@@ -4,6 +4,8 @@ exports.lowercase = lowercase;
|
|
|
4
4
|
exports.uppercase = uppercase;
|
|
5
5
|
exports.kebabCase = kebabCase;
|
|
6
6
|
exports.buildTemplateContext = buildTemplateContext;
|
|
7
|
+
// Context builder for Handlebars, providing variables and helpers for templates
|
|
8
|
+
const types_1 = require("../types");
|
|
7
9
|
// Converts string to lowercase
|
|
8
10
|
function lowercase(str) {
|
|
9
11
|
return str.toLowerCase();
|
|
@@ -20,14 +22,13 @@ function kebabCase(str) {
|
|
|
20
22
|
.toLowerCase();
|
|
21
23
|
}
|
|
22
24
|
function buildTemplateContext(config) {
|
|
23
|
-
const framework = config.framework;
|
|
24
25
|
return {
|
|
25
26
|
projectName: config.projectName,
|
|
26
27
|
packageManager: config.packageManager,
|
|
27
|
-
database: config.database
|
|
28
|
-
framework,
|
|
29
|
-
port:
|
|
30
|
-
useDocker: config.useDocker
|
|
28
|
+
database: config.database,
|
|
29
|
+
framework: config.framework,
|
|
30
|
+
port: types_1.DEFAULT_PORT,
|
|
31
|
+
useDocker: config.useDocker,
|
|
31
32
|
useAuth: config.useAuth,
|
|
32
33
|
helpers: {
|
|
33
34
|
lowercase,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templateContext.js","sourceRoot":"","sources":["../../src/builder/templateContext.ts"],"names":[],"mappings":";;AAIA,8BAEC;AAGD,8BAEC;AAGD,8BAKC;AAED,
|
|
1
|
+
{"version":3,"file":"templateContext.js","sourceRoot":"","sources":["../../src/builder/templateContext.ts"],"names":[],"mappings":";;AAIA,8BAEC;AAGD,8BAEC;AAGD,8BAKC;AAED,oDAoBC;AAzCD,gFAAgF;AAChF,oCAAwE;AAExE,+BAA+B;AAC/B,SAAgB,SAAS,CAAC,GAAW;IACnC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3B,CAAC;AAED,+BAA+B;AAC/B,SAAgB,SAAS,CAAC,GAAW;IACnC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3B,CAAC;AAED,gCAAgC;AAChC,SAAgB,SAAS,CAAC,GAAW;IACnC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,0BAA0B;SAC9D,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,oCAAoC;SAC5D,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,oBAAoB,CAAC,MAAqB;IACxD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,oBAAY;QAClB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE;YACP,SAAS;YACT,SAAS;YACT,SAAS;YACT,EAAE,EAAE,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;YACrC,MAAM,EAAE,GAAG,EAAE;gBACX,IAAI,MAAM,CAAC,cAAc,KAAK,KAAK;oBAAE,OAAO,KAAK,CAAC;gBAClD,OAAO,MAAM,CAAC;YAChB,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,31 +4,56 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_process_1 = require("node:process");
|
|
10
|
+
const args_1 = require("./args");
|
|
11
11
|
const builder_1 = require("./builder");
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
12
|
+
const prompts_1 = require("./prompts");
|
|
13
|
+
const types_1 = require("./types");
|
|
14
|
+
const ui_1 = require("./ui");
|
|
15
|
+
const validators_1 = require("./validators");
|
|
15
16
|
// Main entry point for the CLI tool
|
|
16
17
|
async function main() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
(0, prompts_1.outro)("Happy coding!");
|
|
27
|
-
process.exit(0);
|
|
18
|
+
const args = (0, args_1.parseCliArgs)(process.argv.slice(2));
|
|
19
|
+
if (args.help) {
|
|
20
|
+
console.log(args_1.HELP_TEXT);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { version } = (await fs_extra_1.default.readJson(node_path_1.default.join(__dirname, "../package.json")));
|
|
24
|
+
if (args.version) {
|
|
25
|
+
console.log(version);
|
|
26
|
+
return;
|
|
28
27
|
}
|
|
28
|
+
(0, ui_1.showBanner)(version, !args.yes);
|
|
29
|
+
const projectPath = await (0, prompts_1.collectProjectPath)(args.projectPath, args.yes);
|
|
30
|
+
const targetDir = node_path_1.default.resolve((0, node_process_1.cwd)(), projectPath);
|
|
31
|
+
// Fail before the remaining prompts when the directory cannot be used
|
|
32
|
+
const directoryError = await (0, validators_1.validateDirectoryEmpty)(targetDir);
|
|
33
|
+
if (directoryError)
|
|
34
|
+
throw (0, types_1.buildError)(directoryError, "DIRECTORY_NOT_EMPTY");
|
|
35
|
+
const choices = await (0, prompts_1.collectStackChoices)(args.yes ? { ...types_1.DEFAULT_CHOICES, ...args.choices } : args.choices);
|
|
36
|
+
const config = {
|
|
37
|
+
projectName: node_path_1.default.basename(targetDir),
|
|
38
|
+
applicationType: (0, types_1.getApplicationType)(choices.framework),
|
|
39
|
+
...choices,
|
|
40
|
+
};
|
|
41
|
+
(0, ui_1.showSummary)(config, targetDir);
|
|
42
|
+
if (args.dryRun) {
|
|
43
|
+
(0, ui_1.info)("Dry run: no files were written.");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!args.yes)
|
|
47
|
+
await (0, prompts_1.confirmBuild)();
|
|
48
|
+
const result = await (0, builder_1.build)(config, targetDir);
|
|
49
|
+
(0, ui_1.success)("Project created");
|
|
50
|
+
(0, ui_1.showNextSteps)(result.nextSteps);
|
|
29
51
|
}
|
|
30
|
-
main()
|
|
31
|
-
|
|
52
|
+
main()
|
|
53
|
+
.then(() => process.exit(0))
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
// Errors raised by the CLI carry a code and a message meant for the user
|
|
56
|
+
(0, ui_1.error)(err instanceof Error && "code" in err ? err.message : String(err));
|
|
32
57
|
process.exit(1);
|
|
33
58
|
});
|
|
34
59
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,wDAA0B;AAC1B,0DAA6B;AAC7B,+CAAmC;AAEnC,iCAAiD;AACjD,uCAAkC;AAClC,uCAImB;AACnB,mCAKiB;AACjB,6BAOc;AACd,6CAAsD;AAEtD,oCAAoC;AACpC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,IAAA,mBAAY,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,gBAAS,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,kBAAE,CAAC,QAAQ,CACpC,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CACxC,CAAwB,CAAC;IAE1B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAA,eAAU,EAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,WAAW,GAAG,MAAM,IAAA,4BAAkB,EAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,mBAAI,CAAC,OAAO,CAAC,IAAA,kBAAG,GAAE,EAAE,WAAW,CAAC,CAAC;IAEnD,sEAAsE;IACtE,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAsB,EAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,cAAc;QAAE,MAAM,IAAA,kBAAU,EAAC,cAAc,EAAE,qBAAqB,CAAC,CAAC;IAE5E,MAAM,OAAO,GAAG,MAAM,IAAA,6BAAmB,EACvC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,uBAAe,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAClE,CAAC;IAEF,MAAM,MAAM,GAAkB;QAC5B,WAAW,EAAE,mBAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACrC,eAAe,EAAE,IAAA,0BAAkB,EAAC,OAAO,CAAC,SAAS,CAAC;QACtD,GAAG,OAAO;KACX,CAAC;IAEF,IAAA,gBAAW,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,IAAA,SAAI,EAAC,iCAAiC,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAA,sBAAY,GAAE,CAAC;IAEpC,MAAM,MAAM,GAAG,MAAM,IAAA,eAAK,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE9C,IAAA,YAAO,EAAC,iBAAiB,CAAC,CAAC;IAC3B,IAAA,kBAAa,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE;KACH,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KAC3B,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACb,yEAAyE;IACzE,IAAA,UAAK,EAAC,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { ProjectConfig } from "../types";
|
|
2
|
-
export declare function generateNextSteps(config: ProjectConfig, depsInstalled: boolean): string[];
|
|
3
|
-
export declare function displayNextSteps(_projectName: string, steps: string[]): string;
|
|
2
|
+
export declare function generateNextSteps(config: ProjectConfig, targetDir: string, depsInstalled: boolean): string[];
|
|
4
3
|
//# sourceMappingURL=nextSteps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextSteps.d.ts","sourceRoot":"","sources":["../../src/output/nextSteps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nextSteps.d.ts","sourceRoot":"","sources":["../../src/output/nextSteps.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAmBzC,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,GACrB,MAAM,EAAE,CAyEV"}
|
package/dist/output/nextSteps.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.generateNextSteps = generateNextSteps;
|
|
4
|
-
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_process_1 = require("node:process");
|
|
5
9
|
const MONGODB_AUTH_SETUP_URL = "https://better-ts-stack.abdullahtech.me/docs/modules/database#mongoose-and-mongodb";
|
|
6
10
|
// Node 24 releases before 24.20 report mismatched file stats on Windows, which
|
|
7
11
|
// makes srvx (TanStack's production server) reject every static asset
|
|
@@ -13,11 +17,13 @@ function isNodeBelow([major, minor]) {
|
|
|
13
17
|
return (currentMajor < major || (currentMajor === major && currentMinor < minor));
|
|
14
18
|
}
|
|
15
19
|
// Generates a list of instructions for the user to follow after project creation
|
|
16
|
-
function generateNextSteps(config, depsInstalled) {
|
|
20
|
+
function generateNextSteps(config, targetDir, depsInstalled) {
|
|
17
21
|
const steps = [];
|
|
18
22
|
const isFullstack = config.applicationType === "fullstack";
|
|
19
|
-
// Step 1: cd into project directory
|
|
20
|
-
|
|
23
|
+
// Step 1: cd into project directory, unless it was created in place
|
|
24
|
+
const relativeDir = node_path_1.default.relative((0, node_process_1.cwd)(), targetDir);
|
|
25
|
+
if (relativeDir)
|
|
26
|
+
steps.push(`cd ${relativeDir}`);
|
|
21
27
|
// Step 2: Set environment variables
|
|
22
28
|
if (config.database !== "none") {
|
|
23
29
|
steps.push("Review the generated .env and set your database connection details");
|
|
@@ -64,19 +70,4 @@ function generateNextSteps(config, depsInstalled) {
|
|
|
64
70
|
}
|
|
65
71
|
return steps;
|
|
66
72
|
}
|
|
67
|
-
// Formats the next steps into a success message string
|
|
68
|
-
function displayNextSteps(_projectName, steps) {
|
|
69
|
-
const formattedSteps = steps
|
|
70
|
-
.map((step, index) => ` ${index + 1}. ${step}`)
|
|
71
|
-
.join("\n");
|
|
72
|
-
const message = `
|
|
73
|
-
✨ Project created successfully!
|
|
74
|
-
|
|
75
|
-
Next steps:
|
|
76
|
-
${formattedSteps}
|
|
77
|
-
|
|
78
|
-
Your server will be running at http://localhost:3000
|
|
79
|
-
`;
|
|
80
|
-
return message;
|
|
81
|
-
}
|
|
82
73
|
//# sourceMappingURL=nextSteps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextSteps.js","sourceRoot":"","sources":["../../src/output/nextSteps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nextSteps.js","sourceRoot":"","sources":["../../src/output/nextSteps.ts"],"names":[],"mappings":"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"}
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function confirmBuild(
|
|
1
|
+
export { collectStackChoices } from "./stack";
|
|
2
|
+
export declare function collectProjectPath(preset: string | undefined, isNonInteractive: boolean): Promise<string>;
|
|
3
|
+
export declare function confirmBuild(): Promise<void>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG9C,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,gBAAgB,EAAE,OAAO,GACxB,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAGD,wBAAsB,YAAY,kBAQjC"}
|
package/dist/prompts/index.js
CHANGED
|
@@ -1,70 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
3
|
+
exports.collectStackChoices = void 0;
|
|
4
|
+
exports.collectProjectPath = collectProjectPath;
|
|
7
5
|
exports.confirmBuild = confirmBuild;
|
|
8
|
-
const prompts_1 = require("@clack/prompts");
|
|
9
|
-
const consola_1 = __importDefault(require("consola"));
|
|
10
6
|
const types_1 = require("../types");
|
|
7
|
+
const ui_1 = require("../ui");
|
|
11
8
|
const validators_1 = require("../validators");
|
|
12
9
|
const stack_1 = require("./stack");
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
(0, prompts_1.cancel)("Operation cancelled.");
|
|
22
|
-
process.exit(0);
|
|
10
|
+
var stack_2 = require("./stack");
|
|
11
|
+
Object.defineProperty(exports, "collectStackChoices", { enumerable: true, get: function () { return stack_2.collectStackChoices; } });
|
|
12
|
+
// Returns the project path from the command line, or asks for it
|
|
13
|
+
async function collectProjectPath(preset, isNonInteractive) {
|
|
14
|
+
if (preset !== undefined) {
|
|
15
|
+
const error = (0, validators_1.validateProjectPath)(preset);
|
|
16
|
+
if (error)
|
|
17
|
+
throw (0, types_1.buildError)(error, "INVALID_ARGUMENT");
|
|
23
18
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
options: types_1.applicationTypeOptions,
|
|
27
|
-
initialValue: "backend",
|
|
28
|
-
});
|
|
29
|
-
if ((0, prompts_1.isCancel)(applicationType)) {
|
|
30
|
-
(0, prompts_1.cancel)("Operation cancelled.");
|
|
31
|
-
process.exit(0);
|
|
19
|
+
else if (isNonInteractive) {
|
|
20
|
+
throw (0, types_1.buildError)("A project path is required with --yes, for example: better-ts-stack my-app --yes", "INVALID_ARGUMENT");
|
|
32
21
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
applicationType,
|
|
39
|
-
...userChoices,
|
|
40
|
-
database,
|
|
41
|
-
};
|
|
42
|
-
return choices;
|
|
22
|
+
return (0, stack_1.ask)(preset, () => (0, ui_1.text)({
|
|
23
|
+
message: "Project name",
|
|
24
|
+
placeholder: "my-awesome-project",
|
|
25
|
+
validate: (value) => (0, validators_1.validateProjectPath)(value ?? ""),
|
|
26
|
+
}));
|
|
43
27
|
}
|
|
44
|
-
//
|
|
45
|
-
async function confirmBuild(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
consola_1.default.box(`Project Name: ${config.projectName}\n` +
|
|
49
|
-
`Target Dir: ${targetDir}\n` +
|
|
50
|
-
`App Type: ${appTypeLabel}\n` +
|
|
51
|
-
`Framework: ${config.framework}\n` +
|
|
52
|
-
`Database: ${config.database}\n` +
|
|
53
|
-
`Auth: ${config.useAuth ? "Yes" : "No"}\n` +
|
|
54
|
-
`Docker: ${config.useDocker ? "Yes" : "No"}\n` +
|
|
55
|
-
`Package Mgr: ${config.packageManager}\n` +
|
|
56
|
-
`Git Init: ${config.initGit ? "Yes" : "No"}\n` +
|
|
57
|
-
`Install Deps: ${config.installDeps ? "Yes" : "No"}`);
|
|
58
|
-
const shouldContinue = await (0, prompts_1.confirm)({
|
|
59
|
-
message: "Looks good? Ready to build?",
|
|
60
|
-
initialValue: true,
|
|
61
|
-
});
|
|
62
|
-
if ((0, prompts_1.isCancel)(shouldContinue)) {
|
|
63
|
-
(0, prompts_1.cancel)("Operation cancelled.");
|
|
64
|
-
process.exit(0);
|
|
65
|
-
}
|
|
66
|
-
if (!shouldContinue) {
|
|
67
|
-
(0, prompts_1.cancel)("Building cancelled by user.");
|
|
28
|
+
// Asks for final confirmation before building; declining ends the session
|
|
29
|
+
async function confirmBuild() {
|
|
30
|
+
const shouldBuild = await (0, stack_1.ask)(undefined, () => (0, ui_1.confirm)({ message: "Create this project?", initialValue: true }));
|
|
31
|
+
if (!shouldBuild) {
|
|
68
32
|
process.exit(0);
|
|
69
33
|
}
|
|
70
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":";;;AAQA,gDAqBC;AAGD,oCAQC;AAxCD,oCAAsC;AACtC,8BAAsC;AACtC,8CAAoD;AACpD,mCAA8B;AAE9B,iCAA8C;AAArC,4GAAA,mBAAmB,OAAA;AAE5B,iEAAiE;AAC1D,KAAK,UAAU,kBAAkB,CACtC,MAA0B,EAC1B,gBAAyB;IAEzB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAA,gCAAmB,EAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,KAAK;YAAE,MAAM,IAAA,kBAAU,EAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACzD,CAAC;SAAM,IAAI,gBAAgB,EAAE,CAAC;QAC5B,MAAM,IAAA,kBAAU,EACd,kFAAkF,EAClF,kBAAkB,CACnB,CAAC;IACJ,CAAC;IAED,OAAO,IAAA,WAAG,EAAC,MAAM,EAAE,GAAG,EAAE,CACtB,IAAA,SAAI,EAAC;QACH,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,oBAAoB;QACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,gCAAmB,EAAC,KAAK,IAAI,EAAE,CAAC;KACtD,CAAC,CACH,CAAC;AACJ,CAAC;AAED,0EAA0E;AACnE,KAAK,UAAU,YAAY;IAChC,MAAM,WAAW,GAAG,MAAM,IAAA,WAAG,EAAC,SAAS,EAAE,GAAG,EAAE,CAC5C,IAAA,YAAO,EAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CACjE,CAAC;IAEF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/prompts/stack.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
1
|
+
import { StackChoices } from "../types";
|
|
2
|
+
export declare function ask<T>(preset: T | undefined, prompt: () => Promise<T | symbol>): Promise<T>;
|
|
3
|
+
export declare function collectStackChoices(preset: Partial<StackChoices>): Promise<StackChoices>;
|
|
3
4
|
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/prompts/stack.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/prompts/stack.ts"],"names":[],"mappings":"AAEA,OAAO,EAaL,YAAY,EACb,MAAM,UAAU,CAAC;AAIlB,wBAAsB,GAAG,CAAC,CAAC,EACzB,MAAM,EAAE,CAAC,GAAG,SAAS,EACrB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,GAChC,OAAO,CAAC,CAAC,CAAC,CASZ;AAyCD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAC5B,OAAO,CAAC,YAAY,CAAC,CAgDvB"}
|