@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.
@@ -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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"}