lieko-express 0.0.11 → 0.0.12
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/lieko-express.d.ts +135 -267
- package/lieko-express.js +68 -0
- package/package.json +1 -1
package/lieko-express.d.ts
CHANGED
|
@@ -1,293 +1,161 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
1
|
+
declare module "lieko-express" {
|
|
2
|
+
import { IncomingMessage, ServerResponse } from "http";
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
:
|
|
9
|
-
? { [k in Param]: string }
|
|
10
|
-
: Record<string, never>;
|
|
4
|
+
// -------------------------------
|
|
5
|
+
// Request Extensions
|
|
6
|
+
// -------------------------------
|
|
7
|
+
interface LiekoRequest extends IncomingMessage {
|
|
8
|
+
app: any;
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
// Passport fields
|
|
11
|
+
user?: any;
|
|
12
|
+
session?: any;
|
|
13
|
+
|
|
14
|
+
// Auth helpers
|
|
15
|
+
logout(callback?: (err: any) => void): Promise<void> | void;
|
|
16
|
+
|
|
17
|
+
// URL helpers
|
|
18
|
+
originalUrl: string;
|
|
19
|
+
params: Record<string, string>;
|
|
19
20
|
query: Record<string, any>;
|
|
20
|
-
params: Record<string, any>;
|
|
21
21
|
body: any;
|
|
22
22
|
files: Record<string, any>;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
send(data: any): void;
|
|
34
|
-
text(data: string): void;
|
|
35
|
-
|
|
36
|
-
// headers helpers
|
|
37
|
-
setHeader(name: string, value: string | number): void;
|
|
38
|
-
set(name: string | Record<string, string | number>, value?: string | number): void;
|
|
39
|
-
header(name: string, value: string | number): void;
|
|
40
|
-
getHeader(name: string): string | number | string[] | undefined;
|
|
41
|
-
removeHeader(name: string): void;
|
|
42
|
-
headersSent?: boolean;
|
|
43
|
-
|
|
44
|
-
// redirect helpers
|
|
45
|
-
redirect(url: string): void;
|
|
46
|
-
redirect(status: number, url: string): void;
|
|
47
|
-
|
|
48
|
-
// streaming (optional)
|
|
49
|
-
write?(chunk: any): void;
|
|
50
|
-
end?(chunk?: any): void;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Extended Lieko Request and Response with framework helpers
|
|
54
|
-
interface Request<
|
|
55
|
-
Params extends Record<string, any> = Record<string, any>,
|
|
56
|
-
Query extends Record<string, any> = Record<string, any>,
|
|
57
|
-
Body = any
|
|
58
|
-
> extends RequestBase {
|
|
59
|
-
params: Params;
|
|
60
|
-
query: Query;
|
|
61
|
-
body: Body;
|
|
62
|
-
files: Record<string, {
|
|
63
|
-
filename: string;
|
|
64
|
-
tempFilePath?: string;
|
|
65
|
-
data?: Buffer;
|
|
66
|
-
contentType?: string;
|
|
67
|
-
size?: number;
|
|
68
|
-
}>;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface Response extends ResponseBase {
|
|
72
|
-
// Rich helpers provided by Lieko
|
|
73
|
-
ok(data?: any, message?: string): void;
|
|
74
|
-
success: (data?: any, message?: string) => void;
|
|
75
|
-
created(data?: any, message?: string): void;
|
|
76
|
-
noContent(): void;
|
|
77
|
-
accepted(data?: any, message?: string): void;
|
|
78
|
-
|
|
79
|
-
badRequest(message?: string, details?: any): void;
|
|
80
|
-
unauthorized(message?: string, details?: any): void;
|
|
81
|
-
forbidden(message?: string, details?: any): void;
|
|
82
|
-
notFound(message?: string, details?: any): void;
|
|
83
|
-
error(message?: string, status?: number, details?: any): void;
|
|
84
|
-
fail: (message?: string, status?: number, details?: any) => void;
|
|
85
|
-
serverError(message?: string, details?: any): void;
|
|
86
|
-
|
|
87
|
-
// convenience helpers sometimes provided
|
|
88
|
-
paginated?(items: any[], total: number, message?: string): void;
|
|
89
|
-
html?(html: string, status?: number): void;
|
|
90
|
-
|
|
91
|
-
// short alias
|
|
92
|
-
statusCode?: number;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// -------------- Handler / Middleware --------------
|
|
96
|
-
type Handler<
|
|
97
|
-
Params extends Record<string, any> = Record<string, any>,
|
|
98
|
-
Query extends Record<string, any> = Record<string, any>,
|
|
99
|
-
Body = any
|
|
100
|
-
> = (req: Request<Params, Query, Body>, res: Response, next?: (err?: any) => void) => any | Promise<any>;
|
|
101
|
-
|
|
102
|
-
// -------------- CORS / BodyParser options --------------
|
|
103
|
-
interface CorsOptions {
|
|
104
|
-
enabled?: boolean;
|
|
105
|
-
origin?: "*" | string | string[]; // supports wildcard like https://*.example.com
|
|
106
|
-
methods?: string[]; // allowed methods
|
|
107
|
-
headers?: string[]; // allowed headers
|
|
108
|
-
exposedHeaders?: string[];
|
|
109
|
-
credentials?: boolean;
|
|
110
|
-
maxAge?: number;
|
|
111
|
-
debug?: boolean;
|
|
112
|
-
strictOrigin?: boolean; // 403 if origin not allowed
|
|
113
|
-
allowPrivateNetwork?: boolean; // Access-Control-Allow-Private-Network
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
interface JsonBodyOptions {
|
|
117
|
-
limit?: string; // e.g. "10mb"
|
|
118
|
-
strict?: boolean;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
interface UrlencodedOptions {
|
|
122
|
-
limit?: string;
|
|
123
|
-
extended?: boolean;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
interface MultipartOptions {
|
|
127
|
-
limit?: string;
|
|
128
|
-
tempDir?: string;
|
|
129
|
-
}
|
|
23
|
+
xhr: boolean;
|
|
24
|
+
|
|
25
|
+
// IP helpers
|
|
26
|
+
ip: {
|
|
27
|
+
raw: string | null;
|
|
28
|
+
ipv4: string | null;
|
|
29
|
+
ipv6: string | null;
|
|
30
|
+
display: string;
|
|
31
|
+
};
|
|
32
|
+
ips: string[];
|
|
130
33
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
34
|
+
protocol: string;
|
|
35
|
+
secure: boolean;
|
|
36
|
+
hostname: string;
|
|
37
|
+
subdomains: string[];
|
|
136
38
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
type ValidatorFn = (value: any, field: string, data: any) => { field: string; message: string; type: string } | null;
|
|
39
|
+
get(name: string): string | undefined;
|
|
40
|
+
header(name: string): string | undefined;
|
|
140
41
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
string(message?: string): ValidatorFn;
|
|
146
|
-
number(message?: string): ValidatorFn;
|
|
147
|
-
boolean(message?: string): ValidatorFn;
|
|
148
|
-
integer(message?: string): ValidatorFn;
|
|
149
|
-
positive(message?: string): ValidatorFn;
|
|
150
|
-
negative(message?: string): ValidatorFn;
|
|
151
|
-
email(message?: string): ValidatorFn;
|
|
152
|
-
min(minValue: number, message?: string): ValidatorFn;
|
|
153
|
-
max(maxValue: number, message?: string): ValidatorFn;
|
|
154
|
-
length(n: number, message?: string): ValidatorFn;
|
|
155
|
-
minLength(minLength: number, message?: string): ValidatorFn;
|
|
156
|
-
maxLength(maxLength: number, message?: string): ValidatorFn;
|
|
157
|
-
pattern(regex: RegExp, message?: string): ValidatorFn;
|
|
158
|
-
oneOf(allowedValues: any[], message?: string): ValidatorFn;
|
|
159
|
-
notOneOf(values: any[], message?: string): ValidatorFn;
|
|
160
|
-
custom(validatorFn: (value: any, data: any) => boolean, message?: string): ValidatorFn;
|
|
161
|
-
equal(expectedValue: any, message?: string): ValidatorFn;
|
|
162
|
-
mustBeTrue(message?: string): ValidatorFn;
|
|
163
|
-
mustBeFalse(message?: string): ValidatorFn;
|
|
164
|
-
date(message?: string): ValidatorFn;
|
|
165
|
-
before(limit: string | Date, message?: string): ValidatorFn;
|
|
166
|
-
after(limit: string | Date, message?: string): ValidatorFn;
|
|
167
|
-
startsWith(prefix: string, message?: string): ValidatorFn;
|
|
168
|
-
endsWith(suffix: string, message?: string): ValidatorFn;
|
|
169
|
-
}
|
|
42
|
+
accepts(types: string | string[]): string | false;
|
|
43
|
+
acceptsLanguages(langs: string | string[]): string | false;
|
|
44
|
+
acceptsCharsets(charsets: string | string[]): string | false;
|
|
45
|
+
acceptsEncodings(enc: string | string[]): string | false;
|
|
170
46
|
|
|
171
|
-
|
|
172
|
-
constructor(rules: Record<string, ValidatorFn[]>);
|
|
173
|
-
rules: Record<string, ValidatorFn[]>;
|
|
174
|
-
fields: Record<string, ValidatorFn[]>;
|
|
175
|
-
validate(data: Record<string, any>): true | never;
|
|
47
|
+
is(type: string): boolean;
|
|
176
48
|
}
|
|
177
49
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
50
|
+
// -------------------------------
|
|
51
|
+
// Response Extensions
|
|
52
|
+
// -------------------------------
|
|
53
|
+
interface LiekoResponse extends ServerResponse {
|
|
54
|
+
app: any;
|
|
55
|
+
locals: Record<string, any>;
|
|
181
56
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
): this;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
57
|
+
status(code: number): this;
|
|
58
|
+
set(name: string, value: string): this;
|
|
59
|
+
header(name: string, value: string): this;
|
|
60
|
+
type(mime: string): this;
|
|
61
|
+
|
|
62
|
+
json(data: any): this;
|
|
63
|
+
send(data: any): this;
|
|
64
|
+
html(html: string, status?: number): this;
|
|
65
|
+
|
|
66
|
+
redirect(url: string, status?: number): this;
|
|
67
|
+
|
|
68
|
+
ok(data: any, message?: string): this;
|
|
69
|
+
success(data: any, message?: string): this;
|
|
70
|
+
created(data: any, message?: string): this;
|
|
71
|
+
noContent(): this;
|
|
72
|
+
accepted(data?: any, message?: string): this;
|
|
73
|
+
paginated(items: any[], total: number, message?: string): this;
|
|
74
|
+
|
|
75
|
+
// Cookie helpers
|
|
76
|
+
cookie(
|
|
77
|
+
name: string,
|
|
78
|
+
value: string,
|
|
79
|
+
options?: {
|
|
80
|
+
path?: string;
|
|
81
|
+
httpOnly?: boolean;
|
|
82
|
+
secure?: boolean;
|
|
83
|
+
sameSite?: "lax" | "strict" | "none";
|
|
84
|
+
maxAge?: number;
|
|
85
|
+
expires?: Date;
|
|
86
|
+
domain?: string;
|
|
87
|
+
}
|
|
208
88
|
): this;
|
|
209
89
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
90
|
+
clearCookie(
|
|
91
|
+
name: string,
|
|
92
|
+
options?: {
|
|
93
|
+
path?: string;
|
|
94
|
+
httpOnly?: boolean;
|
|
95
|
+
secure?: boolean;
|
|
96
|
+
sameSite?: "lax" | "strict" | "none";
|
|
97
|
+
}
|
|
213
98
|
): this;
|
|
214
99
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
): this;
|
|
100
|
+
error(obj: any): this;
|
|
101
|
+
fail(obj: any): this;
|
|
102
|
+
badRequest(msg?: string): this;
|
|
103
|
+
unauthorized(msg?: string): this;
|
|
104
|
+
forbidden(msg?: string): this;
|
|
105
|
+
notFound(msg?: string): this;
|
|
106
|
+
serverError(msg?: string): this;
|
|
107
|
+
}
|
|
219
108
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
109
|
+
// -------------------------------
|
|
110
|
+
// Handler Types
|
|
111
|
+
// -------------------------------
|
|
112
|
+
type LiekoHandler = (
|
|
113
|
+
req: LiekoRequest,
|
|
114
|
+
res: LiekoResponse,
|
|
115
|
+
next: (err?: any) => void
|
|
116
|
+
) => any;
|
|
117
|
+
|
|
118
|
+
type LiekoErrorHandler = (
|
|
119
|
+
err: any,
|
|
120
|
+
req: LiekoRequest,
|
|
121
|
+
res: LiekoResponse,
|
|
122
|
+
next: (err?: any) => void
|
|
123
|
+
) => any;
|
|
124
|
+
|
|
125
|
+
// -------------------------------
|
|
126
|
+
// Router / App Class
|
|
127
|
+
// -------------------------------
|
|
128
|
+
class LiekoExpress {
|
|
129
|
+
constructor();
|
|
130
|
+
|
|
131
|
+
get(path: string, ...handlers: LiekoHandler[]): this;
|
|
132
|
+
post(path: string, ...handlers: LiekoHandler[]): this;
|
|
133
|
+
put(path: string, ...handlers: LiekoHandler[]): this;
|
|
134
|
+
patch(path: string, ...handlers: LiekoHandler[]): this;
|
|
135
|
+
delete(path: string, ...handlers: LiekoHandler[]): this;
|
|
136
|
+
all(path: string, ...handlers: LiekoHandler[]): this;
|
|
137
|
+
|
|
138
|
+
use(mw: LiekoHandler): this;
|
|
139
|
+
use(path: string, mw: LiekoHandler): this;
|
|
140
|
+
use(path: string, router: LiekoExpress): this;
|
|
141
|
+
use(path: string, mw: LiekoHandler, router: LiekoExpress): this;
|
|
142
|
+
|
|
143
|
+
group(
|
|
144
|
+
basePath: string,
|
|
145
|
+
...middlewares: LiekoHandler[]
|
|
223
146
|
): this;
|
|
224
147
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
use(path: string, handler: Handler | App): this;
|
|
148
|
+
errorHandler(handler: LiekoErrorHandler): this;
|
|
149
|
+
notFound(handler: LiekoHandler): this;
|
|
228
150
|
|
|
229
|
-
|
|
230
|
-
|
|
151
|
+
set(name: string, value: any): this;
|
|
152
|
+
get(setting: string): any;
|
|
231
153
|
|
|
232
|
-
// CORS
|
|
233
|
-
cors(options?: Partial<CorsOptions>): Handler;
|
|
234
|
-
|
|
235
|
-
// body parser
|
|
236
|
-
bodyParser: {
|
|
237
|
-
json(options?: JsonBodyOptions): Handler;
|
|
238
|
-
urlencoded(options?: UrlencodedOptions): Handler;
|
|
239
|
-
multipart(options?: MultipartOptions): Handler;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
// static files
|
|
243
|
-
static(root: string, options?: { maxAge?: number; index?: string }): Handler;
|
|
244
|
-
|
|
245
|
-
// error handler
|
|
246
|
-
error(res: Response, obj: any): void;
|
|
247
|
-
|
|
248
|
-
// settings
|
|
249
|
-
set(key: string, value: any): this;
|
|
250
|
-
get(key: string): any;
|
|
251
|
-
|
|
252
|
-
// debug
|
|
253
|
-
debug(value?: boolean | string): this;
|
|
254
|
-
|
|
255
|
-
// utilities
|
|
256
|
-
listRoutes(): { method: string; path: string | string[]; middlewares: number }[];
|
|
257
|
-
printRoutes(): void;
|
|
258
|
-
|
|
259
|
-
// server control
|
|
260
154
|
listen(port: number, host?: string, callback?: () => void): any;
|
|
261
|
-
listen(...args: any[]): any;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// -------------- Factory / Constructor --------------
|
|
265
|
-
interface ConstructorOptions {
|
|
266
|
-
// initial options
|
|
267
|
-
cors?: Partial<CorsOptions>;
|
|
268
|
-
bodyParser?: Partial<BodyParserOptions>;
|
|
269
|
-
trustProxy?: boolean | string | string[];
|
|
270
|
-
debug?: boolean;
|
|
271
|
-
allowTrailingSlash?: boolean;
|
|
272
|
-
strictTrailingSlash?: boolean;
|
|
273
|
-
// other global options
|
|
274
|
-
[key: string]: any;
|
|
275
155
|
}
|
|
276
156
|
|
|
277
|
-
|
|
278
|
-
|
|
157
|
+
function Lieko(): LiekoExpress;
|
|
158
|
+
function Router(): LiekoExpress;
|
|
279
159
|
|
|
280
|
-
|
|
281
|
-
Router: () => App;
|
|
282
|
-
Schema: typeof Schema;
|
|
283
|
-
schema: (...args: any[]) => Schema;
|
|
284
|
-
validators: Validators;
|
|
285
|
-
validate: typeof validate;
|
|
286
|
-
validatePartial: (schema: Schema) => Handler;
|
|
287
|
-
ValidationError: typeof ValidationError;
|
|
288
|
-
static: (root: string, options?: { maxAge?: number; index?: string }) => Handler;
|
|
289
|
-
}
|
|
160
|
+
export = Lieko;
|
|
290
161
|
}
|
|
291
|
-
|
|
292
|
-
declare const Lieko: Lieko.LiekoStatic;
|
|
293
|
-
export = Lieko;
|
package/lieko-express.js
CHANGED
|
@@ -1200,6 +1200,26 @@ ${cyan} (req, res, next) => {
|
|
|
1200
1200
|
if (t === 'multipart') return ct.includes('multipart');
|
|
1201
1201
|
return false;
|
|
1202
1202
|
};
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* Passport-compatible logout (Passport 0.6+ / 0.7)
|
|
1206
|
+
* This ensures logout(cb) always calls cb(null) and never overwrites Express res
|
|
1207
|
+
*/
|
|
1208
|
+
req.logout = function logout(callback) {
|
|
1209
|
+
req.user = null;
|
|
1210
|
+
|
|
1211
|
+
// Remove passport session field if it exists
|
|
1212
|
+
if (req.session && req.session.passport) {
|
|
1213
|
+
delete req.session.passport;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
// Passport v0.6+ expects async logout
|
|
1217
|
+
if (typeof callback === "function") {
|
|
1218
|
+
return callback(null);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
return Promise.resolve();
|
|
1222
|
+
};
|
|
1203
1223
|
}
|
|
1204
1224
|
|
|
1205
1225
|
_enhanceResponse(req, res) {
|
|
@@ -1478,6 +1498,54 @@ ${cyan} (req, res, next) => {
|
|
|
1478
1498
|
return res.status(500).error(msg);
|
|
1479
1499
|
};
|
|
1480
1500
|
|
|
1501
|
+
res.cookie = (name, value, options = {}) => {
|
|
1502
|
+
const opts = {
|
|
1503
|
+
path: '/',
|
|
1504
|
+
httpOnly: true,
|
|
1505
|
+
secure: req.secure || false,
|
|
1506
|
+
sameSite: 'lax',
|
|
1507
|
+
maxAge: null,
|
|
1508
|
+
expires: null,
|
|
1509
|
+
...options
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
let cookie = `${name}=${encodeURIComponent(value)}`;
|
|
1513
|
+
|
|
1514
|
+
if (opts.maxAge) cookie += `; Max-Age=${Math.floor(opts.maxAge / 1000)}`;
|
|
1515
|
+
if (opts.expires) cookie += `; Expires=${opts.expires.toUTCString()}`;
|
|
1516
|
+
cookie += `; Path=${opts.path}`;
|
|
1517
|
+
if (opts.domain) cookie += `; Domain=${opts.domain}`;
|
|
1518
|
+
if (opts.httpOnly) cookie += '; HttpOnly';
|
|
1519
|
+
if (opts.secure) cookie += '; Secure';
|
|
1520
|
+
if (opts.sameSite) cookie += `; SameSite=${opts.sameSite}`;
|
|
1521
|
+
|
|
1522
|
+
res.setHeader('Set-Cookie', cookie);
|
|
1523
|
+
return res;
|
|
1524
|
+
};
|
|
1525
|
+
|
|
1526
|
+
res.clearCookie = (name, options = {}) => {
|
|
1527
|
+
if (responseSent) return res;
|
|
1528
|
+
|
|
1529
|
+
const opts = {
|
|
1530
|
+
path: '/',
|
|
1531
|
+
httpOnly: true,
|
|
1532
|
+
secure: req.secure || false,
|
|
1533
|
+
sameSite: 'lax',
|
|
1534
|
+
...options
|
|
1535
|
+
};
|
|
1536
|
+
|
|
1537
|
+
const cookieValue = `${name}=; Max-Age=0; Expires=${new Date(0).toUTCString()}; Path=${opts.path}`;
|
|
1538
|
+
|
|
1539
|
+
let header = cookieValue;
|
|
1540
|
+
|
|
1541
|
+
if (opts.httpOnly) header += '; HttpOnly';
|
|
1542
|
+
if (opts.secure) header += '; Secure';
|
|
1543
|
+
if (opts.sameSite && opts.sameSite !== 'none') header += `; SameSite=${opts.sameSite}`;
|
|
1544
|
+
|
|
1545
|
+
res.setHeader('Set-Cookie', header);
|
|
1546
|
+
return res;
|
|
1547
|
+
};
|
|
1548
|
+
|
|
1481
1549
|
const originalEnd = res.end.bind(res);
|
|
1482
1550
|
|
|
1483
1551
|
res.end = (...args) => {
|