backend-starter-kit 1.0.5
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 +0 -0
- package/bin/cli.js +105 -0
- package/package.json +44 -0
- package/template/.biomeignore +40 -0
- package/template/.github/PULL_REQUEST_TEMPLATE.md +18 -0
- package/template/.github/workflows/check.yml +107 -0
- package/template/.husky/pre-commit +4 -0
- package/template/README.md +66 -0
- package/template/biome.json +65 -0
- package/template/bun.lock +643 -0
- package/template/package.json +67 -0
- package/template/prisma/schema.prisma +8 -0
- package/template/prisma.config.js +12 -0
- package/template/src/app.js +45 -0
- package/template/src/config/cookie.config.js +21 -0
- package/template/src/config/env.config.js +43 -0
- package/template/src/config/swagger.config.js +62 -0
- package/template/src/constants/api.constants.js +6 -0
- package/template/src/constants/app.constants.js +5 -0
- package/template/src/constants/http.constants.js +90 -0
- package/template/src/constants/queue.constants.js +5 -0
- package/template/src/constants/security.constants.js +22 -0
- package/template/src/constants/validation.constants.js +8 -0
- package/template/src/core/db/prisma.connection.js +0 -0
- package/template/src/core/db/prisma.js +0 -0
- package/template/src/core/http/api.error.js +162 -0
- package/template/src/core/http/api.response.js +118 -0
- package/template/src/core/middlewares/asyncHandler.middleware.js +7 -0
- package/template/src/core/middlewares/error.middleware.js +43 -0
- package/template/src/core/middlewares/notFound.middleware.js +8 -0
- package/template/src/core/middlewares/validate.middleware.js +33 -0
- package/template/src/core/utils/logger.utils.js +78 -0
- package/template/src/core/utils/zod.utils.js +74 -0
- package/template/src/index.js +29 -0
- package/template/src/routes/createRoute.js +10 -0
- package/template/src/routes/health.route.js +28 -0
- package/template/src/routes/index.route.js +38 -0
package/README.md
ADDED
|
File without changes
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { existsSync, mkdirSync, cpSync } from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import ora from "ora";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import prompts from "prompts";
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
function runCommand(command, options = {}) {
|
|
14
|
+
try {
|
|
15
|
+
return execSync(command, {
|
|
16
|
+
stdio: "pipe",
|
|
17
|
+
encoding: "utf-8",
|
|
18
|
+
...options,
|
|
19
|
+
}).trim();
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
let projectName = process.argv[2];
|
|
27
|
+
if (!projectName) {
|
|
28
|
+
const response = await prompts({
|
|
29
|
+
type: "text",
|
|
30
|
+
name: "projectName",
|
|
31
|
+
message: "What is your project named?",
|
|
32
|
+
initial: "my-app",
|
|
33
|
+
});
|
|
34
|
+
projectName = response.projectName;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const projectPath = path.resolve(process.cwd(), projectName);
|
|
38
|
+
if (projectName !== "." && existsSync(projectPath)) {
|
|
39
|
+
console.error(chalk.red(`❌ Folder "${projectName}" already exists.`));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const { packageManager } = await prompts({
|
|
44
|
+
type: "select",
|
|
45
|
+
name: "packageManager",
|
|
46
|
+
message: "Which package manager would you like to use?",
|
|
47
|
+
choices: [
|
|
48
|
+
{ title: "pnpm (recommended)", value: "pnpm" },
|
|
49
|
+
{ title: "npm", value: "npm" },
|
|
50
|
+
{ title: "yarn", value: "yarn" },
|
|
51
|
+
{ title: "bun", value: "bun" },
|
|
52
|
+
],
|
|
53
|
+
initial: 0,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
console.log(`\nCreating a new Backend app in ${chalk.cyan(projectPath)}.\n`);
|
|
57
|
+
console.log(`Using ${chalk.cyan(packageManager)}.\n`);
|
|
58
|
+
console.log(`Initializing project with template: backend\n`);
|
|
59
|
+
|
|
60
|
+
if (projectName !== ".") mkdirSync(projectPath);
|
|
61
|
+
const templateDir = path.join(__dirname, "../template");
|
|
62
|
+
cpSync(templateDir, projectPath, { recursive: true });
|
|
63
|
+
|
|
64
|
+
const spinner = ora("Initializing git repository...").start();
|
|
65
|
+
runCommand("git init", { cwd: projectPath });
|
|
66
|
+
spinner.stop();
|
|
67
|
+
console.log(chalk.green("Initialized a git repository.\n"));
|
|
68
|
+
|
|
69
|
+
console.log(chalk.cyan(`Installing dependencies...\n`));
|
|
70
|
+
try {
|
|
71
|
+
if (packageManager === "npm")
|
|
72
|
+
runCommand("npm install", { cwd: projectPath });
|
|
73
|
+
else if (packageManager === "pnpm")
|
|
74
|
+
runCommand("pnpm install", { cwd: projectPath });
|
|
75
|
+
else if (packageManager === "yarn")
|
|
76
|
+
runCommand("yarn install", { cwd: projectPath });
|
|
77
|
+
else if (packageManager === "bun")
|
|
78
|
+
runCommand("bun install", { cwd: projectPath });
|
|
79
|
+
} catch {
|
|
80
|
+
console.log(
|
|
81
|
+
chalk.yellow("\n⚠ Warning: Some build scripts were ignored.\n"),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
console.log(
|
|
85
|
+
chalk.green(
|
|
86
|
+
`Done in ${chalk.cyan("~10s")} using ${chalk.cyan(packageManager)}.`,
|
|
87
|
+
),
|
|
88
|
+
);
|
|
89
|
+
console.log(
|
|
90
|
+
chalk.green(
|
|
91
|
+
`\n✅ Success! Created ${projectName} at ${chalk.cyan(projectPath)}`,
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
console.log(chalk.cyan(`\nNext steps:`));
|
|
95
|
+
console.log(chalk.cyan(` 1. cd ${projectName}`));
|
|
96
|
+
console.log(chalk.cyan(` 2. Update .env with your database credentials`));
|
|
97
|
+
console.log(
|
|
98
|
+
chalk.cyan(
|
|
99
|
+
` 3. Run ${packageManager} run dev to start the backend server`,
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
console.log(chalk.cyan(` 4. Access API docs at /api/v1/docs`));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "backend-starter-kit",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"bin": {
|
|
5
|
+
"create-backend-starter": "bin/cli.js"
|
|
6
|
+
},
|
|
7
|
+
"keywords": [
|
|
8
|
+
"backend",
|
|
9
|
+
"bunjs",
|
|
10
|
+
"express"
|
|
11
|
+
],
|
|
12
|
+
"description": "Create backend-powered applications with one command",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/harshit-ostwal/backend-starter-kit.git"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/harshit-ostwal/backend-starter-kit.git",
|
|
18
|
+
"author": "Harshit Ostwal <codewithharshitjain@gmail.com>",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/harshit-ostwal/backend-starter-kit.git/issues"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"template"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"chalk": "^5.6.0",
|
|
30
|
+
"commander": "^14.0.0",
|
|
31
|
+
"ora": "^8.2.0",
|
|
32
|
+
"prompts": "^2.4.2",
|
|
33
|
+
"readline": "^1.3.0"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"bun": ">=1.3.4"
|
|
37
|
+
},
|
|
38
|
+
"nextBundleAnalysis": {
|
|
39
|
+
"budget": 358400,
|
|
40
|
+
"budgetPercentIncreaseRed": 20,
|
|
41
|
+
"minimumChangeThreshold": 0,
|
|
42
|
+
"showDetails": true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules
|
|
3
|
+
|
|
4
|
+
# Output directories
|
|
5
|
+
dist
|
|
6
|
+
build
|
|
7
|
+
out
|
|
8
|
+
coverage
|
|
9
|
+
*.tgz
|
|
10
|
+
.next
|
|
11
|
+
.nuxt
|
|
12
|
+
.output
|
|
13
|
+
.vercel
|
|
14
|
+
.netlify
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
logs
|
|
18
|
+
*.log
|
|
19
|
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
20
|
+
|
|
21
|
+
# Environment files
|
|
22
|
+
.env
|
|
23
|
+
.env.*
|
|
24
|
+
!.env.example
|
|
25
|
+
!.env.ci
|
|
26
|
+
|
|
27
|
+
# Generated files
|
|
28
|
+
/src/generated/prisma
|
|
29
|
+
prisma/migrations
|
|
30
|
+
|
|
31
|
+
# System files
|
|
32
|
+
.DS_Store
|
|
33
|
+
|
|
34
|
+
# Cache files
|
|
35
|
+
.cache
|
|
36
|
+
.eslintcache
|
|
37
|
+
*.tsbuildinfo
|
|
38
|
+
|
|
39
|
+
# IDE
|
|
40
|
+
.idea
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## 📌 What’s changing?
|
|
2
|
+
|
|
3
|
+
<!-- Briefly explain what this PR does -->
|
|
4
|
+
|
|
5
|
+
## ✅ Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] I tested this change locally
|
|
8
|
+
- [ ] I updated related docs (if needed)
|
|
9
|
+
- [ ] This PR is rebased on the latest base branch
|
|
10
|
+
- [ ] This PR is ready to squash & merge
|
|
11
|
+
|
|
12
|
+
## 🚀 Deployment notes
|
|
13
|
+
|
|
14
|
+
<!-- Optional: Add notes if anything special is needed during deploy -->
|
|
15
|
+
|
|
16
|
+
## 🎯 Related Issues or Cards
|
|
17
|
+
|
|
18
|
+
Closes #
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: PR Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- dev
|
|
7
|
+
- test
|
|
8
|
+
- prod
|
|
9
|
+
|
|
10
|
+
push:
|
|
11
|
+
branches:
|
|
12
|
+
- dev
|
|
13
|
+
- test
|
|
14
|
+
- prod
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
lint-and-build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
env:
|
|
20
|
+
NODE_ENV: development
|
|
21
|
+
PORT: "8080"
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Use Bun
|
|
28
|
+
uses: oven-sh/setup-bun@v1
|
|
29
|
+
with:
|
|
30
|
+
bun-version: latest
|
|
31
|
+
|
|
32
|
+
- name: Enable Corepack & Install
|
|
33
|
+
run: |
|
|
34
|
+
corepack enable
|
|
35
|
+
bun install --frozen-lockfile
|
|
36
|
+
|
|
37
|
+
- name: Check Formatting
|
|
38
|
+
run: bunx biome check --write
|
|
39
|
+
|
|
40
|
+
- name: Lint Code
|
|
41
|
+
run: bunx biome lint --write
|
|
42
|
+
|
|
43
|
+
- name: Formatting Code
|
|
44
|
+
run: bunx biome format --write
|
|
45
|
+
|
|
46
|
+
test:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
needs: lint-and-build
|
|
49
|
+
env:
|
|
50
|
+
NODE_ENV: development
|
|
51
|
+
PORT: "8080"
|
|
52
|
+
DATABASE_URL: "postgresql://postgres:password@localhost:5432/mydb?schema=public"
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- name: Checkout
|
|
56
|
+
uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Use Bun
|
|
59
|
+
uses: oven-sh/setup-bun@v1
|
|
60
|
+
with:
|
|
61
|
+
bun-version: latest
|
|
62
|
+
|
|
63
|
+
- name: Install Dependencies
|
|
64
|
+
run: bun install --frozen-lockfile
|
|
65
|
+
|
|
66
|
+
- name: Prisma Generate
|
|
67
|
+
run: bunx prisma generate
|
|
68
|
+
|
|
69
|
+
- name: Start Server in Background
|
|
70
|
+
run: |
|
|
71
|
+
# start the server in background and redirect logs to server.log
|
|
72
|
+
nohup bun start > server.log 2>&1 &
|
|
73
|
+
|
|
74
|
+
# Print a quick message and show the last few lines to help debugging
|
|
75
|
+
echo "Server started in background (check server.log)."
|
|
76
|
+
sleep 1
|
|
77
|
+
tail -n 20 server.log || true
|
|
78
|
+
|
|
79
|
+
- name: Wait for service to become healthy
|
|
80
|
+
run: |
|
|
81
|
+
set -euo pipefail
|
|
82
|
+
URL="http://localhost:${PORT:-8080}/api/v1/health"
|
|
83
|
+
ATTEMPTS=30
|
|
84
|
+
SLEEP_SECS=2
|
|
85
|
+
|
|
86
|
+
echo "Waiting for service to become healthy at: $URL"
|
|
87
|
+
i=0
|
|
88
|
+
until [ $i -ge $ATTEMPTS ]; do
|
|
89
|
+
if curl -fsS "$URL" >/dev/null 2>&1; then
|
|
90
|
+
echo "Service is healthy."
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
i=$((i+1))
|
|
94
|
+
echo "Waiting... ($i/$ATTEMPTS)"
|
|
95
|
+
sleep "$SLEEP_SECS"
|
|
96
|
+
done
|
|
97
|
+
|
|
98
|
+
echo "Service did not become healthy after $ATTEMPTS attempts."
|
|
99
|
+
echo "====== Last 200 lines of server.log ======"
|
|
100
|
+
tail -n 200 server.log || true
|
|
101
|
+
echo "=========================================="
|
|
102
|
+
exit 1
|
|
103
|
+
|
|
104
|
+
- name: Call Health Check API (final verify)
|
|
105
|
+
run: |
|
|
106
|
+
echo "Final health-check..."
|
|
107
|
+
curl -f http://localhost:${PORT}/api/v1/health
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Backend Starter Template
|
|
2
|
+
|
|
3
|
+
Production-ready backend using Bun, Express, Prisma, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- Bun runtime for fast performance
|
|
7
|
+
- Express.js for routing and middleware
|
|
8
|
+
- Prisma ORM for PostgreSQL
|
|
9
|
+
- Zod for validation
|
|
10
|
+
- Swagger UI for API docs
|
|
11
|
+
- Winston for logging
|
|
12
|
+
- Helmet, CORS, cookie-parser, JWT, and more for security
|
|
13
|
+
- Ready-to-use project structure
|
|
14
|
+
- Biome for formatting and linting
|
|
15
|
+
|
|
16
|
+
## Getting Started
|
|
17
|
+
|
|
18
|
+
### 1. Create a new project
|
|
19
|
+
```sh
|
|
20
|
+
bunx backend-starter <your-project-name>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Install dependencies
|
|
24
|
+
```sh
|
|
25
|
+
cd <your-project-name>
|
|
26
|
+
# Use your chosen package manager
|
|
27
|
+
bun install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. Configure environment variables
|
|
31
|
+
Edit `.env` with your database credentials and other settings.
|
|
32
|
+
|
|
33
|
+
### 4. Run the development server
|
|
34
|
+
```sh
|
|
35
|
+
bun run dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 5. Access API documentation
|
|
39
|
+
Visit `http://localhost:8080/api/v1/docs` for Swagger UI.
|
|
40
|
+
|
|
41
|
+
## Scripts
|
|
42
|
+
- `dev`: Start server with hot reload
|
|
43
|
+
- `start`: Start server
|
|
44
|
+
- `biome:*`: Format, lint, check, clean code
|
|
45
|
+
- `prisma:*`: Prisma ORM commands
|
|
46
|
+
|
|
47
|
+
## Project Structure
|
|
48
|
+
```
|
|
49
|
+
├── src/
|
|
50
|
+
│ ├── app.js
|
|
51
|
+
│ ├── index.js
|
|
52
|
+
│ ├── config/
|
|
53
|
+
│ ├── constants/
|
|
54
|
+
│ ├── core/
|
|
55
|
+
│ ├── routes/
|
|
56
|
+
├── prisma/
|
|
57
|
+
│ └── schema.prisma
|
|
58
|
+
├── .env
|
|
59
|
+
├── package.json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
MIT
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
Made by Harshit Ostwal
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": false
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false
|
|
10
|
+
},
|
|
11
|
+
"formatter": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"formatWithErrors": false,
|
|
14
|
+
"indentStyle": "space",
|
|
15
|
+
"indentWidth": 4,
|
|
16
|
+
"lineEnding": "lf",
|
|
17
|
+
"lineWidth": 80,
|
|
18
|
+
"attributePosition": "auto",
|
|
19
|
+
"bracketSameLine": false,
|
|
20
|
+
"bracketSpacing": true,
|
|
21
|
+
"expand": "auto",
|
|
22
|
+
"useEditorconfig": true
|
|
23
|
+
},
|
|
24
|
+
"linter": {
|
|
25
|
+
"enabled": true,
|
|
26
|
+
"rules": {
|
|
27
|
+
"recommended": false,
|
|
28
|
+
"correctness": {
|
|
29
|
+
"noUnusedVariables": "warn"
|
|
30
|
+
},
|
|
31
|
+
"suspicious": {
|
|
32
|
+
"noConsole": "warn"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"includes": ["**/*.{js,cjs,mjs}"]
|
|
36
|
+
},
|
|
37
|
+
"javascript": {
|
|
38
|
+
"formatter": {
|
|
39
|
+
"jsxQuoteStyle": "double",
|
|
40
|
+
"quoteProperties": "asNeeded",
|
|
41
|
+
"trailingCommas": "es5",
|
|
42
|
+
"semicolons": "always",
|
|
43
|
+
"arrowParentheses": "always",
|
|
44
|
+
"bracketSameLine": false,
|
|
45
|
+
"quoteStyle": "double",
|
|
46
|
+
"attributePosition": "auto",
|
|
47
|
+
"bracketSpacing": true
|
|
48
|
+
},
|
|
49
|
+
"globals": ["exports"]
|
|
50
|
+
},
|
|
51
|
+
"html": {
|
|
52
|
+
"formatter": {
|
|
53
|
+
"indentScriptAndStyle": false,
|
|
54
|
+
"selfCloseVoidElements": "always"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"assist": {
|
|
58
|
+
"enabled": true,
|
|
59
|
+
"actions": {
|
|
60
|
+
"source": {
|
|
61
|
+
"organizeImports": "on"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|