lieko-express 0.0.20 → 1.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/LICENSE +21 -0
- package/README.md +387 -1
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 eiwSrvt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1 +1,387 @@
|
|
|
1
|
-
|
|
1
|
+
# Lieko Express
|
|
2
|
+
|
|
3
|
+
A modern, minimal, Express-like framework for Node.js with built-in body parsing, CORS, validation, and more. Lieko-express is designed to be a drop-in replacement for Express.js with additional features and better performance.
|
|
4
|
+
|
|
5
|
+
Online documentation
|
|
6
|
+
[Lieko Express Documentation](https://express.lieko.app/)
|
|
7
|
+
|
|
8
|
+
## Key Features
|
|
9
|
+
|
|
10
|
+
- **Express-compatible API**: Familiar routing, middleware, and request/response handling.
|
|
11
|
+
- **Built-in Body Parsing**: JSON, URL-encoded, and multipart form-data support.
|
|
12
|
+
- **CORS Support**: Configurable cross-origin resource sharing with flexible options.
|
|
13
|
+
- **Schema Validation**: Built-in validation system with comprehensive validators.
|
|
14
|
+
- **Static File Serving**: Efficient static file middleware with caching and ETags.
|
|
15
|
+
- **Template Engine**: Simple HTML templating with support for custom engines.
|
|
16
|
+
- **Route Groups**: Organize routes with nested groups and shared middleware.
|
|
17
|
+
- **Debug Mode**: Detailed request logging with timing and payload information.
|
|
18
|
+
|
|
19
|
+
> **Note**: Lieko-express requires Node.js ≥14.0.0.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### NPM
|
|
24
|
+
```bash
|
|
25
|
+
npm install lieko-express
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Yarn
|
|
29
|
+
```bash
|
|
30
|
+
yarn add lieko-express
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
Create your first Lieko-express application:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const Lieko = require('lieko-express');
|
|
39
|
+
const app = Lieko();
|
|
40
|
+
|
|
41
|
+
app.get('/', (req, res) => {
|
|
42
|
+
res.json({ message: 'Hello World!' });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
app.listen(3000, () => {
|
|
46
|
+
console.log('Server running on http://localhost:3000');
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Basic REST API Example
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
const Lieko = require('lieko-express');
|
|
54
|
+
const app = Lieko();
|
|
55
|
+
|
|
56
|
+
// Enable debug mode
|
|
57
|
+
app.debug(true);
|
|
58
|
+
|
|
59
|
+
// Simple in-memory database
|
|
60
|
+
const users = [];
|
|
61
|
+
let idCounter = 1;
|
|
62
|
+
|
|
63
|
+
// Get all users
|
|
64
|
+
app.get('/api/users', (req, res) => {
|
|
65
|
+
res.json(users);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Get user by ID
|
|
69
|
+
app.get('/api/users/:id', (req, res) => {
|
|
70
|
+
const user = users.find(u => u.id === req.params.id);
|
|
71
|
+
|
|
72
|
+
if (!user) {
|
|
73
|
+
return res.status(404).json({
|
|
74
|
+
error: 'User not found'
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
res.json(user);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Create user
|
|
82
|
+
app.post('/api/users', (req, res) => {
|
|
83
|
+
const user = {
|
|
84
|
+
id: String(idCounter++),
|
|
85
|
+
name: req.body.name,
|
|
86
|
+
email: req.body.email,
|
|
87
|
+
createdAt: new Date().toISOString()
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
users.push(user);
|
|
91
|
+
res.status(201).json(user);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Update user
|
|
95
|
+
app.patch('/api/users/:id', (req, res) => {
|
|
96
|
+
const user = users.find(u => u.id === req.params.id);
|
|
97
|
+
|
|
98
|
+
if (!user) {
|
|
99
|
+
return res.status(404).json({
|
|
100
|
+
error: 'User not found'
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Object.assign(user, req.body);
|
|
105
|
+
res.json(user);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Delete user
|
|
109
|
+
app.delete('/api/users/:id', (req, res) => {
|
|
110
|
+
const index = users.findIndex(u => u.id === req.params.id);
|
|
111
|
+
|
|
112
|
+
if (index === -1) {
|
|
113
|
+
return res.status(404).json({
|
|
114
|
+
error: 'User not found'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
users.splice(index, 1);
|
|
119
|
+
res.status(204).end();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
app.listen(3000, () => {
|
|
123
|
+
console.log('API running on http://localhost:3000');
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Configuration
|
|
128
|
+
|
|
129
|
+
Customize Lieko-express with settings:
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
const app = Lieko();
|
|
133
|
+
|
|
134
|
+
// Enable/disable features
|
|
135
|
+
app.set('x-powered-by', 'MyApp');
|
|
136
|
+
app.set('trust proxy', true);
|
|
137
|
+
app.set('views', './templates');
|
|
138
|
+
app.set('view engine', 'html');
|
|
139
|
+
|
|
140
|
+
// Enable debug mode
|
|
141
|
+
app.debug(true);
|
|
142
|
+
|
|
143
|
+
// Disable strict trailing slash
|
|
144
|
+
app.set('strictTrailingSlash', false);
|
|
145
|
+
app.set('allowTrailingSlash', true);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Configuration Options
|
|
149
|
+
|
|
150
|
+
| Setting | Type | Default | Description |
|
|
151
|
+
|----------------------|---------------|---------------|---------------------------------|
|
|
152
|
+
| `debug` | boolean | false | Enable detailed request logging |
|
|
153
|
+
| `x-powered-by` | string\|boolean | 'lieko-express' | X-Powered-By header value |
|
|
154
|
+
| `trust proxy` | boolean | false | Trust X-Forwarded-* headers |
|
|
155
|
+
| `strictTrailingSlash` | boolean | true | Strict trailing slash matching |
|
|
156
|
+
| `allowTrailingSlash` | boolean | true | Allow optional trailing slash |
|
|
157
|
+
| `views` | string | './views' | Template directory path |
|
|
158
|
+
| `view engine` | string | 'html' | Default template engine |
|
|
159
|
+
|
|
160
|
+
## Routing
|
|
161
|
+
|
|
162
|
+
Define routes with flexible patterns:
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
// GET request
|
|
166
|
+
app.get('/users', (req, res) => {
|
|
167
|
+
res.json({ users: [] });
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// POST request
|
|
171
|
+
app.post('/users', (req, res) => {
|
|
172
|
+
res.status(201).json({ message: 'User created' });
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Route parameters
|
|
176
|
+
app.get('/users/:id', (req, res) => {
|
|
177
|
+
const userId = req.params.id;
|
|
178
|
+
res.json({ userId });
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Multiple handlers
|
|
182
|
+
app.get('/protected', authMiddleware, (req, res) => {
|
|
183
|
+
res.json({ message: 'Protected route' });
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Middleware
|
|
188
|
+
|
|
189
|
+
Middleware for request processing:
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
// Application-level
|
|
193
|
+
app.use((req, res, next) => {
|
|
194
|
+
console.log(`${req.method} ${req.url}`);
|
|
195
|
+
next();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Error handling
|
|
199
|
+
app.errorHandler((err, req, res, next) => {
|
|
200
|
+
console.error('Error:', err.message);
|
|
201
|
+
res.status(err.status || 500).json({
|
|
202
|
+
error: {
|
|
203
|
+
message: err.message,
|
|
204
|
+
code: err.code || 'SERVER_ERROR'
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Request Object
|
|
211
|
+
|
|
212
|
+
Properties and methods:
|
|
213
|
+
|
|
214
|
+
| Property | Type | Description |
|
|
215
|
+
|-------------------|---------|--------------------------------------|
|
|
216
|
+
| `req.body` | object | Parsed request body |
|
|
217
|
+
| `req.params` | object | Route parameters |
|
|
218
|
+
| `req.query` | object | Query string parameters |
|
|
219
|
+
| `req.files` | object | Uploaded files |
|
|
220
|
+
| `req.headers` | object | HTTP headers |
|
|
221
|
+
| `req.method` | string | HTTP method |
|
|
222
|
+
|
|
223
|
+
Methods like `req.get('Content-Type')`, `req.accepts(['json', 'html'])`.
|
|
224
|
+
|
|
225
|
+
## Response Object
|
|
226
|
+
|
|
227
|
+
Methods for sending responses:
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
// Send JSON
|
|
231
|
+
res.json({ message: 'Hello' });
|
|
232
|
+
|
|
233
|
+
// Status and helpers
|
|
234
|
+
res.status(201).json({ message: 'Created' });
|
|
235
|
+
res.ok({ data: users });
|
|
236
|
+
res.created({ user });
|
|
237
|
+
res.noContent();
|
|
238
|
+
res.badRequest('Invalid input');
|
|
239
|
+
res.redirect('/new-url');
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Body Parsing
|
|
243
|
+
|
|
244
|
+
Automatic parsing with limits:
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
app.bodyParser({
|
|
248
|
+
limit: '50mb',
|
|
249
|
+
extended: true,
|
|
250
|
+
strict: true
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## CORS
|
|
255
|
+
|
|
256
|
+
Configure CORS:
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
app.cors({
|
|
260
|
+
origin: '*',
|
|
261
|
+
methods: ['GET', 'POST'],
|
|
262
|
+
credentials: true
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Static Files
|
|
267
|
+
|
|
268
|
+
Serve static files:
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
app.use(app.static('public'));
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Template Engine
|
|
275
|
+
|
|
276
|
+
Render templates:
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
res.render('index', {
|
|
280
|
+
title: 'My Page',
|
|
281
|
+
user: { name: 'Alice' }
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Schema Validation
|
|
286
|
+
|
|
287
|
+
Validate requests:
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
const { Schema, validators: v, validate } = require('lieko-express');
|
|
291
|
+
|
|
292
|
+
const schema = new Schema({
|
|
293
|
+
name: [v.required(), v.string(), v.minLength(3)],
|
|
294
|
+
age: [v.optional(), v.number(), v.min(18)]
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
app.post('/users', validate(schema), (req, res) => {
|
|
298
|
+
res.created(req.body);
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Route Groups
|
|
303
|
+
|
|
304
|
+
Organize routes:
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
app.group('/api', (api) => {
|
|
308
|
+
api.get('/users', handler);
|
|
309
|
+
api.post('/users', handler);
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Error Handling
|
|
314
|
+
|
|
315
|
+
Custom handlers:
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
app.notFound((req, res) => {
|
|
319
|
+
res.notFound('Page not found');
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Cookies
|
|
324
|
+
|
|
325
|
+
Set and clear cookies:
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
res.cookie('session', 'abc123', {
|
|
329
|
+
maxAge: 86400000,
|
|
330
|
+
httpOnly: true,
|
|
331
|
+
secure: true
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
res.clearCookie('session');
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## File Uploads
|
|
338
|
+
|
|
339
|
+
Handle uploads:
|
|
340
|
+
|
|
341
|
+
```javascript
|
|
342
|
+
app.post('/upload', (req, res) => {
|
|
343
|
+
const file = req.files.avatar;
|
|
344
|
+
// Process file
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## API Methods Reference
|
|
349
|
+
|
|
350
|
+
See the full documentation for complete lists of application and response methods.
|
|
351
|
+
|
|
352
|
+
## Validators Reference
|
|
353
|
+
|
|
354
|
+
Built-in validators like `v.required()`, `v.email()`, `v.min(10)`.
|
|
355
|
+
|
|
356
|
+
## Best Practices
|
|
357
|
+
|
|
358
|
+
- Use modular routes and controllers.
|
|
359
|
+
- Handle environment variables with `dotenv`.
|
|
360
|
+
- Implement security headers.
|
|
361
|
+
- Add rate limiting for APIs.
|
|
362
|
+
|
|
363
|
+
## Examples
|
|
364
|
+
|
|
365
|
+
### Basic REST API
|
|
366
|
+
|
|
367
|
+
(See code in Quick Start)
|
|
368
|
+
|
|
369
|
+
### Authentication
|
|
370
|
+
|
|
371
|
+
JWT-based auth example (see full code in documentation).
|
|
372
|
+
|
|
373
|
+
### File Upload
|
|
374
|
+
|
|
375
|
+
Upload service example (see full code in documentation).
|
|
376
|
+
|
|
377
|
+
### Real-world App
|
|
378
|
+
|
|
379
|
+
Blog API with auth and posts (see full code in documentation).
|
|
380
|
+
|
|
381
|
+
## Contributing
|
|
382
|
+
|
|
383
|
+
Contributions welcome! Please submit issues or pull requests on GitHub.
|
|
384
|
+
|
|
385
|
+
## License
|
|
386
|
+
|
|
387
|
+
MIT License. See [LICENSE](LICENSE) for details.
|