@thisisagile/easy 15.9.9 → 15.10.2

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,23 +1,23 @@
1
1
  import { Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';
2
- export declare class Req implements Omit<PageOptions, 'sort'> {
2
+ export declare class Req<T = unknown> implements Omit<PageOptions, 'sort'> {
3
3
  readonly path: Json;
4
4
  readonly query: Json;
5
- readonly body: unknown;
5
+ readonly body: T;
6
6
  readonly headers: Record<string, OneOrMore<string>>;
7
7
  readonly skip: Optional<number>;
8
8
  readonly take: Optional<number>;
9
- constructor(path: Json, query: Json, body: unknown, headers: Record<string, OneOrMore<string>>);
9
+ constructor(path: Json, query: Json, body: T, headers: Record<string, OneOrMore<string>>);
10
10
  get id(): Id;
11
11
  get q(): JsonValue;
12
12
  get: (key: Text) => any;
13
13
  }
14
- export declare const toReq: (req: {
14
+ export declare function toReq<T = unknown>(req: {
15
15
  params?: {
16
16
  id?: unknown;
17
17
  };
18
18
  query?: {
19
19
  q?: unknown;
20
20
  };
21
- body?: unknown;
21
+ body?: T;
22
22
  headers?: unknown;
23
- }) => Req;
23
+ }): Req;
@@ -43,7 +43,9 @@ class Req {
43
43
  }
44
44
  get = (key) => this.path[key.toString()] ?? this.query[key.toString()];
45
45
  }
46
- const toReq = (req) => new Req(req.params, req.query, req.body, req.headers);
46
+ function toReq(req) {
47
+ return new Req(req.params, req.query, req.body, req.headers);
48
+ }
47
49
  // Annotate the CommonJS export names for ESM import in node:
48
50
  0 && (module.exports = {
49
51
  Req,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/resources/Req.ts"],"sourcesContent":["import { asNumber, Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';\nimport { ifDefined } from '../utils';\n\nexport class Req implements Omit<PageOptions, 'sort'> {\n readonly skip: Optional<number>;\n readonly take: Optional<number>;\n constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: unknown, readonly headers: Record<string, OneOrMore<string>>) {\n this.skip = ifDefined(query.skip, s => asNumber(s));\n this.take = ifDefined(query.take, t => asNumber(t));\n }\n\n get id(): Id {\n return this.get('id');\n }\n\n get q(): JsonValue {\n return this.get('q');\n }\n\n get = (key: Text): any => this.path[key.toString()] ?? this.query[key.toString()];\n}\n\nexport const toReq = (req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: unknown; headers?: unknown }): Req =>\n new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAsF;AACtF,mBAA0B;AAEnB,MAAM,IAAyC;AAAA,EAGpD,YAAqB,OAAa,CAAC,GAAY,QAAc,CAAC,GAAY,MAAwB,SAA4C;AAAzH;AAA0B;AAA2B;AAAwB;AAChG,SAAK,WAAO,wBAAU,MAAM,MAAM,WAAK,uBAAS,CAAC,CAAC;AAClD,SAAK,WAAO,wBAAU,MAAM,MAAM,WAAK,uBAAS,CAAC,CAAC;AAAA,EACpD;AAAA,EALS;AAAA,EACA;AAAA,EAMT,IAAI,KAAS;AACX,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,IAAI,IAAe;AACjB,WAAO,KAAK,IAAI,GAAG;AAAA,EACrB;AAAA,EAEA,MAAM,CAAC,QAAmB,KAAK,KAAK,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM,IAAI,SAAS,CAAC;AAClF;AAEO,MAAM,QAAQ,CAAC,QACpB,IAAI,IAAI,IAAI,QAAgB,IAAI,OAAe,IAAI,MAAc,IAAI,OAA4C;","names":[]}
1
+ {"version":3,"sources":["../../src/resources/Req.ts"],"sourcesContent":["import { asNumber, Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';\nimport { ifDefined } from '../utils';\n\nexport class Req<T = unknown> implements Omit<PageOptions, 'sort'> {\n readonly skip: Optional<number>;\n readonly take: Optional<number>;\n constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: T, readonly headers: Record<string, OneOrMore<string>>) {\n this.skip = ifDefined(query.skip, s => asNumber(s));\n this.take = ifDefined(query.take, t => asNumber(t));\n }\n\n get id(): Id {\n return this.get('id');\n }\n\n get q(): JsonValue {\n return this.get('q');\n }\n\n get = (key: Text): any => this.path[key.toString()] ?? this.query[key.toString()];\n}\n\nexport function toReq<T = unknown>(req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: T; headers?: unknown }): Req {\n return new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAsF;AACtF,mBAA0B;AAEnB,MAAM,IAAsD;AAAA,EAGjE,YAAqB,OAAa,CAAC,GAAY,QAAc,CAAC,GAAY,MAAkB,SAA4C;AAAnH;AAA0B;AAA2B;AAAkB;AAC1F,SAAK,WAAO,wBAAU,MAAM,MAAM,WAAK,uBAAS,CAAC,CAAC;AAClD,SAAK,WAAO,wBAAU,MAAM,MAAM,WAAK,uBAAS,CAAC,CAAC;AAAA,EACpD;AAAA,EALS;AAAA,EACA;AAAA,EAMT,IAAI,KAAS;AACX,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,IAAI,IAAe;AACjB,WAAO,KAAK,IAAI,GAAG;AAAA,EACrB;AAAA,EAEA,MAAM,CAAC,QAAmB,KAAK,KAAK,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM,IAAI,SAAS,CAAC;AAClF;AAEO,SAAS,MAAmB,KAA+F;AAChI,SAAO,IAAI,IAAI,IAAI,QAAgB,IAAI,OAAe,IAAI,MAAc,IAAI,OAA4C;AAC1H;","names":[]}
@@ -20,7 +20,9 @@ class Req {
20
20
  }
21
21
  get = (key) => this.path[key.toString()] ?? this.query[key.toString()];
22
22
  }
23
- const toReq = (req) => new Req(req.params, req.query, req.body, req.headers);
23
+ function toReq(req) {
24
+ return new Req(req.params, req.query, req.body, req.headers);
25
+ }
24
26
  export {
25
27
  Req,
26
28
  toReq
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/resources/Req.ts"],"sourcesContent":["import { asNumber, Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';\nimport { ifDefined } from '../utils';\n\nexport class Req implements Omit<PageOptions, 'sort'> {\n readonly skip: Optional<number>;\n readonly take: Optional<number>;\n constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: unknown, readonly headers: Record<string, OneOrMore<string>>) {\n this.skip = ifDefined(query.skip, s => asNumber(s));\n this.take = ifDefined(query.take, t => asNumber(t));\n }\n\n get id(): Id {\n return this.get('id');\n }\n\n get q(): JsonValue {\n return this.get('q');\n }\n\n get = (key: Text): any => this.path[key.toString()] ?? this.query[key.toString()];\n}\n\nexport const toReq = (req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: unknown; headers?: unknown }): Req =>\n new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);\n"],"mappings":";AAAA,SAAS,gBAA6E;AACtF,SAAS,iBAAiB;AAEnB,MAAM,IAAyC;AAAA,EAGpD,YAAqB,OAAa,CAAC,GAAY,QAAc,CAAC,GAAY,MAAwB,SAA4C;AAAzH;AAA0B;AAA2B;AAAwB;AAChG,SAAK,OAAO,UAAU,MAAM,MAAM,OAAK,SAAS,CAAC,CAAC;AAClD,SAAK,OAAO,UAAU,MAAM,MAAM,OAAK,SAAS,CAAC,CAAC;AAAA,EACpD;AAAA,EALS;AAAA,EACA;AAAA,EAMT,IAAI,KAAS;AACX,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,IAAI,IAAe;AACjB,WAAO,KAAK,IAAI,GAAG;AAAA,EACrB;AAAA,EAEA,MAAM,CAAC,QAAmB,KAAK,KAAK,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM,IAAI,SAAS,CAAC;AAClF;AAEO,MAAM,QAAQ,CAAC,QACpB,IAAI,IAAI,IAAI,QAAgB,IAAI,OAAe,IAAI,MAAc,IAAI,OAA4C;","names":[]}
1
+ {"version":3,"sources":["../../src/resources/Req.ts"],"sourcesContent":["import { asNumber, Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';\nimport { ifDefined } from '../utils';\n\nexport class Req<T = unknown> implements Omit<PageOptions, 'sort'> {\n readonly skip: Optional<number>;\n readonly take: Optional<number>;\n constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: T, readonly headers: Record<string, OneOrMore<string>>) {\n this.skip = ifDefined(query.skip, s => asNumber(s));\n this.take = ifDefined(query.take, t => asNumber(t));\n }\n\n get id(): Id {\n return this.get('id');\n }\n\n get q(): JsonValue {\n return this.get('q');\n }\n\n get = (key: Text): any => this.path[key.toString()] ?? this.query[key.toString()];\n}\n\nexport function toReq<T = unknown>(req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: T; headers?: unknown }): Req {\n return new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);\n}\n"],"mappings":";AAAA,SAAS,gBAA6E;AACtF,SAAS,iBAAiB;AAEnB,MAAM,IAAsD;AAAA,EAGjE,YAAqB,OAAa,CAAC,GAAY,QAAc,CAAC,GAAY,MAAkB,SAA4C;AAAnH;AAA0B;AAA2B;AAAkB;AAC1F,SAAK,OAAO,UAAU,MAAM,MAAM,OAAK,SAAS,CAAC,CAAC;AAClD,SAAK,OAAO,UAAU,MAAM,MAAM,OAAK,SAAS,CAAC,CAAC;AAAA,EACpD;AAAA,EALS;AAAA,EACA;AAAA,EAMT,IAAI,KAAS;AACX,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,IAAI,IAAe;AACjB,WAAO,KAAK,IAAI,GAAG;AAAA,EACrB;AAAA,EAEA,MAAM,CAAC,QAAmB,KAAK,KAAK,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM,IAAI,SAAS,CAAC;AAClF;AAEO,SAAS,MAAmB,KAA+F;AAChI,SAAO,IAAI,IAAI,IAAI,QAAgB,IAAI,OAAe,IAAI,MAAc,IAAI,OAA4C;AAC1H;","names":[]}
@@ -23,6 +23,7 @@ export interface RequestContext {
23
23
  jwt: string;
24
24
  correlationId?: Uuid;
25
25
  lastError?: string;
26
+ lastErrorStack?: string;
26
27
  get<T>(key: string): T;
27
28
  set<T>(key: string, value: T): T;
28
29
  create: (f: () => void) => void;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/Context.ts"],"sourcesContent":["import { Uuid } from './Uuid';\nimport { text } from './Text';\nimport { Identity } from './Identity';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\n\nexport interface EnvContext {\n readonly domain: string;\n readonly name: string;\n readonly host: string;\n readonly port: number;\n readonly app: string;\n\n get(key: string, alt?: string): Optional<string>;\n}\n\nexport class DotEnvContext implements EnvContext {\n readonly domain = process.env.DOMAIN ?? 'easy';\n readonly name = process.env.ENVIRONMENT_NAME ?? '';\n readonly host = process.env.HOST ?? '';\n readonly port = Number.parseInt(process.env.PORT ?? '8080');\n readonly app = process.env.APP ?? '';\n\n readonly get = (key: string, alt?: string): Optional<string> =>\n tryTo(() =>\n text(key)\n .map(k => k.replace(/([a-z])([A-Z])/g, '$1 $2'))\n .snake.toString()\n ).map(k => process.env[k] ?? alt).value;\n}\n\nexport interface RequestContext {\n token?: any;\n identity?: Identity;\n jwt: string;\n correlationId?: Uuid;\n lastError?: string;\n get<T>(key: string): T;\n set<T>(key: string, value: T): T;\n create: (f: () => void) => void;\n wrap<T>(f: () => Promise<T>): Promise<T>;\n}\n\nexport class BaseRequestContext implements RequestContext {\n private state: any = {};\n\n get token(): any {\n return this.get('token');\n }\n\n set token(token: any) {\n this.set('token', token);\n }\n\n get identity(): Identity {\n return this.token as Identity;\n }\n\n get jwt(): string {\n return this.get('jwt');\n }\n\n set jwt(jwt: string) {\n this.set('jwt', jwt);\n }\n\n get correlationId(): Uuid {\n return this.get('correlationId');\n }\n\n set correlationId(id: Uuid) {\n this.set('correlationId', id);\n }\n\n get lastError(): Optional<string> {\n return this.get('lastError');\n }\n\n set lastError(error: Optional<string>) {\n this.set('lastError', error);\n }\n\n public get<T>(key: string): T {\n return this.state[key] as T;\n }\n\n public set<T>(key: string, value: T): T {\n return (this.state[key] = value);\n }\n\n public readonly create = (f: () => void): void => f();\n\n public readonly wrap = <T>(f: () => Promise<T>): Promise<T> => f();\n}\n\n/**\n * @deprecated Renamed to BaseRequestContext\n */\nexport class BaseContext extends BaseRequestContext {}\n\nexport interface Contexts {\n env?: EnvContext;\n request?: RequestContext;\n other?: any;\n}\n\nexport class Context {\n constructor(protected state: Contexts = {}) {\n this.state = {\n ...{\n env: new DotEnvContext(),\n request: new BaseRequestContext(),\n other: {},\n },\n ...this.state,\n };\n }\n\n get env(): EnvContext {\n return this.state.env as EnvContext;\n }\n\n set env(env: EnvContext) {\n this.state.env = env;\n }\n\n get request(): RequestContext {\n return this.state.request as RequestContext;\n }\n\n set request(request: RequestContext) {\n this.state.request = request;\n }\n\n get other(): any {\n return this.state.other;\n }\n}\n\nexport const ctx = new Context();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAqB;AAErB,iBAAsB;AAaf,MAAM,cAAoC;AAAA,EACtC,SAAS,QAAQ,IAAI,UAAU;AAAA,EAC/B,OAAO,QAAQ,IAAI,oBAAoB;AAAA,EACvC,OAAO,QAAQ,IAAI,QAAQ;AAAA,EAC3B,OAAO,OAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM;AAAA,EACjD,MAAM,QAAQ,IAAI,OAAO;AAAA,EAEzB,MAAM,CAAC,KAAa,YAC3B;AAAA,IAAM,UACJ,kBAAK,GAAG,EACL,IAAI,OAAK,EAAE,QAAQ,mBAAmB,OAAO,CAAC,EAC9C,MAAM,SAAS;AAAA,EACpB,EAAE,IAAI,OAAK,QAAQ,IAAI,CAAC,KAAK,GAAG,EAAE;AACtC;AAcO,MAAM,mBAA6C;AAAA,EAChD,QAAa,CAAC;AAAA,EAEtB,IAAI,QAAa;AACf,WAAO,KAAK,IAAI,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,MAAM,OAAY;AACpB,SAAK,IAAI,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAc;AAChB,WAAO,KAAK,IAAI,KAAK;AAAA,EACvB;AAAA,EAEA,IAAI,IAAI,KAAa;AACnB,SAAK,IAAI,OAAO,GAAG;AAAA,EACrB;AAAA,EAEA,IAAI,gBAAsB;AACxB,WAAO,KAAK,IAAI,eAAe;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc,IAAU;AAC1B,SAAK,IAAI,iBAAiB,EAAE;AAAA,EAC9B;AAAA,EAEA,IAAI,YAA8B;AAChC,WAAO,KAAK,IAAI,WAAW;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAU,OAAyB;AACrC,SAAK,IAAI,aAAa,KAAK;AAAA,EAC7B;AAAA,EAEO,IAAO,KAAgB;AAC5B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EAC5B;AAAA,EAEgB,SAAS,CAAC,MAAwB,EAAE;AAAA,EAEpC,OAAO,CAAI,MAAoC,EAAE;AACnE;AAKO,MAAM,oBAAoB,mBAAmB;AAAC;AAQ9C,MAAM,QAAQ;AAAA,EACnB,YAAsB,QAAkB,CAAC,GAAG;AAAtB;AACpB,SAAK,QAAQ;AAAA,MACX,GAAG;AAAA,QACD,KAAK,IAAI,cAAc;AAAA,QACvB,SAAS,IAAI,mBAAmB;AAAA,QAChC,OAAO,CAAC;AAAA,MACV;AAAA,MACA,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EAEA,IAAI,MAAkB;AACpB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,IAAI,KAAiB;AACvB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,IAAI,UAA0B;AAC5B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAQ,SAAyB;AACnC,SAAK,MAAM,UAAU;AAAA,EACvB;AAAA,EAEA,IAAI,QAAa;AACf,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEO,MAAM,MAAM,IAAI,QAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/types/Context.ts"],"sourcesContent":["import { Uuid } from './Uuid';\nimport { text } from './Text';\nimport { Identity } from './Identity';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\n\nexport interface EnvContext {\n readonly domain: string;\n readonly name: string;\n readonly host: string;\n readonly port: number;\n readonly app: string;\n\n get(key: string, alt?: string): Optional<string>;\n}\n\nexport class DotEnvContext implements EnvContext {\n readonly domain = process.env.DOMAIN ?? 'easy';\n readonly name = process.env.ENVIRONMENT_NAME ?? '';\n readonly host = process.env.HOST ?? '';\n readonly port = Number.parseInt(process.env.PORT ?? '8080');\n readonly app = process.env.APP ?? '';\n\n readonly get = (key: string, alt?: string): Optional<string> =>\n tryTo(() =>\n text(key)\n .map(k => k.replace(/([a-z])([A-Z])/g, '$1 $2'))\n .snake.toString()\n ).map(k => process.env[k] ?? alt).value;\n}\n\nexport interface RequestContext {\n token?: any;\n identity?: Identity;\n jwt: string;\n correlationId?: Uuid;\n lastError?: string;\n lastErrorStack?: string;\n get<T>(key: string): T;\n set<T>(key: string, value: T): T;\n create: (f: () => void) => void;\n wrap<T>(f: () => Promise<T>): Promise<T>;\n}\n\nexport class BaseRequestContext implements RequestContext {\n private state: any = {};\n\n get token(): any {\n return this.get('token');\n }\n\n set token(token: any) {\n this.set('token', token);\n }\n\n get identity(): Identity {\n return this.token as Identity;\n }\n\n get jwt(): string {\n return this.get('jwt');\n }\n\n set jwt(jwt: string) {\n this.set('jwt', jwt);\n }\n\n get correlationId(): Uuid {\n return this.get('correlationId');\n }\n\n set correlationId(id: Uuid) {\n this.set('correlationId', id);\n }\n\n get lastError(): Optional<string> {\n return this.get('lastError');\n }\n\n set lastError(error: Optional<string>) {\n this.set('lastError', error);\n }\n\n public get<T>(key: string): T {\n return this.state[key] as T;\n }\n\n public set<T>(key: string, value: T): T {\n return (this.state[key] = value);\n }\n\n public readonly create = (f: () => void): void => f();\n\n public readonly wrap = <T>(f: () => Promise<T>): Promise<T> => f();\n}\n\n/**\n * @deprecated Renamed to BaseRequestContext\n */\nexport class BaseContext extends BaseRequestContext {}\n\nexport interface Contexts {\n env?: EnvContext;\n request?: RequestContext;\n other?: any;\n}\n\nexport class Context {\n constructor(protected state: Contexts = {}) {\n this.state = {\n ...{\n env: new DotEnvContext(),\n request: new BaseRequestContext(),\n other: {},\n },\n ...this.state,\n };\n }\n\n get env(): EnvContext {\n return this.state.env as EnvContext;\n }\n\n set env(env: EnvContext) {\n this.state.env = env;\n }\n\n get request(): RequestContext {\n return this.state.request as RequestContext;\n }\n\n set request(request: RequestContext) {\n this.state.request = request;\n }\n\n get other(): any {\n return this.state.other;\n }\n}\n\nexport const ctx = new Context();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAqB;AAErB,iBAAsB;AAaf,MAAM,cAAoC;AAAA,EACtC,SAAS,QAAQ,IAAI,UAAU;AAAA,EAC/B,OAAO,QAAQ,IAAI,oBAAoB;AAAA,EACvC,OAAO,QAAQ,IAAI,QAAQ;AAAA,EAC3B,OAAO,OAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM;AAAA,EACjD,MAAM,QAAQ,IAAI,OAAO;AAAA,EAEzB,MAAM,CAAC,KAAa,YAC3B;AAAA,IAAM,UACJ,kBAAK,GAAG,EACL,IAAI,OAAK,EAAE,QAAQ,mBAAmB,OAAO,CAAC,EAC9C,MAAM,SAAS;AAAA,EACpB,EAAE,IAAI,OAAK,QAAQ,IAAI,CAAC,KAAK,GAAG,EAAE;AACtC;AAeO,MAAM,mBAA6C;AAAA,EAChD,QAAa,CAAC;AAAA,EAEtB,IAAI,QAAa;AACf,WAAO,KAAK,IAAI,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,MAAM,OAAY;AACpB,SAAK,IAAI,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAc;AAChB,WAAO,KAAK,IAAI,KAAK;AAAA,EACvB;AAAA,EAEA,IAAI,IAAI,KAAa;AACnB,SAAK,IAAI,OAAO,GAAG;AAAA,EACrB;AAAA,EAEA,IAAI,gBAAsB;AACxB,WAAO,KAAK,IAAI,eAAe;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc,IAAU;AAC1B,SAAK,IAAI,iBAAiB,EAAE;AAAA,EAC9B;AAAA,EAEA,IAAI,YAA8B;AAChC,WAAO,KAAK,IAAI,WAAW;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAU,OAAyB;AACrC,SAAK,IAAI,aAAa,KAAK;AAAA,EAC7B;AAAA,EAEO,IAAO,KAAgB;AAC5B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EAC5B;AAAA,EAEgB,SAAS,CAAC,MAAwB,EAAE;AAAA,EAEpC,OAAO,CAAI,MAAoC,EAAE;AACnE;AAKO,MAAM,oBAAoB,mBAAmB;AAAC;AAQ9C,MAAM,QAAQ;AAAA,EACnB,YAAsB,QAAkB,CAAC,GAAG;AAAtB;AACpB,SAAK,QAAQ;AAAA,MACX,GAAG;AAAA,QACD,KAAK,IAAI,cAAc;AAAA,QACvB,SAAS,IAAI,mBAAmB;AAAA,QAChC,OAAO,CAAC;AAAA,MACV;AAAA,MACA,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EAEA,IAAI,MAAkB;AACpB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,IAAI,KAAiB;AACvB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,IAAI,UAA0B;AAC5B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAQ,SAAyB;AACnC,SAAK,MAAM,UAAU;AAAA,EACvB;AAAA,EAEA,IAAI,QAAa;AACf,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEO,MAAM,MAAM,IAAI,QAAQ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/Context.ts"],"sourcesContent":["import { Uuid } from './Uuid';\nimport { text } from './Text';\nimport { Identity } from './Identity';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\n\nexport interface EnvContext {\n readonly domain: string;\n readonly name: string;\n readonly host: string;\n readonly port: number;\n readonly app: string;\n\n get(key: string, alt?: string): Optional<string>;\n}\n\nexport class DotEnvContext implements EnvContext {\n readonly domain = process.env.DOMAIN ?? 'easy';\n readonly name = process.env.ENVIRONMENT_NAME ?? '';\n readonly host = process.env.HOST ?? '';\n readonly port = Number.parseInt(process.env.PORT ?? '8080');\n readonly app = process.env.APP ?? '';\n\n readonly get = (key: string, alt?: string): Optional<string> =>\n tryTo(() =>\n text(key)\n .map(k => k.replace(/([a-z])([A-Z])/g, '$1 $2'))\n .snake.toString()\n ).map(k => process.env[k] ?? alt).value;\n}\n\nexport interface RequestContext {\n token?: any;\n identity?: Identity;\n jwt: string;\n correlationId?: Uuid;\n lastError?: string;\n get<T>(key: string): T;\n set<T>(key: string, value: T): T;\n create: (f: () => void) => void;\n wrap<T>(f: () => Promise<T>): Promise<T>;\n}\n\nexport class BaseRequestContext implements RequestContext {\n private state: any = {};\n\n get token(): any {\n return this.get('token');\n }\n\n set token(token: any) {\n this.set('token', token);\n }\n\n get identity(): Identity {\n return this.token as Identity;\n }\n\n get jwt(): string {\n return this.get('jwt');\n }\n\n set jwt(jwt: string) {\n this.set('jwt', jwt);\n }\n\n get correlationId(): Uuid {\n return this.get('correlationId');\n }\n\n set correlationId(id: Uuid) {\n this.set('correlationId', id);\n }\n\n get lastError(): Optional<string> {\n return this.get('lastError');\n }\n\n set lastError(error: Optional<string>) {\n this.set('lastError', error);\n }\n\n public get<T>(key: string): T {\n return this.state[key] as T;\n }\n\n public set<T>(key: string, value: T): T {\n return (this.state[key] = value);\n }\n\n public readonly create = (f: () => void): void => f();\n\n public readonly wrap = <T>(f: () => Promise<T>): Promise<T> => f();\n}\n\n/**\n * @deprecated Renamed to BaseRequestContext\n */\nexport class BaseContext extends BaseRequestContext {}\n\nexport interface Contexts {\n env?: EnvContext;\n request?: RequestContext;\n other?: any;\n}\n\nexport class Context {\n constructor(protected state: Contexts = {}) {\n this.state = {\n ...{\n env: new DotEnvContext(),\n request: new BaseRequestContext(),\n other: {},\n },\n ...this.state,\n };\n }\n\n get env(): EnvContext {\n return this.state.env as EnvContext;\n }\n\n set env(env: EnvContext) {\n this.state.env = env;\n }\n\n get request(): RequestContext {\n return this.state.request as RequestContext;\n }\n\n set request(request: RequestContext) {\n this.state.request = request;\n }\n\n get other(): any {\n return this.state.other;\n }\n}\n\nexport const ctx = new Context();\n"],"mappings":";AACA,SAAS,YAAY;AAErB,SAAS,aAAa;AAaf,MAAM,cAAoC;AAAA,EACtC,SAAS,QAAQ,IAAI,UAAU;AAAA,EAC/B,OAAO,QAAQ,IAAI,oBAAoB;AAAA,EACvC,OAAO,QAAQ,IAAI,QAAQ;AAAA,EAC3B,OAAO,OAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM;AAAA,EACjD,MAAM,QAAQ,IAAI,OAAO;AAAA,EAEzB,MAAM,CAAC,KAAa,QAC3B;AAAA,IAAM,MACJ,KAAK,GAAG,EACL,IAAI,OAAK,EAAE,QAAQ,mBAAmB,OAAO,CAAC,EAC9C,MAAM,SAAS;AAAA,EACpB,EAAE,IAAI,OAAK,QAAQ,IAAI,CAAC,KAAK,GAAG,EAAE;AACtC;AAcO,MAAM,mBAA6C;AAAA,EAChD,QAAa,CAAC;AAAA,EAEtB,IAAI,QAAa;AACf,WAAO,KAAK,IAAI,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,MAAM,OAAY;AACpB,SAAK,IAAI,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAc;AAChB,WAAO,KAAK,IAAI,KAAK;AAAA,EACvB;AAAA,EAEA,IAAI,IAAI,KAAa;AACnB,SAAK,IAAI,OAAO,GAAG;AAAA,EACrB;AAAA,EAEA,IAAI,gBAAsB;AACxB,WAAO,KAAK,IAAI,eAAe;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc,IAAU;AAC1B,SAAK,IAAI,iBAAiB,EAAE;AAAA,EAC9B;AAAA,EAEA,IAAI,YAA8B;AAChC,WAAO,KAAK,IAAI,WAAW;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAU,OAAyB;AACrC,SAAK,IAAI,aAAa,KAAK;AAAA,EAC7B;AAAA,EAEO,IAAO,KAAgB;AAC5B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EAC5B;AAAA,EAEgB,SAAS,CAAC,MAAwB,EAAE;AAAA,EAEpC,OAAO,CAAI,MAAoC,EAAE;AACnE;AAKO,MAAM,oBAAoB,mBAAmB;AAAC;AAQ9C,MAAM,QAAQ;AAAA,EACnB,YAAsB,QAAkB,CAAC,GAAG;AAAtB;AACpB,SAAK,QAAQ;AAAA,MACX,GAAG;AAAA,QACD,KAAK,IAAI,cAAc;AAAA,QACvB,SAAS,IAAI,mBAAmB;AAAA,QAChC,OAAO,CAAC;AAAA,MACV;AAAA,MACA,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EAEA,IAAI,MAAkB;AACpB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,IAAI,KAAiB;AACvB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,IAAI,UAA0B;AAC5B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAQ,SAAyB;AACnC,SAAK,MAAM,UAAU;AAAA,EACvB;AAAA,EAEA,IAAI,QAAa;AACf,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEO,MAAM,MAAM,IAAI,QAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/types/Context.ts"],"sourcesContent":["import { Uuid } from './Uuid';\nimport { text } from './Text';\nimport { Identity } from './Identity';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\n\nexport interface EnvContext {\n readonly domain: string;\n readonly name: string;\n readonly host: string;\n readonly port: number;\n readonly app: string;\n\n get(key: string, alt?: string): Optional<string>;\n}\n\nexport class DotEnvContext implements EnvContext {\n readonly domain = process.env.DOMAIN ?? 'easy';\n readonly name = process.env.ENVIRONMENT_NAME ?? '';\n readonly host = process.env.HOST ?? '';\n readonly port = Number.parseInt(process.env.PORT ?? '8080');\n readonly app = process.env.APP ?? '';\n\n readonly get = (key: string, alt?: string): Optional<string> =>\n tryTo(() =>\n text(key)\n .map(k => k.replace(/([a-z])([A-Z])/g, '$1 $2'))\n .snake.toString()\n ).map(k => process.env[k] ?? alt).value;\n}\n\nexport interface RequestContext {\n token?: any;\n identity?: Identity;\n jwt: string;\n correlationId?: Uuid;\n lastError?: string;\n lastErrorStack?: string;\n get<T>(key: string): T;\n set<T>(key: string, value: T): T;\n create: (f: () => void) => void;\n wrap<T>(f: () => Promise<T>): Promise<T>;\n}\n\nexport class BaseRequestContext implements RequestContext {\n private state: any = {};\n\n get token(): any {\n return this.get('token');\n }\n\n set token(token: any) {\n this.set('token', token);\n }\n\n get identity(): Identity {\n return this.token as Identity;\n }\n\n get jwt(): string {\n return this.get('jwt');\n }\n\n set jwt(jwt: string) {\n this.set('jwt', jwt);\n }\n\n get correlationId(): Uuid {\n return this.get('correlationId');\n }\n\n set correlationId(id: Uuid) {\n this.set('correlationId', id);\n }\n\n get lastError(): Optional<string> {\n return this.get('lastError');\n }\n\n set lastError(error: Optional<string>) {\n this.set('lastError', error);\n }\n\n public get<T>(key: string): T {\n return this.state[key] as T;\n }\n\n public set<T>(key: string, value: T): T {\n return (this.state[key] = value);\n }\n\n public readonly create = (f: () => void): void => f();\n\n public readonly wrap = <T>(f: () => Promise<T>): Promise<T> => f();\n}\n\n/**\n * @deprecated Renamed to BaseRequestContext\n */\nexport class BaseContext extends BaseRequestContext {}\n\nexport interface Contexts {\n env?: EnvContext;\n request?: RequestContext;\n other?: any;\n}\n\nexport class Context {\n constructor(protected state: Contexts = {}) {\n this.state = {\n ...{\n env: new DotEnvContext(),\n request: new BaseRequestContext(),\n other: {},\n },\n ...this.state,\n };\n }\n\n get env(): EnvContext {\n return this.state.env as EnvContext;\n }\n\n set env(env: EnvContext) {\n this.state.env = env;\n }\n\n get request(): RequestContext {\n return this.state.request as RequestContext;\n }\n\n set request(request: RequestContext) {\n this.state.request = request;\n }\n\n get other(): any {\n return this.state.other;\n }\n}\n\nexport const ctx = new Context();\n"],"mappings":";AACA,SAAS,YAAY;AAErB,SAAS,aAAa;AAaf,MAAM,cAAoC;AAAA,EACtC,SAAS,QAAQ,IAAI,UAAU;AAAA,EAC/B,OAAO,QAAQ,IAAI,oBAAoB;AAAA,EACvC,OAAO,QAAQ,IAAI,QAAQ;AAAA,EAC3B,OAAO,OAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM;AAAA,EACjD,MAAM,QAAQ,IAAI,OAAO;AAAA,EAEzB,MAAM,CAAC,KAAa,QAC3B;AAAA,IAAM,MACJ,KAAK,GAAG,EACL,IAAI,OAAK,EAAE,QAAQ,mBAAmB,OAAO,CAAC,EAC9C,MAAM,SAAS;AAAA,EACpB,EAAE,IAAI,OAAK,QAAQ,IAAI,CAAC,KAAK,GAAG,EAAE;AACtC;AAeO,MAAM,mBAA6C;AAAA,EAChD,QAAa,CAAC;AAAA,EAEtB,IAAI,QAAa;AACf,WAAO,KAAK,IAAI,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,MAAM,OAAY;AACpB,SAAK,IAAI,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAc;AAChB,WAAO,KAAK,IAAI,KAAK;AAAA,EACvB;AAAA,EAEA,IAAI,IAAI,KAAa;AACnB,SAAK,IAAI,OAAO,GAAG;AAAA,EACrB;AAAA,EAEA,IAAI,gBAAsB;AACxB,WAAO,KAAK,IAAI,eAAe;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc,IAAU;AAC1B,SAAK,IAAI,iBAAiB,EAAE;AAAA,EAC9B;AAAA,EAEA,IAAI,YAA8B;AAChC,WAAO,KAAK,IAAI,WAAW;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAU,OAAyB;AACrC,SAAK,IAAI,aAAa,KAAK;AAAA,EAC7B;AAAA,EAEO,IAAO,KAAgB;AAC5B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EAC5B;AAAA,EAEgB,SAAS,CAAC,MAAwB,EAAE;AAAA,EAEpC,OAAO,CAAI,MAAoC,EAAE;AACnE;AAKO,MAAM,oBAAoB,mBAAmB;AAAC;AAQ9C,MAAM,QAAQ;AAAA,EACnB,YAAsB,QAAkB,CAAC,GAAG;AAAtB;AACpB,SAAK,QAAQ;AAAA,MACX,GAAG;AAAA,QACD,KAAK,IAAI,cAAc;AAAA,QACvB,SAAS,IAAI,mBAAmB;AAAA,QAChC,OAAO,CAAC;AAAA,MACV;AAAA,MACA,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EAEA,IAAI,MAAkB;AACpB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,IAAI,KAAiB;AACvB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,IAAI,UAA0B;AAC5B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAQ,SAAyB;AACnC,SAAK,MAAM,UAAU;AAAA,EACvB;AAAA,EAEA,IAAI,QAAa;AACf,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEO,MAAM,MAAM,IAAI,QAAQ;","names":[]}
@@ -1,4 +1,6 @@
1
+ import { Json } from "../types";
1
2
  export declare const base64: {
2
3
  decode: (data: string) => string;
3
4
  encode: (data: string) => string;
5
+ toJson: (data: string) => Json;
4
6
  };
@@ -23,7 +23,8 @@ __export(Base64_exports, {
23
23
  module.exports = __toCommonJS(Base64_exports);
24
24
  const base64 = {
25
25
  decode: (data) => Buffer.from(data, "base64").toString("utf-8"),
26
- encode: (data) => Buffer.from(data, "utf-8").toString("base64")
26
+ encode: (data) => Buffer.from(data, "utf-8").toString("base64"),
27
+ toJson: (data) => JSON.parse(base64.decode(data))
27
28
  };
28
29
  // Annotate the CommonJS export names for ESM import in node:
29
30
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/Base64.ts"],"sourcesContent":["export const base64 = {\n decode: (data: string): string => Buffer.from(data, \"base64\").toString(\"utf-8\"),\n encode: (data: string): string => Buffer.from(data, \"utf-8\").toString(\"base64\")\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,SAAS;AAAA,EACpB,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,QAAQ,EAAE,SAAS,OAAO;AAAA,EAC9E,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAChF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/Base64.ts"],"sourcesContent":["import { Json } from \"../types\";\n\nexport const base64 = {\n decode: (data: string): string => Buffer.from(data, \"base64\").toString(\"utf-8\"),\n encode: (data: string): string => Buffer.from(data, \"utf-8\").toString(\"base64\"),\n toJson: (data: string): Json => JSON.parse(base64.decode(data))\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,SAAS;AAAA,EACpB,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,QAAQ,EAAE,SAAS,OAAO;AAAA,EAC9E,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAAA,EAC9E,QAAQ,CAAC,SAAuB,KAAK,MAAM,OAAO,OAAO,IAAI,CAAC;AAChE;","names":[]}
@@ -1,7 +1,8 @@
1
1
  import "../chunk-4N72FQFX.mjs";
2
2
  const base64 = {
3
3
  decode: (data) => Buffer.from(data, "base64").toString("utf-8"),
4
- encode: (data) => Buffer.from(data, "utf-8").toString("base64")
4
+ encode: (data) => Buffer.from(data, "utf-8").toString("base64"),
5
+ toJson: (data) => JSON.parse(base64.decode(data))
5
6
  };
6
7
  export {
7
8
  base64
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/Base64.ts"],"sourcesContent":["export const base64 = {\n decode: (data: string): string => Buffer.from(data, \"base64\").toString(\"utf-8\"),\n encode: (data: string): string => Buffer.from(data, \"utf-8\").toString(\"base64\")\n};\n"],"mappings":";AAAO,MAAM,SAAS;AAAA,EACpB,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,QAAQ,EAAE,SAAS,OAAO;AAAA,EAC9E,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAChF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/Base64.ts"],"sourcesContent":["import { Json } from \"../types\";\n\nexport const base64 = {\n decode: (data: string): string => Buffer.from(data, \"base64\").toString(\"utf-8\"),\n encode: (data: string): string => Buffer.from(data, \"utf-8\").toString(\"base64\"),\n toJson: (data: string): Json => JSON.parse(base64.decode(data))\n};\n"],"mappings":";AAEO,MAAM,SAAS;AAAA,EACpB,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,QAAQ,EAAE,SAAS,OAAO;AAAA,EAC9E,QAAQ,CAAC,SAAyB,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAAA,EAC9E,QAAQ,CAAC,SAAuB,KAAK,MAAM,OAAO,OAAO,IAAI,CAAC;AAChE;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thisisagile/easy",
3
- "version": "15.9.9",
3
+ "version": "15.10.2",
4
4
  "description": "Straightforward library for building domain-driven microservice architectures",
5
5
  "author": "Sander Hoogendoorn",
6
6
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "devDependencies": {
36
- "@thisisagile/easy-test": "15.9.9",
36
+ "@thisisagile/easy-test": "15.10.2",
37
37
  "@types/form-urlencoded": "^4.4.0",
38
38
  "@types/jsonwebtoken": "^9.0.2",
39
39
  "@types/luxon": "3.2.0",
@@ -1,10 +1,10 @@
1
1
  import { asNumber, Id, Json, JsonValue, OneOrMore, Optional, PageOptions, Text } from '../types';
2
2
  import { ifDefined } from '../utils';
3
3
 
4
- export class Req implements Omit<PageOptions, 'sort'> {
4
+ export class Req<T = unknown> implements Omit<PageOptions, 'sort'> {
5
5
  readonly skip: Optional<number>;
6
6
  readonly take: Optional<number>;
7
- constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: unknown, readonly headers: Record<string, OneOrMore<string>>) {
7
+ constructor(readonly path: Json = {}, readonly query: Json = {}, readonly body: T, readonly headers: Record<string, OneOrMore<string>>) {
8
8
  this.skip = ifDefined(query.skip, s => asNumber(s));
9
9
  this.take = ifDefined(query.take, t => asNumber(t));
10
10
  }
@@ -20,5 +20,6 @@ export class Req implements Omit<PageOptions, 'sort'> {
20
20
  get = (key: Text): any => this.path[key.toString()] ?? this.query[key.toString()];
21
21
  }
22
22
 
23
- export const toReq = (req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: unknown; headers?: unknown }): Req =>
24
- new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);
23
+ export function toReq<T = unknown>(req: { params?: { id?: unknown }; query?: { q?: unknown }; body?: T; headers?: unknown }): Req {
24
+ return new Req(req.params as Json, req.query as Json, req.body as Json, req.headers as Record<string, OneOrMore<string>>);
25
+ }
@@ -35,6 +35,7 @@ export interface RequestContext {
35
35
  jwt: string;
36
36
  correlationId?: Uuid;
37
37
  lastError?: string;
38
+ lastErrorStack?: string;
38
39
  get<T>(key: string): T;
39
40
  set<T>(key: string, value: T): T;
40
41
  create: (f: () => void) => void;
@@ -1,4 +1,7 @@
1
+ import { Json } from "../types";
2
+
1
3
  export const base64 = {
2
4
  decode: (data: string): string => Buffer.from(data, "base64").toString("utf-8"),
3
- encode: (data: string): string => Buffer.from(data, "utf-8").toString("base64")
5
+ encode: (data: string): string => Buffer.from(data, "utf-8").toString("base64"),
6
+ toJson: (data: string): Json => JSON.parse(base64.decode(data))
4
7
  };