frontend-hamroun 1.2.15 → 1.2.17
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 -0
- package/bin/cli.js +673 -0
- package/dist/component.d.ts +1 -1
- package/dist/context.d.ts +4 -3
- package/dist/index.client.d.ts +11 -0
- package/dist/index.d.ts +9 -89
- package/dist/index.js +396 -67
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +392 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +0 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/renderer.d.ts +0 -10
- package/dist/server-renderer.d.ts +0 -3
- package/dist/server-types.d.ts +42 -0
- package/package.json +69 -50
- package/templates/basic-app/index.html +6 -6
- package/templates/basic-app/package.json +15 -11
- package/templates/basic-app/postcss.config.js +0 -1
- package/templates/basic-app/src/main.tsx +1 -10
- package/templates/basic-app/tailwind.config.js +2 -23
- package/templates/basic-app/tsconfig.json +4 -17
- package/templates/basic-app/vite.config.ts +3 -54
- package/templates/fullstack-app/api/hello.ts +18 -0
- package/templates/fullstack-app/api/users/[id].ts +73 -0
- package/templates/fullstack-app/api/users/index.ts +32 -0
- package/templates/fullstack-app/package.json +31 -0
- package/templates/fullstack-app/server.ts +46 -0
- package/templates/fullstack-app/src/pages/index.tsx +59 -0
- package/templates/ssr-template/vite.config.ts +1 -11
- package/bin/cli.cjs +0 -16
- package/bin/cli.mjs +0 -237
- package/dist/backend/api-utils.d.ts +0 -38
- package/dist/backend/api-utils.js +0 -135
- package/dist/backend/auth.d.ts +0 -134
- package/dist/backend/auth.js +0 -387
- package/dist/backend/database.d.ts +0 -27
- package/dist/backend/database.js +0 -91
- package/dist/backend/model.d.ts +0 -43
- package/dist/backend/model.js +0 -178
- package/dist/backend/router.d.ts +0 -27
- package/dist/backend/router.js +0 -137
- package/dist/backend/server.d.ts +0 -19
- package/dist/backend/server.js +0 -268
- package/dist/backend/types.d.ts +0 -217
- package/dist/backend/types.js +0 -1
- package/dist/batch.js +0 -22
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -215
- package/dist/component.js +0 -84
- package/dist/components/Counter.js +0 -2
- package/dist/context.js +0 -18
- package/dist/frontend-hamroun.es.js +0 -1378
- package/dist/frontend-hamroun.umd.js +0 -66
- package/dist/hooks.js +0 -164
- package/dist/jsx-runtime/index.d.ts +0 -11
- package/dist/jsx-runtime/index.js +0 -19
- package/dist/jsx-runtime/jsx-dev-runtime.js +0 -1
- package/dist/jsx-runtime/jsx-runtime.js +0 -95
- package/dist/jsx-runtime.js +0 -192
- package/dist/renderer.js +0 -51
- package/dist/server-renderer.js +0 -102
- package/dist/types.js +0 -1
- package/dist/vdom.js +0 -27
- package/scripts/build-cli.js +0 -1107
- package/scripts/generate.js +0 -134
- package/src/backend/api-utils.ts +0 -178
- package/src/backend/auth.ts +0 -544
- package/src/backend/database.ts +0 -104
- package/src/backend/model.ts +0 -198
- package/src/backend/router.ts +0 -176
- package/src/backend/server.ts +0 -330
- package/src/backend/types.ts +0 -257
- package/src/batch.ts +0 -24
- package/src/cli/index.js +0 -554
- package/src/cli/index.ts +0 -257
- package/src/component.ts +0 -98
- package/src/components/Counter.tsx +0 -4
- package/src/context.ts +0 -29
- package/src/hooks.ts +0 -211
- package/src/index.ts +0 -144
- package/src/jsx-runtime/index.ts +0 -27
- package/src/jsx-runtime/jsx-dev-runtime.ts +0 -0
- package/src/jsx-runtime/jsx-runtime.ts +0 -104
- package/src/jsx-runtime.ts +0 -226
- package/src/renderer.ts +0 -55
- package/src/server-renderer.ts +0 -114
- package/src/shims.d.ts +0 -20
- package/src/types/bcrypt.d.ts +0 -30
- package/src/types/jsonwebtoken.d.ts +0 -55
- package/src/types.d.ts +0 -26
- package/src/types.ts +0 -21
- package/src/vdom.ts +0 -34
- package/templates/basic/.eslintignore +0 -5
- package/templates/basic/.eslintrc.json +0 -25
- package/templates/basic/docs/rapport_pfe.aux +0 -27
- package/templates/basic/docs/rapport_pfe.log +0 -399
- package/templates/basic/docs/rapport_pfe.out +0 -10
- package/templates/basic/docs/rapport_pfe.pdf +0 -0
- package/templates/basic/docs/rapport_pfe.tex +0 -68
- package/templates/basic/docs/rapport_pfe.toc +0 -14
- package/templates/basic/index.html +0 -12
- package/templates/basic/jsconfig.json +0 -14
- package/templates/basic/package.json +0 -20
- package/templates/basic/postcss.config.js +0 -7
- package/templates/basic/src/App.js +0 -105
- package/templates/basic/src/App.tsx +0 -65
- package/templates/basic/src/api.ts +0 -58
- package/templates/basic/src/components/Counter.tsx +0 -26
- package/templates/basic/src/components/Header.tsx +0 -9
- package/templates/basic/src/components/TodoList.tsx +0 -90
- package/templates/basic/src/main.css +0 -3
- package/templates/basic/src/main.js +0 -11
- package/templates/basic/src/main.ts +0 -20
- package/templates/basic/src/main.tsx +0 -144
- package/templates/basic/src/server.ts +0 -99
- package/templates/basic/tailwind.config.js +0 -32
- package/templates/basic/tsconfig.json +0 -20
- package/templates/basic/tsconfig.node.json +0 -10
- package/templates/basic/vite.config.js +0 -18
- package/templates/basic/vite.config.ts +0 -86
- package/templates/basic-app/src/App.js +0 -105
- package/templates/basic-app/src/App.tsx +0 -143
- package/templates/basic-app/src/api.ts +0 -58
- package/templates/basic-app/src/components/Counter.tsx +0 -26
- package/templates/basic-app/src/components/Header.tsx +0 -9
- package/templates/basic-app/src/components/TodoList.tsx +0 -90
- package/templates/basic-app/src/main.js +0 -10
- package/templates/basic-app/src/main.ts +0 -21
- package/templates/basic-app/src/react/index.ts +0 -35
- package/templates/basic-app/src/react/jsx-dev-runtime.ts +0 -13
- package/templates/basic-app/src/react/jsx-runtime.ts +0 -12
- package/templates/basic-app/src/server.ts +0 -99
- package/templates/basic-app/src/shims.ts +0 -9
- package/templates/basic-app/tsconfig.node.json +0 -10
- package/templates/basic-app/vite.config.js +0 -22
- package/templates/full-stack/.env.example +0 -11
- package/templates/full-stack/README.md +0 -51
- package/templates/full-stack/index.html +0 -12
- package/templates/full-stack/jsconfig.json +0 -14
- package/templates/full-stack/package.json +0 -20
- package/templates/full-stack/src/App.js +0 -105
- package/templates/full-stack/src/client/App.tsx +0 -50
- package/templates/full-stack/src/client/components/Header.tsx +0 -42
- package/templates/full-stack/src/client/components/UserList.tsx +0 -29
- package/templates/full-stack/src/client/main.tsx +0 -5
- package/templates/full-stack/src/main.css +0 -3
- package/templates/full-stack/src/main.js +0 -11
- package/templates/full-stack/src/main.ts +0 -20
- package/templates/full-stack/src/server/index.ts +0 -99
- package/templates/full-stack/src/server/routes/auth.ts +0 -39
- package/templates/full-stack/src/server/routes/users.ts +0 -48
- package/templates/full-stack/src/shims.ts +0 -9
- package/templates/full-stack/tsconfig.json +0 -20
- package/templates/full-stack/tsconfig.node.json +0 -10
- package/templates/full-stack/tsconfig.server.json +0 -15
- package/templates/full-stack/vite.config.js +0 -18
- package/templates/full-stack/vite.config.ts +0 -85
package/bin/cli.mjs
DELETED
@@ -1,237 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
import fs from 'fs';
|
4
|
-
import path from 'path';
|
5
|
-
import { fileURLToPath } from 'url';
|
6
|
-
import { execSync } from 'child_process';
|
7
|
-
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
9
|
-
const __dirname = path.dirname(__filename);
|
10
|
-
|
11
|
-
// Templates available
|
12
|
-
const TEMPLATES = {
|
13
|
-
'basic': 'Basic frontend only template',
|
14
|
-
'full-stack': 'Complete frontend and backend template'
|
15
|
-
};
|
16
|
-
|
17
|
-
// Colors for CLI output
|
18
|
-
const colors = {
|
19
|
-
reset: '\x1b[0m',
|
20
|
-
bright: '\x1b[1m',
|
21
|
-
green: '\x1b[32m',
|
22
|
-
blue: '\x1b[34m',
|
23
|
-
red: '\x1b[31m',
|
24
|
-
yellow: '\x1b[33m'
|
25
|
-
};
|
26
|
-
|
27
|
-
// Get package.json to read version
|
28
|
-
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
29
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
30
|
-
|
31
|
-
// Print banner
|
32
|
-
function printBanner() {
|
33
|
-
console.log(`
|
34
|
-
${colors.blue}${colors.bright}╔══════════════════════════════════════════════╗
|
35
|
-
║ ║
|
36
|
-
║ Frontend Hamroun v${packageJson.version.padEnd(25)}║
|
37
|
-
║ A lightweight frontend & backend framework ║
|
38
|
-
║ ║
|
39
|
-
╚══════════════════════════════════════════════╝${colors.reset}
|
40
|
-
`);
|
41
|
-
}
|
42
|
-
|
43
|
-
// Print help
|
44
|
-
function printHelp() {
|
45
|
-
console.log(`
|
46
|
-
${colors.bright}USAGE:${colors.reset}
|
47
|
-
${colors.blue}npx frontend-hamroun${colors.reset} [command] [options]
|
48
|
-
|
49
|
-
${colors.bright}COMMANDS:${colors.reset}
|
50
|
-
${colors.blue}create${colors.reset} <project-name> [options] Create a new project
|
51
|
-
${colors.blue}help${colors.reset} Display this help message
|
52
|
-
${colors.blue}version${colors.reset} Display version information
|
53
|
-
|
54
|
-
${colors.bright}OPTIONS:${colors.reset}
|
55
|
-
${colors.blue}--template${colors.reset}, ${colors.blue}-t${colors.reset} <template> Specify template (default: basic)
|
56
|
-
${colors.blue}--skip-install${colors.reset}, ${colors.blue}-s${colors.reset} Skip package installation
|
57
|
-
|
58
|
-
${colors.bright}AVAILABLE TEMPLATES:${colors.reset}
|
59
|
-
${Object.entries(TEMPLATES).map(([name, desc]) => ` ${colors.blue}${name.padEnd(12)}${colors.reset} ${desc}`).join('\n')}
|
60
|
-
|
61
|
-
${colors.bright}EXAMPLES:${colors.reset}
|
62
|
-
${colors.blue}npx frontend-hamroun create${colors.reset} my-app
|
63
|
-
${colors.blue}npx frontend-hamroun create${colors.reset} my-app --template full-stack
|
64
|
-
`);
|
65
|
-
}
|
66
|
-
|
67
|
-
// Create project from template
|
68
|
-
function createProject(projectName, options) {
|
69
|
-
const template = options.template || 'basic';
|
70
|
-
|
71
|
-
// Check if template exists
|
72
|
-
if (!Object.keys(TEMPLATES).includes(template)) {
|
73
|
-
console.error(`${colors.red}error:${colors.reset} Template "${template}" not found.`);
|
74
|
-
console.log(`Available templates: ${Object.keys(TEMPLATES).join(', ')}`);
|
75
|
-
process.exit(1);
|
76
|
-
}
|
77
|
-
|
78
|
-
// Check if project directory already exists
|
79
|
-
const projectPath = path.resolve(process.cwd(), projectName);
|
80
|
-
if (fs.existsSync(projectPath)) {
|
81
|
-
console.error(`${colors.red}error:${colors.reset} Directory ${projectName} already exists.`);
|
82
|
-
process.exit(1);
|
83
|
-
}
|
84
|
-
|
85
|
-
console.log(`
|
86
|
-
${colors.bright}Creating a new project with Frontend Hamroun...${colors.reset}
|
87
|
-
${colors.blue}• Project name:${colors.reset} ${projectName}
|
88
|
-
${colors.blue}• Template:${colors.reset} ${template}
|
89
|
-
${colors.blue}• Directory:${colors.reset} ${projectPath}
|
90
|
-
`);
|
91
|
-
|
92
|
-
try {
|
93
|
-
// Find templates directory
|
94
|
-
const templateDir = path.resolve(__dirname, '../templates', template);
|
95
|
-
|
96
|
-
if (!fs.existsSync(templateDir)) {
|
97
|
-
console.error(`${colors.red}error:${colors.reset} Template directory not found: ${templateDir}`);
|
98
|
-
// Try to find template with -app suffix as fallback
|
99
|
-
const fallbackTemplateDir = path.resolve(__dirname, '../templates', `${template}-app`);
|
100
|
-
if (fs.existsSync(fallbackTemplateDir)) {
|
101
|
-
console.log(`${colors.yellow}Using fallback template:${colors.reset} ${template}-app`);
|
102
|
-
templateDir = fallbackTemplateDir;
|
103
|
-
} else {
|
104
|
-
process.exit(1);
|
105
|
-
}
|
106
|
-
}
|
107
|
-
|
108
|
-
// Create project directory
|
109
|
-
fs.mkdirSync(projectPath, { recursive: true });
|
110
|
-
|
111
|
-
// Copy template files (recursive function)
|
112
|
-
function copyDir(src, dest) {
|
113
|
-
const entries = fs.readdirSync(src, { withFileTypes: true });
|
114
|
-
|
115
|
-
for (const entry of entries) {
|
116
|
-
const srcPath = path.join(src, entry.name);
|
117
|
-
const destPath = path.join(dest, entry.name);
|
118
|
-
|
119
|
-
if (entry.isDirectory()) {
|
120
|
-
fs.mkdirSync(destPath, { recursive: true });
|
121
|
-
copyDir(srcPath, destPath);
|
122
|
-
} else {
|
123
|
-
fs.copyFileSync(srcPath, destPath);
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
127
|
-
|
128
|
-
// Copy the files
|
129
|
-
copyDir(templateDir, projectPath);
|
130
|
-
console.log(`${colors.green}•${colors.reset} Copied template files`);
|
131
|
-
|
132
|
-
// Update package.json with project name
|
133
|
-
const projectPackageJsonPath = path.join(projectPath, 'package.json');
|
134
|
-
if (fs.existsSync(projectPackageJsonPath)) {
|
135
|
-
const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, 'utf8'));
|
136
|
-
projectPackageJson.name = projectName;
|
137
|
-
fs.writeFileSync(
|
138
|
-
projectPackageJsonPath,
|
139
|
-
JSON.stringify(projectPackageJson, null, 2)
|
140
|
-
);
|
141
|
-
}
|
142
|
-
|
143
|
-
// Install dependencies
|
144
|
-
if (!options.skipInstall) {
|
145
|
-
console.log(`\n${colors.blue}Installing dependencies...${colors.reset}`);
|
146
|
-
|
147
|
-
try {
|
148
|
-
execSync(`npm install`, {
|
149
|
-
cwd: projectPath,
|
150
|
-
stdio: 'inherit'
|
151
|
-
});
|
152
|
-
} catch (error) {
|
153
|
-
console.error(`\n${colors.red}Failed to install dependencies. You can install them manually:${colors.reset}`);
|
154
|
-
console.log(` cd ${projectName} && npm install`);
|
155
|
-
}
|
156
|
-
}
|
157
|
-
|
158
|
-
// Success message
|
159
|
-
console.log(`
|
160
|
-
${colors.green}${colors.bright}Success!${colors.reset} Created ${projectName} at ${projectPath}
|
161
|
-
|
162
|
-
${colors.blue}Inside that directory, you can run several commands:${colors.reset}
|
163
|
-
|
164
|
-
${colors.bright}npm run dev${colors.reset}
|
165
|
-
Starts the development server.
|
166
|
-
|
167
|
-
${colors.bright}npm run build${colors.reset}
|
168
|
-
Builds the app for production.
|
169
|
-
|
170
|
-
${colors.bright}npm start${colors.reset}
|
171
|
-
Runs the built app in production mode.
|
172
|
-
|
173
|
-
${colors.blue}We suggest that you begin by typing:${colors.reset}
|
174
|
-
|
175
|
-
${colors.bright}cd${colors.reset} ${projectName}
|
176
|
-
${colors.bright}npm run dev${colors.reset}
|
177
|
-
|
178
|
-
${colors.green}Happy coding!${colors.reset}
|
179
|
-
`);
|
180
|
-
|
181
|
-
} catch (error) {
|
182
|
-
console.error(`${colors.red}Failed to create project:${colors.reset}`, error);
|
183
|
-
process.exit(1);
|
184
|
-
}
|
185
|
-
}
|
186
|
-
|
187
|
-
// Parse command line arguments
|
188
|
-
function parseArgs() {
|
189
|
-
const args = process.argv.slice(2);
|
190
|
-
const command = args[0];
|
191
|
-
|
192
|
-
if (!command || command === 'help') {
|
193
|
-
printBanner();
|
194
|
-
printHelp();
|
195
|
-
process.exit(0);
|
196
|
-
}
|
197
|
-
|
198
|
-
if (command === 'version') {
|
199
|
-
console.log(`frontend-hamroun v${packageJson.version}`);
|
200
|
-
process.exit(0);
|
201
|
-
}
|
202
|
-
|
203
|
-
if (command === 'create') {
|
204
|
-
const projectName = args[1];
|
205
|
-
|
206
|
-
if (!projectName) {
|
207
|
-
console.error(`${colors.red}error:${colors.reset} Project name is required.`);
|
208
|
-
console.log(`Run ${colors.blue}npx frontend-hamroun help${colors.reset} for usage information.`);
|
209
|
-
process.exit(1);
|
210
|
-
}
|
211
|
-
|
212
|
-
// Parse options
|
213
|
-
const options = {
|
214
|
-
template: 'basic',
|
215
|
-
skipInstall: false
|
216
|
-
};
|
217
|
-
|
218
|
-
for (let i = 2; i < args.length; i++) {
|
219
|
-
if (args[i] === '--template' || args[i] === '-t') {
|
220
|
-
options.template = args[++i];
|
221
|
-
} else if (args[i] === '--skip-install' || args[i] === '-s') {
|
222
|
-
options.skipInstall = true;
|
223
|
-
}
|
224
|
-
}
|
225
|
-
|
226
|
-
printBanner();
|
227
|
-
createProject(projectName, options);
|
228
|
-
return;
|
229
|
-
}
|
230
|
-
|
231
|
-
console.error(`${colors.red}error:${colors.reset} Unknown command: ${command}`);
|
232
|
-
console.log(`Run ${colors.blue}npx frontend-hamroun help${colors.reset} for usage information.`);
|
233
|
-
process.exit(1);
|
234
|
-
}
|
235
|
-
|
236
|
-
// Run CLI
|
237
|
-
parseArgs();
|
@@ -1,38 +0,0 @@
|
|
1
|
-
import { Request, Response, NextFunction, Router } from 'express';
|
2
|
-
import { ApiResponse, PaginationOptions, RouterOptions } from './types';
|
3
|
-
/**
|
4
|
-
* Creates a consistent API response structure
|
5
|
-
*/
|
6
|
-
export declare function apiResponse<T>(success: boolean, data?: T, message?: string, error?: string, meta?: Record<string, any>): ApiResponse<T>;
|
7
|
-
/**
|
8
|
-
* Helper to send successful responses
|
9
|
-
*/
|
10
|
-
export declare function sendSuccess<T>(res: Response, data?: T, message?: string, statusCode?: number, meta?: Record<string, any>): void;
|
11
|
-
/**
|
12
|
-
* Helper to send error responses
|
13
|
-
*/
|
14
|
-
export declare function sendError(res: Response, error: string | Error, statusCode?: number, meta?: Record<string, any>): void;
|
15
|
-
/**
|
16
|
-
* Helper to extract pagination parameters from request
|
17
|
-
*/
|
18
|
-
export declare function getPaginationParams(req: Request): PaginationOptions;
|
19
|
-
/**
|
20
|
-
* Middleware to extract and validate pagination parameters
|
21
|
-
*/
|
22
|
-
export declare function paginationMiddleware(req: Request, res: Response, next: NextFunction): void;
|
23
|
-
/**
|
24
|
-
* Middleware for basic request validation
|
25
|
-
*/
|
26
|
-
export declare function validateRequest(schema: any): (req: Request, res: Response, next: NextFunction) => void;
|
27
|
-
/**
|
28
|
-
* Create a new router with common middleware and options
|
29
|
-
*/
|
30
|
-
export declare function createApiRouter(options?: RouterOptions, auth?: any): Router;
|
31
|
-
/**
|
32
|
-
* Wrap an async route handler to catch errors
|
33
|
-
*/
|
34
|
-
export declare function asyncHandler(fn: (req: Request, res: Response, next: NextFunction) => Promise<any>): (req: Request, res: Response, next: NextFunction) => void;
|
35
|
-
/**
|
36
|
-
* Create standard REST endpoints for a model
|
37
|
-
*/
|
38
|
-
export declare function createRestEndpoints<T>(model: any): import("express-serve-static-core").Router;
|
@@ -1,135 +0,0 @@
|
|
1
|
-
import { Router } from 'express';
|
2
|
-
/**
|
3
|
-
* Creates a consistent API response structure
|
4
|
-
*/
|
5
|
-
export function apiResponse(success, data, message, error, meta) {
|
6
|
-
const response = { success };
|
7
|
-
if (data !== undefined)
|
8
|
-
response.data = data;
|
9
|
-
if (message)
|
10
|
-
response.message = message;
|
11
|
-
if (error)
|
12
|
-
response.error = error;
|
13
|
-
if (meta)
|
14
|
-
response.meta = meta;
|
15
|
-
return response;
|
16
|
-
}
|
17
|
-
/**
|
18
|
-
* Helper to send successful responses
|
19
|
-
*/
|
20
|
-
export function sendSuccess(res, data, message, statusCode = 200, meta) {
|
21
|
-
res.status(statusCode).json(apiResponse(true, data, message, undefined, meta));
|
22
|
-
}
|
23
|
-
/**
|
24
|
-
* Helper to send error responses
|
25
|
-
*/
|
26
|
-
export function sendError(res, error, statusCode = 400, meta) {
|
27
|
-
const errorMessage = error instanceof Error ? error.message : error;
|
28
|
-
res.status(statusCode).json(apiResponse(false, undefined, undefined, errorMessage, meta));
|
29
|
-
}
|
30
|
-
/**
|
31
|
-
* Helper to extract pagination parameters from request
|
32
|
-
*/
|
33
|
-
export function getPaginationParams(req) {
|
34
|
-
const page = parseInt(req.query.page) || 1;
|
35
|
-
const limit = parseInt(req.query.limit) || 10;
|
36
|
-
const sort = req.query.sort || 'createdAt';
|
37
|
-
const order = req.query.order === 'asc' ? 'asc' : 'desc';
|
38
|
-
return { page, limit, sort, order };
|
39
|
-
}
|
40
|
-
/**
|
41
|
-
* Middleware to extract and validate pagination parameters
|
42
|
-
*/
|
43
|
-
export function paginationMiddleware(req, res, next) {
|
44
|
-
req.pagination = getPaginationParams(req);
|
45
|
-
next();
|
46
|
-
}
|
47
|
-
/**
|
48
|
-
* Middleware for basic request validation
|
49
|
-
*/
|
50
|
-
export function validateRequest(schema) {
|
51
|
-
return (req, res, next) => {
|
52
|
-
try {
|
53
|
-
const { error, value } = schema.validate(req.body);
|
54
|
-
if (error) {
|
55
|
-
sendError(res, `Validation error: ${error.message}`, 400);
|
56
|
-
return;
|
57
|
-
}
|
58
|
-
// Replace request body with validated value
|
59
|
-
req.body = value;
|
60
|
-
next();
|
61
|
-
}
|
62
|
-
catch (err) {
|
63
|
-
sendError(res, 'Validation error', 400);
|
64
|
-
}
|
65
|
-
};
|
66
|
-
}
|
67
|
-
/**
|
68
|
-
* Create a new router with common middleware and options
|
69
|
-
*/
|
70
|
-
export function createApiRouter(options = {}, auth) {
|
71
|
-
const router = Router();
|
72
|
-
// Add authentication middleware if required
|
73
|
-
if (options.requireAuth && auth) {
|
74
|
-
router.use(auth.authenticate);
|
75
|
-
// Add role check if specified
|
76
|
-
if (options.requiredRole) {
|
77
|
-
router.use(auth.hasRole(options.requiredRole));
|
78
|
-
}
|
79
|
-
}
|
80
|
-
// Add rate limiting if specified
|
81
|
-
if (options.rateLimit) {
|
82
|
-
console.warn('Rate limiting is disabled: express-rate-limit dependency is not installed');
|
83
|
-
// Note: To use rate limiting, install express-rate-limit: npm install express-rate-limit
|
84
|
-
}
|
85
|
-
return router;
|
86
|
-
}
|
87
|
-
/**
|
88
|
-
* Wrap an async route handler to catch errors
|
89
|
-
*/
|
90
|
-
export function asyncHandler(fn) {
|
91
|
-
return (req, res, next) => {
|
92
|
-
fn(req, res, next).catch(next);
|
93
|
-
};
|
94
|
-
}
|
95
|
-
/**
|
96
|
-
* Create standard REST endpoints for a model
|
97
|
-
*/
|
98
|
-
export function createRestEndpoints(model) {
|
99
|
-
const router = Router();
|
100
|
-
// GET all with pagination
|
101
|
-
router.get('/', paginationMiddleware, asyncHandler(async (req, res) => {
|
102
|
-
const result = await model.getAll(req.pagination);
|
103
|
-
sendSuccess(res, result);
|
104
|
-
}));
|
105
|
-
// GET by ID
|
106
|
-
router.get('/:id', asyncHandler(async (req, res) => {
|
107
|
-
const item = await model.getById(req.params.id);
|
108
|
-
if (!item) {
|
109
|
-
return sendError(res, 'Item not found', 404);
|
110
|
-
}
|
111
|
-
sendSuccess(res, item);
|
112
|
-
}));
|
113
|
-
// POST new item
|
114
|
-
router.post('/', asyncHandler(async (req, res) => {
|
115
|
-
const newItem = await model.create(req.body);
|
116
|
-
sendSuccess(res, newItem, 'Item created successfully', 201);
|
117
|
-
}));
|
118
|
-
// PUT update item
|
119
|
-
router.put('/:id', asyncHandler(async (req, res) => {
|
120
|
-
const updatedItem = await model.update(req.params.id, req.body);
|
121
|
-
if (!updatedItem) {
|
122
|
-
return sendError(res, 'Item not found', 404);
|
123
|
-
}
|
124
|
-
sendSuccess(res, updatedItem, 'Item updated successfully');
|
125
|
-
}));
|
126
|
-
// DELETE item
|
127
|
-
router.delete('/:id', asyncHandler(async (req, res) => {
|
128
|
-
const result = await model.delete(req.params.id);
|
129
|
-
if (!result) {
|
130
|
-
return sendError(res, 'Item not found', 404);
|
131
|
-
}
|
132
|
-
sendSuccess(res, null, 'Item deleted successfully');
|
133
|
-
}));
|
134
|
-
return router;
|
135
|
-
}
|
package/dist/backend/auth.d.ts
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
import { Request, Response, NextFunction } from 'express';
|
2
|
-
/**
|
3
|
-
* Authentication configuration options
|
4
|
-
*/
|
5
|
-
export interface AuthOptions {
|
6
|
-
/**
|
7
|
-
* Secret key for JWT signing
|
8
|
-
*/
|
9
|
-
jwtSecret: string;
|
10
|
-
/**
|
11
|
-
* Secret key for refresh token signing (defaults to jwtSecret if not provided)
|
12
|
-
*/
|
13
|
-
refreshSecret?: string;
|
14
|
-
/**
|
15
|
-
* JWT token expiration time (default: '15m')
|
16
|
-
*/
|
17
|
-
tokenExpiration?: string;
|
18
|
-
/**
|
19
|
-
* Refresh token expiration time (default: '7d')
|
20
|
-
*/
|
21
|
-
refreshExpiration?: string;
|
22
|
-
/**
|
23
|
-
* Number of bcrypt salt rounds (default: 10)
|
24
|
-
*/
|
25
|
-
saltRounds?: number;
|
26
|
-
/**
|
27
|
-
* Custom user finder function
|
28
|
-
*/
|
29
|
-
findUser?: (username: string) => Promise<any>;
|
30
|
-
/**
|
31
|
-
* Custom password verification (defaults to bcrypt compare)
|
32
|
-
*/
|
33
|
-
verifyPassword?: (password: string, hashedPassword: string) => Promise<boolean>;
|
34
|
-
/**
|
35
|
-
* Custom function to save refresh token
|
36
|
-
*/
|
37
|
-
saveRefreshToken?: (userId: string, token: string, expires: Date) => Promise<void>;
|
38
|
-
/**
|
39
|
-
* Custom function to verify refresh token
|
40
|
-
*/
|
41
|
-
verifyRefreshToken?: (userId: string, token: string) => Promise<boolean>;
|
42
|
-
/**
|
43
|
-
* Use secure cookies for tokens (default: process.env.NODE_ENV === 'production')
|
44
|
-
*/
|
45
|
-
secureCookies?: boolean;
|
46
|
-
/**
|
47
|
-
* Cookie domain
|
48
|
-
*/
|
49
|
-
cookieDomain?: string;
|
50
|
-
/**
|
51
|
-
* Use HTTP-only cookies (default: true)
|
52
|
-
*/
|
53
|
-
httpOnlyCookies?: boolean;
|
54
|
-
/**
|
55
|
-
* Implement rate limiting for login attempts (default: true)
|
56
|
-
*/
|
57
|
-
rateLimit?: boolean;
|
58
|
-
}
|
59
|
-
/**
|
60
|
-
* Token pair containing access and refresh tokens
|
61
|
-
*/
|
62
|
-
export interface TokenPair {
|
63
|
-
accessToken: string;
|
64
|
-
refreshToken: string;
|
65
|
-
expiresIn: number;
|
66
|
-
}
|
67
|
-
/**
|
68
|
-
* Authentication service
|
69
|
-
*/
|
70
|
-
export declare class Auth {
|
71
|
-
private options;
|
72
|
-
private loginAttempts;
|
73
|
-
constructor(options: AuthOptions);
|
74
|
-
/**
|
75
|
-
* Hash a password using bcrypt
|
76
|
-
*/
|
77
|
-
hashPassword(password: string): Promise<string>;
|
78
|
-
/**
|
79
|
-
* Verify a password against a hash using bcrypt
|
80
|
-
*/
|
81
|
-
private verifyPasswordWithBcrypt;
|
82
|
-
/**
|
83
|
-
* Generate a cryptographically secure random token
|
84
|
-
*/
|
85
|
-
generateSecureToken(length?: number): string;
|
86
|
-
/**
|
87
|
-
* Generate token pair (access token + refresh token)
|
88
|
-
*/
|
89
|
-
generateTokenPair(payload: any): TokenPair;
|
90
|
-
/**
|
91
|
-
* Convert JWT expiration time to seconds
|
92
|
-
*/
|
93
|
-
private getExpirationSeconds;
|
94
|
-
/**
|
95
|
-
* Verify a JWT token
|
96
|
-
*/
|
97
|
-
verifyToken(token: string, type?: 'access' | 'refresh'): any;
|
98
|
-
/**
|
99
|
-
* Set authentication cookies
|
100
|
-
*/
|
101
|
-
setAuthCookies(res: Response, tokens: TokenPair): void;
|
102
|
-
/**
|
103
|
-
* Clear authentication cookies
|
104
|
-
*/
|
105
|
-
clearAuthCookies(res: Response): void;
|
106
|
-
/**
|
107
|
-
* Check and handle rate limiting
|
108
|
-
*/
|
109
|
-
private checkRateLimit;
|
110
|
-
/**
|
111
|
-
* Login middleware to authenticate users
|
112
|
-
*/
|
113
|
-
login: (req: Request, res: Response) => Promise<void>;
|
114
|
-
/**
|
115
|
-
* Refresh token handler
|
116
|
-
*/
|
117
|
-
refreshToken: (req: Request, res: Response) => Promise<void>;
|
118
|
-
/**
|
119
|
-
* Logout handler
|
120
|
-
*/
|
121
|
-
logout: (req: Request, res: Response) => Promise<void>;
|
122
|
-
/**
|
123
|
-
* Middleware to verify user is authenticated
|
124
|
-
*/
|
125
|
-
authenticate: (req: Request, res: Response, next: NextFunction) => void;
|
126
|
-
/**
|
127
|
-
* Middleware to check if user has required role
|
128
|
-
*/
|
129
|
-
hasRole: (role: string | string[]) => (req: Request, res: Response, next: NextFunction) => void;
|
130
|
-
}
|
131
|
-
/**
|
132
|
-
* Create an authentication service
|
133
|
-
*/
|
134
|
-
export declare function createAuth(options: AuthOptions): Auth;
|