@arkstack/http 0.8.0 → 0.9.1
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/dist/app.d.ts +7 -0
- package/dist/index-BfxuYaPt.d.ts +363 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -0
- package/dist/redirect-CZvhBHqO.js +1245 -0
- package/dist/redirect-CZvhBHqO.js.map +1 -0
- package/dist/setup.d.ts +3 -1
- package/dist/setup.js +4 -2
- package/dist/setup.js.map +1 -1
- package/package.json +4 -3
- package/dist/index-_YjYYnYr.d.ts +0 -175
- package/dist/session-gK9S8Go9.js +0 -543
- package/dist/session-gK9S8Go9.js.map +0 -1
package/dist/session-gK9S8Go9.js
DELETED
|
@@ -1,543 +0,0 @@
|
|
|
1
|
-
import { Request, Response } from "clear-router";
|
|
2
|
-
import { definePlugin } from "clear-router/core";
|
|
3
|
-
import { definePlugin as definePlugin$1 } from "kanun";
|
|
4
|
-
//#region src/helpers.ts
|
|
5
|
-
const unwrapRequestSource = (source) => {
|
|
6
|
-
if (source.headers) return source;
|
|
7
|
-
if (source.req) return source.req;
|
|
8
|
-
if (source.request) return source.request;
|
|
9
|
-
return source;
|
|
10
|
-
};
|
|
11
|
-
const makeHeaders = (headers) => {
|
|
12
|
-
return new Headers(normalizeHeaders(headers));
|
|
13
|
-
};
|
|
14
|
-
const normalizeHeaders = (headers) => {
|
|
15
|
-
const normalized = {};
|
|
16
|
-
if (!headers) return normalized;
|
|
17
|
-
if (isHeaders(headers)) {
|
|
18
|
-
headers.forEach((value, key) => {
|
|
19
|
-
normalized[key.toLowerCase()] = value;
|
|
20
|
-
});
|
|
21
|
-
return normalized;
|
|
22
|
-
}
|
|
23
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
24
|
-
const normalizedValue = normalizeHeaderValue(value);
|
|
25
|
-
if (typeof normalizedValue === "string") normalized[key.toLowerCase()] = normalizedValue;
|
|
26
|
-
}
|
|
27
|
-
return normalized;
|
|
28
|
-
};
|
|
29
|
-
const normalizeHeaderValue = (value) => {
|
|
30
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
31
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
32
|
-
return value ?? void 0;
|
|
33
|
-
};
|
|
34
|
-
const isHeaders = (value) => typeof Headers !== "undefined" && value instanceof Headers;
|
|
35
|
-
const isRecord$1 = (value) => {
|
|
36
|
-
return typeof value === "object" && value !== null;
|
|
37
|
-
};
|
|
38
|
-
//#endregion
|
|
39
|
-
//#region src/Request.ts
|
|
40
|
-
/**
|
|
41
|
-
* Represents an HTTP request, providing a consistent interface for accessing request data.
|
|
42
|
-
*
|
|
43
|
-
* @author 3m1n3nc3
|
|
44
|
-
*/
|
|
45
|
-
var Request$1 = class Request$1 extends Request {
|
|
46
|
-
headers;
|
|
47
|
-
ip;
|
|
48
|
-
source;
|
|
49
|
-
user;
|
|
50
|
-
authToken;
|
|
51
|
-
constructor(options = {}) {
|
|
52
|
-
super(options);
|
|
53
|
-
this.headers = normalizeHeaders(options.headers);
|
|
54
|
-
if (this.method) this.method = options.method;
|
|
55
|
-
if (this.url) this.url = options.url;
|
|
56
|
-
if (this.path) this.path = options.path;
|
|
57
|
-
this.ip = options.ip ?? null;
|
|
58
|
-
this.user = options.user;
|
|
59
|
-
this.authToken = options.authToken;
|
|
60
|
-
this.source = options.source;
|
|
61
|
-
globalThis.request = (key) => key ? this.input(key) : this;
|
|
62
|
-
}
|
|
63
|
-
static from(source) {
|
|
64
|
-
if (!source) return;
|
|
65
|
-
if (source instanceof Request$1) return source;
|
|
66
|
-
const request = unwrapRequestSource(source);
|
|
67
|
-
return new Request$1({
|
|
68
|
-
headers: request.headers,
|
|
69
|
-
method: request.method,
|
|
70
|
-
url: request.originalUrl ?? request.url,
|
|
71
|
-
path: request.path,
|
|
72
|
-
ip: request.ip ?? null,
|
|
73
|
-
user: request.user,
|
|
74
|
-
authToken: request.authToken,
|
|
75
|
-
source
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
header(name) {
|
|
79
|
-
return this.headers[name.toLowerCase()];
|
|
80
|
-
}
|
|
81
|
-
bearerToken() {
|
|
82
|
-
const authorization = this.header("authorization");
|
|
83
|
-
if (!authorization?.startsWith("Bearer ")) return null;
|
|
84
|
-
return authorization.substring(7);
|
|
85
|
-
}
|
|
86
|
-
setUser(user) {
|
|
87
|
-
this.user = user;
|
|
88
|
-
if (isRecord$1(this.source)) this.source.user = user;
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
//#endregion
|
|
93
|
-
//#region src/Response.ts
|
|
94
|
-
/**
|
|
95
|
-
* Represents an HTTP response, providing a consistent interface for accessing response data.
|
|
96
|
-
*
|
|
97
|
-
* @author 3m1n3nc3
|
|
98
|
-
*/
|
|
99
|
-
var Response$1 = class Response$1 extends Response {
|
|
100
|
-
body;
|
|
101
|
-
source;
|
|
102
|
-
constructor(options = {}) {
|
|
103
|
-
super({
|
|
104
|
-
body: options.body,
|
|
105
|
-
headers: makeHeaders(options.headers),
|
|
106
|
-
statusCode: options.statusCode ?? 200
|
|
107
|
-
});
|
|
108
|
-
this.body = options.body ?? {};
|
|
109
|
-
this.source = options.source;
|
|
110
|
-
globalThis.response = () => this;
|
|
111
|
-
}
|
|
112
|
-
static from(source) {
|
|
113
|
-
if (!source) return;
|
|
114
|
-
if (source instanceof Response$1) return source;
|
|
115
|
-
return new Response$1({
|
|
116
|
-
statusCode: typeof source.status === "number" ? source.status : source.statusCode,
|
|
117
|
-
headers: source.headers,
|
|
118
|
-
source
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
status(code) {
|
|
122
|
-
this.statusCode = code;
|
|
123
|
-
if (isRecord$1(this.source)) if (typeof this.source.status === "function") this.source.status(code);
|
|
124
|
-
else this.source.statusCode = code;
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
header(name, value) {
|
|
128
|
-
this.headers.set(name.toLowerCase(), value);
|
|
129
|
-
if (isRecord$1(this.source) && typeof this.source.setHeader === "function") this.source.setHeader(name, value);
|
|
130
|
-
return this;
|
|
131
|
-
}
|
|
132
|
-
getHeaders() {
|
|
133
|
-
return normalizeHeaders(this.headers);
|
|
134
|
-
}
|
|
135
|
-
json(body) {
|
|
136
|
-
this.body = body;
|
|
137
|
-
if (isRecord$1(this.source) && typeof this.source.json === "function") return this.source.json(body);
|
|
138
|
-
return body;
|
|
139
|
-
}
|
|
140
|
-
send(body) {
|
|
141
|
-
this.body = body;
|
|
142
|
-
if (isRecord$1(this.source) && typeof this.source.send === "function") return this.source.send(body);
|
|
143
|
-
return body;
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
const sessionKey = Symbol.for("arkstack:http:session");
|
|
147
|
-
const isRecord = (value) => {
|
|
148
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
149
|
-
};
|
|
150
|
-
const asMessageRecord = (value) => {
|
|
151
|
-
if (!isRecord(value)) return;
|
|
152
|
-
return value;
|
|
153
|
-
};
|
|
154
|
-
const callRecordMethod = (source, method) => {
|
|
155
|
-
if (typeof source[method] !== "function") return;
|
|
156
|
-
return asMessageRecord(source[method]());
|
|
157
|
-
};
|
|
158
|
-
const resolveMessageRecord = (source) => {
|
|
159
|
-
if (!isRecord(source)) return;
|
|
160
|
-
if (typeof source.getMessageBag === "function") {
|
|
161
|
-
const bag = source.getMessageBag();
|
|
162
|
-
if (bag && bag !== source) {
|
|
163
|
-
const messages = resolveMessageRecord(bag);
|
|
164
|
-
if (messages) return messages;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
if (typeof source.errors === "function") {
|
|
168
|
-
const errors = source.errors();
|
|
169
|
-
const messages = resolveMessageRecord(errors) || asMessageRecord(errors);
|
|
170
|
-
if (messages) return messages;
|
|
171
|
-
}
|
|
172
|
-
return callRecordMethod(source, "getMessages") || callRecordMethod(source, "messagesRaw") || callRecordMethod(source, "toArray") || resolveMessageRecord(source.errors) || asMessageRecord(source.errors);
|
|
173
|
-
};
|
|
174
|
-
const getValidationIssueField = (issue) => {
|
|
175
|
-
if (typeof issue.field === "string") return issue.field;
|
|
176
|
-
if (typeof issue.attribute === "string") return issue.attribute;
|
|
177
|
-
if (typeof issue.key === "string") return issue.key;
|
|
178
|
-
if (typeof issue.path === "string") return issue.path;
|
|
179
|
-
if (Array.isArray(issue.path)) return issue.path.join(".") || "_";
|
|
180
|
-
return "_";
|
|
181
|
-
};
|
|
182
|
-
const toMessages = (value) => {
|
|
183
|
-
if (Array.isArray(value)) return value.flatMap((item) => toMessages(item));
|
|
184
|
-
if (value instanceof Error) return [value.message];
|
|
185
|
-
if (isRecord(value) && typeof value.message === "string") return [value.message];
|
|
186
|
-
if (value === null || typeof value === "undefined") return [];
|
|
187
|
-
return [String(value)];
|
|
188
|
-
};
|
|
189
|
-
//#endregion
|
|
190
|
-
//#region src/session/ErrorBag.ts
|
|
191
|
-
var ErrorBag = class ErrorBag {
|
|
192
|
-
bag = {};
|
|
193
|
-
constructor(errors) {
|
|
194
|
-
if (errors) this.merge(errors);
|
|
195
|
-
}
|
|
196
|
-
add(field, message) {
|
|
197
|
-
const key = field || "_";
|
|
198
|
-
const messages = toMessages(message);
|
|
199
|
-
if (!messages.length) return this;
|
|
200
|
-
this.bag[key] = [...this.bag[key] || [], ...messages];
|
|
201
|
-
return this;
|
|
202
|
-
}
|
|
203
|
-
addIf(condition, field, message) {
|
|
204
|
-
if (condition) this.add(field, message);
|
|
205
|
-
return this;
|
|
206
|
-
}
|
|
207
|
-
merge(errors) {
|
|
208
|
-
const incoming = resolveMessageRecord(errors) || (isRecord(errors) ? errors : void 0);
|
|
209
|
-
if (!incoming) return this.validation(errors);
|
|
210
|
-
for (const [field, messages] of Object.entries(incoming)) this.add(field, messages);
|
|
211
|
-
return this;
|
|
212
|
-
}
|
|
213
|
-
validation(error) {
|
|
214
|
-
if (!error) return this;
|
|
215
|
-
if (error instanceof ErrorBag) return this.merge(error);
|
|
216
|
-
const messages = resolveMessageRecord(error);
|
|
217
|
-
if (messages) return this.merge(messages);
|
|
218
|
-
if (Array.isArray(error)) {
|
|
219
|
-
for (const item of error) if (isRecord(item) && "message" in item) this.add(getValidationIssueField(item), item.message);
|
|
220
|
-
else this.add("_", item);
|
|
221
|
-
return this;
|
|
222
|
-
}
|
|
223
|
-
if (isRecord(error)) {
|
|
224
|
-
if (typeof error.errors === "function") return this.validation(error.errors());
|
|
225
|
-
if (error.errors) return this.validation(error.errors);
|
|
226
|
-
if (Array.isArray(error.issues)) return this.validation(error.issues);
|
|
227
|
-
if ("message" in error) return this.add(getValidationIssueField(error), error.message);
|
|
228
|
-
return this.merge(error);
|
|
229
|
-
}
|
|
230
|
-
if (error instanceof Error) return this.add("_", error.message);
|
|
231
|
-
return this.add("_", error);
|
|
232
|
-
}
|
|
233
|
-
keys() {
|
|
234
|
-
return Object.keys(this.bag);
|
|
235
|
-
}
|
|
236
|
-
get(field = "_") {
|
|
237
|
-
return [...this.bag[field] || []];
|
|
238
|
-
}
|
|
239
|
-
first(field) {
|
|
240
|
-
if (field) return this.bag[field]?.[0] || "";
|
|
241
|
-
return this.all()[0] || "";
|
|
242
|
-
}
|
|
243
|
-
has(field) {
|
|
244
|
-
if (Array.isArray(field)) return field.every((key) => this.has(key));
|
|
245
|
-
if (field) return (this.bag[field]?.length || 0) > 0;
|
|
246
|
-
return this.any();
|
|
247
|
-
}
|
|
248
|
-
hasAny(fields) {
|
|
249
|
-
return (Array.isArray(fields) ? fields : [fields]).some((key) => this.has(key));
|
|
250
|
-
}
|
|
251
|
-
missing(fields) {
|
|
252
|
-
return (Array.isArray(fields) ? fields : [fields]).every((key) => !this.has(key));
|
|
253
|
-
}
|
|
254
|
-
any() {
|
|
255
|
-
return Object.values(this.bag).some((messages) => messages.length > 0);
|
|
256
|
-
}
|
|
257
|
-
isEmpty() {
|
|
258
|
-
return !this.any();
|
|
259
|
-
}
|
|
260
|
-
isNotEmpty() {
|
|
261
|
-
return this.any();
|
|
262
|
-
}
|
|
263
|
-
count() {
|
|
264
|
-
return Object.values(this.bag).reduce((total, messages) => total + messages.length, 0);
|
|
265
|
-
}
|
|
266
|
-
all() {
|
|
267
|
-
return Object.values(this.bag).flat();
|
|
268
|
-
}
|
|
269
|
-
unique() {
|
|
270
|
-
return [...new Set(this.all())];
|
|
271
|
-
}
|
|
272
|
-
clear(field) {
|
|
273
|
-
if (Array.isArray(field)) {
|
|
274
|
-
for (const key of field) delete this.bag[key];
|
|
275
|
-
return this;
|
|
276
|
-
}
|
|
277
|
-
if (field) {
|
|
278
|
-
delete this.bag[field];
|
|
279
|
-
return this;
|
|
280
|
-
}
|
|
281
|
-
this.bag = {};
|
|
282
|
-
return this;
|
|
283
|
-
}
|
|
284
|
-
forget(field) {
|
|
285
|
-
return this.clear(field);
|
|
286
|
-
}
|
|
287
|
-
messagesRaw() {
|
|
288
|
-
return this.toJSON();
|
|
289
|
-
}
|
|
290
|
-
getMessages() {
|
|
291
|
-
return this.messagesRaw();
|
|
292
|
-
}
|
|
293
|
-
getMessageBag() {
|
|
294
|
-
return this;
|
|
295
|
-
}
|
|
296
|
-
toArray() {
|
|
297
|
-
return this.toJSON();
|
|
298
|
-
}
|
|
299
|
-
toJSON() {
|
|
300
|
-
return Object.entries(this.bag).reduce((errors, [field, messages]) => {
|
|
301
|
-
errors[field] = [...messages];
|
|
302
|
-
return errors;
|
|
303
|
-
}, {});
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
//#endregion
|
|
307
|
-
//#region src/session/Session.ts
|
|
308
|
-
var Session = class {
|
|
309
|
-
errors;
|
|
310
|
-
data;
|
|
311
|
-
constructor(initial) {
|
|
312
|
-
const state = initial && ("data" in initial || "errors" in initial) ? initial : { data: initial };
|
|
313
|
-
this.data = { ...state.data || {} };
|
|
314
|
-
this.errors = state.errors instanceof ErrorBag ? state.errors : new ErrorBag(state.errors);
|
|
315
|
-
globalThis.session = (key) => key ? this.get(key) : this;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Get an item from the session bag
|
|
319
|
-
*
|
|
320
|
-
* @param key
|
|
321
|
-
* @param defaultValue
|
|
322
|
-
* @returns
|
|
323
|
-
*/
|
|
324
|
-
get(key, defaultValue) {
|
|
325
|
-
return key in this.data ? this.data[key] : defaultValue;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Add an item to the session bag
|
|
329
|
-
*
|
|
330
|
-
* @param key
|
|
331
|
-
* @param defaultValue
|
|
332
|
-
* @returns
|
|
333
|
-
*/
|
|
334
|
-
put(key, value) {
|
|
335
|
-
this.data[key] = value;
|
|
336
|
-
return this;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Add an item to the session bag
|
|
340
|
-
*
|
|
341
|
-
* @param key
|
|
342
|
-
* @param defaultValue
|
|
343
|
-
* @returns
|
|
344
|
-
*/
|
|
345
|
-
set(key, value) {
|
|
346
|
-
return this.put(key, value);
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Check if an item exist in the session bag
|
|
350
|
-
*
|
|
351
|
-
* @param key
|
|
352
|
-
* @returns
|
|
353
|
-
*/
|
|
354
|
-
has(key) {
|
|
355
|
-
return key in this.data;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Remove an item from the session bag
|
|
359
|
-
*
|
|
360
|
-
* @param key
|
|
361
|
-
* @returns
|
|
362
|
-
*/
|
|
363
|
-
forget(key) {
|
|
364
|
-
delete this.data[key];
|
|
365
|
-
return this;
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Clear the session bag
|
|
369
|
-
*
|
|
370
|
-
* @returns
|
|
371
|
-
*/
|
|
372
|
-
clear() {
|
|
373
|
-
this.data = {};
|
|
374
|
-
this.errors.clear();
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Get all items in the session bag
|
|
379
|
-
*
|
|
380
|
-
* @returns
|
|
381
|
-
*/
|
|
382
|
-
all() {
|
|
383
|
-
return { ...this.data };
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Add an error to the session error bag
|
|
387
|
-
*
|
|
388
|
-
* @param field
|
|
389
|
-
* @param message
|
|
390
|
-
* @returns
|
|
391
|
-
*/
|
|
392
|
-
addError(field, message) {
|
|
393
|
-
this.errors.add(field, message);
|
|
394
|
-
return this;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Add multiple errors to the session error bag
|
|
398
|
-
*
|
|
399
|
-
* @param errors
|
|
400
|
-
* @returns
|
|
401
|
-
*/
|
|
402
|
-
addErrors(errors) {
|
|
403
|
-
this.errors.merge(errors);
|
|
404
|
-
return this;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Add a validation error to the session error bag
|
|
408
|
-
*
|
|
409
|
-
* @param error
|
|
410
|
-
* @returns
|
|
411
|
-
*/
|
|
412
|
-
addValidationErrors(error) {
|
|
413
|
-
this.errors.validation(error);
|
|
414
|
-
return this;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Check if the session error bag has any errors
|
|
418
|
-
*
|
|
419
|
-
* @param field
|
|
420
|
-
* @returns
|
|
421
|
-
*/
|
|
422
|
-
hasErrors(field) {
|
|
423
|
-
return this.errors.has(field);
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Clear all errors in the session error bag
|
|
427
|
-
*
|
|
428
|
-
* @param field
|
|
429
|
-
* @returns
|
|
430
|
-
*/
|
|
431
|
-
clearErrors(field) {
|
|
432
|
-
this.errors.clear(field);
|
|
433
|
-
return this;
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Parse session for views
|
|
437
|
-
*
|
|
438
|
-
* @returns
|
|
439
|
-
*/
|
|
440
|
-
forView() {
|
|
441
|
-
return {
|
|
442
|
-
...this.all(),
|
|
443
|
-
errors: this.errors
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Return session as json
|
|
448
|
-
*
|
|
449
|
-
* @returns
|
|
450
|
-
*/
|
|
451
|
-
toJSON() {
|
|
452
|
-
return {
|
|
453
|
-
...this.all(),
|
|
454
|
-
errors: this.errors.toJSON()
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
//#endregion
|
|
459
|
-
//#region src/session/helpers.ts
|
|
460
|
-
const attachSessionProperty = (target, session) => {
|
|
461
|
-
target.httpSession = session;
|
|
462
|
-
if (!("session" in target) || target.session instanceof Session) target.session = session;
|
|
463
|
-
};
|
|
464
|
-
const attachViewState = (target, session) => {
|
|
465
|
-
attachSessionProperty(target, session);
|
|
466
|
-
target.errors = session.errors;
|
|
467
|
-
if (isRecord$1(target.res)) target.res.locals = {
|
|
468
|
-
...target.res.locals || {},
|
|
469
|
-
session,
|
|
470
|
-
errors: session.errors
|
|
471
|
-
};
|
|
472
|
-
if (isRecord$1(target.response?.source)) target.response.source.locals = {
|
|
473
|
-
...target.response.source.locals || {},
|
|
474
|
-
session,
|
|
475
|
-
errors: session.errors
|
|
476
|
-
};
|
|
477
|
-
if (isRecord$1(target.context)) {
|
|
478
|
-
attachSessionProperty(target.context, session);
|
|
479
|
-
target.context.errors = session.errors;
|
|
480
|
-
}
|
|
481
|
-
if (isRecord$1(target.state)) {
|
|
482
|
-
attachSessionProperty(target.state, session);
|
|
483
|
-
target.state.errors = session.errors;
|
|
484
|
-
}
|
|
485
|
-
if (typeof target.set === "function") {
|
|
486
|
-
target.set("session", session);
|
|
487
|
-
target.set("errors", session.errors);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
/**
|
|
491
|
-
* Ensure a valid session exists
|
|
492
|
-
*
|
|
493
|
-
* @param ctx
|
|
494
|
-
* @param initial
|
|
495
|
-
* @returns
|
|
496
|
-
*/
|
|
497
|
-
const ensureSession = (ctx, initial) => {
|
|
498
|
-
if (!isRecord$1(ctx)) return new Session(initial);
|
|
499
|
-
const existing = ctx[sessionKey] ?? (ctx.session instanceof Session ? ctx.session : void 0);
|
|
500
|
-
const session = existing instanceof Session ? existing : new Session(initial);
|
|
501
|
-
ctx[sessionKey] = session;
|
|
502
|
-
attachViewState(ctx, session);
|
|
503
|
-
return session;
|
|
504
|
-
};
|
|
505
|
-
/**
|
|
506
|
-
* Get the current session
|
|
507
|
-
*
|
|
508
|
-
* @param ctx
|
|
509
|
-
* @returns
|
|
510
|
-
*/
|
|
511
|
-
const getSession = (ctx) => {
|
|
512
|
-
if (!isRecord$1(ctx)) return;
|
|
513
|
-
const session = ctx[sessionKey] ?? ctx.session;
|
|
514
|
-
return session instanceof Session ? session : void 0;
|
|
515
|
-
};
|
|
516
|
-
//#endregion
|
|
517
|
-
//#region src/session/plugins.ts
|
|
518
|
-
const clearRouterSessionPlugin = definePlugin({
|
|
519
|
-
name: "arkstack-http-session",
|
|
520
|
-
setup: ({ bind, useHttpContext }) => {
|
|
521
|
-
bind(Session, ({ ctx }) => ensureSession(ctx));
|
|
522
|
-
useHttpContext((context) => {
|
|
523
|
-
const session = ensureSession(context.ctx);
|
|
524
|
-
context.httpSession = session;
|
|
525
|
-
if (!("session" in context) || context.session instanceof Session) context.session = session;
|
|
526
|
-
context.errors = session.errors;
|
|
527
|
-
attachViewState(context, session);
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
});
|
|
531
|
-
const kanunSessionPlugin = definePlugin$1({
|
|
532
|
-
name: "kanun-session-plugin",
|
|
533
|
-
install({ onValidationError }) {
|
|
534
|
-
onValidationError((validator) => {
|
|
535
|
-
const currentSession = globalThis.session?.();
|
|
536
|
-
if (currentSession instanceof Session) currentSession.addValidationErrors(validator);
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
//#endregion
|
|
541
|
-
export { getSession as a, Response$1 as c, isRecord$1 as d, makeHeaders as f, unwrapRequestSource as h, ensureSession as i, Request$1 as l, normalizeHeaders as m, kanunSessionPlugin as n, Session as o, normalizeHeaderValue as p, attachViewState as r, ErrorBag as s, clearRouterSessionPlugin as t, isHeaders as u };
|
|
542
|
-
|
|
543
|
-
//# sourceMappingURL=session-gK9S8Go9.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-gK9S8Go9.js","names":["isRecord","Request","BaseRequest","isRecord","Response","BaseResponse","isRecord","isRecord","defineClearRouterPlugin","defineKanunPlugin"],"sources":["../src/helpers.ts","../src/Request.ts","../src/Response.ts","../src/session/utils.ts","../src/session/ErrorBag.ts","../src/session/Session.ts","../src/session/helpers.ts","../src/session/plugins.ts"],"sourcesContent":["import { HeaderMap, HeaderSource, HeaderValue, RequestSource } from './types/Http'\n\nexport const unwrapRequestSource = <TUser> (\n source: RequestSource<TUser>\n): RequestSource<TUser> => {\n if (source.headers) {\n return source\n }\n\n if (source.req) {\n return source.req\n }\n\n if (source.request) {\n return source.request\n }\n\n return source\n}\n\nexport const makeHeaders = (headers?: HeaderSource) => {\n return new Headers(normalizeHeaders(headers))\n}\n\nexport const normalizeHeaders = (headers?: HeaderSource): HeaderMap => {\n const normalized: HeaderMap = {}\n\n if (!headers) {\n return normalized\n }\n\n if (isHeaders(headers)) {\n headers.forEach((value, key) => {\n normalized[key.toLowerCase()] = value\n })\n\n return normalized\n }\n\n for (const [key, value] of Object.entries(headers)) {\n const normalizedValue = normalizeHeaderValue(value)\n\n if (typeof normalizedValue === 'string') {\n normalized[key.toLowerCase()] = normalizedValue\n }\n }\n\n return normalized\n}\n\nexport const normalizeHeaderValue = (value: HeaderValue) => {\n if (Array.isArray(value)) {\n return value.join(', ')\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value)\n }\n\n return value ?? undefined\n}\n\nexport const isHeaders = (value: unknown): value is Headers => (\n typeof Headers !== 'undefined' && value instanceof Headers\n)\n\nexport const isRecord = (value: unknown): value is Record<PropertyKey, any> => {\n return typeof value === 'object' && value !== null\n}\n","import { HeaderMap, RequestOptions, RequestSource } from './types/Http'\nimport { isRecord, normalizeHeaders, unwrapRequestSource } from './helpers'\n\nimport { Request as BaseRequest } from 'clear-router'\n\n/**\n * Represents an HTTP request, providing a consistent interface for accessing request data.\n * \n * @author 3m1n3nc3\n */\nexport class Request<TUser = unknown> extends BaseRequest {\n readonly headers: HeaderMap\n readonly ip: string | null\n readonly source?: unknown\n user?: TUser\n authToken?: string\n\n constructor(options: RequestOptions<TUser> = {}) {\n super(options)\n\n this.headers = normalizeHeaders(options.headers)\n if (this.method)\n this.method = options.method!\n if (this.url)\n this.url = options.url!\n if (this.path)\n this.path = options.path!\n this.ip = options.ip ?? null\n this.user = options.user\n this.authToken = options.authToken\n this.source = options.source\n\n globalThis.request = (key?: string) => key ? this.input(key) : this\n }\n\n static from<TUser = unknown> (\n source?: Request<TUser> | RequestSource<TUser>\n ): Request<TUser> | undefined {\n if (!source) {\n return undefined\n }\n\n if (source instanceof Request) {\n return source\n }\n\n const request = unwrapRequestSource(source)\n\n return new Request<TUser>({\n headers: request.headers,\n method: request.method,\n url: request.originalUrl ?? request.url,\n path: request.path,\n ip: request.ip ?? null,\n user: request.user,\n authToken: request.authToken,\n source,\n })\n }\n\n header (name: string): string {\n return this.headers[name.toLowerCase()]\n }\n\n bearerToken (): string | null {\n const authorization = this.header('authorization')\n\n if (!authorization?.startsWith('Bearer ')) {\n return null\n }\n\n return authorization.substring(7)\n }\n\n setUser (user: TUser) {\n this.user = user\n\n if (isRecord(this.source)) {\n this.source.user = user\n }\n\n return this\n }\n}","import { HeaderSource, ResponseSource } from './types/Http'\nimport { isRecord, makeHeaders, normalizeHeaders } from './helpers'\n\nimport { Response as BaseResponse } from 'clear-router'\nimport { RequestData } from 'clear-router/types/basic'\n\n/**\n * Represents an HTTP response, providing a consistent interface for accessing response data.\n * \n * @author 3m1n3nc3\n */\nexport class Response<TBody = unknown> extends BaseResponse {\n override body: TBody\n readonly source?: unknown\n\n constructor(options: {\n statusCode?: number;\n headers?: HeaderSource;\n body?: TBody;\n source?: unknown;\n } = {}) {\n super({\n body: options.body,\n headers: makeHeaders(options.headers),\n statusCode: options.statusCode ?? 200,\n })\n\n this.body = options.body ?? {} as TBody\n this.source = options.source\n\n globalThis.response = () => this\n }\n\n static from<TBody extends RequestData = RequestData> (\n source?: Response<TBody> | ResponseSource\n ): Response<TBody> | undefined {\n if (!source) {\n return undefined\n }\n\n if (source instanceof Response) {\n return source\n }\n\n return new Response<TBody>({\n statusCode: typeof source.status === 'number' ? source.status : source.statusCode,\n headers: source.headers,\n source,\n })\n }\n\n status (code: number) {\n this.statusCode = code\n\n if (isRecord(this.source)) {\n if (typeof this.source.status === 'function') {\n this.source.status(code)\n } else {\n this.source.statusCode = code\n }\n }\n\n return this\n }\n\n header (name: string, value: string) {\n this.headers.set(name.toLowerCase(), value)\n\n if (isRecord(this.source) && typeof this.source.setHeader === 'function') {\n this.source.setHeader(name, value)\n }\n\n return this\n }\n\n getHeaders () {\n return normalizeHeaders(this.headers)\n }\n\n json (body: TBody) {\n this.body = body\n\n if (isRecord(this.source) && typeof this.source.json === 'function') {\n return this.source.json(body)\n }\n\n return body\n }\n\n send (body: TBody) {\n this.body = body\n\n if (isRecord(this.source) && typeof this.source.send === 'function') {\n return this.source.send(body)\n }\n\n return body\n }\n}","import type { SessionErrorRecord, SessionErrorValue } from './types'\n\nexport const defaultErrorKey = '_'\nexport const sessionKey = Symbol.for('arkstack:http:session')\n\nexport const isRecord = (value: unknown): value is Record<string, any> => {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst asMessageRecord = (value: unknown): SessionErrorRecord | undefined => {\n if (!isRecord(value)) {\n return undefined\n }\n\n return value as SessionErrorRecord\n}\n\nconst callRecordMethod = (source: Record<string, any>, method: string): SessionErrorRecord | undefined => {\n if (typeof source[method] !== 'function') {\n return undefined\n }\n\n const value = source[method]()\n\n return asMessageRecord(value)\n}\n\nexport const resolveMessageRecord = (source: unknown): SessionErrorRecord | undefined => {\n if (!isRecord(source)) {\n return undefined\n }\n\n if (typeof source.getMessageBag === 'function') {\n const bag = source.getMessageBag()\n\n if (bag && bag !== source) {\n const messages = resolveMessageRecord(bag)\n\n if (messages) {\n return messages\n }\n }\n }\n\n if (typeof source.errors === 'function') {\n const errors = source.errors()\n const messages = resolveMessageRecord(errors) || asMessageRecord(errors)\n\n if (messages) {\n return messages\n }\n }\n\n return callRecordMethod(source, 'getMessages')\n || callRecordMethod(source, 'messagesRaw')\n || callRecordMethod(source, 'toArray')\n || resolveMessageRecord(source.errors)\n || asMessageRecord(source.errors)\n}\n\nexport const getValidationIssueField = (issue: Record<string, any>) => {\n if (typeof issue.field === 'string') {\n return issue.field\n }\n\n if (typeof issue.attribute === 'string') {\n return issue.attribute\n }\n\n if (typeof issue.key === 'string') {\n return issue.key\n }\n\n if (typeof issue.path === 'string') {\n return issue.path\n }\n\n if (Array.isArray(issue.path)) {\n return issue.path.join('.') || defaultErrorKey\n }\n\n return defaultErrorKey\n}\n\nexport const toMessages = (value: SessionErrorValue): string[] => {\n if (Array.isArray(value)) {\n return value.flatMap(item => toMessages(item))\n }\n\n if (value instanceof Error) {\n return [value.message]\n }\n\n if (isRecord(value) && typeof value.message === 'string') {\n return [value.message]\n }\n\n if (value === null || typeof value === 'undefined') {\n return []\n }\n\n return [String(value)]\n}\n","import type { SessionErrorRecord, SessionErrorSource, SessionErrorValue } from './types'\nimport { defaultErrorKey, getValidationIssueField, isRecord, resolveMessageRecord, toMessages } from './utils'\n\nexport class ErrorBag {\n private bag: Record<string, string[]> = {}\n\n constructor(errors?: SessionErrorSource) {\n if (errors) {\n this.merge(errors)\n }\n }\n\n add (field: string, message: SessionErrorValue) {\n const key = field || defaultErrorKey\n const messages = toMessages(message)\n\n if (!messages.length) {\n return this\n }\n\n this.bag[key] = [\n ...(this.bag[key] || []),\n ...messages,\n ]\n\n return this\n }\n\n addIf (condition: boolean, field: string, message: SessionErrorValue) {\n if (condition) {\n this.add(field, message)\n }\n\n return this\n }\n\n merge (errors: SessionErrorSource) {\n const incoming = resolveMessageRecord(errors) || (isRecord(errors) ? errors as SessionErrorRecord : undefined)\n\n if (!incoming) {\n return this.validation(errors)\n }\n\n for (const [field, messages] of Object.entries(incoming)) {\n this.add(field, messages)\n }\n\n return this\n }\n\n validation (error: unknown): ErrorBag {\n if (!error) {\n return this\n }\n\n if (error instanceof ErrorBag) {\n return this.merge(error)\n }\n\n const messages = resolveMessageRecord(error)\n\n if (messages) {\n return this.merge(messages)\n }\n\n if (Array.isArray(error)) {\n for (const item of error) {\n if (isRecord(item) && 'message' in item) {\n this.add(getValidationIssueField(item), item.message)\n } else {\n this.add(defaultErrorKey, item)\n }\n }\n\n return this\n }\n\n if (isRecord(error)) {\n if (typeof error.errors === 'function') {\n return this.validation(error.errors())\n }\n\n if (error.errors) {\n return this.validation(error.errors)\n }\n\n if (Array.isArray(error.issues)) {\n return this.validation(error.issues)\n }\n\n if ('message' in error) {\n return this.add(getValidationIssueField(error), error.message)\n }\n\n return this.merge(error as SessionErrorRecord)\n }\n\n if (error instanceof Error) {\n return this.add(defaultErrorKey, error.message)\n }\n\n return this.add(defaultErrorKey, error)\n }\n\n keys () {\n return Object.keys(this.bag)\n }\n\n get (field: string = defaultErrorKey) {\n return [...(this.bag[field] || [])]\n }\n\n first (field?: string | null) {\n if (field) {\n return this.bag[field]?.[0] || ''\n }\n\n return this.all()[0] || ''\n }\n\n has (field?: string | string[] | null): boolean {\n if (Array.isArray(field)) {\n return field.every(key => this.has(key))\n }\n\n if (field) {\n return (this.bag[field]?.length || 0) > 0\n }\n\n return this.any()\n }\n\n hasAny (fields: string | string[]) {\n const keys = Array.isArray(fields) ? fields : [fields]\n\n return keys.some(key => this.has(key))\n }\n\n missing (fields: string | string[]) {\n const keys = Array.isArray(fields) ? fields : [fields]\n\n return keys.every(key => !this.has(key))\n }\n\n any () {\n return Object.values(this.bag).some(messages => messages.length > 0)\n }\n\n isEmpty () {\n return !this.any()\n }\n\n isNotEmpty () {\n return this.any()\n }\n\n count () {\n return Object.values(this.bag).reduce((total, messages) => total + messages.length, 0)\n }\n\n all () {\n return Object.values(this.bag).flat()\n }\n\n unique () {\n return [...new Set(this.all())]\n }\n\n clear (field?: string | string[]) {\n if (Array.isArray(field)) {\n for (const key of field) {\n delete this.bag[key]\n }\n\n return this\n }\n\n if (field) {\n delete this.bag[field]\n\n return this\n }\n\n this.bag = {}\n\n return this\n }\n\n forget (field: string) {\n return this.clear(field)\n }\n\n messagesRaw () {\n return this.toJSON()\n }\n\n getMessages () {\n return this.messagesRaw()\n }\n\n getMessageBag () {\n return this\n }\n\n toArray () {\n return this.toJSON()\n }\n\n toJSON () {\n return Object.entries(this.bag).reduce<Record<string, string[]>>((errors, [field, messages]) => {\n errors[field] = [...messages]\n\n return errors\n }, {})\n }\n}\n","import type { SessionErrorRecord, SessionErrorValue, SessionInitialState } from './types'\n\nimport { ErrorBag } from './ErrorBag'\n\nexport class Session {\n public readonly errors: ErrorBag\n private data: Record<string, any>\n\n constructor(initial?: SessionInitialState | Record<string, any>) {\n const state = initial && ('data' in initial || 'errors' in initial)\n ? initial as SessionInitialState\n : { data: initial as Record<string, any> | undefined }\n\n this.data = { ...(state.data || {}) }\n this.errors = state.errors instanceof ErrorBag\n ? state.errors\n : new ErrorBag(state.errors)\n\n globalThis.session = (key?: string) => key ? this.get(key) : this\n }\n\n /**\n * Get an item from the session bag\n * \n * @param key \n * @param defaultValue \n * @returns \n */\n get<T = any> (key: string, defaultValue?: T): T {\n return (key in this.data ? this.data[key] : defaultValue) as T\n }\n\n /**\n * Add an item to the session bag\n * \n * @param key \n * @param defaultValue \n * @returns \n */\n put<T = any> (key: string, value: T) {\n this.data[key] = value\n\n return this\n }\n\n /**\n * Add an item to the session bag\n * \n * @param key \n * @param defaultValue \n * @returns \n */\n set<T = any> (key: string, value: T) {\n return this.put(key, value)\n }\n\n /**\n * Check if an item exist in the session bag\n * \n * @param key \n * @returns \n */\n has (key: string) {\n return key in this.data\n }\n\n /**\n * Remove an item from the session bag\n * \n * @param key \n * @returns \n */\n forget (key: string) {\n delete this.data[key]\n\n return this\n }\n\n /**\n * Clear the session bag\n * \n * @returns \n */\n clear () {\n this.data = {}\n this.errors.clear()\n\n return this\n }\n\n /**\n * Get all items in the session bag\n * \n * @returns \n */\n all () {\n return { ...this.data }\n }\n\n /**\n * Add an error to the session error bag\n * \n * @param field \n * @param message \n * @returns \n */\n addError (field: string, message: SessionErrorValue) {\n this.errors.add(field, message)\n\n return this\n }\n\n /**\n * Add multiple errors to the session error bag\n * \n * @param errors \n * @returns \n */\n addErrors (errors: SessionErrorRecord | ErrorBag) {\n this.errors.merge(errors)\n\n return this\n }\n\n /**\n * Add a validation error to the session error bag\n * \n * @param error \n * @returns \n */\n addValidationErrors (error: unknown) {\n this.errors.validation(error)\n\n return this\n }\n\n /**\n * Check if the session error bag has any errors\n * \n * @param field \n * @returns \n */\n hasErrors (field?: string) {\n return this.errors.has(field)\n }\n\n /**\n * Clear all errors in the session error bag\n * \n * @param field \n * @returns \n */\n clearErrors (field?: string) {\n this.errors.clear(field)\n\n return this\n }\n\n /**\n * Parse session for views\n * \n * @returns \n */\n forView () {\n return {\n ...this.all(),\n errors: this.errors,\n }\n }\n\n /**\n * Return session as json\n * \n * @returns \n */\n toJSON () {\n return {\n ...this.all(),\n errors: this.errors.toJSON(),\n }\n }\n}","import { Session } from './Session'\nimport type { SessionInitialState } from './types'\nimport { isRecord } from '../helpers'\nimport { sessionKey } from './utils'\n\nconst attachSessionProperty = (target: Record<PropertyKey, any>, session: Session) => {\n target.httpSession = session\n\n if (!('session' in target) || target.session instanceof Session) {\n target.session = session\n }\n}\n\nexport const attachViewState = (target: Record<PropertyKey, any>, session: Session) => {\n attachSessionProperty(target, session)\n target.errors = session.errors\n\n if (isRecord(target.res)) {\n target.res.locals = {\n ...(target.res.locals || {}),\n session,\n errors: session.errors,\n }\n }\n\n if (isRecord(target.response?.source)) {\n target.response.source.locals = {\n ...(target.response.source.locals || {}),\n session,\n errors: session.errors,\n }\n }\n\n if (isRecord(target.context)) {\n attachSessionProperty(target.context, session)\n target.context.errors = session.errors\n }\n\n if (isRecord(target.state)) {\n attachSessionProperty(target.state, session)\n target.state.errors = session.errors\n }\n\n if (typeof target.set === 'function') {\n target.set('session', session)\n target.set('errors', session.errors)\n }\n}\n\n/**\n * Ensure a valid session exists\n * \n * @param ctx \n * @param initial \n * @returns \n */\nexport const ensureSession = (\n ctx: unknown,\n initial?: SessionInitialState | Record<string, any>\n): Session => {\n if (!isRecord(ctx)) {\n return new Session(initial)\n }\n\n const existing = ctx[sessionKey] ?? (ctx.session instanceof Session ? ctx.session : undefined)\n const session = existing instanceof Session\n ? existing\n : new Session(initial)\n\n ctx[sessionKey] = session\n attachViewState(ctx, session)\n\n return session\n}\n\n/**\n * Get the current session\n * \n * @param ctx \n * @returns \n */\nexport const getSession = (ctx: unknown): Session | undefined => {\n if (!isRecord(ctx)) {\n return undefined\n }\n\n const session = ctx[sessionKey] ?? ctx.session\n\n return session instanceof Session ? session : undefined\n}","import { attachViewState, ensureSession } from './helpers'\n\nimport { HttpContext } from '../types/Http'\nimport { Session } from './Session'\nimport { definePlugin as defineClearRouterPlugin } from 'clear-router/core'\nimport { definePlugin as defineKanunPlugin } from 'kanun'\n\nexport const clearRouterSessionPlugin = defineClearRouterPlugin<any, HttpContext>({\n name: 'arkstack-http-session',\n setup: ({ bind, useHttpContext }) => {\n bind(Session, ({ ctx }: { ctx: HttpContext }) => ensureSession(ctx))\n useHttpContext((context) => {\n const session = ensureSession(context.ctx)\n\n context.httpSession = session\n if (!('session' in context) || context.session instanceof Session) {\n context.session = session\n }\n context.errors = session.errors\n attachViewState(context, session)\n })\n },\n})\n\nexport const kanunSessionPlugin = defineKanunPlugin({\n name: 'kanun-session-plugin',\n install ({ onValidationError }) {\n onValidationError((validator) => {\n const currentSession = globalThis.session?.()\n\n if (currentSession instanceof Session) {\n currentSession.addValidationErrors(validator)\n }\n })\n },\n})"],"mappings":"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"}
|