@thisisagile/easy-express 17.25.2 → 17.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,3 +1,207 @@
1
- export * from "./express";
2
- export * from "./types";
1
+ // src/express/AuthError.ts
2
+ import { isError } from "@thisisagile/easy";
3
+ var AuthError = class extends Error {
4
+ status;
5
+ constructor({ name, status }) {
6
+ super(name);
7
+ this.name = "AuthenticationError";
8
+ this.status = status;
9
+ }
10
+ };
11
+ var authError = (status) => new AuthError(status);
12
+ var isAuthError = (e) => isError(e) && e.name === "AuthenticationError";
13
+
14
+ // src/express/CorrelationHandler.ts
15
+ import { ctx, HttpHeader, toUuid } from "@thisisagile/easy";
16
+ var correlation = (req, res, next) => {
17
+ res.setHeader(HttpHeader.Correlation, ctx.request.correlationId = req?.header(HttpHeader.Correlation) ?? toUuid());
18
+ next();
19
+ };
20
+
21
+ // src/express/ErrorHandler.ts
22
+ import {
23
+ asString,
24
+ choose,
25
+ ctx as ctx2,
26
+ HttpStatus as HttpStatus2,
27
+ isDoesNotExist,
28
+ isError as isError2,
29
+ isException,
30
+ isResponse,
31
+ isResults,
32
+ isText,
33
+ rest,
34
+ toHttpStatus,
35
+ toResult,
36
+ tryTo
37
+ } from "@thisisagile/easy";
38
+ import { toOriginatedError } from "@thisisagile/easy-service";
39
+ var toResponse = (status, errors = []) => ({
40
+ status,
41
+ body: rest.toError(status, errors)
42
+ });
43
+ var toBody = ({ origin, options }) => {
44
+ return choose(origin).type(isAuthError, (ae) => toResponse(toHttpStatus(ae.status), [toResult(ae.message)])).type(isDoesNotExist, (e) => toResponse(options?.onNotFound ?? HttpStatus2.NotFound, [toResult(e.reason ?? e.message)])).type(isError2, (e) => toResponse(HttpStatus2.InternalServerError, [toResult(e.message)])).type(isResults, (r) => toResponse(options?.onError ?? HttpStatus2.BadRequest, r.results)).type(isResponse, (r) => toResponse(HttpStatus2.InternalServerError, r.body.error?.errors)).type(isException, (e) => toResponse(options?.onError ?? HttpStatus2.BadRequest, [toResult(e.reason ?? e.message)])).type(isText, (t) => toResponse(options?.onError ?? HttpStatus2.BadRequest, [toResult(asString(t))])).else(() => toResponse(HttpStatus2.InternalServerError, [toResult("Unknown error")]));
45
+ };
46
+ var error = (e, req, res, _next) => {
47
+ let response;
48
+ tryTo(() => toOriginatedError(e)).map((oe) => toBody(oe)).accept((r) => response = r).accept((r) => ctx2.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : void 0).accept((r) => ctx2.request.lastErrorStack = r.status.isServerError ? e.stack : void 0).recover(() => response).accept((r) => res.status(r.status.status).json(r.body));
49
+ };
50
+
51
+ // src/express/ExpressProvider.ts
52
+ import express from "express";
53
+
54
+ // src/express/SecurityHandler.ts
55
+ import passport from "passport";
56
+ import { ExtractJwt, Strategy as JwtStrategy } from "passport-jwt";
57
+ import { ctx as ctx3, Environment, HttpStatus as HttpStatus3, ifFalse } from "@thisisagile/easy";
58
+ var checkLabCoat = () => (req, res, next) => next(ifFalse(Environment.Dev.equals(ctx3.env.name), authError(HttpStatus3.Forbidden)));
59
+ var checkToken = () => passport.authenticate("jwt", { session: false, failWithError: true });
60
+ var checkScope = (scope) => (req, res, next) => next(ifFalse(req.user?.scopes?.includes(scope.id), authError(HttpStatus3.Forbidden)));
61
+ var checkUseCase = (uc) => (req, res, next) => next(ifFalse(req.user?.usecases?.includes(uc.id), authError(HttpStatus3.Forbidden)));
62
+ var wrapSecretOrKeyProvider = (p) => p ? (request, rawJwtToken, done) => p(request, rawJwtToken).then((t) => done(null, t)).catch((e) => done(e)) : void 0;
63
+ var security = ({ jwtStrategyOptions } = {}) => {
64
+ jwtStrategyOptions ??= {};
65
+ if ("secretOrKeyProvider" in jwtStrategyOptions)
66
+ jwtStrategyOptions.secretOrKeyProvider = wrapSecretOrKeyProvider(jwtStrategyOptions.secretOrKeyProvider);
67
+ else if (!("secretOrKey" in jwtStrategyOptions))
68
+ jwtStrategyOptions.secretOrKey = ctx3.env.get("tokenPublicKey");
69
+ const strategy = new JwtStrategy(
70
+ {
71
+ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
72
+ passReqToCallback: true,
73
+ ...jwtStrategyOptions
74
+ },
75
+ (req, payload, done) => {
76
+ ctx3.request.token = payload;
77
+ ctx3.request.jwt = ExtractJwt.fromAuthHeaderAsBearerToken()(req) ?? "";
78
+ done(null, payload);
79
+ }
80
+ );
81
+ passport.use(strategy);
82
+ return passport.initialize();
83
+ };
84
+
85
+ // src/express/ExpressProvider.ts
86
+ import { HttpStatus as HttpStatus4, isEmpty, rest as rest2, toList, toReq } from "@thisisagile/easy";
87
+ import {
88
+ routes,
89
+ Service,
90
+ toOriginatedError as toOriginatedError2,
91
+ toVerbOptions
92
+ } from "@thisisagile/easy-service";
93
+ var ExpressProvider = class {
94
+ constructor(app = express()) {
95
+ this.app = app;
96
+ this.app.set("trust proxy", ["loopback", "linklocal", "uniquelocal"]);
97
+ }
98
+ use = (handler) => {
99
+ this.app.use(handler);
100
+ };
101
+ route = (service2, resource) => {
102
+ const { route, endpoints, middleware } = routes(resource);
103
+ const router = express.Router({ mergeParams: true });
104
+ if (!isEmpty(middleware))
105
+ router.all(route.route(service2.name), middleware);
106
+ endpoints.forEach(({ endpoint, verb, requires, middleware: middleware2 }) => {
107
+ console.log(verb.verb.code, route.route(service2.name));
108
+ router[verb.verb.toString()](
109
+ route.route(service2.name),
110
+ ...this.addSecurityMiddleware(requires),
111
+ ...middleware2,
112
+ this.handle(endpoint, verb.options, requires)
113
+ );
114
+ });
115
+ this.app.use(router);
116
+ };
117
+ listen = (port, message = `Service is listening on port ${port}.`) => {
118
+ this.app.listen(port, () => {
119
+ console.log(message);
120
+ });
121
+ };
122
+ addSecurityMiddleware(requires) {
123
+ const middleware = [];
124
+ if (requires.labCoat)
125
+ middleware.push(checkLabCoat());
126
+ if (requires.token)
127
+ middleware.push(checkToken());
128
+ if (requires.scope)
129
+ middleware.push(checkScope(requires.scope));
130
+ if (requires.uc)
131
+ middleware.push(checkUseCase(requires.uc));
132
+ return middleware;
133
+ }
134
+ handle = (endpoint, options, requires) => (req, res, next) => endpoint(toReq(req)).then((r) => this.toResponse(res, r, toVerbOptions(options))).catch((error2) => next(toOriginatedError2(error2, options)));
135
+ toResponse(res, result, options) {
136
+ res.status(options.onOk.status);
137
+ res.type(options.type.code);
138
+ if (options.cache.enabled)
139
+ res.setHeader(options.cache.name, options.cache.value());
140
+ (this[options.type.name] ?? this.json)(res, result, options);
141
+ }
142
+ // Handling responses depending on content type
143
+ json(res, result, options) {
144
+ if (HttpStatus4.NoContent.equals(options.onOk)) {
145
+ res.send();
146
+ } else {
147
+ res.json(rest2.toData(options.onOk, toList(result), result?.total, result?.meta));
148
+ }
149
+ }
150
+ rawJson(res, result, options) {
151
+ if (HttpStatus4.NoContent.equals(options.onOk)) {
152
+ res.send();
153
+ } else {
154
+ res.json(result);
155
+ }
156
+ }
157
+ stream(res, result) {
158
+ res.end(result);
159
+ }
160
+ text(res, data) {
161
+ res.send(data);
162
+ }
163
+ };
164
+ var service = (name) => new Service(name, new ExpressProvider());
165
+
166
+ // src/express/NotFoundHandler.ts
167
+ import { Exception } from "@thisisagile/easy";
168
+ import { toOriginatedError as toOriginatedError3 } from "@thisisagile/easy-service";
169
+ var notFound = (req, res, next) => {
170
+ next(toOriginatedError3(Exception.DoesNotExist));
171
+ };
172
+
173
+ // src/express/RequestContextHandler.ts
174
+ import { ctx as ctx4 } from "@thisisagile/easy";
175
+ var requestContext = (req, res, next) => ctx4.request.create(() => next());
176
+
177
+ // src/types/NamespaceContext.ts
178
+ import { createNamespace } from "cls-hooked";
179
+ import { BaseRequestContext } from "@thisisagile/easy";
180
+ var NamespaceContext = class extends BaseRequestContext {
181
+ namespace = createNamespace("context");
182
+ get(key) {
183
+ return this.namespace.get(key);
184
+ }
185
+ set(key, value) {
186
+ return this.namespace.set(key, value);
187
+ }
188
+ create = (f) => this.namespace.run(f);
189
+ };
190
+ export {
191
+ AuthError,
192
+ ExpressProvider,
193
+ NamespaceContext,
194
+ authError,
195
+ checkLabCoat,
196
+ checkScope,
197
+ checkToken,
198
+ checkUseCase,
199
+ correlation,
200
+ error,
201
+ isAuthError,
202
+ notFound,
203
+ requestContext,
204
+ security,
205
+ service
206
+ };
3
207
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './express';\nexport * from './types';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/express/AuthError.ts","../src/express/CorrelationHandler.ts","../src/express/ErrorHandler.ts","../src/express/ExpressProvider.ts","../src/express/SecurityHandler.ts","../src/express/NotFoundHandler.ts","../src/express/RequestContextHandler.ts","../src/types/NamespaceContext.ts"],"sourcesContent":["import { HttpStatus, isError } from '@thisisagile/easy';\n\nexport class AuthError extends Error {\n status: number;\n\n constructor({ name, status }: HttpStatus) {\n super(name);\n this.name = 'AuthenticationError';\n this.status = status;\n }\n}\n\nexport const authError = (status: HttpStatus): AuthError => new AuthError(status);\n\nexport const isAuthError = (e?: unknown): e is AuthError => isError(e) && e.name === 'AuthenticationError';\n","import express from 'express';\nimport { ctx, HttpHeader, toUuid } from '@thisisagile/easy';\n\nexport const correlation = (req: express.Request, res: express.Response, next: express.NextFunction): void => {\n res.setHeader(HttpHeader.Correlation, (ctx.request.correlationId = req?.header(HttpHeader.Correlation) ?? toUuid()));\n next();\n};\n","import express from 'express';\nimport { isAuthError } from './AuthError';\nimport {\n asString,\n choose,\n ctx,\n HttpStatus,\n isDoesNotExist,\n isError,\n isException,\n isResponse,\n isResults,\n isText,\n Response,\n rest,\n Result,\n toHttpStatus,\n toResult,\n tryTo,\n} from '@thisisagile/easy';\nimport { OriginatedError, toOriginatedError } from '@thisisagile/easy-service';\n\nconst toResponse = (status: HttpStatus, errors: Result[] = []): Response => ({\n status,\n body: rest.toError(status, errors),\n});\n\nconst toBody = ({ origin, options }: OriginatedError): Response => {\n return (\n choose(origin)\n .type(isAuthError, ae => toResponse(toHttpStatus(ae.status), [toResult(ae.message)]))\n .type(isDoesNotExist, e => toResponse(options?.onNotFound ?? HttpStatus.NotFound, [toResult(e.reason ?? e.message)]))\n // This service breaks with an error\n .type(isError, e => toResponse(HttpStatus.InternalServerError, [toResult(e.message)]))\n // This service fails\n .type(isResults, r => toResponse(options?.onError ?? HttpStatus.BadRequest, r.results))\n // Underlying service fails\n .type(isResponse, r => toResponse(HttpStatus.InternalServerError, r.body.error?.errors))\n .type(isException, e => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(e.reason ?? e.message)]))\n // This service fails with a string\n .type(isText, t => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(asString(t))]))\n .else(() => toResponse(HttpStatus.InternalServerError, [toResult('Unknown error')]))\n );\n};\n\nexport const error = (e: Error, req: express.Request, res: express.Response, _next: express.NextFunction): void => {\n let response: Response;\n tryTo(() => toOriginatedError(e))\n .map(oe => toBody(oe))\n .accept(r => (response = r))\n .accept(r => (ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined))\n .accept(r => (ctx.request.lastErrorStack = r.status.isServerError ? e.stack : undefined))\n .recover(() => response)\n .accept(r => res.status(r.status.status).json(r.body));\n};\n","import express, { Express, NextFunction, Request, RequestHandler, Response } from 'express';\nimport { checkLabCoat, checkScope, checkToken, checkUseCase } from './SecurityHandler';\nimport { HttpStatus, isEmpty, PageList, rest, toList, toReq } from '@thisisagile/easy';\nimport {\n AppProvider,\n Endpoint,\n Handler,\n Resource,\n Route,\n RouteRequires,\n routes,\n Service,\n toOriginatedError,\n toVerbOptions,\n VerbOptions,\n} from '@thisisagile/easy-service';\n\nexport type ExpressVerb = 'get' | 'post' | 'put' | 'patch' | 'delete';\n\nexport class ExpressProvider implements AppProvider {\n constructor(protected app: Express = express()) {\n this.app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']);\n }\n\n use = (handler: Handler): void => {\n this.app.use(handler);\n };\n\n route = (service: Service, resource: Resource): void => {\n const { route, endpoints, middleware } = routes(resource);\n const router = express.Router({ mergeParams: true });\n if (!isEmpty(middleware)) router.all(route.route(service.name), middleware);\n\n endpoints.forEach(({ endpoint, verb, requires, middleware }: Route) => {\n console.log(verb.verb.code, route.route(service.name));\n router[verb.verb.toString() as ExpressVerb](\n route.route(service.name),\n ...this.addSecurityMiddleware(requires),\n ...middleware,\n this.handle(endpoint, verb.options, requires)\n );\n });\n\n this.app.use(router);\n };\n\n listen = (port: number, message = `Service is listening on port ${port}.`): void => {\n this.app.listen(port, () => {\n console.log(message);\n });\n };\n\n protected addSecurityMiddleware(requires: RouteRequires): RequestHandler[] {\n const middleware: RequestHandler[] = [];\n if (requires.labCoat) middleware.push(checkLabCoat());\n if (requires.token) middleware.push(checkToken());\n if (requires.scope) middleware.push(checkScope(requires.scope));\n if (requires.uc) middleware.push(checkUseCase(requires.uc));\n return middleware;\n }\n\n protected handle =\n (endpoint: Endpoint, options?: VerbOptions, requires?: RouteRequires): RequestHandler =>\n (req: Request, res: Response, next: NextFunction) =>\n endpoint(toReq(req))\n .then((r: any) => this.toResponse(res, r, toVerbOptions(options)))\n .catch(error => next(toOriginatedError(error, options)));\n\n protected toResponse(res: Response, result: unknown, options: Required<VerbOptions>): void {\n res.status(options.onOk.status);\n res.type(options.type.code);\n if (options.cache.enabled) res.setHeader(options.cache.name, options.cache.value());\n\n ((this as any)[options.type.name] ?? this.json)(res, result, options);\n }\n\n // Handling responses depending on content type\n\n protected json(res: Response, result: unknown, options: Required<VerbOptions>): void {\n if (HttpStatus.NoContent.equals(options.onOk)) {\n res.send();\n } else {\n res.json(rest.toData(options.onOk, toList<any>(result), (result as PageList<any>)?.total, (result as PageList<any>)?.meta));\n }\n }\n\n protected rawJson(res: Response, result: unknown, options: Required<VerbOptions>): void {\n if (HttpStatus.NoContent.equals(options.onOk)) {\n res.send();\n } else {\n res.json(result);\n }\n }\n\n protected stream(res: Response, result: unknown): void {\n res.end(result);\n }\n\n protected text(res: Response, data: unknown): void {\n res.send(data);\n }\n}\n\nexport const service = (name: string): Service => new Service(name, new ExpressProvider());\n","import type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport passport from 'passport';\nimport { ExtractJwt, Strategy as JwtStrategy } from 'passport-jwt';\nimport type { SecretOrKeyProvider, StrategyOptionsWithRequest } from 'passport-jwt';\nimport type { Algorithm } from 'jsonwebtoken';\nimport { authError } from './AuthError';\nimport { ctx, Environment, HttpStatus, ifFalse } from '@thisisagile/easy';\nimport type { Scope, UseCase } from '@thisisagile/easy';\n\ntype EasySecretOrKeyProvider = (request: Request, rawJwtToken: any) => Promise<string | Buffer>;\n\nexport interface SecurityOptions {\n /** Configuration for verifying JWTs */\n jwtStrategyOptions?: {\n /** The secret (symmetric) or PEM-encoded public key (asymmetric) for verifying the token's signature.\n * REQUIRED unless secretOrKeyProvider is provided. Defaults to JWT_PUBLIC_KEY from the system environment. */\n secretOrKey?: string | Buffer;\n\n /** Should return a secret (symmetric) or PEM-encoded public key (asymmetric) for the given key and request combination.\n * REQUIRED unless secretOrKey is provided. Note it is up to the implementer to decode rawJwtToken. */\n secretOrKeyProvider?: EasySecretOrKeyProvider;\n\n /** If defined, the token issuer (iss) will be verified against this value. */\n issuer?: string;\n\n /** If defined, the token audience (aud) will be verified against this value. */\n audience?: string;\n\n /** If defined, the token algorithm (alg) must be in this list. */\n algorithms?: Algorithm[];\n };\n}\n\nexport const checkLabCoat = (): RequestHandler => (req, res, next) => next(ifFalse(Environment.Dev.equals(ctx.env.name), authError(HttpStatus.Forbidden)));\n\nexport const checkToken = (): RequestHandler => passport.authenticate('jwt', { session: false, failWithError: true });\n\nexport const checkScope =\n (scope: Scope): RequestHandler =>\n (req, res, next) =>\n next(ifFalse((req.user as any)?.scopes?.includes(scope.id), authError(HttpStatus.Forbidden)));\n\nexport const checkUseCase =\n (uc: UseCase): RequestHandler =>\n (req, res, next) =>\n next(ifFalse((req.user as any)?.usecases?.includes(uc.id), authError(HttpStatus.Forbidden)));\n\nconst wrapSecretOrKeyProvider = (p?: EasySecretOrKeyProvider): SecretOrKeyProvider | undefined =>\n p\n ? (request, rawJwtToken, done) =>\n p(request, rawJwtToken)\n .then(t => done(null, t))\n .catch(e => done(e))\n : undefined;\n\nexport const security = ({ jwtStrategyOptions }: SecurityOptions = {}): ((req: Request, res: Response, next: NextFunction) => void) => {\n jwtStrategyOptions ??= {};\n if ('secretOrKeyProvider' in jwtStrategyOptions)\n (jwtStrategyOptions as any).secretOrKeyProvider = wrapSecretOrKeyProvider(jwtStrategyOptions.secretOrKeyProvider);\n else if (!('secretOrKey' in jwtStrategyOptions)) jwtStrategyOptions.secretOrKey = ctx.env.get('tokenPublicKey') as string;\n\n const strategy = new JwtStrategy(\n {\n jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n passReqToCallback: true,\n ...jwtStrategyOptions,\n } as StrategyOptionsWithRequest,\n (req: Request, payload: any, done: (err: any, user: any) => void) => {\n ctx.request.token = payload;\n ctx.request.jwt = ExtractJwt.fromAuthHeaderAsBearerToken()(req) ?? '';\n done(null, payload);\n }\n );\n\n passport.use(strategy);\n return passport.initialize();\n};\n","import { NextFunction, Request, Response } from 'express';\nimport { Exception } from '@thisisagile/easy';\nimport { toOriginatedError } from '@thisisagile/easy-service';\n\nexport const notFound = (req: Request, res: Response, next: NextFunction): void => {\n next(toOriginatedError(Exception.DoesNotExist));\n};\n","import express from 'express';\nimport { ctx } from '@thisisagile/easy';\n\nexport const requestContext = (req: express.Request, res: express.Response, next: express.NextFunction): void => ctx.request.create(() => next());\n","import { createNamespace } from 'cls-hooked';\nimport { BaseRequestContext } from '@thisisagile/easy';\n\nexport class NamespaceContext extends BaseRequestContext {\n protected readonly namespace = createNamespace('context');\n\n public get<T>(key: string): T {\n return this.namespace.get(key) as T;\n }\n\n public set<T>(key: string, value: T): T {\n return this.namespace.set(key, value);\n }\n\n public readonly create = (f: () => void): void => this.namespace.run(f);\n}\n"],"mappings":";AAAA,SAAqB,eAAe;AAE7B,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC;AAAA,EAEA,YAAY,EAAE,MAAM,OAAO,GAAe;AACxC,UAAM,IAAI;AACV,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,YAAY,CAAC,WAAkC,IAAI,UAAU,MAAM;AAEzE,IAAM,cAAc,CAAC,MAAgC,QAAQ,CAAC,KAAK,EAAE,SAAS;;;ACbrF,SAAS,KAAK,YAAY,cAAc;AAEjC,IAAM,cAAc,CAAC,KAAsB,KAAuB,SAAqC;AAC5G,MAAI,UAAU,WAAW,aAAc,IAAI,QAAQ,gBAAgB,KAAK,OAAO,WAAW,WAAW,KAAK,OAAO,CAAE;AACnH,OAAK;AACP;;;ACJA;AAAA,EACE;AAAA,EACA;AAAA,EACA,OAAAA;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA0B,yBAAyB;AAEnD,IAAM,aAAa,CAAC,QAAoB,SAAmB,CAAC,OAAiB;AAAA,EAC3E;AAAA,EACA,MAAM,KAAK,QAAQ,QAAQ,MAAM;AACnC;AAEA,IAAM,SAAS,CAAC,EAAE,QAAQ,QAAQ,MAAiC;AACjE,SACE,OAAO,MAAM,EACV,KAAK,aAAa,QAAM,WAAW,aAAa,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,EACnF,KAAK,gBAAgB,OAAK,WAAW,SAAS,cAAcD,YAAW,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EAEnH,KAAKC,UAAS,OAAK,WAAWD,YAAW,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAEpF,KAAK,WAAW,OAAK,WAAW,SAAS,WAAWA,YAAW,YAAY,EAAE,OAAO,CAAC,EAErF,KAAK,YAAY,OAAK,WAAWA,YAAW,qBAAqB,EAAE,KAAK,OAAO,MAAM,CAAC,EACtF,KAAK,aAAa,OAAK,WAAW,SAAS,WAAWA,YAAW,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EAE/G,KAAK,QAAQ,OAAK,WAAW,SAAS,WAAWA,YAAW,YAAY,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAChG,KAAK,MAAM,WAAWA,YAAW,qBAAqB,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC;AAEzF;AAEO,IAAM,QAAQ,CAAC,GAAU,KAAsB,KAAuB,UAAsC;AACjH,MAAI;AACJ,QAAM,MAAM,kBAAkB,CAAC,CAAC,EAC7B,IAAI,QAAM,OAAO,EAAE,CAAC,EACpB,OAAO,OAAM,WAAW,CAAE,EAC1B,OAAO,OAAMD,KAAI,QAAQ,YAAY,EAAE,OAAO,gBAAgB,EAAE,KAAK,OAAO,OAAO,CAAC,GAAG,UAAU,MAAU,EAC3G,OAAO,OAAMA,KAAI,QAAQ,iBAAiB,EAAE,OAAO,gBAAgB,EAAE,QAAQ,MAAU,EACvF,QAAQ,MAAM,QAAQ,EACtB,OAAO,OAAK,IAAI,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC;AACzD;;;ACtDA,OAAO,aAA2E;;;ACClF,OAAO,cAAc;AACrB,SAAS,YAAY,YAAY,mBAAmB;AAIpD,SAAS,OAAAG,MAAK,aAAa,cAAAC,aAAY,eAAe;AA2B/C,IAAM,eAAe,MAAsB,CAAC,KAAK,KAAK,SAAS,KAAK,QAAQ,YAAY,IAAI,OAAOD,KAAI,IAAI,IAAI,GAAG,UAAUC,YAAW,SAAS,CAAC,CAAC;AAElJ,IAAM,aAAa,MAAsB,SAAS,aAAa,OAAO,EAAE,SAAS,OAAO,eAAe,KAAK,CAAC;AAE7G,IAAM,aACX,CAAC,UACD,CAAC,KAAK,KAAK,SACT,KAAK,QAAS,IAAI,MAAc,QAAQ,SAAS,MAAM,EAAE,GAAG,UAAUA,YAAW,SAAS,CAAC,CAAC;AAEzF,IAAM,eACX,CAAC,OACD,CAAC,KAAK,KAAK,SACT,KAAK,QAAS,IAAI,MAAc,UAAU,SAAS,GAAG,EAAE,GAAG,UAAUA,YAAW,SAAS,CAAC,CAAC;AAE/F,IAAM,0BAA0B,CAAC,MAC/B,IACI,CAAC,SAAS,aAAa,SACrB,EAAE,SAAS,WAAW,EACnB,KAAK,OAAK,KAAK,MAAM,CAAC,CAAC,EACvB,MAAM,OAAK,KAAK,CAAC,CAAC,IACvB;AAEC,IAAM,WAAW,CAAC,EAAE,mBAAmB,IAAqB,CAAC,MAAmE;AACrI,yBAAuB,CAAC;AACxB,MAAI,yBAAyB;AAC3B,IAAC,mBAA2B,sBAAsB,wBAAwB,mBAAmB,mBAAmB;AAAA,WACzG,EAAE,iBAAiB;AAAqB,uBAAmB,cAAcD,KAAI,IAAI,IAAI,gBAAgB;AAE9G,QAAM,WAAW,IAAI;AAAA,IACnB;AAAA,MACE,gBAAgB,WAAW,4BAA4B;AAAA,MACvD,mBAAmB;AAAA,MACnB,GAAG;AAAA,IACL;AAAA,IACA,CAAC,KAAc,SAAc,SAAwC;AACnE,MAAAA,KAAI,QAAQ,QAAQ;AACpB,MAAAA,KAAI,QAAQ,MAAM,WAAW,4BAA4B,EAAE,GAAG,KAAK;AACnE,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,IAAI,QAAQ;AACrB,SAAO,SAAS,WAAW;AAC7B;;;AD1EA,SAAS,cAAAE,aAAY,SAAmB,QAAAC,OAAM,QAAQ,aAAa;AACnE;AAAA,EAOE;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,OAEK;AAIA,IAAM,kBAAN,MAA6C;AAAA,EAClD,YAAsB,MAAe,QAAQ,GAAG;AAA1B;AACpB,SAAK,IAAI,IAAI,eAAe,CAAC,YAAY,aAAa,aAAa,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,CAAC,YAA2B;AAChC,SAAK,IAAI,IAAI,OAAO;AAAA,EACtB;AAAA,EAEA,QAAQ,CAACC,UAAkB,aAA6B;AACtD,UAAM,EAAE,OAAO,WAAW,WAAW,IAAI,OAAO,QAAQ;AACxD,UAAM,SAAS,QAAQ,OAAO,EAAE,aAAa,KAAK,CAAC;AACnD,QAAI,CAAC,QAAQ,UAAU;AAAG,aAAO,IAAI,MAAM,MAAMA,SAAQ,IAAI,GAAG,UAAU;AAE1E,cAAU,QAAQ,CAAC,EAAE,UAAU,MAAM,UAAU,YAAAC,YAAW,MAAa;AACrE,cAAQ,IAAI,KAAK,KAAK,MAAM,MAAM,MAAMD,SAAQ,IAAI,CAAC;AACrD,aAAO,KAAK,KAAK,SAAS,CAAgB;AAAA,QACxC,MAAM,MAAMA,SAAQ,IAAI;AAAA,QACxB,GAAG,KAAK,sBAAsB,QAAQ;AAAA,QACtC,GAAGC;AAAA,QACH,KAAK,OAAO,UAAU,KAAK,SAAS,QAAQ;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,SAAK,IAAI,IAAI,MAAM;AAAA,EACrB;AAAA,EAEA,SAAS,CAAC,MAAc,UAAU,gCAAgC,IAAI,QAAc;AAClF,SAAK,IAAI,OAAO,MAAM,MAAM;AAC1B,cAAQ,IAAI,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEU,sBAAsB,UAA2C;AACzE,UAAM,aAA+B,CAAC;AACtC,QAAI,SAAS;AAAS,iBAAW,KAAK,aAAa,CAAC;AACpD,QAAI,SAAS;AAAO,iBAAW,KAAK,WAAW,CAAC;AAChD,QAAI,SAAS;AAAO,iBAAW,KAAK,WAAW,SAAS,KAAK,CAAC;AAC9D,QAAI,SAAS;AAAI,iBAAW,KAAK,aAAa,SAAS,EAAE,CAAC;AAC1D,WAAO;AAAA,EACT;AAAA,EAEU,SACR,CAAC,UAAoB,SAAuB,aAC5C,CAAC,KAAc,KAAe,SAC5B,SAAS,MAAM,GAAG,CAAC,EAChB,KAAK,CAAC,MAAW,KAAK,WAAW,KAAK,GAAG,cAAc,OAAO,CAAC,CAAC,EAChE,MAAM,CAAAC,WAAS,KAAKH,mBAAkBG,QAAO,OAAO,CAAC,CAAC;AAAA,EAEnD,WAAW,KAAe,QAAiB,SAAsC;AACzF,QAAI,OAAO,QAAQ,KAAK,MAAM;AAC9B,QAAI,KAAK,QAAQ,KAAK,IAAI;AAC1B,QAAI,QAAQ,MAAM;AAAS,UAAI,UAAU,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,CAAC;AAElF,KAAE,KAAa,QAAQ,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,QAAQ,OAAO;AAAA,EACtE;AAAA;AAAA,EAIU,KAAK,KAAe,QAAiB,SAAsC;AACnF,QAAIL,YAAW,UAAU,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAI,KAAK;AAAA,IACX,OAAO;AACL,UAAI,KAAKC,MAAK,OAAO,QAAQ,MAAM,OAAY,MAAM,GAAI,QAA0B,OAAQ,QAA0B,IAAI,CAAC;AAAA,IAC5H;AAAA,EACF;AAAA,EAEU,QAAQ,KAAe,QAAiB,SAAsC;AACtF,QAAID,YAAW,UAAU,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAI,KAAK;AAAA,IACX,OAAO;AACL,UAAI,KAAK,MAAM;AAAA,IACjB;AAAA,EACF;AAAA,EAEU,OAAO,KAAe,QAAuB;AACrD,QAAI,IAAI,MAAM;AAAA,EAChB;AAAA,EAEU,KAAK,KAAe,MAAqB;AACjD,QAAI,KAAK,IAAI;AAAA,EACf;AACF;AAEO,IAAM,UAAU,CAAC,SAA0B,IAAI,QAAQ,MAAM,IAAI,gBAAgB,CAAC;;;AEtGzF,SAAS,iBAAiB;AAC1B,SAAS,qBAAAM,0BAAyB;AAE3B,IAAM,WAAW,CAAC,KAAc,KAAe,SAA6B;AACjF,OAAKA,mBAAkB,UAAU,YAAY,CAAC;AAChD;;;ACLA,SAAS,OAAAC,YAAW;AAEb,IAAM,iBAAiB,CAAC,KAAsB,KAAuB,SAAqCA,KAAI,QAAQ,OAAO,MAAM,KAAK,CAAC;;;ACHhJ,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAE5B,IAAM,mBAAN,cAA+B,mBAAmB;AAAA,EACpC,YAAY,gBAAgB,SAAS;AAAA,EAEjD,IAAO,KAAgB;AAC5B,WAAO,KAAK,UAAU,IAAI,GAAG;AAAA,EAC/B;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAO,KAAK,UAAU,IAAI,KAAK,KAAK;AAAA,EACtC;AAAA,EAEgB,SAAS,CAAC,MAAwB,KAAK,UAAU,IAAI,CAAC;AACxE;","names":["ctx","HttpStatus","isError","ctx","HttpStatus","HttpStatus","rest","toOriginatedError","service","middleware","error","toOriginatedError","ctx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thisisagile/easy-express",
3
- "version": "17.25.2",
3
+ "version": "17.26.0",
4
4
  "description": "Straightforward library for building domain-driven microservice architectures",
5
5
  "author": "Sander Hoogendoorn",
6
6
  "license": "MIT",
@@ -52,8 +52,8 @@
52
52
  "@types/validator": "^13.12.2"
53
53
  },
54
54
  "dependencies": {
55
- "@thisisagile/easy": "^17.25.2",
56
- "@thisisagile/easy-service": "^17.25.2",
55
+ "@thisisagile/easy": "^17.26.0",
56
+ "@thisisagile/easy-service": "^17.26.0",
57
57
  "@types/express": "^4.17.21",
58
58
  "cls-hooked": "^4.2.2",
59
59
  "express": "^4.21.2",
@@ -1,43 +0,0 @@
1
- import {
2
- authError
3
- } from "./chunk-RL5ICAHT.mjs";
4
-
5
- // src/express/SecurityHandler.ts
6
- import passport from "passport";
7
- import { ExtractJwt, Strategy as JwtStrategy } from "passport-jwt";
8
- import { ctx, Environment, HttpStatus, ifFalse } from "@thisisagile/easy";
9
- var checkLabCoat = () => (req, res, next) => next(ifFalse(Environment.Dev.equals(ctx.env.name), authError(HttpStatus.Forbidden)));
10
- var checkToken = () => passport.authenticate("jwt", { session: false, failWithError: true });
11
- var checkScope = (scope) => (req, res, next) => next(ifFalse(req.user?.scopes?.includes(scope.id), authError(HttpStatus.Forbidden)));
12
- var checkUseCase = (uc) => (req, res, next) => next(ifFalse(req.user?.usecases?.includes(uc.id), authError(HttpStatus.Forbidden)));
13
- var wrapSecretOrKeyProvider = (p) => p ? (request, rawJwtToken, done) => p(request, rawJwtToken).then((t) => done(null, t)).catch((e) => done(e)) : void 0;
14
- var security = ({ jwtStrategyOptions } = {}) => {
15
- jwtStrategyOptions ??= {};
16
- if ("secretOrKeyProvider" in jwtStrategyOptions)
17
- jwtStrategyOptions.secretOrKeyProvider = wrapSecretOrKeyProvider(jwtStrategyOptions.secretOrKeyProvider);
18
- else if (!("secretOrKey" in jwtStrategyOptions))
19
- jwtStrategyOptions.secretOrKey = ctx.env.get("tokenPublicKey");
20
- const strategy = new JwtStrategy(
21
- {
22
- jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
23
- passReqToCallback: true,
24
- ...jwtStrategyOptions
25
- },
26
- (req, payload, done) => {
27
- ctx.request.token = payload;
28
- ctx.request.jwt = ExtractJwt.fromAuthHeaderAsBearerToken()(req) ?? "";
29
- done(null, payload);
30
- }
31
- );
32
- passport.use(strategy);
33
- return passport.initialize();
34
- };
35
-
36
- export {
37
- checkLabCoat,
38
- checkToken,
39
- checkScope,
40
- checkUseCase,
41
- security
42
- };
43
- //# sourceMappingURL=chunk-G54PL2JB.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/express/SecurityHandler.ts"],"sourcesContent":["import type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport passport from 'passport';\nimport { ExtractJwt, Strategy as JwtStrategy } from 'passport-jwt';\nimport type { SecretOrKeyProvider, StrategyOptionsWithRequest } from 'passport-jwt';\nimport type { Algorithm } from 'jsonwebtoken';\nimport { authError } from './AuthError';\nimport { ctx, Environment, HttpStatus, ifFalse } from '@thisisagile/easy';\nimport type { Scope, UseCase } from '@thisisagile/easy';\n\ntype EasySecretOrKeyProvider = (request: Request, rawJwtToken: any) => Promise<string | Buffer>;\n\nexport interface SecurityOptions {\n /** Configuration for verifying JWTs */\n jwtStrategyOptions?: {\n /** The secret (symmetric) or PEM-encoded public key (asymmetric) for verifying the token's signature.\n * REQUIRED unless secretOrKeyProvider is provided. Defaults to JWT_PUBLIC_KEY from the system environment. */\n secretOrKey?: string | Buffer;\n\n /** Should return a secret (symmetric) or PEM-encoded public key (asymmetric) for the given key and request combination.\n * REQUIRED unless secretOrKey is provided. Note it is up to the implementer to decode rawJwtToken. */\n secretOrKeyProvider?: EasySecretOrKeyProvider;\n\n /** If defined, the token issuer (iss) will be verified against this value. */\n issuer?: string;\n\n /** If defined, the token audience (aud) will be verified against this value. */\n audience?: string;\n\n /** If defined, the token algorithm (alg) must be in this list. */\n algorithms?: Algorithm[];\n };\n}\n\nexport const checkLabCoat = (): RequestHandler => (req, res, next) => next(ifFalse(Environment.Dev.equals(ctx.env.name), authError(HttpStatus.Forbidden)));\n\nexport const checkToken = (): RequestHandler => passport.authenticate('jwt', { session: false, failWithError: true });\n\nexport const checkScope =\n (scope: Scope): RequestHandler =>\n (req, res, next) =>\n next(ifFalse((req.user as any)?.scopes?.includes(scope.id), authError(HttpStatus.Forbidden)));\n\nexport const checkUseCase =\n (uc: UseCase): RequestHandler =>\n (req, res, next) =>\n next(ifFalse((req.user as any)?.usecases?.includes(uc.id), authError(HttpStatus.Forbidden)));\n\nconst wrapSecretOrKeyProvider = (p?: EasySecretOrKeyProvider): SecretOrKeyProvider | undefined =>\n p\n ? (request, rawJwtToken, done) =>\n p(request, rawJwtToken)\n .then(t => done(null, t))\n .catch(e => done(e))\n : undefined;\n\nexport const security = ({ jwtStrategyOptions }: SecurityOptions = {}): ((req: Request, res: Response, next: NextFunction) => void) => {\n jwtStrategyOptions ??= {};\n if ('secretOrKeyProvider' in jwtStrategyOptions)\n (jwtStrategyOptions as any).secretOrKeyProvider = wrapSecretOrKeyProvider(jwtStrategyOptions.secretOrKeyProvider);\n else if (!('secretOrKey' in jwtStrategyOptions)) jwtStrategyOptions.secretOrKey = ctx.env.get('tokenPublicKey') as string;\n\n const strategy = new JwtStrategy(\n {\n jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n passReqToCallback: true,\n ...jwtStrategyOptions,\n } as StrategyOptionsWithRequest,\n (req: Request, payload: any, done: (err: any, user: any) => void) => {\n ctx.request.token = payload;\n ctx.request.jwt = ExtractJwt.fromAuthHeaderAsBearerToken()(req) ?? '';\n done(null, payload);\n }\n );\n\n passport.use(strategy);\n return passport.initialize();\n};\n"],"mappings":";;;;;AACA,OAAO,cAAc;AACrB,SAAS,YAAY,YAAY,mBAAmB;AAIpD,SAAS,KAAK,aAAa,YAAY,eAAe;AA2B/C,IAAM,eAAe,MAAsB,CAAC,KAAK,KAAK,SAAS,KAAK,QAAQ,YAAY,IAAI,OAAO,IAAI,IAAI,IAAI,GAAG,UAAU,WAAW,SAAS,CAAC,CAAC;AAElJ,IAAM,aAAa,MAAsB,SAAS,aAAa,OAAO,EAAE,SAAS,OAAO,eAAe,KAAK,CAAC;AAE7G,IAAM,aACX,CAAC,UACD,CAAC,KAAK,KAAK,SACT,KAAK,QAAS,IAAI,MAAc,QAAQ,SAAS,MAAM,EAAE,GAAG,UAAU,WAAW,SAAS,CAAC,CAAC;AAEzF,IAAM,eACX,CAAC,OACD,CAAC,KAAK,KAAK,SACT,KAAK,QAAS,IAAI,MAAc,UAAU,SAAS,GAAG,EAAE,GAAG,UAAU,WAAW,SAAS,CAAC,CAAC;AAE/F,IAAM,0BAA0B,CAAC,MAC/B,IACI,CAAC,SAAS,aAAa,SACrB,EAAE,SAAS,WAAW,EACnB,KAAK,OAAK,KAAK,MAAM,CAAC,CAAC,EACvB,MAAM,OAAK,KAAK,CAAC,CAAC,IACvB;AAEC,IAAM,WAAW,CAAC,EAAE,mBAAmB,IAAqB,CAAC,MAAmE;AACrI,yBAAuB,CAAC;AACxB,MAAI,yBAAyB;AAC3B,IAAC,mBAA2B,sBAAsB,wBAAwB,mBAAmB,mBAAmB;AAAA,WACzG,EAAE,iBAAiB;AAAqB,uBAAmB,cAAc,IAAI,IAAI,IAAI,gBAAgB;AAE9G,QAAM,WAAW,IAAI;AAAA,IACnB;AAAA,MACE,gBAAgB,WAAW,4BAA4B;AAAA,MACvD,mBAAmB;AAAA,MACnB,GAAG;AAAA,IACL;AAAA,IACA,CAAC,KAAc,SAAc,SAAwC;AACnE,UAAI,QAAQ,QAAQ;AACpB,UAAI,QAAQ,MAAM,WAAW,4BAA4B,EAAE,GAAG,KAAK;AACnE,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,IAAI,QAAQ;AACrB,SAAO,SAAS,WAAW;AAC7B;","names":[]}
@@ -1,19 +0,0 @@
1
- // src/express/AuthError.ts
2
- import { isError } from "@thisisagile/easy";
3
- var AuthError = class extends Error {
4
- status;
5
- constructor({ name, status }) {
6
- super(name);
7
- this.name = "AuthenticationError";
8
- this.status = status;
9
- }
10
- };
11
- var authError = (status) => new AuthError(status);
12
- var isAuthError = (e) => isError(e) && e.name === "AuthenticationError";
13
-
14
- export {
15
- AuthError,
16
- authError,
17
- isAuthError
18
- };
19
- //# sourceMappingURL=chunk-RL5ICAHT.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/express/AuthError.ts"],"sourcesContent":["import { HttpStatus, isError } from '@thisisagile/easy';\n\nexport class AuthError extends Error {\n status: number;\n\n constructor({ name, status }: HttpStatus) {\n super(name);\n this.name = 'AuthenticationError';\n this.status = status;\n }\n}\n\nexport const authError = (status: HttpStatus): AuthError => new AuthError(status);\n\nexport const isAuthError = (e?: unknown): e is AuthError => isError(e) && e.name === 'AuthenticationError';\n"],"mappings":";AAAA,SAAqB,eAAe;AAE7B,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC;AAAA,EAEA,YAAY,EAAE,MAAM,OAAO,GAAe;AACxC,UAAM,IAAI;AACV,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,YAAY,CAAC,WAAkC,IAAI,UAAU,MAAM;AAEzE,IAAM,cAAc,CAAC,MAAgC,QAAQ,CAAC,KAAK,EAAE,SAAS;","names":[]}
@@ -1,11 +0,0 @@
1
- import {
2
- AuthError,
3
- authError,
4
- isAuthError
5
- } from "../chunk-RL5ICAHT.mjs";
6
- export {
7
- AuthError,
8
- authError,
9
- isAuthError
10
- };
11
- //# sourceMappingURL=AuthError.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,10 +0,0 @@
1
- // src/express/CorrelationHandler.ts
2
- import { ctx, HttpHeader, toUuid } from "@thisisagile/easy";
3
- var correlation = (req, res, next) => {
4
- res.setHeader(HttpHeader.Correlation, ctx.request.correlationId = req?.header(HttpHeader.Correlation) ?? toUuid());
5
- next();
6
- };
7
- export {
8
- correlation
9
- };
10
- //# sourceMappingURL=CorrelationHandler.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/CorrelationHandler.ts"],"sourcesContent":["import express from 'express';\nimport { ctx, HttpHeader, toUuid } from '@thisisagile/easy';\n\nexport const correlation = (req: express.Request, res: express.Response, next: express.NextFunction): void => {\n res.setHeader(HttpHeader.Correlation, (ctx.request.correlationId = req?.header(HttpHeader.Correlation) ?? toUuid()));\n next();\n};\n"],"mappings":";AACA,SAAS,KAAK,YAAY,cAAc;AAEjC,IAAM,cAAc,CAAC,KAAsB,KAAuB,SAAqC;AAC5G,MAAI,UAAU,WAAW,aAAc,IAAI,QAAQ,gBAAgB,KAAK,OAAO,WAAW,WAAW,KAAK,OAAO,CAAE;AACnH,OAAK;AACP;","names":[]}
@@ -1,37 +0,0 @@
1
- import {
2
- isAuthError
3
- } from "../chunk-RL5ICAHT.mjs";
4
-
5
- // src/express/ErrorHandler.ts
6
- import {
7
- asString,
8
- choose,
9
- ctx,
10
- HttpStatus,
11
- isDoesNotExist,
12
- isError,
13
- isException,
14
- isResponse,
15
- isResults,
16
- isText,
17
- rest,
18
- toHttpStatus,
19
- toResult,
20
- tryTo
21
- } from "@thisisagile/easy";
22
- import { toOriginatedError } from "@thisisagile/easy-service";
23
- var toResponse = (status, errors = []) => ({
24
- status,
25
- body: rest.toError(status, errors)
26
- });
27
- var toBody = ({ origin, options }) => {
28
- return choose(origin).type(isAuthError, (ae) => toResponse(toHttpStatus(ae.status), [toResult(ae.message)])).type(isDoesNotExist, (e) => toResponse(options?.onNotFound ?? HttpStatus.NotFound, [toResult(e.reason ?? e.message)])).type(isError, (e) => toResponse(HttpStatus.InternalServerError, [toResult(e.message)])).type(isResults, (r) => toResponse(options?.onError ?? HttpStatus.BadRequest, r.results)).type(isResponse, (r) => toResponse(HttpStatus.InternalServerError, r.body.error?.errors)).type(isException, (e) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(e.reason ?? e.message)])).type(isText, (t) => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(asString(t))])).else(() => toResponse(HttpStatus.InternalServerError, [toResult("Unknown error")]));
29
- };
30
- var error = (e, req, res, _next) => {
31
- let response;
32
- tryTo(() => toOriginatedError(e)).map((oe) => toBody(oe)).accept((r) => response = r).accept((r) => ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : void 0).accept((r) => ctx.request.lastErrorStack = r.status.isServerError ? e.stack : void 0).recover(() => response).accept((r) => res.status(r.status.status).json(r.body));
33
- };
34
- export {
35
- error
36
- };
37
- //# sourceMappingURL=ErrorHandler.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/ErrorHandler.ts"],"sourcesContent":["import express from 'express';\nimport { isAuthError } from './AuthError';\nimport {\n asString,\n choose,\n ctx,\n HttpStatus,\n isDoesNotExist,\n isError,\n isException,\n isResponse,\n isResults,\n isText,\n Response,\n rest,\n Result,\n toHttpStatus,\n toResult,\n tryTo,\n} from '@thisisagile/easy';\nimport { OriginatedError, toOriginatedError } from '@thisisagile/easy-service';\n\nconst toResponse = (status: HttpStatus, errors: Result[] = []): Response => ({\n status,\n body: rest.toError(status, errors),\n});\n\nconst toBody = ({ origin, options }: OriginatedError): Response => {\n return (\n choose(origin)\n .type(isAuthError, ae => toResponse(toHttpStatus(ae.status), [toResult(ae.message)]))\n .type(isDoesNotExist, e => toResponse(options?.onNotFound ?? HttpStatus.NotFound, [toResult(e.reason ?? e.message)]))\n // This service breaks with an error\n .type(isError, e => toResponse(HttpStatus.InternalServerError, [toResult(e.message)]))\n // This service fails\n .type(isResults, r => toResponse(options?.onError ?? HttpStatus.BadRequest, r.results))\n // Underlying service fails\n .type(isResponse, r => toResponse(HttpStatus.InternalServerError, r.body.error?.errors))\n .type(isException, e => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(e.reason ?? e.message)]))\n // This service fails with a string\n .type(isText, t => toResponse(options?.onError ?? HttpStatus.BadRequest, [toResult(asString(t))]))\n .else(() => toResponse(HttpStatus.InternalServerError, [toResult('Unknown error')]))\n );\n};\n\nexport const error = (e: Error, req: express.Request, res: express.Response, _next: express.NextFunction): void => {\n let response: Response;\n tryTo(() => toOriginatedError(e))\n .map(oe => toBody(oe))\n .accept(r => (response = r))\n .accept(r => (ctx.request.lastError = r.status.isServerError ? r.body.error?.errors[0]?.message : undefined))\n .accept(r => (ctx.request.lastErrorStack = r.status.isServerError ? e.stack : undefined))\n .recover(() => response)\n .accept(r => res.status(r.status.status).json(r.body));\n};\n"],"mappings":";;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA0B,yBAAyB;AAEnD,IAAM,aAAa,CAAC,QAAoB,SAAmB,CAAC,OAAiB;AAAA,EAC3E;AAAA,EACA,MAAM,KAAK,QAAQ,QAAQ,MAAM;AACnC;AAEA,IAAM,SAAS,CAAC,EAAE,QAAQ,QAAQ,MAAiC;AACjE,SACE,OAAO,MAAM,EACV,KAAK,aAAa,QAAM,WAAW,aAAa,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,EACnF,KAAK,gBAAgB,OAAK,WAAW,SAAS,cAAc,WAAW,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EAEnH,KAAK,SAAS,OAAK,WAAW,WAAW,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAEpF,KAAK,WAAW,OAAK,WAAW,SAAS,WAAW,WAAW,YAAY,EAAE,OAAO,CAAC,EAErF,KAAK,YAAY,OAAK,WAAW,WAAW,qBAAqB,EAAE,KAAK,OAAO,MAAM,CAAC,EACtF,KAAK,aAAa,OAAK,WAAW,SAAS,WAAW,WAAW,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EAE/G,KAAK,QAAQ,OAAK,WAAW,SAAS,WAAW,WAAW,YAAY,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAChG,KAAK,MAAM,WAAW,WAAW,qBAAqB,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC;AAEzF;AAEO,IAAM,QAAQ,CAAC,GAAU,KAAsB,KAAuB,UAAsC;AACjH,MAAI;AACJ,QAAM,MAAM,kBAAkB,CAAC,CAAC,EAC7B,IAAI,QAAM,OAAO,EAAE,CAAC,EACpB,OAAO,OAAM,WAAW,CAAE,EAC1B,OAAO,OAAM,IAAI,QAAQ,YAAY,EAAE,OAAO,gBAAgB,EAAE,KAAK,OAAO,OAAO,CAAC,GAAG,UAAU,MAAU,EAC3G,OAAO,OAAM,IAAI,QAAQ,iBAAiB,EAAE,OAAO,gBAAgB,EAAE,QAAQ,MAAU,EACvF,QAAQ,MAAM,QAAQ,EACtB,OAAO,OAAK,IAAI,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC;AACzD;","names":[]}
@@ -1,94 +0,0 @@
1
- import {
2
- checkLabCoat,
3
- checkScope,
4
- checkToken,
5
- checkUseCase
6
- } from "../chunk-G54PL2JB.mjs";
7
- import "../chunk-RL5ICAHT.mjs";
8
-
9
- // src/express/ExpressProvider.ts
10
- import express from "express";
11
- import { HttpStatus, isEmpty, rest, toList, toReq } from "@thisisagile/easy";
12
- import {
13
- routes,
14
- Service,
15
- toOriginatedError,
16
- toVerbOptions
17
- } from "@thisisagile/easy-service";
18
- var ExpressProvider = class {
19
- constructor(app = express()) {
20
- this.app = app;
21
- this.app.set("trust proxy", ["loopback", "linklocal", "uniquelocal"]);
22
- }
23
- use = (handler) => {
24
- this.app.use(handler);
25
- };
26
- route = (service2, resource) => {
27
- const { route, endpoints, middleware } = routes(resource);
28
- const router = express.Router({ mergeParams: true });
29
- if (!isEmpty(middleware))
30
- router.all(route.route(service2.name), middleware);
31
- endpoints.forEach(({ endpoint, verb, requires, middleware: middleware2 }) => {
32
- console.log(verb.verb.code, route.route(service2.name));
33
- router[verb.verb.toString()](
34
- route.route(service2.name),
35
- ...this.addSecurityMiddleware(requires),
36
- ...middleware2,
37
- this.handle(endpoint, verb.options, requires)
38
- );
39
- });
40
- this.app.use(router);
41
- };
42
- listen = (port, message = `Service is listening on port ${port}.`) => {
43
- this.app.listen(port, () => {
44
- console.log(message);
45
- });
46
- };
47
- addSecurityMiddleware(requires) {
48
- const middleware = [];
49
- if (requires.labCoat)
50
- middleware.push(checkLabCoat());
51
- if (requires.token)
52
- middleware.push(checkToken());
53
- if (requires.scope)
54
- middleware.push(checkScope(requires.scope));
55
- if (requires.uc)
56
- middleware.push(checkUseCase(requires.uc));
57
- return middleware;
58
- }
59
- handle = (endpoint, options, requires) => (req, res, next) => endpoint(toReq(req)).then((r) => this.toResponse(res, r, toVerbOptions(options))).catch((error) => next(toOriginatedError(error, options)));
60
- toResponse(res, result, options) {
61
- res.status(options.onOk.status);
62
- res.type(options.type.code);
63
- if (options.cache.enabled)
64
- res.setHeader(options.cache.name, options.cache.value());
65
- (this[options.type.name] ?? this.json)(res, result, options);
66
- }
67
- // Handling responses depending on content type
68
- json(res, result, options) {
69
- if (HttpStatus.NoContent.equals(options.onOk)) {
70
- res.send();
71
- } else {
72
- res.json(rest.toData(options.onOk, toList(result), result?.total, result?.meta));
73
- }
74
- }
75
- rawJson(res, result, options) {
76
- if (HttpStatus.NoContent.equals(options.onOk)) {
77
- res.send();
78
- } else {
79
- res.json(result);
80
- }
81
- }
82
- stream(res, result) {
83
- res.end(result);
84
- }
85
- text(res, data) {
86
- res.send(data);
87
- }
88
- };
89
- var service = (name) => new Service(name, new ExpressProvider());
90
- export {
91
- ExpressProvider,
92
- service
93
- };
94
- //# sourceMappingURL=ExpressProvider.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/ExpressProvider.ts"],"sourcesContent":["import express, { Express, NextFunction, Request, RequestHandler, Response } from 'express';\nimport { checkLabCoat, checkScope, checkToken, checkUseCase } from './SecurityHandler';\nimport { HttpStatus, isEmpty, PageList, rest, toList, toReq } from '@thisisagile/easy';\nimport {\n AppProvider,\n Endpoint,\n Handler,\n Resource,\n Route,\n RouteRequires,\n routes,\n Service,\n toOriginatedError,\n toVerbOptions,\n VerbOptions,\n} from '@thisisagile/easy-service';\n\nexport type ExpressVerb = 'get' | 'post' | 'put' | 'patch' | 'delete';\n\nexport class ExpressProvider implements AppProvider {\n constructor(protected app: Express = express()) {\n this.app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']);\n }\n\n use = (handler: Handler): void => {\n this.app.use(handler);\n };\n\n route = (service: Service, resource: Resource): void => {\n const { route, endpoints, middleware } = routes(resource);\n const router = express.Router({ mergeParams: true });\n if (!isEmpty(middleware)) router.all(route.route(service.name), middleware);\n\n endpoints.forEach(({ endpoint, verb, requires, middleware }: Route) => {\n console.log(verb.verb.code, route.route(service.name));\n router[verb.verb.toString() as ExpressVerb](\n route.route(service.name),\n ...this.addSecurityMiddleware(requires),\n ...middleware,\n this.handle(endpoint, verb.options, requires)\n );\n });\n\n this.app.use(router);\n };\n\n listen = (port: number, message = `Service is listening on port ${port}.`): void => {\n this.app.listen(port, () => {\n console.log(message);\n });\n };\n\n protected addSecurityMiddleware(requires: RouteRequires): RequestHandler[] {\n const middleware: RequestHandler[] = [];\n if (requires.labCoat) middleware.push(checkLabCoat());\n if (requires.token) middleware.push(checkToken());\n if (requires.scope) middleware.push(checkScope(requires.scope));\n if (requires.uc) middleware.push(checkUseCase(requires.uc));\n return middleware;\n }\n\n protected handle =\n (endpoint: Endpoint, options?: VerbOptions, requires?: RouteRequires): RequestHandler =>\n (req: Request, res: Response, next: NextFunction) =>\n endpoint(toReq(req))\n .then((r: any) => this.toResponse(res, r, toVerbOptions(options)))\n .catch(error => next(toOriginatedError(error, options)));\n\n protected toResponse(res: Response, result: unknown, options: Required<VerbOptions>): void {\n res.status(options.onOk.status);\n res.type(options.type.code);\n if (options.cache.enabled) res.setHeader(options.cache.name, options.cache.value());\n\n ((this as any)[options.type.name] ?? this.json)(res, result, options);\n }\n\n // Handling responses depending on content type\n\n protected json(res: Response, result: unknown, options: Required<VerbOptions>): void {\n if (HttpStatus.NoContent.equals(options.onOk)) {\n res.send();\n } else {\n res.json(rest.toData(options.onOk, toList<any>(result), (result as PageList<any>)?.total, (result as PageList<any>)?.meta));\n }\n }\n\n protected rawJson(res: Response, result: unknown, options: Required<VerbOptions>): void {\n if (HttpStatus.NoContent.equals(options.onOk)) {\n res.send();\n } else {\n res.json(result);\n }\n }\n\n protected stream(res: Response, result: unknown): void {\n res.end(result);\n }\n\n protected text(res: Response, data: unknown): void {\n res.send(data);\n }\n}\n\nexport const service = (name: string): Service => new Service(name, new ExpressProvider());\n"],"mappings":";;;;;;;;;AAAA,OAAO,aAA2E;AAElF,SAAS,YAAY,SAAmB,MAAM,QAAQ,aAAa;AACnE;AAAA,EAOE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAIA,IAAM,kBAAN,MAA6C;AAAA,EAClD,YAAsB,MAAe,QAAQ,GAAG;AAA1B;AACpB,SAAK,IAAI,IAAI,eAAe,CAAC,YAAY,aAAa,aAAa,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,CAAC,YAA2B;AAChC,SAAK,IAAI,IAAI,OAAO;AAAA,EACtB;AAAA,EAEA,QAAQ,CAACA,UAAkB,aAA6B;AACtD,UAAM,EAAE,OAAO,WAAW,WAAW,IAAI,OAAO,QAAQ;AACxD,UAAM,SAAS,QAAQ,OAAO,EAAE,aAAa,KAAK,CAAC;AACnD,QAAI,CAAC,QAAQ,UAAU;AAAG,aAAO,IAAI,MAAM,MAAMA,SAAQ,IAAI,GAAG,UAAU;AAE1E,cAAU,QAAQ,CAAC,EAAE,UAAU,MAAM,UAAU,YAAAC,YAAW,MAAa;AACrE,cAAQ,IAAI,KAAK,KAAK,MAAM,MAAM,MAAMD,SAAQ,IAAI,CAAC;AACrD,aAAO,KAAK,KAAK,SAAS,CAAgB;AAAA,QACxC,MAAM,MAAMA,SAAQ,IAAI;AAAA,QACxB,GAAG,KAAK,sBAAsB,QAAQ;AAAA,QACtC,GAAGC;AAAA,QACH,KAAK,OAAO,UAAU,KAAK,SAAS,QAAQ;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,SAAK,IAAI,IAAI,MAAM;AAAA,EACrB;AAAA,EAEA,SAAS,CAAC,MAAc,UAAU,gCAAgC,IAAI,QAAc;AAClF,SAAK,IAAI,OAAO,MAAM,MAAM;AAC1B,cAAQ,IAAI,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEU,sBAAsB,UAA2C;AACzE,UAAM,aAA+B,CAAC;AACtC,QAAI,SAAS;AAAS,iBAAW,KAAK,aAAa,CAAC;AACpD,QAAI,SAAS;AAAO,iBAAW,KAAK,WAAW,CAAC;AAChD,QAAI,SAAS;AAAO,iBAAW,KAAK,WAAW,SAAS,KAAK,CAAC;AAC9D,QAAI,SAAS;AAAI,iBAAW,KAAK,aAAa,SAAS,EAAE,CAAC;AAC1D,WAAO;AAAA,EACT;AAAA,EAEU,SACR,CAAC,UAAoB,SAAuB,aAC5C,CAAC,KAAc,KAAe,SAC5B,SAAS,MAAM,GAAG,CAAC,EAChB,KAAK,CAAC,MAAW,KAAK,WAAW,KAAK,GAAG,cAAc,OAAO,CAAC,CAAC,EAChE,MAAM,WAAS,KAAK,kBAAkB,OAAO,OAAO,CAAC,CAAC;AAAA,EAEnD,WAAW,KAAe,QAAiB,SAAsC;AACzF,QAAI,OAAO,QAAQ,KAAK,MAAM;AAC9B,QAAI,KAAK,QAAQ,KAAK,IAAI;AAC1B,QAAI,QAAQ,MAAM;AAAS,UAAI,UAAU,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,CAAC;AAElF,KAAE,KAAa,QAAQ,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,QAAQ,OAAO;AAAA,EACtE;AAAA;AAAA,EAIU,KAAK,KAAe,QAAiB,SAAsC;AACnF,QAAI,WAAW,UAAU,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAI,KAAK;AAAA,IACX,OAAO;AACL,UAAI,KAAK,KAAK,OAAO,QAAQ,MAAM,OAAY,MAAM,GAAI,QAA0B,OAAQ,QAA0B,IAAI,CAAC;AAAA,IAC5H;AAAA,EACF;AAAA,EAEU,QAAQ,KAAe,QAAiB,SAAsC;AACtF,QAAI,WAAW,UAAU,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAI,KAAK;AAAA,IACX,OAAO;AACL,UAAI,KAAK,MAAM;AAAA,IACjB;AAAA,EACF;AAAA,EAEU,OAAO,KAAe,QAAuB;AACrD,QAAI,IAAI,MAAM;AAAA,EAChB;AAAA,EAEU,KAAK,KAAe,MAAqB;AACjD,QAAI,KAAK,IAAI;AAAA,EACf;AACF;AAEO,IAAM,UAAU,CAAC,SAA0B,IAAI,QAAQ,MAAM,IAAI,gBAAgB,CAAC;","names":["service","middleware"]}
@@ -1,10 +0,0 @@
1
- // src/express/NotFoundHandler.ts
2
- import { Exception } from "@thisisagile/easy";
3
- import { toOriginatedError } from "@thisisagile/easy-service";
4
- var notFound = (req, res, next) => {
5
- next(toOriginatedError(Exception.DoesNotExist));
6
- };
7
- export {
8
- notFound
9
- };
10
- //# sourceMappingURL=NotFoundHandler.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/NotFoundHandler.ts"],"sourcesContent":["import { NextFunction, Request, Response } from 'express';\nimport { Exception } from '@thisisagile/easy';\nimport { toOriginatedError } from '@thisisagile/easy-service';\n\nexport const notFound = (req: Request, res: Response, next: NextFunction): void => {\n next(toOriginatedError(Exception.DoesNotExist));\n};\n"],"mappings":";AACA,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAE3B,IAAM,WAAW,CAAC,KAAc,KAAe,SAA6B;AACjF,OAAK,kBAAkB,UAAU,YAAY,CAAC;AAChD;","names":[]}
@@ -1,7 +0,0 @@
1
- // src/express/RequestContextHandler.ts
2
- import { ctx } from "@thisisagile/easy";
3
- var requestContext = (req, res, next) => ctx.request.create(() => next());
4
- export {
5
- requestContext
6
- };
7
- //# sourceMappingURL=RequestContextHandler.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/RequestContextHandler.ts"],"sourcesContent":["import express from 'express';\nimport { ctx } from '@thisisagile/easy';\n\nexport const requestContext = (req: express.Request, res: express.Response, next: express.NextFunction): void => ctx.request.create(() => next());\n"],"mappings":";AACA,SAAS,WAAW;AAEb,IAAM,iBAAiB,CAAC,KAAsB,KAAuB,SAAqC,IAAI,QAAQ,OAAO,MAAM,KAAK,CAAC;","names":[]}
@@ -1,16 +0,0 @@
1
- import {
2
- checkLabCoat,
3
- checkScope,
4
- checkToken,
5
- checkUseCase,
6
- security
7
- } from "../chunk-G54PL2JB.mjs";
8
- import "../chunk-RL5ICAHT.mjs";
9
- export {
10
- checkLabCoat,
11
- checkScope,
12
- checkToken,
13
- checkUseCase,
14
- security
15
- };
16
- //# sourceMappingURL=SecurityHandler.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,8 +0,0 @@
1
- export * from "./AuthError";
2
- export * from "./CorrelationHandler";
3
- export * from "./ErrorHandler";
4
- export * from "./ExpressProvider";
5
- export * from "./NotFoundHandler";
6
- export * from "./RequestContextHandler";
7
- export * from "./SecurityHandler";
8
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/express/index.ts"],"sourcesContent":["export * from './AuthError';\nexport * from './CorrelationHandler';\nexport * from './ErrorHandler';\nexport * from './ExpressProvider';\nexport * from './NotFoundHandler';\nexport * from './RequestContextHandler';\nexport * from './SecurityHandler';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -1,17 +0,0 @@
1
- // src/types/NamespaceContext.ts
2
- import { createNamespace } from "cls-hooked";
3
- import { BaseRequestContext } from "@thisisagile/easy";
4
- var NamespaceContext = class extends BaseRequestContext {
5
- namespace = createNamespace("context");
6
- get(key) {
7
- return this.namespace.get(key);
8
- }
9
- set(key, value) {
10
- return this.namespace.set(key, value);
11
- }
12
- create = (f) => this.namespace.run(f);
13
- };
14
- export {
15
- NamespaceContext
16
- };
17
- //# sourceMappingURL=NamespaceContext.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/types/NamespaceContext.ts"],"sourcesContent":["import { createNamespace } from 'cls-hooked';\nimport { BaseRequestContext } from '@thisisagile/easy';\n\nexport class NamespaceContext extends BaseRequestContext {\n protected readonly namespace = createNamespace('context');\n\n public get<T>(key: string): T {\n return this.namespace.get(key) as T;\n }\n\n public set<T>(key: string, value: T): T {\n return this.namespace.set(key, value);\n }\n\n public readonly create = (f: () => void): void => this.namespace.run(f);\n}\n"],"mappings":";AAAA,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAE5B,IAAM,mBAAN,cAA+B,mBAAmB;AAAA,EACpC,YAAY,gBAAgB,SAAS;AAAA,EAEjD,IAAO,KAAgB;AAC5B,WAAO,KAAK,UAAU,IAAI,GAAG;AAAA,EAC/B;AAAA,EAEO,IAAO,KAAa,OAAa;AACtC,WAAO,KAAK,UAAU,IAAI,KAAK,KAAK;AAAA,EACtC;AAAA,EAEgB,SAAS,CAAC,MAAwB,KAAK,UAAU,IAAI,CAAC;AACxE;","names":[]}
@@ -1,2 +0,0 @@
1
- export * from "./NamespaceContext";
2
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export * from './NamespaceContext';\n"],"mappings":"AAAA,cAAc;","names":[]}