deploy-bbc 1.3.0 → 1.3.2
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 +22 -8
- package/dist/index.js +22 -3
- package/dist/templates/templates/base-express/src/index.ts +4 -2
- package/dist/templates/templates/base-express/src/middleware/error-handler.ts +42 -0
- package/dist/templates/templates/base-express/src/middleware/succcess-handler.ts +20 -0
- package/dist/templates/templates/base-express/src/types/common/api-response.types.ts +14 -19
- package/dist/templates/templates/base-express/src/types/common/mongodb.types.ts +5 -0
- package/dist/templates/templates/base-express/src/types/models/user.types.ts +8 -16
- package/dist/templates/templates/base-express/src/utils/CustomError.ts +17 -0
- package/dist/templates/templates/base-express/src/utils/env.ts +10 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,24 +198,38 @@ During setup, you'll be asked:
|
|
|
198
198
|
|
|
199
199
|
### Usage
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
When you enable Docker during setup, a convenient `docker:dev` script is automatically added to your `package.json`.
|
|
202
|
+
|
|
203
|
+
#### Quick Start
|
|
202
204
|
|
|
203
205
|
```bash
|
|
204
|
-
# Start
|
|
206
|
+
# Start all Docker services (databases and/or backend)
|
|
207
|
+
bun run docker:dev
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
This script runs `docker-compose up`, starting all services defined in your `docker-compose.yml`.
|
|
211
|
+
|
|
212
|
+
#### Manual Control
|
|
213
|
+
|
|
214
|
+
You can also use docker-compose directly for more control:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Start only specific services (e.g., databases only)
|
|
205
218
|
docker-compose up postgres redis -d
|
|
206
219
|
|
|
207
220
|
# Run your app locally
|
|
208
221
|
bun run dev
|
|
209
222
|
```
|
|
210
223
|
|
|
211
|
-
If you dockerized both databases and backend:
|
|
212
|
-
|
|
213
224
|
```bash
|
|
214
|
-
# Start everything
|
|
215
|
-
docker-compose up
|
|
216
|
-
|
|
217
|
-
# Or in detached mode
|
|
225
|
+
# Start everything in detached mode
|
|
218
226
|
docker-compose up -d
|
|
227
|
+
|
|
228
|
+
# View logs
|
|
229
|
+
docker-compose logs -f
|
|
230
|
+
|
|
231
|
+
# Stop services
|
|
232
|
+
docker-compose down
|
|
219
233
|
```
|
|
220
234
|
|
|
221
235
|
### SQLite with Docker
|
package/dist/index.js
CHANGED
|
@@ -16800,7 +16800,7 @@ async function init_git(projectDir) {
|
|
|
16800
16800
|
}
|
|
16801
16801
|
|
|
16802
16802
|
// src/helpers/log-next-steps.ts
|
|
16803
|
-
function log_next_steps(options,
|
|
16803
|
+
function log_next_steps(options, cliResults) {
|
|
16804
16804
|
const { appName, packages, projectDir } = options;
|
|
16805
16805
|
const isCurrentDirectory = projectDir === process.cwd();
|
|
16806
16806
|
console.log(`
|
|
@@ -16820,10 +16820,10 @@ function log_next_steps(options, _cliResults) {
|
|
|
16820
16820
|
console.log(` ${source_default.gray("# Edit .env with your configuration")}`);
|
|
16821
16821
|
console.log();
|
|
16822
16822
|
stepNumber++;
|
|
16823
|
-
const hasDocker =
|
|
16823
|
+
const hasDocker = cliResults.flags.dockerizeDb || cliResults.flags.dockerizeBackend;
|
|
16824
16824
|
if (hasDocker) {
|
|
16825
16825
|
console.log(source_default.cyan(`${stepNumber}.`) + " Start Docker services:");
|
|
16826
|
-
console.log(` ${source_default.gray("
|
|
16826
|
+
console.log(` ${source_default.gray("bun run docker:dev")}`);
|
|
16827
16827
|
console.log();
|
|
16828
16828
|
stepNumber++;
|
|
16829
16829
|
}
|
|
@@ -16851,6 +16851,22 @@ function render_title(title) {
|
|
|
16851
16851
|
` + source_default.bold.cyan(`▸ ${title}`));
|
|
16852
16852
|
}
|
|
16853
16853
|
|
|
16854
|
+
// src/utils/add-package-scripts.ts
|
|
16855
|
+
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
16856
|
+
import path24 from "path";
|
|
16857
|
+
async function add_package_scripts(projectDir, scripts) {
|
|
16858
|
+
const packageJsonPath = path24.join(projectDir, "package.json");
|
|
16859
|
+
const packageJson = await import_fs_extra18.default.readJson(packageJsonPath);
|
|
16860
|
+
if (!packageJson.scripts) {
|
|
16861
|
+
packageJson.scripts = {};
|
|
16862
|
+
}
|
|
16863
|
+
packageJson.scripts = {
|
|
16864
|
+
...packageJson.scripts,
|
|
16865
|
+
...scripts
|
|
16866
|
+
};
|
|
16867
|
+
await import_fs_extra18.default.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
16868
|
+
}
|
|
16869
|
+
|
|
16854
16870
|
// src/helpers/create-project.ts
|
|
16855
16871
|
async function create_project(cliResults) {
|
|
16856
16872
|
try {
|
|
@@ -16877,6 +16893,9 @@ async function create_project(cliResults) {
|
|
|
16877
16893
|
}
|
|
16878
16894
|
if (cliResults.flags.dockerizeDb || cliResults.flags.dockerizeBackend) {
|
|
16879
16895
|
await generate_docker_compose(installerOptions);
|
|
16896
|
+
await add_package_scripts(projectDir, {
|
|
16897
|
+
"docker:dev": "docker-compose up"
|
|
16898
|
+
});
|
|
16880
16899
|
}
|
|
16881
16900
|
}
|
|
16882
16901
|
if (!cliResults.flags.noInstall) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import { logger as loggerMiddleware } from "./middleware/logger.js";
|
|
3
|
-
import {
|
|
3
|
+
import {error_handler} from "./middleware/error-handler.js";
|
|
4
4
|
import routes from "./routes/index.js";
|
|
5
5
|
import { config } from "./config/index.js";
|
|
6
|
+
import { success_handler } from "./middleware/succcess-handler.js";
|
|
6
7
|
|
|
7
8
|
const app = express();
|
|
8
9
|
|
|
@@ -10,6 +11,7 @@ const app = express();
|
|
|
10
11
|
app.use(express.json());
|
|
11
12
|
app.use(express.urlencoded({ extended: true }));
|
|
12
13
|
app.use(loggerMiddleware);
|
|
14
|
+
app.use(success_handler)
|
|
13
15
|
|
|
14
16
|
// Routes
|
|
15
17
|
app.use("/", routes);
|
|
@@ -20,7 +22,7 @@ app.get("/health", (req, res) => {
|
|
|
20
22
|
});
|
|
21
23
|
|
|
22
24
|
// Error handler (must be last)
|
|
23
|
-
app.use(
|
|
25
|
+
app.use(error_handler);
|
|
24
26
|
|
|
25
27
|
app.listen(config.port, () => {
|
|
26
28
|
console.log(`🚀 Server running on http://localhost:${config.port}`);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from "express";
|
|
2
|
+
import CustomError from "../utils/CustomError";
|
|
3
|
+
|
|
4
|
+
type TSendErrorAsResponse = {
|
|
5
|
+
error: Error | CustomError;
|
|
6
|
+
req: Request;
|
|
7
|
+
res: Response;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type TErrorResponse = {
|
|
11
|
+
message: string;
|
|
12
|
+
status_code: number;
|
|
13
|
+
stack?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const error_handler = (
|
|
17
|
+
err: Error | CustomError,
|
|
18
|
+
req: Request,
|
|
19
|
+
res: Response,
|
|
20
|
+
_next: NextFunction
|
|
21
|
+
) => {
|
|
22
|
+
|
|
23
|
+
console.error(`Error: ${err.message}`, err);
|
|
24
|
+
//TODO: Update error handler based on type of database and type of validator
|
|
25
|
+
send_error_as_response({error:err,req,res})
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
const send_error_as_response =(
|
|
32
|
+
{error,req,res}: TSendErrorAsResponse
|
|
33
|
+
) => {
|
|
34
|
+
//TODO: update send_error_as_response based on type of logger
|
|
35
|
+
const error_response: TErrorResponse = {
|
|
36
|
+
message: error.message,
|
|
37
|
+
status_code: error instanceof CustomError ? error.status_code : 500,
|
|
38
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
res.status(error_response.status_code).json(error_response);
|
|
42
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { NextFunction, Request, Response} from 'express'
|
|
2
|
+
|
|
3
|
+
type TSuccessHandler= {
|
|
4
|
+
req: Request,
|
|
5
|
+
res: Response,
|
|
6
|
+
next: NextFunction
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const success_handler = (
|
|
10
|
+
{req, res, next} : TSuccessHandler)=>{
|
|
11
|
+
|
|
12
|
+
const original_json = res.json
|
|
13
|
+
|
|
14
|
+
res.json = function (json: any): Response {
|
|
15
|
+
//TODO: logic to have logger and other success resposne parsing
|
|
16
|
+
return original_json.call(this,json)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
next();
|
|
20
|
+
}
|
|
@@ -2,29 +2,24 @@
|
|
|
2
2
|
* Common API response types
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export interface ApiResponse<T = unknown> {
|
|
6
|
-
success: boolean;
|
|
7
|
-
data?: T;
|
|
8
|
-
error?: string;
|
|
9
|
-
message?: string;
|
|
10
|
-
}
|
|
11
5
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
total: number;
|
|
17
|
-
totalPages: number;
|
|
18
|
-
};
|
|
6
|
+
export type TApiSuccess<T =unknown> = {
|
|
7
|
+
data?: T;
|
|
8
|
+
message: string;
|
|
9
|
+
pagination?: TPaginationResponse
|
|
19
10
|
}
|
|
20
11
|
|
|
21
|
-
export
|
|
22
|
-
|
|
12
|
+
export type TApiError = {
|
|
13
|
+
status_code: number;
|
|
23
14
|
message: string;
|
|
24
15
|
}
|
|
25
16
|
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
export type TApiResponse<T = unknown> = TApiSuccess<T> | TApiError
|
|
18
|
+
|
|
19
|
+
export type TPaginationResponse = {
|
|
20
|
+
page: number;
|
|
21
|
+
limit: number;
|
|
22
|
+
total_pages: number;
|
|
23
|
+
total_count: number;
|
|
30
24
|
}
|
|
25
|
+
|
|
@@ -2,25 +2,17 @@
|
|
|
2
2
|
* User model types
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
email: string;
|
|
8
|
-
name: string;
|
|
9
|
-
createdAt: Date;
|
|
10
|
-
updatedAt: Date;
|
|
11
|
-
}
|
|
5
|
+
import { TDocument } from "../common/mongodb.types";
|
|
6
|
+
|
|
12
7
|
|
|
13
|
-
|
|
8
|
+
|
|
9
|
+
export type TUser<Tid= string> = TDocument<Tid> & {
|
|
14
10
|
email: string;
|
|
15
11
|
name: string;
|
|
16
12
|
}
|
|
17
13
|
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
14
|
+
export type TCreateUserInput = Pick<TUser, 'email' | 'name'>
|
|
15
|
+
|
|
16
|
+
export type TUpdateUserInput = Partial<Pick<TUser, 'email' | 'name'>>
|
|
22
17
|
|
|
23
|
-
export type
|
|
24
|
-
createdAt: string;
|
|
25
|
-
updatedAt: string;
|
|
26
|
-
};
|
|
18
|
+
export type TUserResponse = Omit<TUser, "createdAt" | "updatedAt"> & Pick<TDocument, 'createdAt' | 'updatedAt'>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class CustomError extends Error {
|
|
2
|
+
status_code: number;
|
|
3
|
+
|
|
4
|
+
constructor(
|
|
5
|
+
message: string = 'Internal Server Error',
|
|
6
|
+
status_code: number = 500
|
|
7
|
+
){
|
|
8
|
+
super(message);
|
|
9
|
+
this.status_code = status_code;
|
|
10
|
+
|
|
11
|
+
Object.setPrototypeOf(this, CustomError.prototype);
|
|
12
|
+
|
|
13
|
+
Error.captureStackTrace(this, this.constructor);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default CustomError;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import dotenv from 'dotenv'
|
|
2
|
+
import path from 'path'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
dotenv.config({path: path.resolve(__dirname, '../../.env')})
|
|
5
|
+
|
|
6
|
+
export type TEnv = {
|
|
7
|
+
port: number
|
|
5
8
|
}
|
|
9
|
+
|
|
10
|
+
export const env: TEnv = {
|
|
11
|
+
port: parseInt(process.env.PORT || '8000');
|
|
12
|
+
}
|