@decaf-ts/for-nest 0.12.1 → 0.13.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/README.md +31 -5
- package/dist/for-nest.cjs +1 -1
- package/dist/for-nest.cjs.map +1 -1
- package/dist/for-nest.js +1 -1
- package/dist/for-nest.js.map +1 -1
- package/lib/cjs/auth/AuthInterceptor.cjs +3 -11
- package/lib/cjs/auth/AuthInterceptor.cjs.map +1 -1
- package/lib/cjs/auth/AuthMiddleware.cjs +51 -0
- package/lib/cjs/auth/AuthMiddleware.cjs.map +1 -0
- package/lib/cjs/auth/DecafAuthHandler.cjs +8 -3
- package/lib/cjs/auth/DecafAuthHandler.cjs.map +1 -1
- package/lib/cjs/auth/DecafAuthModule.cjs +6 -1
- package/lib/cjs/auth/DecafAuthModule.cjs.map +1 -1
- package/lib/cjs/auth/constants.cjs +3 -1
- package/lib/cjs/auth/constants.cjs.map +1 -1
- package/lib/cjs/auth/decorators.cjs +4 -0
- package/lib/cjs/auth/decorators.cjs.map +1 -1
- package/lib/cjs/auth/index.cjs +1 -0
- package/lib/cjs/auth/index.cjs.map +1 -1
- package/lib/cjs/decaf-model/FromModelController.cjs +6 -0
- package/lib/cjs/decaf-model/FromModelController.cjs.map +1 -1
- package/lib/cjs/events-module/DecafStreamModule.cjs +13 -2
- package/lib/cjs/events-module/DecafStreamModule.cjs.map +1 -1
- package/lib/cjs/events-module/EventsController.cjs +28 -5
- package/lib/cjs/events-module/EventsController.cjs.map +1 -1
- package/lib/cjs/events-module/EventsSubscriptionController.cjs +81 -0
- package/lib/cjs/events-module/EventsSubscriptionController.cjs.map +1 -0
- package/lib/cjs/events-module/ObserverSubscriptionRegistry.cjs +51 -0
- package/lib/cjs/events-module/ObserverSubscriptionRegistry.cjs.map +1 -0
- package/lib/cjs/events-module/constant.cjs +2 -1
- package/lib/cjs/events-module/constant.cjs.map +1 -1
- package/lib/cjs/events-module/index.cjs +3 -0
- package/lib/cjs/events-module/index.cjs.map +1 -1
- package/lib/cjs/index.cjs +3 -3
- package/lib/cjs/interceptors/DecafRequestHandlerInterceptor.cjs +3 -31
- package/lib/cjs/interceptors/DecafRequestHandlerInterceptor.cjs.map +1 -1
- package/lib/cjs/module.cjs +1 -1
- package/lib/cjs/module.cjs.map +1 -1
- package/lib/cjs/request/contextualize.cjs +46 -0
- package/lib/cjs/request/contextualize.cjs.map +1 -0
- package/lib/cjs/request/index.cjs +1 -0
- package/lib/cjs/request/index.cjs.map +1 -1
- package/lib/esm/auth/AuthInterceptor.js +4 -12
- package/lib/esm/auth/AuthInterceptor.js.map +1 -1
- package/lib/esm/auth/AuthMiddleware.js +42 -0
- package/lib/esm/auth/AuthMiddleware.js.map +1 -0
- package/lib/esm/auth/DecafAuthHandler.js +8 -3
- package/lib/esm/auth/DecafAuthHandler.js.map +1 -1
- package/lib/esm/auth/DecafAuthModule.js +7 -2
- package/lib/esm/auth/DecafAuthModule.js.map +1 -1
- package/lib/esm/auth/constants.js +2 -0
- package/lib/esm/auth/constants.js.map +1 -1
- package/lib/esm/auth/decorators.js +4 -1
- package/lib/esm/auth/decorators.js.map +1 -1
- package/lib/esm/auth/index.js +1 -0
- package/lib/esm/auth/index.js.map +1 -1
- package/lib/esm/decaf-model/FromModelController.js +8 -2
- package/lib/esm/decaf-model/FromModelController.js.map +1 -1
- package/lib/esm/events-module/DecafStreamModule.js +14 -3
- package/lib/esm/events-module/DecafStreamModule.js.map +1 -1
- package/lib/esm/events-module/EventsController.js +30 -7
- package/lib/esm/events-module/EventsController.js.map +1 -1
- package/lib/esm/events-module/EventsSubscriptionController.js +72 -0
- package/lib/esm/events-module/EventsSubscriptionController.js.map +1 -0
- package/lib/esm/events-module/ObserverSubscriptionRegistry.js +43 -0
- package/lib/esm/events-module/ObserverSubscriptionRegistry.js.map +1 -0
- package/lib/esm/events-module/constant.js +1 -0
- package/lib/esm/events-module/constant.js.map +1 -1
- package/lib/esm/events-module/index.js +3 -0
- package/lib/esm/events-module/index.js.map +1 -1
- package/lib/esm/index.js +3 -3
- package/lib/esm/interceptors/DecafRequestHandlerInterceptor.js +3 -31
- package/lib/esm/interceptors/DecafRequestHandlerInterceptor.js.map +1 -1
- package/lib/esm/module.js +1 -1
- package/lib/esm/module.js.map +1 -1
- package/lib/esm/request/contextualize.js +42 -0
- package/lib/esm/request/contextualize.js.map +1 -0
- package/lib/esm/request/index.js +1 -0
- package/lib/esm/request/index.js.map +1 -1
- package/lib/types/auth/AuthMiddleware.d.cts +9 -0
- package/lib/types/auth/AuthMiddleware.d.mts +9 -0
- package/lib/types/auth/DecafAuthHandler.d.cts +6 -4
- package/lib/types/auth/DecafAuthHandler.d.mts +6 -4
- package/lib/types/auth/DecafAuthModule.d.cts +3 -2
- package/lib/types/auth/DecafAuthModule.d.mts +3 -2
- package/lib/types/auth/constants.d.cts +2 -0
- package/lib/types/auth/constants.d.mts +2 -0
- package/lib/types/auth/decorators.d.cts +1 -0
- package/lib/types/auth/decorators.d.mts +1 -0
- package/lib/types/auth/index.d.cts +1 -0
- package/lib/types/auth/index.d.mts +1 -0
- package/lib/types/events-module/DecafStreamModule.d.cts +2 -1
- package/lib/types/events-module/DecafStreamModule.d.mts +2 -1
- package/lib/types/events-module/EventsController.d.cts +6 -2
- package/lib/types/events-module/EventsController.d.mts +6 -2
- package/lib/types/events-module/EventsSubscriptionController.d.cts +17 -0
- package/lib/types/events-module/EventsSubscriptionController.d.mts +17 -0
- package/lib/types/events-module/ObserverSubscriptionRegistry.d.cts +13 -0
- package/lib/types/events-module/ObserverSubscriptionRegistry.d.mts +13 -0
- package/lib/types/events-module/constant.d.cts +1 -0
- package/lib/types/events-module/constant.d.mts +1 -0
- package/lib/types/events-module/index.d.cts +3 -0
- package/lib/types/events-module/index.d.mts +3 -0
- package/lib/types/index.d.cts +3 -3
- package/lib/types/index.d.mts +3 -3
- package/lib/types/request/contextualize.d.cts +2 -0
- package/lib/types/request/contextualize.d.mts +2 -0
- package/lib/types/request/index.d.cts +1 -0
- package/lib/types/request/index.d.mts +1 -0
- package/lib/types/types.d.cts +7 -2
- package/lib/types/types.d.mts +7 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ This repository is meant to provide an enterprise template for any standard Type
|
|
|
28
28
|
|
|
29
29
|
Documentation available [here](https://decaf-ts.github.io/for-nest/)
|
|
30
30
|
|
|
31
|
-
Minimal size: 14 KB kb gzipped
|
|
31
|
+
Minimal size: 14.8 KB kb gzipped
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
### Description
|
|
@@ -127,7 +127,9 @@ Applied at the **class level** to every auto-generated controller for that model
|
|
|
127
127
|
|---|---|---|---|
|
|
128
128
|
| `public` | `boolean` | `false` | When `true`, applies `@Public()` — the `AuthInterceptor` skips authorization entirely. |
|
|
129
129
|
| `roles` | `string[]` | — | When provided, applies `@RequireRoles(...roles)` — the auth handler validates the user has all listed roles. |
|
|
130
|
+
| `namespaces` | `string[]` | — | When provided, applies `@RequireNamespaces(...namespaces)` — the auth handler validates the user has all listed namespace scopes. |
|
|
130
131
|
| `skipModelRoles` | `boolean` | `false` | When `true`, sets `SKIP_MODEL_ROLES_KEY` metadata — the `AuthInterceptor` passes `undefined` as the model to `authHandler.authorize()`, so model-level `@roles()` checks are skipped. Route-level roles (if set) still apply. |
|
|
132
|
+
| `skipModelNamespaces` | `boolean` | `false` | When `true`, sets `SKIP_MODEL_NAMESPACES_KEY` metadata — the `AuthInterceptor` skips model-level `@namespace()` checks while still enforcing route-level namespaces. |
|
|
131
133
|
|
|
132
134
|
If `auth` is omitted, `@Auth(Model)` is applied by default (requires authentication + model-level role checks).
|
|
133
135
|
|
|
@@ -226,6 +228,16 @@ Requires the user to have all listed roles. Applies `ApiSecurity("bearer")`, `Se
|
|
|
226
228
|
update() {}
|
|
227
229
|
```
|
|
228
230
|
|
|
231
|
+
### `@RequireNamespaces(...namespaces)`
|
|
232
|
+
|
|
233
|
+
Namespace-scope counterpart to `@RequireRoles(...)`. Requires the user to have all listed namespace scopes. Applies `ApiSecurity("bearer")`, `SetMetadata(REQUIRED_NAMESPACES_KEY, namespaces)`, and `UseInterceptors(AuthInterceptor)`.
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
@RequireNamespaces("tenant:acme", "org:engineering")
|
|
237
|
+
@Get("tenant-data")
|
|
238
|
+
listTenantData() {}
|
|
239
|
+
```
|
|
240
|
+
|
|
229
241
|
### `@SkipFabricIdentity()` *(application-specific)*
|
|
230
242
|
|
|
231
243
|
Application-level decorator (e.g. in ew-backend) that sets metadata to skip Fabric identity re-enrollment for specific routes. Not part of `for-nest`.
|
|
@@ -242,7 +254,7 @@ Abstract base class from `@decaf-ts/for-http/server`. Concrete handlers extend i
|
|
|
242
254
|
|---|---|---|
|
|
243
255
|
| `extractFromAuth(ctx: EC): D \| Promise<D>` | Yes | Pulls auth data (user, roles, organization) from the platform execution context. MUST throw `AuthorizationError` when unauthenticated. |
|
|
244
256
|
| `bindToContext(ctx: C, data: D)` | Yes* | Binds auth data to the request context. Default implementation calls `ctx.accumulate(data)`. Override to add adapter-specific keys (e.g. `UUID`, `organization`). |
|
|
245
|
-
| `validate(data, routeRoles, model, ...args)` | No | Default validates route roles
|
|
257
|
+
| `validate(data, routeRoles, routeNamespaces, skipModelNamespaces, model, ...args)` | No | Default validates route roles, route namespaces, model-level roles, and model-level namespaces (from `@namespace()`). Override for custom logic. |
|
|
246
258
|
|
|
247
259
|
\* The default `bindToContext` exists but every concrete handler typically overrides it.
|
|
248
260
|
|
|
@@ -264,12 +276,26 @@ class CustomAuthHandler extends AuthHandler {
|
|
|
264
276
|
}
|
|
265
277
|
```
|
|
266
278
|
|
|
279
|
+
## Namespace authorization
|
|
280
|
+
|
|
281
|
+
Use the `namespace(...)` decorator exported from `@decaf-ts/integrations/nest` on models to attach namespace scopes in the same way `@roles(...)` attaches model roles. The `AuthInterceptor` forwards those scopes to `AuthHandler.authorize(...)`, and the base auth handler checks them against the authenticated principal.
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { namespace } from "@decaf-ts/integrations/nest";
|
|
285
|
+
|
|
286
|
+
@namespace(["tenant:acme", "org:engineering"])
|
|
287
|
+
class Product extends Model {}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Route-level namespace guards can be layered with `@RequireNamespaces(...)` and skipped at the model level with `skipModelNamespaces: true` in `AuthConfig`.
|
|
291
|
+
|
|
267
292
|
### `AuthData` / `UserData`
|
|
268
293
|
|
|
269
294
|
| Field | Type | Description |
|
|
270
295
|
|---|---|---|
|
|
271
296
|
| `user` | `string` | Authenticated user identifier. |
|
|
272
297
|
| `roles` | `string[]` | Roles granted to the user. |
|
|
298
|
+
| `namespaces` | `string[]` | Namespace scopes granted to the user. |
|
|
273
299
|
| `organization` | `string` | Organization / tenant / MSP. |
|
|
274
300
|
|
|
275
301
|
---
|
|
@@ -282,9 +308,9 @@ Request → AuthInterceptor → DecafRequestHandlerInterceptor → Controller
|
|
|
282
308
|
|
|
283
309
|
1. **`AuthInterceptor`** (request-scoped):
|
|
284
310
|
- Reads `IS_PUBLIC_KEY` — if `true`, skips auth.
|
|
285
|
-
- Reads `AUTH_META_KEY` (model name)
|
|
286
|
-
- Reads `SKIP_MODEL_ROLES_KEY`
|
|
287
|
-
- Calls `authHandler.authorize(ctx, effectiveModel, requiredRoles, requestContext)`.
|
|
311
|
+
- Reads `AUTH_META_KEY` (model name), `REQUIRED_ROLES_KEY` (route roles), and `REQUIRED_NAMESPACES_KEY` (route namespaces).
|
|
312
|
+
- Reads `SKIP_MODEL_ROLES_KEY` and `SKIP_MODEL_NAMESPACES_KEY` to selectively skip model-level role or namespace checks.
|
|
313
|
+
- Calls `authHandler.authorize(ctx, effectiveModel, requiredRoles, requiredNamespaces, skipModelNamespaces, requestContext)`.
|
|
288
314
|
- Runs `applyTransformers()` — iterates `Adapter.flavoursToTransform()`, instantiates each `RequestToContextTransformer` if needed, calls `transformer.from(requestContext)`, and accumulates the result.
|
|
289
315
|
- Enriches the logger with `user` / `organization` if present.
|
|
290
316
|
|
package/dist/for-nest.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e,t;e=this,t=function(e,t,r,o,a,s,n,i,c,p,d,l,u,f,h,m,y,g){"use strict";function A(e){var t=Object.create(null);return e&&Object.keys(e).forEach(r=>{if("default"!==r){var o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}}),t.default=e,Object.freeze(t)}var E=A(m);const b="swagger",P={API_OPERATION:b+"/apiOperation",API_RESPONSE:b+"/apiResponse",API_PRODUCES:b+"/apiProduces",API_CONSUMES:b+"/apiConsumes",API_TAGS:b+"/apiUseTags",API_CALLBACKS:b+"/apiCallbacks",API_PARAMETERS:b+"/apiParameters",API_HEADERS:b+"/apiHeaders",API_MODEL_PROPERTIES:b+"/apiModelProperties",API_MODEL_PROPERTIES_ARRAY:b+"/apiModelPropertiesArray",API_SECURITY:b+"/apiSecurity",API_EXCLUDE_ENDPOINT:b+"/apiExcludeEndpoint",API_EXCLUDE_CONTROLLER:b+"/apiExcludeController",API_EXTRA_MODELS:b+"/apiExtraModels",API_EXTENSION:b+"/apiExtension",API_SCHEMA:b+"/apiSchema",API_DEFAULT_GETTER:b+"/apiDefaultGetter",API_LINK:b+"/apiLink"},v=e=>void 0===e;function R(e){if("function"==typeof e)return R(e());if(Array.isArray(e))return e;if("object"!=typeof e)return[];const t=Object.values(e).filter(e=>"number"==typeof e).map(e=>e.toString());return Object.keys(e).filter(e=>!t.includes(e)).map(t=>e[t])}function O(e){return e.filter(n.isString).length>0?"string":"number"}function D(e,t,r=!0){return(o,a)=>{const s=Reflect.getMetadata(P.API_MODEL_PROPERTIES_ARRAY,o)||[],i=":"+a;s.includes(i)||Reflect.defineMetadata(P.API_MODEL_PROPERTIES_ARRAY,[...s,":"+a],o);const c=Reflect.getMetadata(e,o,a);if(c){const s=n.pickBy(t,n.negate(v)),i=r?{...c,...s}:{...s,...c};Reflect.defineMetadata(e,i,o,a)}else{const r=o?.constructor?._OPENAPI_METADATA_FACTORY?.()[a]?.type??Reflect.getMetadata("design:type",o,a);Reflect.defineMetadata(e,{type:r,required:!1,...n.pickBy(t,n.negate(v))},o,a)}}}function S(e={}){return _(e)}function _(e={},t=!0){const[r,o]=((e,t)=>{if(!e)return[e,t];if(t)return[e,t];const r=n.isArray(e);return[r?e[0]:e,r]})(e.type,e.isArray);if((a=e={...e,type:r,isArray:o}).isArray&&"enum"in a&&void 0!==a.enum){e.type="array";const t=R(e.enum);e.items={type:O(t),enum:t},delete e.enum}else if("enum"in e&&void 0!==e.enum){const t=R(e.enum);e.enum=t,e.type=O(t)}var a;return Array.isArray(e.type)&&(e.type="array",e.items={type:"array",items:{type:e.type[0]}}),D(P.API_MODEL_PROPERTIES,e,t)}function C(e,r,a){const n={GET:[c.OperationKeys.READ,o.Get],POST:[c.OperationKeys.CREATE,o.Post],PUT:[c.OperationKeys.UPDATE,o.Put],PATCH:[c.OperationKeys.UPDATE,o.Patch],DELETE:[c.OperationKeys.DELETE,o.Delete]},[p,d]=n[r],l=T(r,a);return l?s.isOperationBlocked(e,l.kind,l.value)?t.apply(i.ApiExcludeEndpoint()):t.apply(d(a)):s.isOperationBlocked(e,p)?t.apply(i.ApiExcludeEndpoint()):t.apply(d(a))}function T(e,t){if(!t)return;const r=t.replace(/^\/+|\/+$/g,""),o={"listBy/:key":s.PreparedStatementKeys.LIST_BY,"paginateBy/:key/:page":s.PreparedStatementKeys.PAGE_BY,"find/:value":s.PreparedStatementKeys.FIND,"page/:value":s.PreparedStatementKeys.PAGE,"findOneBy/:key/:value":s.PreparedStatementKeys.FIND_ONE_BY,"findBy/:key/:value":s.PreparedStatementKeys.FIND_BY,"statement/:method/*args":"statement","countOf/:field":s.PreparedStatementKeys.COUNT_OF,"maxOf/:field":s.PreparedStatementKeys.MAX_OF,"minOf/:field":s.PreparedStatementKeys.MIN_OF,"avgOf/:field":s.PreparedStatementKeys.AVG_OF,"sumOf/:field":s.PreparedStatementKeys.SUM_OF,"distinctOf/:field":s.PreparedStatementKeys.DISTINCT_OF,"groupOf/:field":s.PreparedStatementKeys.GROUP_OF};if(r.startsWith("query/"))return{kind:"query",value:r.replace(/^query\//,"")};const a=o[r];return a?{kind:"statement",value:a}:"GET"===e&&""===r?{kind:"crud",value:c.OperationKeys.READ}:void 0}function M(e=[]){const t=e.map(e=>i.ApiParam({name:e.name,description:e.description??"Path parameter: "+e.name,required:e.required??!0,type:e.type??String}));return o.applyDecorators(...t)}const x=o.createParamDecorator((e,t)=>{const r=t.switchToHttp().getRequest().body,a=t.getClass(),s=a.class;if(!s)throw new o.InternalServerErrorException(`ModelConstructor not found on controller ${a.name}. Ensure the controller was created via FromModelController.`);return r?Array.isArray(r)?r.map(e=>new s(e)):new s(r):r}),I=o.createParamDecorator((e,t)=>{const r=t.switchToHttp().getRequest(),o=r?.params??{},a=e??Object.keys(o),s=a.map(e=>o[e]);return{raw:o,valuesInOrder:s,keysInOrder:a}});function w(e=[]){const t=e.map(e=>e.name);return I(t)}const q=o.createParamDecorator((e,t)=>{const r={...t.switchToHttp().getRequest().query??{}};if(void 0!==r.limit){const e=Number(r.limit);Number.isNaN(e)||(r.limit=e)}if(void 0!==r.offset){const e=Number(r.offset);Number.isNaN(e)||(r.offset=e)}if(void 0!==r.bookmark){const e=Number(r.bookmark);r.bookmark=Number.isNaN(e)?r.bookmark:e}return r}),N="DecafModuleOptions",k="DecafAdapter",F="DecafRoute",$=Symbol("DecafHandlers"),j="DecafExpose",B="DecafControllerConfig",L=Symbol("decaf:context"),U=Symbol("AUTH_HANDLER"),K="auth:meta",H="isPublic",G="requiredRoles",Q="skipModelRoles";function z(t){const r=t?"string"==typeof t?t:t.name:void 0,a=[i.ApiBearerAuth(),o.UseInterceptors(e.AuthInterceptor)];return r&&a.push(o.SetMetadata(K,r)),o.applyDecorators(...a)}function W(){return o.applyDecorators(o.SetMetadata(H,!0))}function Y(...t){return o.applyDecorators(i.ApiSecurity("bearer"),o.SetMetadata(G,t),o.UseInterceptors(e.AuthInterceptor))}function V(e){const t={GET:o.Get,POST:o.Post,PUT:o.Put,PATCH:o.Patch,DELETE:o.Delete}[e];if(!t)throw new s.UnsupportedError(`Unsupported HTTP verb "${e}". No NestJS decorator mapping was found.`);return t}e.DecafRequestContext=class extends u.RequestContext{constructor(e){super({headersOf:e=>e?.headers||void 0},e),this.req=e,this.uuid=s.UUID.instance.generate(),this.request=e}get headers(){return this.getOrUndefined("headers")}put(e){let t;try{t=this.get("overrides")}catch(e){t={}}this.accumulate({overrides:Object.assign(t,e)})}},e.DecafRequestContext=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(0,o.Inject(d.REQUEST)),p.__metadata("design:paramtypes",[Object])],e.DecafRequestContext),e.AuthInterceptor=class{constructor(e,t,r){this.reflector=e,this.requestContext=t,this.authHandler=r}async intercept(e,t){const r=l.Logging.for(this).for(this.intercept),o=this.reflector.getAllAndOverride(H,[e.getHandler(),e.getClass()]),a=this.reflector.get(K,e.getHandler())??this.reflector.get(K,e.getClass()),s=this.reflector.getAllAndOverride(G,[e.getHandler(),e.getClass()]),n=this.reflector.getAllAndOverride(Q,[e.getHandler(),e.getClass()])?void 0:a;r.verbose("Intercepted request"+(a?" for "+a:"")),o?r.debug("Public route \u2014 skipping auth"):this.authHandler?await this.authHandler.authorize(e,n,s,this.requestContext):r.debug("No auth handler registered"),await this.applyTransformers();const i=this.requestContext.getOrUndefined("user"),c=this.requestContext.getOrUndefined("organization");if(i||c){const e=this.requestContext.get("logger").for({user:i,organization:c});this.requestContext.accumulate({logger:e})}return t.handle()}async applyTransformers(){const e=s.Adapter.flavoursToTransform();if(e)for(const t of e){const e=s.Adapter.transformerFor(t);if(!e)continue;const r=e.from?e:new e,o=await r.from(this.requestContext);o&&this.requestContext.accumulate(o)}}},e.AuthInterceptor=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(2,o.Optional()),p.__param(2,o.Inject(U)),p.__metadata("design:paramtypes",[d.Reflector,e.DecafRequestContext,Object])],e.AuthInterceptor);const X=e=>({name:e,description:e+" parameter for the query",required:!0,type:String});function J(e,t,...r){if(e instanceof s.ModelService)return"function"==typeof e[t]?e[t](...r):e.statement(t,...r);if("function"==typeof e[t])return e[t](...r);throw new c.InternalError(`Persistence method "${t}" not found on ${e?.constructor?.name}`)}class Z extends u.AuthHandler{parseRequest(e){const t=e.headers.authorization?.split(" ")[1];return t}extractFromAuth(e){const t=e.switchToHttp().getRequest(),r=this.parseRequest(t);if(!r)throw new s.AuthorizationError("Unauthenticated");return{user:r,roles:[r]}}}var ee,te;e.DecafAuthModule=ee=class{static forRoot(t={}){const r=[e.AuthInterceptor];return t.handler&&(r.push(t.handler),r.push({provide:U,useClass:t.handler})),t.global&&r.push({provide:d.APP_INTERCEPTOR,useExisting:e.AuthInterceptor}),{module:ee,global:t.global??!1,providers:r,exports:[e.AuthInterceptor,U]}}},e.DecafAuthModule=ee=p.__decorate([o.Module({})],e.DecafAuthModule),e.DecafHandlerExecutor=te=class{constructor(e,t){this.handlers=e,this.context=t}async exec(e,t){l.Logging.for(te.name).for(this.exec).debug(`CONTEXT ${this.context.uuid} running ${this.handlers.length} handlers for request ${e.method} ${e.url}`);for(const r of this.handlers)await r.handle(this.context,e,t)}},e.DecafHandlerExecutor=te=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(0,o.Inject($)),p.__metadata("design:paramtypes",[Array,e.DecafRequestContext])],e.DecafHandlerExecutor),e.DecafResponseInterceptor=class{constructor(e){this.ctx=e}intercept(e,t){let r=e.switchToHttp().getResponse();return t.handle().pipe(f.tap(e=>{r=this.ctx.toResponse(r)}))}},e.DecafResponseInterceptor=p.__decorate([o.Injectable(),p.__metadata("design:paramtypes",[e.DecafRequestContext])],e.DecafResponseInterceptor);class re extends u.DecafController{constructor(e,t){super(e),this.clientContext=e}}class oe extends re{constructor(e,t){super(e,t),this.clientContext=e}persistence(e){if(!this._persistence)try{this._persistence=s.Service.get(this.class)}catch{try{this._persistence=s.ModelService.getService(this.class)}catch{this._persistence=s.Repository.forModel(this.class)}}const t=(e??this.clientContext).toOverrides();return e?this._persistence instanceof s.Repository?this._persistence.override(t):this._persistence.for(t):this._persistence}}const ae=new Map;function se(e,r,o=new Set){if(!s.TransactionOperationKeys.includes(e))return r;const n=(e=>(ae.has(e)||ae.set(e,new WeakMap),ae.get(e)))(e),i=n.get(r);if(i)return i;const p=[c.OperationKeys.UPDATE,c.BulkCrudOperationKeys.UPDATE_ALL].includes(e);class d{}n.set(r,d),Object.defineProperty(d,"name",{value:`${l.toPascalCase(r.name)}${l.toPascalCase(e)}DTO`});const u=(()=>{try{return a.Model.pk(r)}catch{return}})(),f=u?a.Model.pkProps(r):void 0,h=u?Reflect.getMetadata("design:type",r.prototype,u):void 0,m=h===Number||h===BigInt,y=!!f?.generated||!!u&&(a.Model.generatedBySequence(r,u)||de(r,u)||m),g=Array.from(new Set(t.Metadata.properties(r)||[])),A=new Set(a.Model.relations(r)||[]),E=[];for(const e of g)e&&(A.has(e)||e===u&&!p&&y||e!==u&&de(r,e)||E.push(e));for(const e of E){const t=le(r,e),o=!!t?.[a.ValidationKeys.REQUIRED],s=ue(r,e)??Reflect.getMetadata("design:type",r.prototype,e),n={required:o};s&&(n.type=s),S(n)(d.prototype,e);const i=Reflect.getMetadata("design:type",r.prototype,e)??s;void 0!==i&&Reflect.defineMetadata("design:type",i,d.prototype,e),Object.defineProperty(d.prototype,e,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}for(const s of A){const n=t.Metadata.relations(r,s);if(!n)throw new c.InternalError(`Metadata for relation ${s} not found`);let i=n.class;if("function"!=typeof i||i.name||(i=i()),!i||"function"!=typeof i)throw new c.InternalError(`Type for relation ${s} not found`);if(!a.Model.get(i.name))continue;const l=t.Metadata.validationFor(r,s),u=!!l?.[a.ValidationKeys.LIST],f=!!l?.[a.ValidationKeys.REQUIRED];if(o.has(i)){ie(d,s,pe(i),u,f);continue}const h=se(e,i,new Set(o).add(r));p?ce(d,s,i,h,u,f):ne(d,s,h,u,f)}return d}function ne(e,t,r,o,a){S({type:r,required:a,isArray:o})(e.prototype,t),Reflect.defineMetadata("design:type",o?Array:r,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function ie(e,t,r,o,a){S(o?{type:"array",items:{type:r},required:a}:{type:"integer"===r?Number:String,required:a})(e.prototype,t),Reflect.defineMetadata("design:type",o?Array:"integer"===r?Number:String,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function ce(e,t,r,o,a,s){const n=Reflect.getMetadata(P.API_EXTRA_MODELS,e)||[];n.includes(o)||Reflect.defineMetadata(P.API_EXTRA_MODELS,[...n,o],e);const i=[{$ref:"#/components/schemas/"+o.name},{type:pe(r)}];S(a?{type:"array",required:s,oneOf:i}:{type:Object,required:s,oneOf:i})(e.prototype,t),Reflect.defineMetadata("design:type",a?Array:Object,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function pe(e){try{const t=a.Model.pkProps(e),r=t?.type;return r===Number||r===BigInt?"integer":"string"}catch{return"string"}}function de(e,t){let r=e;for(;r&&r!==Object&&r!==Function;){if(a.Model.generated(r,t))return!0;r=Object.getPrototypeOf(r)}return!1}function le(e,r){let o=e;for(;o&&o!==Object&&o!==Function;){const e=t.Metadata.validationFor(o,r);if(e)return e;o=Object.getPrototypeOf(o)}}function ue(e,r){let o=e;for(;o&&o!==Object&&o!==Function;){const e=t.Metadata.type(o,r);if(e)return e;o=Object.getPrototypeOf(o)}}s.Adapter.transformerFor=(e=>{const r="string"==typeof e?e:e.alias;return t.Metadata.innerGet(Symbol.for("transformers"),r)}).bind(s.Adapter),s.Adapter.flavoursToTransform=(()=>{const e=t.Metadata.innerGet(Symbol.for("transformers"));if(e)return Object.keys(e)}).bind(s.Adapter),s.Context.prototype.toResponse=function(e){const t=this.pending();return t&&e.header("x-pending-task",JSON.stringify(t)),e};const fe=a.ModelBuilder.prototype;if(fe.decorateClass||(fe.decorateClass=function(e){return this._classDecorators||(this._classDecorators=[]),this._classDecorators.push(e),this}),fe.Auth=function(e){return this.decorateClass(z(e))},!fe.__hasClassDecoratorSupport){const e=fe.build;fe.build=function(){let t=e.call(this);const r=this._classDecorators;if(r?.length)for(const e of r){const r=e(t);r&&(t=r)}return t},fe.__hasClassDecoratorSupport=!0}var he;class me{static{this.log=l.Logging.for(me.name)}static toDecafError(e,t){return e instanceof c.BaseError?e:new c.InternalError(e instanceof Error?`${t}: ${e.message}`:t)}static getPersistence(e){try{return s.Service.get(e)}catch(t){try{return s.ModelService.getService(e)}catch(t){return s.Repository.forModel(e)}}}static createQueryRoutesFromRepository(e,r=s.PersistenceKeys.QUERY){const o=e instanceof s.ModelService?e.repo:e,a=t.Metadata.get(o.constructor,t.Metadata.key(s.PersistenceKeys.QUERY))??{},n=t.Metadata.get(e.constructor,t.Metadata.key(F))??{};class i extends oe{get class(){throw new c.InternalError("Method not implemented.")}constructor(e,t){super(e,t)}}for(const[e,t]of Object.entries(n)){const r=[t.path.replace(/^\/+|\/+$/g,"")].filter(e=>e&&e.trim()).join("/"),o=me.createComplexQueryHandler(e);me.defineMethod(i,e,o);const a=V(t.httpMethod)(r||void 0),s=me.getQueryDecorators(e,r,t.httpMethod);me.applyDecorators(i,e,[a,...s])}for(const[e,t]of Object.entries(a)){const o=[r,e,...(t.fields??[]).map(e=>":"+e)].filter(e=>e&&e.trim()).join("/"),a=me.createComplexQueryHandler(e);me.defineMethod(i,e,a);const s=V("GET")(o||void 0),n=me.getQueryDecorators(e,o,"GET",!0);me.applyDecorators(i,e,[s,...n])}return i}static create(r,n,c){const d=me.log.for(me.create),f=a.Model.tableName(r),h=l.toKebabCase(f),m=r.name,y=me.getPersistence(r),g=y instanceof s.ModelService?y.repo:y,A=t.Metadata.get(r,t.Metadata.key(B)),E=n?.[r.name],b={...c||{},...A||{},...E||{}},P=u.ModelControllerFactory.create(r,g,b).__routes__,{getPK:v,apiProperties:R,path:O}=me.getRouteParametersFromModel(r);d.debug(`Creating controller for model: ${m} with ${P?.length??0} factory routes`);const D=b.auth;let S=he=class extends oe{static get class(){return r}get class(){return r}constructor(e){super(e,he.name),this.pk=a.Model.pk(r),d.info(`Registering dynamic controller for model: ${this.class.name} route: /${h}`)}};var _;if(S=he=p.__decorate([o.Controller(h),i.ApiTags(m),i.ApiExtraModels(r),p.__metadata("design:paramtypes",[e.DecafRequestContext])],S),_=S,D?.public?W()(_):D?.roles?.length?Y(...D.roles)(_):z(r)(_),D?.skipModelRoles&&o.SetMetadata(Q,!0)(_),P){const e=[...P].sort((e,t)=>{const r=e.path.split("/").filter(Boolean),o=t.path.split("/").filter(Boolean),a=r.filter(e=>e.startsWith(":")).length,s=o.filter(e=>e.startsWith(":")).length,n=r.length-a,i=o.length-s;return n!==i?i-n:a!==s?a-s:0});for(const t of e){const e=t.implementation?.name||t.method.toLowerCase(),o=me.matchRoute(e,t,O,R,v,r,m);if(!o)continue;const{methodName:a,handler:s,decorators:n,paramDecorators:i}=o;if(me.defineMethod(S,a,s)){const e=V(t.method)(t.path.replace(/^\/+|\/+$/g,"")||void 0);me.applyDecorators(S,a,[e,...n],i)}}}return S}static getRouteParametersFromModel(e){const r=a.Model.pk(e),o=t.Metadata.get(e,t.Metadata.key(c.DBKeys.COMPOSED,r)),s=o?.args??[],n=Array.isArray(s)&&s.length>0?Array.from(new Set([...s])):Array.from(new Set([r])),i=t.Metadata.description(e)??"";return{path:":"+n.join("/:"),description:i,apiProperties:n.map(r=>({name:r,description:t.Metadata.description(e,r),required:!0,type:String})),getPK:(...e)=>o?.separator?e.join(o.separator):e.join("")}}static routeParamDecorators(e){let t=0;return e.split("/").filter(Boolean).flatMap(e=>e.startsWith(":")||e.startsWith("*")?[{decorator:o.Param(e.slice(1)),index:t++}]:[])}static defineMethod(e,t,r){return Object.defineProperty(e.prototype||e,t,{value:r,writable:!1,configurable:!0,enumerable:!1}),Object.getOwnPropertyDescriptor(e.prototype||e,t)}static applyDecorators(e,t,r,o=[]){const a=e?.prototype??e,s=Object.getOwnPropertyDescriptor(a,t);r.forEach(e=>e(a,t,s)),o.forEach(({decorator:e,index:r})=>e(a,t,r))}static matchRoute(e,t,r,a,n,c,p){const{method:d,path:l}=t,u=l.replace(/^\/+|\/+$/g,""),f=t.implementation;if("POST"===d&&""===u)return me.createRegistration("create",f,me.createCreateDecorators(c,p),[{decorator:x(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("POST"===d&&"bulk"===u)return me.createRegistration("createAll",f,me.bulkCreateDecorators(c,p),[{decorator:x(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("GET"===d&&"bulk"===u)return me.createRegistration("readAll",f,me.bulkReadDecorators(c,p),[{decorator:o.Query("ids"),index:0}]);if("PUT"===d&&"bulk"===u)return me.createRegistration("updateAll",f,me.bulkUpdateDecorators(c,p,a),[{decorator:x(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("DELETE"===d&&"bulk"===u)return me.createRegistration("deleteAll",f,me.bulkDeleteDecorators(c,p,a),[{decorator:o.Query("ids"),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("GET"===d&&u===r)return me.createRegistration("read",f,me.readDecorators(c,p,a,r),me.routeParamDecorators(u));if("PUT"===d&&u===r){const e=me.routeParamDecorators(u);return me.createRegistration("update",f,me.updateDecorators(c,p,a,r),[{decorator:x(),index:0},...e.map(({decorator:e,index:t})=>({decorator:e,index:t+1}))])}if("DELETE"===d&&u===r){const e=me.routeParamDecorators(u);return me.createRegistration("delete",f,me.deleteDecorators(c,p,a,r),e)}const h=u.split("/").filter(Boolean);if(h.length>0&&h.every(e=>e.startsWith(":"))&&u!==r){const e=h.map(e=>e.slice(1)).map(e=>({name:e,description:e+" parameter",required:!0,type:String})),t=h.map(e=>e.slice(1)).join("And"),r=me.routeParamDecorators(u);if("GET"===d)return me.createRegistration("readBy"+t,f,me.readDecorators(c,p,e,u),r);if("PUT"===d)return me.createRegistration("updateBy"+t,f,me.updateDecorators(c,p,e,u),[{decorator:x(),index:0},...r.map(({decorator:e,index:t})=>({decorator:e,index:t+1}))]);if("DELETE"===d)return me.createRegistration("deleteBy"+t,f,me.deleteDecorators(c,p,e,u),r)}if("GET"===d&&"statement/:method/*args"===u)return me.createRegistration("statement",f,me.statementDecorators(c,p),[{decorator:o.Param("method"),index:0},{decorator:o.Param("args"),index:1},{decorator:q(),index:2}]);if("GET"===d&&"findOneBy/:key/:value"===u)return me.createRegistration("findOneBy",f,me.statementShortcutDecorators(c,p,u,s.PreparedStatementKeys.FIND_ONE_BY),me.statementShortcutParams(u));const m={"listBy/:key":s.PreparedStatementKeys.LIST_BY,"paginateBy/:key/:page":s.PreparedStatementKeys.PAGE_BY,"find/:value":s.PreparedStatementKeys.FIND,"page/:value":s.PreparedStatementKeys.PAGE,"findOneBy/:key/:value":s.PreparedStatementKeys.FIND_ONE_BY,"findBy/:key/:value":s.PreparedStatementKeys.FIND_BY,"countOf/:field":s.PreparedStatementKeys.COUNT_OF,"maxOf/:field":s.PreparedStatementKeys.MAX_OF,"minOf/:field":s.PreparedStatementKeys.MIN_OF,"avgOf/:field":s.PreparedStatementKeys.AVG_OF,"sumOf/:field":s.PreparedStatementKeys.SUM_OF,"distinctOf/:field":s.PreparedStatementKeys.DISTINCT_OF,"groupOf/:field":s.PreparedStatementKeys.GROUP_OF}[u];if(m&&"GET"===d)return me.createRegistration(me.statementMethodName(u),f,me.statementShortcutDecorators(c,p,u,m),me.statementShortcutParams(u));if("GET"===d&&u.startsWith("query/")){const e=u.replace(/^query\//,"").split("/")[0];return me.createRegistration(e,f,me.getQueryDecorators(e,u,"GET",!0),me.complexQueryParams(u))}const y=u.split("/").filter(Boolean),g=new Set(["listBy","findBy","findByPaginate","findOneBy","paginateBy","find","page","countOf","maxOf","minOf","avgOf","sumOf","distinctOf","groupOf","statement","bulk","query"]);if(y.length>0&&!u.startsWith("query/")&&!u.startsWith("statement/")&&!g.has(y[0])){const t=y.filter(e=>e.startsWith(":")).map(e=>e.slice(1)).map(e=>({name:e,description:e+" parameter for the query",required:!0,type:String}));return me.createRegistration(e,f,[...t.map(e=>i.ApiParam(e)),i.ApiOperation({summary:`Retrieve records using "${e}".`}),i.ApiOkResponse({description:"Result successfully retrieved."}),i.ApiNoContentResponse({description:"No content returned by the method."})],me.routeParamDecorators(u))}}static createRegistration(e,t,r,o){return{methodName:e,handler:t,decorators:r,paramDecorators:o}}static statementMethodName(e){return e.split("/")[0]}static statementShortcutParams(e){const t=e.split("/").filter(e=>e.startsWith(":")),r=[];return t.forEach((e,t)=>{const a=e.replace(":","");r.push({decorator:o.Param(a),index:t})}),(e.startsWith("listBy/")||e.startsWith("paginateBy/")||e.startsWith("find/")||e.startsWith("page/"))&&r.push({decorator:q(),index:t.length}),r}static complexQueryParams(e){const t=e.split("/").filter(e=>e.startsWith(":")),r=[];return t.forEach((e,t)=>{const a=e.replace(":","");r.push({decorator:o.Param(a),index:t})}),e.startsWith("query/")&&r.push({decorator:q(),index:t.length}),r}static createComplexQueryHandler(e){return async function t(...r){const o=this.log?.for?.(t);try{o&&o.debug(`Invoking custom query "${e}"`);const{ctx:a}=(await this.logCtx([],e,!0)).for(t),s=this.persistence(a),n=me.normalizeQueryArgs(r);if(s?.repo&&"function"==typeof s.repo[e])return s.repo[e](...n);if("function"==typeof s[e])return s[e](...n);if(s?.query&&"function"==typeof s.query)return s.query(e,...n);if("function"==typeof s.statement)return s.statement(e,...n,a);throw new c.InternalError(`Persistence method "${e}" not found on ${s?.constructor?.name}`)}catch(t){throw o&&o.error(`Custom query "${e}" failed`,t),me.toDecafError(t,`Custom query "${e}" failed`)}}}static extractQueryArgs(e){if(0===e.length)return e;const t=e[e.length-1];if(t&&"object"==typeof t&&!Array.isArray(t)){const t=e.pop(),r=void 0!==t.direction,o=void 0!==t.limit,a=void 0!==t.offset;if(!r&&!o&&!a)return e;const s=[];return r?s.push(t.direction):(o||a)&&s.push(void 0),o&&s.push(t.limit),a&&s.push(t.offset),[...e,...s]}return e}static normalizeQueryArgs(e){const t=me.extractQueryArgs(e);if(0===t.length)return t;const r=t[t.length-1];if(!r||"object"!=typeof r||Array.isArray(r))return t;const o=r;return void 0!==o.direction||void 0!==o.limit||void 0!==o.offset||void 0!==o.bookmark?(t.pop(),void 0!==o.direction&&t.push(o.direction),void 0!==o.limit&&t.push(o.limit),void 0!==o.offset&&t.push(o.offset),void 0!==o.bookmark&&t.push(o.bookmark),t):(t.pop(),t)}static createCreateDecorators(e,t){return[C(e,"POST"),i.ApiOperation({summary:`Create a new ${t}.`}),i.ApiBody({description:"Payload for "+t,type:se(c.OperationKeys.CREATE,e)}),i.ApiCreatedResponse({description:t+" created successfully.",schema:{$ref:i.getSchemaPath(e)}}),i.ApiBadRequestResponse({description:"Payload validation failed."}),i.ApiUnprocessableEntityResponse({description:"Repository rejected the provided payload."})]}static bulkCreateDecorators(e,t){return[C(e,"POST","bulk"),i.ApiOperation({summary:`Create a new ${t}.`}),i.ApiBody({description:"Payload for "+t,schema:{type:"array",items:{$ref:i.getSchemaPath(e)}}}),i.ApiCreatedResponse({description:t+" created successfully.",schema:{type:"array",items:{$ref:i.getSchemaPath(e)}}}),i.ApiBadRequestResponse({description:"Payload validation failed."}),i.ApiUnprocessableEntityResponse({description:"Repository rejected the provided payload."})]}static bulkReadDecorators(e,t){return[C(e,"GET","bulk"),i.ApiOperation({summary:`Retrieve ${t} records by ids.`}),i.ApiQuery({name:"ids",required:!0,type:"array"}),i.ApiOkResponse({description:t+" retrieved successfully.",schema:{type:"array",items:{$ref:i.getSchemaPath(e)}}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static bulkUpdateDecorators(e,t,r){return[C(e,"PUT","bulk"),M(r),i.ApiOperation({summary:`Replace existing ${t} records with new payloads.`}),i.ApiBody({description:"Payload for replacing existing records of "+t,schema:{type:"array",$ref:i.getSchemaPath(se(c.OperationKeys.UPDATE,e))}}),i.ApiOkResponse({description:t+" updated successfully.",schema:{type:"array",items:{$ref:i.getSchemaPath(e)}}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`}),i.ApiBadRequestResponse({description:"Payload validation failed."})]}static bulkDeleteDecorators(e,t,r){return[C(e,"DELETE","bulk"),M(r),i.ApiOperation({summary:`Delete ${t} records by ids.`}),i.ApiQuery({name:"ids",required:!0,type:"array"}),i.ApiOkResponse({description:t+" deleted successfully.",schema:{type:"array",items:{$ref:i.getSchemaPath(e)}}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static readDecorators(e,t,r,o){return[C(e,"GET",o),M(r),i.ApiOperation({summary:`Retrieve a ${t} record by id.`}),i.ApiOkResponse({description:t+" retrieved successfully.",schema:{$ref:i.getSchemaPath(e)}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static updateDecorators(e,t,r,o){return[C(e,"PUT",o),M(r),i.ApiOperation({summary:`Replace an existing ${t} record with a new payload.`}),i.ApiBody({description:"Payload for replacing an existing record of "+t,type:se(c.OperationKeys.UPDATE,e)}),i.ApiOkResponse({description:t+" updated successfully.",schema:{$ref:i.getSchemaPath(e)}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`}),i.ApiBadRequestResponse({description:"Payload validation failed."})]}static deleteDecorators(e,t,r,o){return[C(e,"DELETE",o),M(r),i.ApiOperation({summary:`Delete a ${t} record by id.`}),i.ApiOkResponse({description:t+" deleted successfully.",schema:{$ref:i.getSchemaPath(e)}}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static statementDecorators(e,t){return[C(e,"GET","statement/:method/*args"),i.ApiOperation({summary:`Executes a prepared statement on ${t}.`}),i.ApiParam({name:"method",description:"the prepared statement to execute"}),i.ApiParam({name:"args",description:"concatenated list of arguments the prepared statement can accept"}),i.ApiQuery({name:"direction",required:!0,enum:s.OrderDirection,description:"the sort order when applicable"}),i.ApiQuery({name:"limit",required:!0,description:"limit or page size when applicable"}),i.ApiQuery({name:"offset",required:!0,description:"offset or bookmark when applicable"}),i.ApiOkResponse({description:t+" listed found."}),i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static statementShortcutDecorators(e,t,r,o){const a=[C(e,"GET",r),i.ApiOperation({summary:`Retrieve ${t} records.`}),i.ApiOkResponse({description:t+" retrieved successfully."})];return r.split("/").filter(e=>e.startsWith(":")).forEach(e=>{const t=e.replace(":","");a.push(i.ApiParam({name:t,description:`The ${t} parameter`}))}),(r.startsWith("listBy/")||r.startsWith("paginateBy/")||r.startsWith("find/")||r.startsWith("page/"))&&a.push(i.ApiQuery({name:"direction",required:!0,enum:s.OrderDirection,description:"the sort order"})),(r.startsWith("paginateBy/")||r.startsWith("page/"))&&a.push(i.ApiQuery({name:"limit",required:!1,description:"page size"}),i.ApiQuery({name:"offset",required:!1,description:"page number"}),i.ApiQuery({name:"bookmark",required:!1,description:"bookmark for cursor pagination"})),(r.startsWith("findOneBy/")||r.startsWith("findBy/"))&&a.push(i.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})),o!==s.PreparedStatementKeys.COUNT_OF&&o!==s.PreparedStatementKeys.AVG_OF&&o!==s.PreparedStatementKeys.SUM_OF||a.push(i.ApiOkResponse({description:`Result for ${t}.`,type:Number})),o===s.PreparedStatementKeys.DISTINCT_OF&&a.push(i.ApiOkResponse({description:`Distinct values for ${t}.`,type:[String]})),a}static getQueryDecorators(e,t,r,o=!1){var a;const n=[...(a=t,a.split("/").filter(e=>e.startsWith(":")).map(e=>e.slice(1))).map(e=>({name:e,description:e+" parameter for the query",required:!0,type:String})).map(e=>i.ApiParam(e)),i.ApiOperation({summary:`Retrieve records using "${e}".`}),i.ApiOkResponse({description:"Result successfully retrieved."}),i.ApiNoContentResponse({description:"No content returned by the method."})];return"GET"===r&&o&&n.push(i.ApiQuery({name:"direction",required:!1,enum:s.OrderDirection,description:"the sort order when applicable"}),i.ApiQuery({name:"limit",required:!1,description:"limit or page size"}),i.ApiQuery({name:"offset",required:!1,description:"offset or bookmark"})),n}}function ye(e){var r;let a=class{static{r=this}static{this.log=l.Logging.for(r.name).for(e)}static createModelServices(e){return e.map(e=>({provide:e.name+"Service",useFactory:()=>s.ModelService.forModel(e)}))}static isExposed(r,o){const a=o?.[r.name],s=void 0!==a?a:t.Metadata.get(r,t.Metadata.key(j));return void 0===s||!0===s||!!Array.isArray(s)&&s.includes(e)}static forRoot(e,t={}){const o=this.log.for(this.forRoot);o.info("Generating controllers for flavour...");const a=s.Adapter.models(e).filter(e=>this.isExposed(e,t.controllerExposure));for(const e of a)s.ModelService.forModel(e);let n=[];t.autoServices&&(o.info("Auto-services enabled. Initializing service generation."),n=this.createModelServices(a),o.info(`Auto-services completed. ${n.length} services initialized.`));const i={};!1===t.aggregations&&(i.allowGroupingQueries=!1);const c=a.map(e=>me.create(e,t.controllerConfig,i));return o.info(`Generated ${c.length} controllers`),{module:r,controllers:c,providers:[...n]}}};return a=r=p.__decorate([o.Module({})],a),Object.assign(a,"name",{value:"DecafModule"+e}),a}t.Decoration.for(r.InjectablesKeys.INJECTABLE).extend({decorator:(e,t)=>(t=t||("object"==typeof e?Object.assign(e,r.DefaultInjectablesConfig):r.DefaultInjectablesConfig),o.Injectable({scope:t.singleton?o.Scope.DEFAULT:o.Scope.REQUEST,durable:!t.singleton||void 0}))}).apply(),t.Decoration.for(r.InjectablesKeys.INJECT).extend({decorator:(e,t)=>(t,r,a)=>o.Inject(e||t)(t,r,a)}).apply(),t.Decoration.for(a.ValidationKeys.REQUIRED).extend(S({required:!0})).apply(),t.Decoration.for(a.ValidationKeys.MAX).extend({decorator:e=>S({maximum:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MIN).extend({decorator:e=>S({minimum:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MAX_LENGTH).extend({decorator:e=>S({maxLength:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MIN_LENGTH).extend({decorator:e=>S({minLength:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.TYPE).extend({decorator:e=>(t,r)=>("function"!=typeof(e=Array.isArray(e)?e[0]:e)||e.name||(e=e()),S({type:e,required:!1})(t,r))}).apply(),t.Decoration.for(a.ValidationKeys.DATE).extend({decorator:e=>S({type:String,format:"date-time",required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.ENUM).extend({decorator:e=>S({enum:Array.isArray(e)?e:Object.values(e),required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.PATTERN).extend({decorator:e=>S({pattern:"string"==typeof e?e:e.source,required:!1})}).apply(),t.Decoration.for(s.PersistenceKeys.COLUMN).extend({decorator:e=>S({name:e,required:!1})}).apply(),t.Decoration.for(t.DecorationKeys.DESCRIPTION).extend({decorator:e=>S({description:e,required:!1})}).apply(),t.Decoration.for(s.PersistenceKeys.AUTH).extend({decorator:z}).apply();class ge extends s.ForbiddenError{constructor(e){super(e,ge.name)}}class Ae extends c.BaseError{constructor(e){super(Ae.name,e,429)}}const Ee=new Map([[o.UnauthorizedException,e=>new s.AuthorizationError(e)],[o.ForbiddenException,e=>new s.ForbiddenError(e)],[o.BadRequestException,e=>new c.BadRequestError(e)],[o.ConflictException,e=>new c.ConflictError(e)],[o.UnprocessableEntityException,e=>new c.ValidationError(e)]]);e.DecafExceptionFilter=class{constructor(e){this.moduleRef=e}async catch(e,t){const r=t.switchToHttp(),a=r.getResponse(),n=r.getRequest(),i="production"===l.LoggedEnvironment.env;let p;if(e instanceof o.NotFoundException||e instanceof s.UnsupportedError)p=(e=new o.NotAcceptableException(e.message)).getStatus();else if(!(e instanceof c.BaseError)){const t=this.decafErrorFor(e);t?e=t(e.message):429===e.status?e=new Ae(e.message):e instanceof o.HttpException?p=e.getStatus():e=new c.InternalError(e.message)}await this.logError(n,e),a.status(e.code||p).json({status:e.code||p,error:i?e.name:e.message,timestamp:(new Date).toISOString(),path:n.url,method:n.method})}decafErrorFor(e){for(const[t,r]of Ee)if(e instanceof t)return r}async logError(e,t){const r=`Unhandled error on ${e?.method} ${e?.url}`;try{(await this.resolveLogger(e)).error(r,t)}catch{try{l.Logging.get().error(r,t)}catch{}}}async resolveLogger(t){if(this.moduleRef)try{const r=d.ContextIdFactory.getByRequest(t),o=await this.moduleRef.resolve(e.DecafRequestContext,r,{strict:!1});if(o?.logger)return o.logger}catch{}return l.Logging.get()}},e.DecafExceptionFilter=p.__decorate([o.Catch(),o.Injectable(),p.__param(0,o.Optional()),p.__metadata("design:paramtypes",[d.ModuleRef])],e.DecafExceptionFilter);const be={path:"docs",auth:{type:"http",scheme:"bearer",bearerFormat:"JWT",name:"Authorization",description:"Enter JWT token",in:"header"},topbarBgColor:"#000000"};class Pe{constructor(e){this.options={...e}}customCSS(){let e="";return this.options.topbarIconPath&&(e+=`.topbar-wrapper { content: url('data:image/png;base64,${this.b64(this.options.topbarIconPath)}'); width: 200px; height: auto; }\n`),e+`\n .topbar-wrapper svg { visibility: hidden; }\n .swagger-ui .topbar { background-color: ${this.options.topbarBgColor||be.topbarBgColor}; }\n `}getCustomOptions(){const e={};return this.options.faviconPath&&(e.customfavIcon=this.b64(this.options.faviconPath,!0)),{customSiteTitle:this.options.title,...e,customCss:this.customCSS(),swaggerOptions:{persistAuthorization:this.options.persistAuthorization}}}b64(e,t=!1){const r=E.join(this.options.assetsPath||"",e),o=h.readFileSync(r,{encoding:"base64"});return t?"data:image/png;base64,"+o:o}}class ve{constructor(e,t){this.app=e,this.options=t}createDocument(){const e=this.options.path?this.options.description+""+`<br><br><a href="${this.options.openApiJsonPath}">OpenAPI JSON Spec</a> | `+`<a href="${this.options.openApiYamlPath}">OpenAPI YAML Spec</a>`:this.options.description,t=(new i.DocumentBuilder).setTitle(this.options.title).setDescription(e).setVersion(this.options.version||"0.0.1").addBearerAuth(this.options.auth||be.auth).build();return i.SwaggerModule.createDocument(this.app,t,{extraModels:this.options.extraModels||[]})}registerOpenApiRoute(e,t,r){if(!e)return;const o=this.app.getHttpAdapter();e=e.startsWith("/")?e:"/"+e,o.get(e,(e,a)=>{o.reply(a,r(),200,{"Content-Type":t})})}setupSwagger(){const e=this.createDocument(),t=new Pe({title:this.options.title,path:this.options.path||be.path,persistAuthorization:this.options.persistAuthorization??!0,assetsPath:this.options.assetsPath,faviconPath:this.options.faviconFilePath,topbarIconPath:this.options.topbarIconFilePath,topbarBgColor:this.options.topbarBgColor});i.SwaggerModule.setup(this.options.path||be.path,this.app,e,{...t.getCustomOptions(),jsonDocumentUrl:this.options.openApiJsonPath?""+this.options.openApiJsonPath:void 0,yamlDocumentUrl:this.options.openApiYamlPath?""+this.options.openApiYamlPath:void 0}),this.registerOpenApiRoute(this.options.openApiJsonPath,"application/json",()=>e),this.registerOpenApiRoute(this.options.openApiYamlPath,"application/x-yaml",()=>y.stringify(e))}}var Re;e.DecafRequestHandlerInterceptor=Re=class{constructor(e,t){this.requestContext=e,this.executor=t}async contextualize(e){const t={headers:e.headers,overrides:{}},r=(e=>{const t=e.headers;function r(e){if(e)return(Array.isArray(e)?e[0]:e).split(",").map(e=>e.trim()).filter(Boolean)[0]}return r(t?.["x-forwarded-for"])??r(t?.["x-real-ip"])??r(t?.["X-Forwarded-For"])??r(t?.["X-Real-IP"])??e.ip})(e),o=l.Logging.get().for({ip:r});this.requestContext.accumulate(Object.assign({},s.DefaultAdapterFlags,{logger:o,timestamp:new Date,operation:`${e.method} ${e.url}`},t))}async intercept(e,t){const r=e.switchToHttp().getRequest(),o=e.switchToHttp().getResponse(),a=l.Logging.for(Re).for(this.intercept);return a.debug(`CONTEXT ${this.requestContext.uuid} - request: ${r.method} ${r.url}`),await this.contextualize(r),a.debug(`CONTEXT ${this.requestContext.uuid} contextualized - request: ${r.method} ${r.url}`),await this.executor.exec(r,o),a.debug(`CONTEXT ${this.requestContext.uuid} executors finished - request: ${r.method} ${r.url}`),t.handle()}},e.DecafRequestHandlerInterceptor=Re=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__metadata("design:paramtypes",[e.DecafRequestContext,e.DecafHandlerExecutor])],e.DecafRequestHandlerInterceptor);const Oe=new Map;function De(){return Array.from(Oe.values())}function Se(e,t){Oe.has(e)||Oe.set(e,{provide:e,useFactory:t})}var _e;e.DecafCoreModule=class{static{_e=this}static get persistence(){if(!this._persistence)throw new c.InternalError("Persistence service not initialized");return this._persistence}static get log(){return this._logger||(this._logger=l.Logging.for(_e)),this._logger}constructor(e,t){this.options=e,this.moduleRef=t}static forRoot(t){const r=this.log.for(this.forRoot),o=De();return{module:_e,providers:[{provide:N,useValue:t},{provide:k,useValue:this.persistence?.client},{provide:$,useFactory:()=>t.handlers?.map(e=>(r.info("Registered request handler: "+e.name),new e))??[]},e.DecafRequestContext,e.DecafHandlerExecutor,{provide:d.APP_INTERCEPTOR,useClass:e.DecafRequestHandlerInterceptor},...o],exports:[N,k,$,e.DecafRequestContext,e.DecafHandlerExecutor,...o.map(e=>e.provide)]}}static async bootPersistence(e){const t=this.log.for(this.bootPersistence);if(!this._persistence){const r=e.conf.map(([e,t,...r])=>r.pop()?[e,t,...r]:[e,t]);this._persistence=new s.PersistenceService,await this._persistence.boot(r);const o=this._persistence.client;for(let t=0;t<o.length;t++){const r=e.conf[t];let a=r.slice(2,r.length).pop();if(!a||!a.from){const e=s.Adapter.transformerFor(o[t].flavour);if(!e)throw new c.InternalError(`No transformer found for flavour ${o[t].flavour}. you should either @requestToContextTransformer or provide a transformer in the config`);try{a=e.from?e:new e}catch(e){throw new c.InternalError(`Failed to boot transformer for ${o[t].flavour}: ${e}`)}}u.requestToContextTransformer(o[t].flavour)(a)}if(t.info("persistence layer created successfully!"),e.initialization)try{await e.initialization()}catch(e){throw new c.InternalError("Failed to initialize application: "+e)}}return this.persistence.client}async onApplicationShutdown(){const e=_e.log.for(this.onApplicationShutdown),t=this.moduleRef.get(k);for(const r of t)try{r&&(e.info("Shutting down "+r.toString()),await r.shutdown())}catch(t){e.error("Failed to shutdown application",t)}try{await s.Service.shutdown()}catch(t){e.error("Failed to shutdown services",t)}}},e.DecafCoreModule=_e=p.__decorate([o.Global(),o.Module({}),p.__param(0,o.Inject(N)),p.__metadata("design:paramtypes",[Object,d.ModuleRef])],e.DecafCoreModule);const Ce=Symbol("LISTENING_ADAPTERS_FLAVOURS");var Te,Me,xe;e.EventsController=Te=class extends re{constructor(e,t){super(e,Te.name),this.adapters=t.map(e=>s.Adapter.get(e))}listen(){const e=l.Logging.for(Te.name),t=new f.Observable(t=>{const r=("B-"+Math.random().toString(36).slice(2,8)).toUpperCase();e.info(`Creating SSE observer: ${r} for client ${this.clientContext.uuid}`);const o=new class{constructor(){this.observerId=r}refresh(...r){return e.debug(`SSE observer ${this.observerId} received refresh event`),Promise.resolve().then(()=>{const o=(e=>{const[t,r,o,a]=e;return[t?.name??t,r,o,Array.isArray(a)?a.map(e=>{try{return"function"==typeof e.serialize?e.serialize():"string"==typeof e?e:JSON.stringify(e)}catch(e){return}}):a&&"function"==typeof a.serialize?a.serialize():"string"==typeof a?a:JSON.stringify(a)]})(r);t.next({type:"message",data:o}),e.debug(`SSE observer ${this.observerId} event pushed to client`)})}};e.verbose(`Registering observer ${r} across ${this.adapters.length} adapter(s)`);for(const t of this.adapters){const a=t?.constructor?.name??"UnknownAdapter";try{e.debug(`Registering observer ${r} in adapter ${a}`),t.observe(o)}catch(t){e.debug(`Failed to register observer ${r} in adapter ${a}: ${t?.message||t}`),e.error(t)}}return()=>{e.debug("Cleaning up SSE observer "+r);for(const t of this.adapters){const a=t?.constructor?.name??"UnknownAdapter";try{e.debug(`Unregistering observer ${r} from adapter ${a}`),t.unObserve(o)}catch(t){e.debug(`Failed during cleanup of observer ${r} in adapter ${a}: ${t?.message||t}`),e.error(t)}}}}),r=f.interval(15e3).pipe(g.tap(()=>{e.debug("Sending heartbeat")}),g.map(()=>({type:"heartbeat",data:{ts:(new Date).toISOString()}})));return f.merge(t,r)}listenForModel(e){const t=l.Logging.for(Te.name);return new f.Observable(e=>{const r=new class{refresh(...t){return Promise.resolve().then(()=>{e.next({data:t})})}};try{for(const e of this.adapters)e.observe(r)}catch(t){e.error("Failed to observe event: "+(t.message||t))}return()=>{try{for(const e of this.adapters)e.unObserve(r)}catch(e){t.error(e)}}})}},p.__decorate([o.Sse(),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[]),p.__metadata("design:returntype",f.Observable)],e.EventsController.prototype,"listen",null),p.__decorate([o.Sse("/:model"),p.__param(0,o.Query("model")),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[String]),p.__metadata("design:returntype",f.Observable)],e.EventsController.prototype,"listenForModel",null),e.EventsController=Te=p.__decorate([o.Controller(),p.__param(1,o.Inject(Ce)),p.__metadata("design:paramtypes",[e.DecafRequestContext,Array])],e.EventsController),e.DecafStreamModule=Me=class{static forFlavours(t,r="events"){return{module:Me,controllers:[e.EventsController],imports:[d.RouterModule.register([{path:r.replace(/^\//,""),module:Me}])],providers:[e.DecafRequestContext,{provide:Ce,useValue:t??[]}]}}},e.DecafStreamModule=Me=p.__decorate([o.Module({})],e.DecafStreamModule),e.DecafModule=xe=class{static async forRootAsync(t){const{autoControllers:r,autoServices:o}=t,a=(await e.DecafCoreModule.bootPersistence(t)).map(e=>e.flavour),s=[e.DecafCoreModule.forRoot(t)];return r&&a.forEach(e=>{s.push(ye(e).forRoot(e,{autoServices:o,controllerExposure:t.controllerExposure,controllerConfig:t.controllerConfig,aggregations:t.aggregations}))}),t.observerOptions?.enableObserverEvents&&s.push(e.DecafStreamModule.forFlavours(t.observerOptions.observerFlavours||a)),{module:xe,imports:s}}},e.DecafModule=xe=p.__decorate([o.Module({})],e.DecafModule);const Ie="##VERSION##",we="##PACKAGE##";t.Metadata.allowReregistration(!0),t.Metadata.registerLibrary(we,Ie),t.Metadata.allowReregistration(!1),e.AUTH_HANDLER=U,e.AUTH_META_KEY=K,e.ApiOperationFromModel=C,e.ApiParamsFromModel=M,e.ApiProperty=S,e.Auth=z,e.BulkApiOperationFromModel=(e,r,a)=>{const n={GET:[c.BulkCrudOperationKeys.READ_ALL,o.Get],POST:[c.BulkCrudOperationKeys.CREATE_ALL,o.Post],PUT:[c.BulkCrudOperationKeys.UPDATE_ALL,o.Put],PATCH:[c.BulkCrudOperationKeys.UPDATE_ALL,o.Patch],DELETE:[c.BulkCrudOperationKeys.DELETE_ALL,o.Delete]},[p,d]=n[r],l=a?T(r,a):void 0;return l?s.isOperationBlocked(e,l.kind,l.value)?t.apply(i.ApiExcludeEndpoint()):t.apply(d(a)):s.isOperationBlocked(e,"bulk",p)?t.apply(i.ApiExcludeEndpoint()):t.apply(d(a))},e.COMMIT="3ac17fe",e.CorsError=ge,e.DECAF_ADAPTER_ID=k,e.DECAF_CONTEXT_KEY=L,e.DECAF_CONTROLLER_CONFIG=B,e.DECAF_EXPOSE=j,e.DECAF_HANDLERS=$,e.DECAF_MODULE_OPTIONS=N,e.DECAF_ROUTE=F,e.DECAF_TASK_SERVICE_ID="DecafTaskService",e.DECORATORS=P,e.DECORATORS_PREFIX=b,e.DecafAuthHandler=Z,e.DecafBody=x,e.DecafController=re,e.DecafModelController=oe,e.DecafParams=w,e.DecafRoleAuthHandler=class extends Z{},e.DtoFor=se,e.FULL_VERSION="0.12.0-3ac17fe",e.FromModelController=me,e.IS_PUBLIC_KEY=H,e.NestBootstraper=class{static get logger(){return this._logger||(this._logger=new o.Logger("NestBootstrap")),this._logger}static initialize(e){return this.app=e,this}static enableLogger(e){return this._logger=e||new o.Logger("NestBootstrap"),this.app.useLogger(this._logger),this}static enableCors(e=[],t=["GET","POST","PUT","DELETE"]){const r="*"===e?"*":e.map(e=>e.trim().toLowerCase()),o={origin:(e,t)=>e?"*"===r||Array.isArray(r)&&r.includes(e.toLowerCase())?t(null,!0):void t(new ge(`Origin ${e} not allowed`)):t(null,!0),credentials:!0,methods:t.join(",")};return this.app.enableCors(o),this}static useHelmet(e){try{const t=require("helmet");this.app.use(t(e)),this.logger.log("Helmet middleware enabled successfully.")}catch{this.logger.warn("Helmet not installed. Skipping middleware.")}return this}static setupSwagger(e){return new ve(this.app,{title:e.title,description:e.description,version:e.version,path:e.path||"api",persistAuthorization:e.persistAuthorization??!0,assetsPath:e.assetsPath,faviconFilePath:e.faviconPath,topbarIconFilePath:e.topbarIconPath,topbarBgColor:e.topbarBgColor,openApiJsonPath:e.openApiJsonPath,openApiYamlPath:e.openApiYamlPath}).setupSwagger(),this}static useGlobalPipes(...e){return e.length>0&&this.app.useGlobalPipes(...e),this}static useGlobalFilters(...t){return this.app.useGlobalFilters(...t.length>0?t:[new e.DecafExceptionFilter(this.app.get(d.ModuleRef,{strict:!1}))]),this}static useGlobalInterceptors(...e){return e.length>0&&this.app.useGlobalInterceptors(...e),this}static async start(e=Number(process.env.PORT)||3e3,t=void 0,r=!0){this.app.listen(e,t).then(async()=>{if(r){const e=await this.app.getUrl();this.logger.log("\ud83d\ude80 Application is running at: "+e)}})}},e.PACKAGE_NAME=we,e.Public=W,e.REQUIRED_ROLES_KEY=G,e.Repository=(e,t)=>(r,a,n)=>{const i=((e,t)=>t?`${e.name}Repository@${t}`:e.name+"Repository")(e,t);return Se(i,()=>s.Repository.forModel(e,t)),o.Inject(i)(r,a,n)},e.RequireRoles=Y,e.SKIP_MODEL_ROLES_KEY=Q,e.Service=e=>(t,r,n)=>{let i=e;if(void 0===i){const e=Reflect.getMetadata("design:paramtypes",t)||[];i=e[n]}if(void 0===i)throw new c.InternalError(`@Service() could not determine an injection type for parameter ${n} of ${t.name}. Provide an explicit argument, e.g. @Service(SomeService).`);const p="string"!=typeof i&&"function"==typeof(d=i)&&d.prototype instanceof a.Model;var d;const l=p?i.name+"Service":s.injectableServiceKey(i);return Se(l,()=>{if(p)try{return s.Service.get(i)}catch{return s.ModelService.forModel(i)}return s.Service.get(i)}),o.Inject(l)(t,r,n)},e.SwaggerBuilder=ve,e.UseDecafFilter=()=>o.UseFilters(new e.DecafExceptionFilter),e.UseDecafHeaders=()=>o.UseInterceptors(e.DecafResponseInterceptor),e.VERSION=Ie,e.applyApiDecorators=(e,t,r,o)=>{const a=e?.prototype??e;o.method.forEach(e=>e(a,t,r)),o.params?.forEach((e,r)=>e(a,t,r))},e.controllerConfig=e=>r=>(t.Metadata.set(r,B,e),r),e.createApiPropertyDecorator=_,e.createPropertyDecorator=D,e.createRouteHandler=function(e){return async function(t,r){const o=this.log.for(e);try{o.debug(`Invoking persistence method "${e}" given parameters: ${JSON.stringify(t.valuesInOrder)}`);const{direction:a,limit:s,offset:n}=r;return await J(this.persistence(this.ctx),e,...t.valuesInOrder,a,s,n)}catch(t){throw o.error(`Custom query "${e}" failed`,t),s=`Custom query "${e}" failed`,(a=t)instanceof c.BaseError?a:new c.InternalError(a instanceof Error?`${s}: ${a.message}`:s)}var a,s}},e.defineRouteMethod=(e,t,r)=>(Object.defineProperty(e.prototype||e,t,{value:r,writable:!1}),Object.getOwnPropertyDescriptor(e.prototype||e,t)),e.expose=(...e)=>r=>(t.Metadata.set(r,j,!e.length||e),r),e.getApiDecorators=(e,t,r,a=!1)=>{const n=V(r),c=(e=>e.split("/").filter(e=>e.startsWith(":")).map(e=>e.slice(1)))(t).map(X),p=[];return"GET"===r&&a&&p.push(i.ApiQuery({name:"direction",required:!1,enum:s.OrderDirection,description:"the sort order when applicable"}),i.ApiQuery({name:"limit",required:!1,description:"limit or page size when applicable"}),i.ApiQuery({name:"offset",required:!1,description:"offset or bookmark when applicable"})),{method:[n(t),...c.map(i.ApiParam),...p,i.ApiOperation({summary:`Retrieve records using according to "${e}".`}),i.ApiOkResponse({description:"Result successfully retrieved."}),i.ApiNoContentResponse({description:"No content returned by the method."})],params:[w(c),o.Query()]}},e.getEnumType=O,e.getEnumValues=R,e.getModuleFor=ye,e.getRegisteredDecafProviders=De,e.isUndefined=v,e.repoForModel=e=>{const t=a.Model.get(e);if(!t)throw new c.InternalError("Failed to find repository for "+e);return s.Repository.forModel(t)},e.resolvePersistenceMethod=J,e.runMigrations=async()=>{}},"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@decaf-ts/decoration"),require("@decaf-ts/injectable-decorators"),require("@nestjs/common"),require("@decaf-ts/decorator-validation"),require("@decaf-ts/core"),require("lodash"),require("@nestjs/swagger"),require("@decaf-ts/db-decorators"),require("tslib"),require("@nestjs/core"),require("@decaf-ts/logging"),require("@decaf-ts/for-http/server"),require("rxjs"),require("fs"),require("path"),require("yaml"),require("rxjs/operators")):"function"==typeof define&&define.amd?define(["exports","@decaf-ts/decoration","@decaf-ts/injectable-decorators","@nestjs/common","@decaf-ts/decorator-validation","@decaf-ts/core","lodash","@nestjs/swagger","@decaf-ts/db-decorators","tslib","@nestjs/core","@decaf-ts/logging","@decaf-ts/for-http/server","rxjs","fs","path","yaml","rxjs/operators"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["for-nest"]={},e.decafTsDecoration,e.decafTsInjectableDecorators,e.nestjsCommon,e.decafTsDecoratorValidation,e.decafTsCore,e.lodash,e.nestjsSwagger,e.decafTsDbDecorators,e.tslib,e.nestjsCore,e.decafTsLogging,e.server,e.rxjs,e.fs,e.path,e.yaml,e.operators);
|
|
1
|
+
var e,t;e=this,t=function(e,t,r,o,a,s,i,n,c,p,d,u,l,f,h,m,y,g){"use strict";function b(e){var t=Object.create(null);return e&&Object.keys(e).forEach(r=>{if("default"!==r){var o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}}),t.default=e,Object.freeze(t)}var A=b(m);const E="swagger",R={API_OPERATION:E+"/apiOperation",API_RESPONSE:E+"/apiResponse",API_PRODUCES:E+"/apiProduces",API_CONSUMES:E+"/apiConsumes",API_TAGS:E+"/apiUseTags",API_CALLBACKS:E+"/apiCallbacks",API_PARAMETERS:E+"/apiParameters",API_HEADERS:E+"/apiHeaders",API_MODEL_PROPERTIES:E+"/apiModelProperties",API_MODEL_PROPERTIES_ARRAY:E+"/apiModelPropertiesArray",API_SECURITY:E+"/apiSecurity",API_EXCLUDE_ENDPOINT:E+"/apiExcludeEndpoint",API_EXCLUDE_CONTROLLER:E+"/apiExcludeController",API_EXTRA_MODELS:E+"/apiExtraModels",API_EXTENSION:E+"/apiExtension",API_SCHEMA:E+"/apiSchema",API_DEFAULT_GETTER:E+"/apiDefaultGetter",API_LINK:E+"/apiLink"},v=e=>void 0===e;function O(e){if("function"==typeof e)return O(e());if(Array.isArray(e))return e;if("object"!=typeof e)return[];const t=Object.values(e).filter(e=>"number"==typeof e).map(e=>e.toString());return Object.keys(e).filter(e=>!t.includes(e)).map(t=>e[t])}function P(e){return e.filter(i.isString).length>0?"string":"number"}function _(e,t,r=!0){return(o,a)=>{const s=Reflect.getMetadata(R.API_MODEL_PROPERTIES_ARRAY,o)||[],n=":"+a;s.includes(n)||Reflect.defineMetadata(R.API_MODEL_PROPERTIES_ARRAY,[...s,":"+a],o);const c=Reflect.getMetadata(e,o,a);if(c){const s=i.pickBy(t,i.negate(v)),n=r?{...c,...s}:{...s,...c};Reflect.defineMetadata(e,n,o,a)}else{const r=o?.constructor?._OPENAPI_METADATA_FACTORY?.()[a]?.type??Reflect.getMetadata("design:type",o,a);Reflect.defineMetadata(e,{type:r,required:!1,...i.pickBy(t,i.negate(v))},o,a)}}}function S(e={}){return D(e)}function D(e={},t=!0){const[r,o]=((e,t)=>{if(!e)return[e,t];if(t)return[e,t];const r=i.isArray(e);return[r?e[0]:e,r]})(e.type,e.isArray);if((a=e={...e,type:r,isArray:o}).isArray&&"enum"in a&&void 0!==a.enum){e.type="array";const t=O(e.enum);e.items={type:P(t),enum:t},delete e.enum}else if("enum"in e&&void 0!==e.enum){const t=O(e.enum);e.enum=t,e.type=P(t)}var a;return Array.isArray(e.type)&&(e.type="array",e.items={type:"array",items:{type:e.type[0]}}),_(R.API_MODEL_PROPERTIES,e,t)}function C(e,r,a){const i={GET:[c.OperationKeys.READ,o.Get],POST:[c.OperationKeys.CREATE,o.Post],PUT:[c.OperationKeys.UPDATE,o.Put],PATCH:[c.OperationKeys.UPDATE,o.Patch],DELETE:[c.OperationKeys.DELETE,o.Delete]},[p,d]=i[r],u=M(r,a);return u?s.isOperationBlocked(e,u.kind,u.value)?t.apply(n.ApiExcludeEndpoint()):t.apply(d(a)):s.isOperationBlocked(e,p)?t.apply(n.ApiExcludeEndpoint()):t.apply(d(a))}function M(e,t){if(!t)return;const r=t.replace(/^\/+|\/+$/g,""),o={"listBy/:key":s.PreparedStatementKeys.LIST_BY,"paginateBy/:key/:page":s.PreparedStatementKeys.PAGE_BY,"find/:value":s.PreparedStatementKeys.FIND,"page/:value":s.PreparedStatementKeys.PAGE,"findOneBy/:key/:value":s.PreparedStatementKeys.FIND_ONE_BY,"findBy/:key/:value":s.PreparedStatementKeys.FIND_BY,"statement/:method/*args":"statement","countOf/:field":s.PreparedStatementKeys.COUNT_OF,"maxOf/:field":s.PreparedStatementKeys.MAX_OF,"minOf/:field":s.PreparedStatementKeys.MIN_OF,"avgOf/:field":s.PreparedStatementKeys.AVG_OF,"sumOf/:field":s.PreparedStatementKeys.SUM_OF,"distinctOf/:field":s.PreparedStatementKeys.DISTINCT_OF,"groupOf/:field":s.PreparedStatementKeys.GROUP_OF};if(r.startsWith("query/"))return{kind:"query",value:r.replace(/^query\//,"")};const a=o[r];return a?{kind:"statement",value:a}:"GET"===e&&""===r?{kind:"crud",value:c.OperationKeys.READ}:void 0}function T(e=[]){const t=e.map(e=>n.ApiParam({name:e.name,description:e.description??"Path parameter: "+e.name,required:e.required??!0,type:e.type??String}));return o.applyDecorators(...t)}const I=o.createParamDecorator((e,t)=>{const r=t.switchToHttp().getRequest().body,a=t.getClass(),s=a.class;if(!s)throw new o.InternalServerErrorException(`ModelConstructor not found on controller ${a.name}. Ensure the controller was created via FromModelController.`);return r?Array.isArray(r)?r.map(e=>new s(e)):new s(r):r}),x=o.createParamDecorator((e,t)=>{const r=t.switchToHttp().getRequest(),o=r?.params??{},a=e??Object.keys(o),s=a.map(e=>o[e]);return{raw:o,valuesInOrder:s,keysInOrder:a}});function w(e=[]){const t=e.map(e=>e.name);return x(t)}const q=o.createParamDecorator((e,t)=>{const r={...t.switchToHttp().getRequest().query??{}};if(void 0!==r.limit){const e=Number(r.limit);Number.isNaN(e)||(r.limit=e)}if(void 0!==r.offset){const e=Number(r.offset);Number.isNaN(e)||(r.offset=e)}if(void 0!==r.bookmark){const e=Number(r.bookmark);r.bookmark=Number.isNaN(e)?r.bookmark:e}return r}),N="DecafModuleOptions",F="DecafAdapter",k="DecafRoute",$=Symbol("DecafHandlers"),j="DecafExpose",B="DecafControllerConfig",L=Symbol("decaf:context"),U=Symbol("AUTH_HANDLER"),K="auth:meta",H="isPublic",G="requiredRoles",Q="requiredNamespaces",z="skipModelRoles",V="skipModelNamespaces";function W(t){const r=t?"string"==typeof t?t:t.name:void 0,a=[n.ApiBearerAuth(),o.UseInterceptors(e.AuthInterceptor)];return r&&a.push(o.SetMetadata(K,r)),o.applyDecorators(...a)}function Y(){return o.applyDecorators(o.SetMetadata(H,!0))}function X(...t){return o.applyDecorators(n.ApiSecurity("bearer"),o.SetMetadata(G,t),o.UseInterceptors(e.AuthInterceptor))}function J(...t){return o.applyDecorators(n.ApiSecurity("bearer"),o.SetMetadata(Q,t),o.UseInterceptors(e.AuthInterceptor))}function Z(e){const t={GET:o.Get,POST:o.Post,PUT:o.Put,PATCH:o.Patch,DELETE:o.Delete}[e];if(!t)throw new s.UnsupportedError(`Unsupported HTTP verb "${e}". No NestJS decorator mapping was found.`);return t}e.DecafRequestContext=class extends l.RequestContext{constructor(e){super({headersOf:e=>e?.headers||void 0},e),this.req=e,this.uuid=s.UUID.instance.generate(),this.request=e}get headers(){return this.getOrUndefined("headers")}put(e){let t;try{t=this.get("overrides")}catch(e){t={}}this.accumulate({overrides:Object.assign(t,e)})}},e.DecafRequestContext=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(0,o.Inject(d.REQUEST)),p.__metadata("design:paramtypes",[Object])],e.DecafRequestContext),e.AuthInterceptor=class{constructor(e,t,r){this.reflector=e,this.requestContext=t,this.authHandler=r}async intercept(e,t){const r=u.Logging.for(this).for(this.intercept),o=this.reflector.getAllAndOverride(H,[e.getHandler(),e.getClass()]),a=this.reflector.get(K,e.getHandler())??this.reflector.get(K,e.getClass()),s=this.reflector.getAllAndOverride(G,[e.getHandler(),e.getClass()]),i=this.reflector.getAllAndOverride(Q,[e.getHandler(),e.getClass()]),n=this.reflector.getAllAndOverride(z,[e.getHandler(),e.getClass()]),c=this.reflector.getAllAndOverride(V,[e.getHandler(),e.getClass()]),p=n?void 0:a;return r.verbose("Intercepted request"+(a?" for "+a:"")),o?r.debug("Public route \u2014 skipping auth"):this.authHandler?await this.authHandler.authorize(e,p,s,i,c,this.requestContext):r.debug("No auth handler registered"),await this.applyTransformers(),t.handle()}async applyTransformers(){const e=s.Adapter.flavoursToTransform();if(e)for(const t of e){const e=s.Adapter.transformerFor(t);if(!e)continue;const r=e.from?e:new e,o=await r.from(this.requestContext);o&&this.requestContext.accumulate(o)}}},e.AuthInterceptor=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(2,o.Optional()),p.__param(2,o.Inject(U)),p.__metadata("design:paramtypes",[d.Reflector,e.DecafRequestContext,Object])],e.AuthInterceptor);const ee=e=>({name:e,description:e+" parameter for the query",required:!0,type:String});function te(e,t,...r){if(e instanceof s.ModelService)return"function"==typeof e[t]?e[t](...r):e.statement(t,...r);if("function"==typeof e[t])return e[t](...r);throw new c.InternalError(`Persistence method "${t}" not found on ${e?.constructor?.name}`)}const re="__decafRequestContextContextualized";function oe(e,t){if(e.getOrUndefined(re))return!1;const r={headers:t.headers,overrides:{}},o=(e=>{const t=e.headers;function r(e){if(e)return(Array.isArray(e)?e[0]:e).split(",").map(e=>e.trim()).filter(Boolean)[0]}return r(t?.["x-forwarded-for"])??r(t?.["x-real-ip"])??r(t?.["X-Forwarded-For"])??r(t?.["X-Real-IP"])??e.ip})(t),a=e.getOrUndefined("logger"),i=o?(a??u.Logging.get()).for({ip:o}):a??u.Logging.get();return e.accumulate(Object.assign({},s.DefaultAdapterFlags,{logger:i,timestamp:new Date,operation:`${t.method} ${t.url}`},r,{[re]:!0})),!0}e.AuthMiddleware=class{constructor(e,t){this.authHandler=e,this.requestContext=t}async use(e,t,r){if(oe(this.requestContext,e),this.authHandler)try{await this.authHandler.prime(e,this.requestContext)}catch{}await r()}},e.AuthMiddleware=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(0,o.Optional()),p.__param(0,o.Inject(U)),p.__metadata("design:paramtypes",[Object,e.DecafRequestContext])],e.AuthMiddleware);class ae extends l.AuthHandler{isPublicRequest(e){return!1}parseRequest(e){const t=e.headers.authorization?.split(" ")[1];return t}requestFromContext(e){return e.switchToHttp().getRequest()}extractFromRequest(e){const t=this.parseRequest(e);if(!t)throw new s.AuthorizationError("Unauthenticated");return{user:t,roles:[t]}}}var se,ie;e.DecafAuthModule=se=class{static forRoot(t={}){const r=[e.AuthInterceptor,e.AuthMiddleware];return t.handler&&(r.push(t.handler),r.push({provide:U,useClass:t.handler})),t.global&&r.push({provide:d.APP_INTERCEPTOR,useExisting:e.AuthInterceptor}),{module:se,global:t.global??!1,providers:r,exports:[e.AuthInterceptor,e.AuthMiddleware,U]}}configure(t){t.apply(e.AuthMiddleware).forRoutes({path:"*",method:o.RequestMethod.ALL})}},e.DecafAuthModule=se=p.__decorate([o.Module({})],e.DecafAuthModule),e.DecafHandlerExecutor=ie=class{constructor(e,t){this.handlers=e,this.context=t}async exec(e,t){u.Logging.for(ie.name).for(this.exec).debug(`CONTEXT ${this.context.uuid} running ${this.handlers.length} handlers for request ${e.method} ${e.url}`);for(const r of this.handlers)await r.handle(this.context,e,t)}},e.DecafHandlerExecutor=ie=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__param(0,o.Inject($)),p.__metadata("design:paramtypes",[Array,e.DecafRequestContext])],e.DecafHandlerExecutor),e.DecafResponseInterceptor=class{constructor(e){this.ctx=e}intercept(e,t){let r=e.switchToHttp().getResponse();return t.handle().pipe(f.tap(e=>{r=this.ctx.toResponse(r)}))}},e.DecafResponseInterceptor=p.__decorate([o.Injectable(),p.__metadata("design:paramtypes",[e.DecafRequestContext])],e.DecafResponseInterceptor);class ne extends l.DecafController{constructor(e,t){super(e),this.clientContext=e}}class ce extends ne{constructor(e,t){super(e,t),this.clientContext=e}persistence(e){if(!this._persistence)try{this._persistence=s.Service.get(this.class)}catch{try{this._persistence=s.ModelService.getService(this.class)}catch{this._persistence=s.Repository.forModel(this.class)}}const t=(e??this.clientContext).toOverrides();return e?this._persistence instanceof s.Repository?this._persistence.override(t):this._persistence.for(t):this._persistence}}const pe=new Map;function de(e,r,o=new Set){if(!s.TransactionOperationKeys.includes(e))return r;const i=(e=>(pe.has(e)||pe.set(e,new WeakMap),pe.get(e)))(e),n=i.get(r);if(n)return n;const p=[c.OperationKeys.UPDATE,c.BulkCrudOperationKeys.UPDATE_ALL].includes(e);class d{}i.set(r,d),Object.defineProperty(d,"name",{value:`${u.toPascalCase(r.name)}${u.toPascalCase(e)}DTO`});const l=(()=>{try{return a.Model.pk(r)}catch{return}})(),f=l?a.Model.pkProps(r):void 0,h=l?Reflect.getMetadata("design:type",r.prototype,l):void 0,m=h===Number||h===BigInt,y=!!f?.generated||!!l&&(a.Model.generatedBySequence(r,l)||me(r,l)||m),g=Array.from(new Set(t.Metadata.properties(r)||[])),b=new Set(a.Model.relations(r)||[]),A=[];for(const e of g)e&&(b.has(e)||e===l&&!p&&y||e!==l&&me(r,e)||A.push(e));for(const e of A){const t=ye(r,e),o=!!t?.[a.ValidationKeys.REQUIRED],s=ge(r,e)??Reflect.getMetadata("design:type",r.prototype,e),i={required:o};s&&(i.type=s),S(i)(d.prototype,e);const n=Reflect.getMetadata("design:type",r.prototype,e)??s;void 0!==n&&Reflect.defineMetadata("design:type",n,d.prototype,e),Object.defineProperty(d.prototype,e,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}for(const s of b){const i=t.Metadata.relations(r,s);if(!i)throw new c.InternalError(`Metadata for relation ${s} not found`);let n=i.class;if("function"!=typeof n||n.name||(n=n()),!n||"function"!=typeof n)throw new c.InternalError(`Type for relation ${s} not found`);if(!a.Model.get(n.name))continue;const u=t.Metadata.validationFor(r,s),l=!!u?.[a.ValidationKeys.LIST],f=!!u?.[a.ValidationKeys.REQUIRED];if(o.has(n)){le(d,s,he(n),l,f);continue}const h=de(e,n,new Set(o).add(r));p?fe(d,s,n,h,l,f):ue(d,s,h,l,f)}return d}function ue(e,t,r,o,a){S({type:r,required:a,isArray:o})(e.prototype,t),Reflect.defineMetadata("design:type",o?Array:r,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function le(e,t,r,o,a){S(o?{type:"array",items:{type:r},required:a}:{type:"integer"===r?Number:String,required:a})(e.prototype,t),Reflect.defineMetadata("design:type",o?Array:"integer"===r?Number:String,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function fe(e,t,r,o,a,s){const i=Reflect.getMetadata(R.API_EXTRA_MODELS,e)||[];i.includes(o)||Reflect.defineMetadata(R.API_EXTRA_MODELS,[...i,o],e);const n=[{$ref:"#/components/schemas/"+o.name},{type:he(r)}];S(a?{type:"array",required:s,oneOf:n}:{type:Object,required:s,oneOf:n})(e.prototype,t),Reflect.defineMetadata("design:type",a?Array:Object,e.prototype,t),Object.defineProperty(e.prototype,t,{value:void 0,writable:!0,enumerable:!0,configurable:!0})}function he(e){try{const t=a.Model.pkProps(e),r=t?.type;return r===Number||r===BigInt?"integer":"string"}catch{return"string"}}function me(e,t){let r=e;for(;r&&r!==Object&&r!==Function;){if(a.Model.generated(r,t))return!0;r=Object.getPrototypeOf(r)}return!1}function ye(e,r){let o=e;for(;o&&o!==Object&&o!==Function;){const e=t.Metadata.validationFor(o,r);if(e)return e;o=Object.getPrototypeOf(o)}}function ge(e,r){let o=e;for(;o&&o!==Object&&o!==Function;){const e=t.Metadata.type(o,r);if(e)return e;o=Object.getPrototypeOf(o)}}s.Adapter.transformerFor=(e=>{const r="string"==typeof e?e:e.alias;return t.Metadata.innerGet(Symbol.for("transformers"),r)}).bind(s.Adapter),s.Adapter.flavoursToTransform=(()=>{const e=t.Metadata.innerGet(Symbol.for("transformers"));if(e)return Object.keys(e)}).bind(s.Adapter),s.Context.prototype.toResponse=function(e){const t=this.pending();return t&&e.header("x-pending-task",JSON.stringify(t)),e};const be=a.ModelBuilder.prototype;if(be.decorateClass||(be.decorateClass=function(e){return this._classDecorators||(this._classDecorators=[]),this._classDecorators.push(e),this}),be.Auth=function(e){return this.decorateClass(W(e))},!be.__hasClassDecoratorSupport){const e=be.build;be.build=function(){let t=e.call(this);const r=this._classDecorators;if(r?.length)for(const e of r){const r=e(t);r&&(t=r)}return t},be.__hasClassDecoratorSupport=!0}var Ae;class Ee{static{this.log=u.Logging.for(Ee.name)}static toDecafError(e,t){return e instanceof c.BaseError?e:new c.InternalError(e instanceof Error?`${t}: ${e.message}`:t)}static getPersistence(e){try{return s.Service.get(e)}catch(t){try{return s.ModelService.getService(e)}catch(t){return s.Repository.forModel(e)}}}static createQueryRoutesFromRepository(e,r=s.PersistenceKeys.QUERY){const o=e instanceof s.ModelService?e.repo:e,a=t.Metadata.get(o.constructor,t.Metadata.key(s.PersistenceKeys.QUERY))??{},i=t.Metadata.get(e.constructor,t.Metadata.key(k))??{};class n extends ce{get class(){throw new c.InternalError("Method not implemented.")}constructor(e,t){super(e,t)}}for(const[e,t]of Object.entries(i)){const r=[t.path.replace(/^\/+|\/+$/g,"")].filter(e=>e&&e.trim()).join("/"),o=Ee.createComplexQueryHandler(e);Ee.defineMethod(n,e,o);const a=Z(t.httpMethod)(r||void 0),s=Ee.getQueryDecorators(e,r,t.httpMethod);Ee.applyDecorators(n,e,[a,...s])}for(const[e,t]of Object.entries(a)){const o=[r,e,...(t.fields??[]).map(e=>":"+e)].filter(e=>e&&e.trim()).join("/"),a=Ee.createComplexQueryHandler(e);Ee.defineMethod(n,e,a);const s=Z("GET")(o||void 0),i=Ee.getQueryDecorators(e,o,"GET",!0);Ee.applyDecorators(n,e,[s,...i])}return n}static create(r,i,c){const d=Ee.log.for(Ee.create),f=a.Model.tableName(r),h=u.toKebabCase(f),m=r.name,y=Ee.getPersistence(r),g=y instanceof s.ModelService?y.repo:y,b=t.Metadata.get(r,t.Metadata.key(B)),A=i?.[r.name],E={...c||{},...b||{},...A||{}},R=l.ModelControllerFactory.create(r,g,E).__routes__,{getPK:v,apiProperties:O,path:P}=Ee.getRouteParametersFromModel(r);d.debug(`Creating controller for model: ${m} with ${R?.length??0} factory routes`);const _=E.auth;let S=Ae=class extends ce{static get class(){return r}get class(){return r}constructor(e){super(e,Ae.name),this.pk=a.Model.pk(r),d.info(`Registering dynamic controller for model: ${this.class.name} route: /${h}`)}};var D;if(S=Ae=p.__decorate([o.Controller(h),n.ApiTags(m),n.ApiExtraModels(r),p.__metadata("design:paramtypes",[e.DecafRequestContext])],S),D=S,_?.public?Y()(D):_?.roles?.length?X(..._.roles)(D):W(r)(D),_?.namespaces?.length&&J(..._.namespaces)(D),_?.skipModelRoles&&o.SetMetadata(z,!0)(D),_?.skipModelNamespaces&&o.SetMetadata(V,!0)(D),R){const e=[...R].sort((e,t)=>{const r=e.path.split("/").filter(Boolean),o=t.path.split("/").filter(Boolean),a=r.filter(e=>e.startsWith(":")).length,s=o.filter(e=>e.startsWith(":")).length,i=r.length-a,n=o.length-s;return i!==n?n-i:a!==s?a-s:0});for(const t of e){const e=t.implementation?.name||t.method.toLowerCase(),o=Ee.matchRoute(e,t,P,O,v,r,m);if(!o)continue;const{methodName:a,handler:s,decorators:i,paramDecorators:n}=o;if(Ee.defineMethod(S,a,s)){const e=Z(t.method)(t.path.replace(/^\/+|\/+$/g,"")||void 0);Ee.applyDecorators(S,a,[e,...i],n)}}}return S}static getRouteParametersFromModel(e){const r=a.Model.pk(e),o=t.Metadata.get(e,t.Metadata.key(c.DBKeys.COMPOSED,r)),s=o?.args??[],i=Array.isArray(s)&&s.length>0?Array.from(new Set([...s])):Array.from(new Set([r])),n=t.Metadata.description(e)??"";return{path:":"+i.join("/:"),description:n,apiProperties:i.map(r=>({name:r,description:t.Metadata.description(e,r),required:!0,type:String})),getPK:(...e)=>o?.separator?e.join(o.separator):e.join("")}}static routeParamDecorators(e){let t=0;return e.split("/").filter(Boolean).flatMap(e=>e.startsWith(":")||e.startsWith("*")?[{decorator:o.Param(e.slice(1)),index:t++}]:[])}static defineMethod(e,t,r){return Object.defineProperty(e.prototype||e,t,{value:r,writable:!1,configurable:!0,enumerable:!1}),Object.getOwnPropertyDescriptor(e.prototype||e,t)}static applyDecorators(e,t,r,o=[]){const a=e?.prototype??e,s=Object.getOwnPropertyDescriptor(a,t);r.forEach(e=>e(a,t,s)),o.forEach(({decorator:e,index:r})=>e(a,t,r))}static matchRoute(e,t,r,a,i,c,p){const{method:d,path:u}=t,l=u.replace(/^\/+|\/+$/g,""),f=t.implementation;if("POST"===d&&""===l)return Ee.createRegistration("create",f,Ee.createCreateDecorators(c,p),[{decorator:I(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("POST"===d&&"bulk"===l)return Ee.createRegistration("createAll",f,Ee.bulkCreateDecorators(c,p),[{decorator:I(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("GET"===d&&"bulk"===l)return Ee.createRegistration("readAll",f,Ee.bulkReadDecorators(c,p),[{decorator:o.Query("ids"),index:0}]);if("PUT"===d&&"bulk"===l)return Ee.createRegistration("updateAll",f,Ee.bulkUpdateDecorators(c,p,a),[{decorator:I(),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("DELETE"===d&&"bulk"===l)return Ee.createRegistration("deleteAll",f,Ee.bulkDeleteDecorators(c,p,a),[{decorator:o.Query("ids"),index:0},{decorator:o.Response({passthrough:!0}),index:1}]);if("GET"===d&&l===r)return Ee.createRegistration("read",f,Ee.readDecorators(c,p,a,r),Ee.routeParamDecorators(l));if("PUT"===d&&l===r){const e=Ee.routeParamDecorators(l);return Ee.createRegistration("update",f,Ee.updateDecorators(c,p,a,r),[{decorator:I(),index:0},...e.map(({decorator:e,index:t})=>({decorator:e,index:t+1}))])}if("DELETE"===d&&l===r){const e=Ee.routeParamDecorators(l);return Ee.createRegistration("delete",f,Ee.deleteDecorators(c,p,a,r),e)}const h=l.split("/").filter(Boolean);if(h.length>0&&h.every(e=>e.startsWith(":"))&&l!==r){const e=h.map(e=>e.slice(1)).map(e=>({name:e,description:e+" parameter",required:!0,type:String})),t=h.map(e=>e.slice(1)).join("And"),r=Ee.routeParamDecorators(l);if("GET"===d)return Ee.createRegistration("readBy"+t,f,Ee.readDecorators(c,p,e,l),r);if("PUT"===d)return Ee.createRegistration("updateBy"+t,f,Ee.updateDecorators(c,p,e,l),[{decorator:I(),index:0},...r.map(({decorator:e,index:t})=>({decorator:e,index:t+1}))]);if("DELETE"===d)return Ee.createRegistration("deleteBy"+t,f,Ee.deleteDecorators(c,p,e,l),r)}if("GET"===d&&"statement/:method/*args"===l)return Ee.createRegistration("statement",f,Ee.statementDecorators(c,p),[{decorator:o.Param("method"),index:0},{decorator:o.Param("args"),index:1},{decorator:q(),index:2}]);if("GET"===d&&"findOneBy/:key/:value"===l)return Ee.createRegistration("findOneBy",f,Ee.statementShortcutDecorators(c,p,l,s.PreparedStatementKeys.FIND_ONE_BY),Ee.statementShortcutParams(l));const m={"listBy/:key":s.PreparedStatementKeys.LIST_BY,"paginateBy/:key/:page":s.PreparedStatementKeys.PAGE_BY,"find/:value":s.PreparedStatementKeys.FIND,"page/:value":s.PreparedStatementKeys.PAGE,"findOneBy/:key/:value":s.PreparedStatementKeys.FIND_ONE_BY,"findBy/:key/:value":s.PreparedStatementKeys.FIND_BY,"countOf/:field":s.PreparedStatementKeys.COUNT_OF,"maxOf/:field":s.PreparedStatementKeys.MAX_OF,"minOf/:field":s.PreparedStatementKeys.MIN_OF,"avgOf/:field":s.PreparedStatementKeys.AVG_OF,"sumOf/:field":s.PreparedStatementKeys.SUM_OF,"distinctOf/:field":s.PreparedStatementKeys.DISTINCT_OF,"groupOf/:field":s.PreparedStatementKeys.GROUP_OF}[l];if(m&&"GET"===d)return Ee.createRegistration(Ee.statementMethodName(l),f,Ee.statementShortcutDecorators(c,p,l,m),Ee.statementShortcutParams(l));if("GET"===d&&l.startsWith("query/")){const e=l.replace(/^query\//,"").split("/")[0];return Ee.createRegistration(e,f,Ee.getQueryDecorators(e,l,"GET",!0),Ee.complexQueryParams(l))}const y=l.split("/").filter(Boolean),g=new Set(["listBy","findBy","findByPaginate","findOneBy","paginateBy","find","page","countOf","maxOf","minOf","avgOf","sumOf","distinctOf","groupOf","statement","bulk","query"]);if(y.length>0&&!l.startsWith("query/")&&!l.startsWith("statement/")&&!g.has(y[0])){const t=y.filter(e=>e.startsWith(":")).map(e=>e.slice(1)).map(e=>({name:e,description:e+" parameter for the query",required:!0,type:String}));return Ee.createRegistration(e,f,[...t.map(e=>n.ApiParam(e)),n.ApiOperation({summary:`Retrieve records using "${e}".`}),n.ApiOkResponse({description:"Result successfully retrieved."}),n.ApiNoContentResponse({description:"No content returned by the method."})],Ee.routeParamDecorators(l))}}static createRegistration(e,t,r,o){return{methodName:e,handler:t,decorators:r,paramDecorators:o}}static statementMethodName(e){return e.split("/")[0]}static statementShortcutParams(e){const t=e.split("/").filter(e=>e.startsWith(":")),r=[];return t.forEach((e,t)=>{const a=e.replace(":","");r.push({decorator:o.Param(a),index:t})}),(e.startsWith("listBy/")||e.startsWith("paginateBy/")||e.startsWith("find/")||e.startsWith("page/"))&&r.push({decorator:q(),index:t.length}),r}static complexQueryParams(e){const t=e.split("/").filter(e=>e.startsWith(":")),r=[];return t.forEach((e,t)=>{const a=e.replace(":","");r.push({decorator:o.Param(a),index:t})}),e.startsWith("query/")&&r.push({decorator:q(),index:t.length}),r}static createComplexQueryHandler(e){return async function t(...r){const o=this.log?.for?.(t);try{o&&o.debug(`Invoking custom query "${e}"`);const{ctx:a}=(await this.logCtx([],e,!0)).for(t),s=this.persistence(a),i=Ee.normalizeQueryArgs(r);if(s?.repo&&"function"==typeof s.repo[e])return s.repo[e](...i);if("function"==typeof s[e])return s[e](...i);if(s?.query&&"function"==typeof s.query)return s.query(e,...i);if("function"==typeof s.statement)return s.statement(e,...i,a);throw new c.InternalError(`Persistence method "${e}" not found on ${s?.constructor?.name}`)}catch(t){throw o&&o.error(`Custom query "${e}" failed`,t),Ee.toDecafError(t,`Custom query "${e}" failed`)}}}static extractQueryArgs(e){if(0===e.length)return e;const t=e[e.length-1];if(t&&"object"==typeof t&&!Array.isArray(t)){const t=e.pop(),r=void 0!==t.direction,o=void 0!==t.limit,a=void 0!==t.offset;if(!r&&!o&&!a)return e;const s=[];return r?s.push(t.direction):(o||a)&&s.push(void 0),o&&s.push(t.limit),a&&s.push(t.offset),[...e,...s]}return e}static normalizeQueryArgs(e){const t=Ee.extractQueryArgs(e);if(0===t.length)return t;const r=t[t.length-1];if(!r||"object"!=typeof r||Array.isArray(r))return t;const o=r;return void 0!==o.direction||void 0!==o.limit||void 0!==o.offset||void 0!==o.bookmark?(t.pop(),void 0!==o.direction&&t.push(o.direction),void 0!==o.limit&&t.push(o.limit),void 0!==o.offset&&t.push(o.offset),void 0!==o.bookmark&&t.push(o.bookmark),t):(t.pop(),t)}static createCreateDecorators(e,t){return[C(e,"POST"),n.ApiOperation({summary:`Create a new ${t}.`}),n.ApiBody({description:"Payload for "+t,type:de(c.OperationKeys.CREATE,e)}),n.ApiCreatedResponse({description:t+" created successfully.",schema:{$ref:n.getSchemaPath(e)}}),n.ApiBadRequestResponse({description:"Payload validation failed."}),n.ApiUnprocessableEntityResponse({description:"Repository rejected the provided payload."})]}static bulkCreateDecorators(e,t){return[C(e,"POST","bulk"),n.ApiOperation({summary:`Create a new ${t}.`}),n.ApiBody({description:"Payload for "+t,schema:{type:"array",items:{$ref:n.getSchemaPath(e)}}}),n.ApiCreatedResponse({description:t+" created successfully.",schema:{type:"array",items:{$ref:n.getSchemaPath(e)}}}),n.ApiBadRequestResponse({description:"Payload validation failed."}),n.ApiUnprocessableEntityResponse({description:"Repository rejected the provided payload."})]}static bulkReadDecorators(e,t){return[C(e,"GET","bulk"),n.ApiOperation({summary:`Retrieve ${t} records by ids.`}),n.ApiQuery({name:"ids",required:!0,type:"array"}),n.ApiOkResponse({description:t+" retrieved successfully.",schema:{type:"array",items:{$ref:n.getSchemaPath(e)}}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static bulkUpdateDecorators(e,t,r){return[C(e,"PUT","bulk"),T(r),n.ApiOperation({summary:`Replace existing ${t} records with new payloads.`}),n.ApiBody({description:"Payload for replacing existing records of "+t,schema:{type:"array",$ref:n.getSchemaPath(de(c.OperationKeys.UPDATE,e))}}),n.ApiOkResponse({description:t+" updated successfully.",schema:{type:"array",items:{$ref:n.getSchemaPath(e)}}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`}),n.ApiBadRequestResponse({description:"Payload validation failed."})]}static bulkDeleteDecorators(e,t,r){return[C(e,"DELETE","bulk"),T(r),n.ApiOperation({summary:`Delete ${t} records by ids.`}),n.ApiQuery({name:"ids",required:!0,type:"array"}),n.ApiOkResponse({description:t+" deleted successfully.",schema:{type:"array",items:{$ref:n.getSchemaPath(e)}}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static readDecorators(e,t,r,o){return[C(e,"GET",o),T(r),n.ApiOperation({summary:`Retrieve a ${t} record by id.`}),n.ApiOkResponse({description:t+" retrieved successfully.",schema:{$ref:n.getSchemaPath(e)}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static updateDecorators(e,t,r,o){return[C(e,"PUT",o),T(r),n.ApiOperation({summary:`Replace an existing ${t} record with a new payload.`}),n.ApiBody({description:"Payload for replacing an existing record of "+t,type:de(c.OperationKeys.UPDATE,e)}),n.ApiOkResponse({description:t+" updated successfully.",schema:{$ref:n.getSchemaPath(e)}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`}),n.ApiBadRequestResponse({description:"Payload validation failed."})]}static deleteDecorators(e,t,r,o){return[C(e,"DELETE",o),T(r),n.ApiOperation({summary:`Delete a ${t} record by id.`}),n.ApiOkResponse({description:t+" deleted successfully.",schema:{$ref:n.getSchemaPath(e)}}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static statementDecorators(e,t){return[C(e,"GET","statement/:method/*args"),n.ApiOperation({summary:`Executes a prepared statement on ${t}.`}),n.ApiParam({name:"method",description:"the prepared statement to execute"}),n.ApiParam({name:"args",description:"concatenated list of arguments the prepared statement can accept"}),n.ApiQuery({name:"direction",required:!0,enum:s.OrderDirection,description:"the sort order when applicable"}),n.ApiQuery({name:"limit",required:!0,description:"limit or page size when applicable"}),n.ApiQuery({name:"offset",required:!0,description:"offset or bookmark when applicable"}),n.ApiOkResponse({description:t+" listed found."}),n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})]}static statementShortcutDecorators(e,t,r,o){const a=[C(e,"GET",r),n.ApiOperation({summary:`Retrieve ${t} records.`}),n.ApiOkResponse({description:t+" retrieved successfully."})];return r.split("/").filter(e=>e.startsWith(":")).forEach(e=>{const t=e.replace(":","");a.push(n.ApiParam({name:t,description:`The ${t} parameter`}))}),(r.startsWith("listBy/")||r.startsWith("paginateBy/")||r.startsWith("find/")||r.startsWith("page/"))&&a.push(n.ApiQuery({name:"direction",required:!0,enum:s.OrderDirection,description:"the sort order"})),(r.startsWith("paginateBy/")||r.startsWith("page/"))&&a.push(n.ApiQuery({name:"limit",required:!1,description:"page size"}),n.ApiQuery({name:"offset",required:!1,description:"page number"}),n.ApiQuery({name:"bookmark",required:!1,description:"bookmark for cursor pagination"})),(r.startsWith("findOneBy/")||r.startsWith("findBy/"))&&a.push(n.ApiNotFoundResponse({description:`No ${t} record matches the provided identifier.`})),o!==s.PreparedStatementKeys.COUNT_OF&&o!==s.PreparedStatementKeys.AVG_OF&&o!==s.PreparedStatementKeys.SUM_OF||a.push(n.ApiOkResponse({description:`Result for ${t}.`,type:Number})),o===s.PreparedStatementKeys.DISTINCT_OF&&a.push(n.ApiOkResponse({description:`Distinct values for ${t}.`,type:[String]})),a}static getQueryDecorators(e,t,r,o=!1){var a;const i=[...(a=t,a.split("/").filter(e=>e.startsWith(":")).map(e=>e.slice(1))).map(e=>({name:e,description:e+" parameter for the query",required:!0,type:String})).map(e=>n.ApiParam(e)),n.ApiOperation({summary:`Retrieve records using "${e}".`}),n.ApiOkResponse({description:"Result successfully retrieved."}),n.ApiNoContentResponse({description:"No content returned by the method."})];return"GET"===r&&o&&i.push(n.ApiQuery({name:"direction",required:!1,enum:s.OrderDirection,description:"the sort order when applicable"}),n.ApiQuery({name:"limit",required:!1,description:"limit or page size"}),n.ApiQuery({name:"offset",required:!1,description:"offset or bookmark"})),i}}function Re(e){var r;let a=class{static{r=this}static{this.log=u.Logging.for(r.name).for(e)}static createModelServices(e){return e.map(e=>({provide:e.name+"Service",useFactory:()=>s.ModelService.forModel(e)}))}static isExposed(r,o){const a=o?.[r.name],s=void 0!==a?a:t.Metadata.get(r,t.Metadata.key(j));return void 0===s||!0===s||!!Array.isArray(s)&&s.includes(e)}static forRoot(e,t={}){const o=this.log.for(this.forRoot);o.info("Generating controllers for flavour...");const a=s.Adapter.models(e).filter(e=>this.isExposed(e,t.controllerExposure));for(const e of a)s.ModelService.forModel(e);let i=[];t.autoServices&&(o.info("Auto-services enabled. Initializing service generation."),i=this.createModelServices(a),o.info(`Auto-services completed. ${i.length} services initialized.`));const n={};!1===t.aggregations&&(n.allowGroupingQueries=!1);const c=a.map(e=>Ee.create(e,t.controllerConfig,n));return o.info(`Generated ${c.length} controllers`),{module:r,controllers:c,providers:[...i]}}};return a=r=p.__decorate([o.Module({})],a),Object.assign(a,"name",{value:"DecafModule"+e}),a}t.Decoration.for(r.InjectablesKeys.INJECTABLE).extend({decorator:(e,t)=>(t=t||("object"==typeof e?Object.assign(e,r.DefaultInjectablesConfig):r.DefaultInjectablesConfig),o.Injectable({scope:t.singleton?o.Scope.DEFAULT:o.Scope.REQUEST,durable:!t.singleton||void 0}))}).apply(),t.Decoration.for(r.InjectablesKeys.INJECT).extend({decorator:(e,t)=>(t,r,a)=>o.Inject(e||t)(t,r,a)}).apply(),t.Decoration.for(a.ValidationKeys.REQUIRED).extend(S({required:!0})).apply(),t.Decoration.for(a.ValidationKeys.MAX).extend({decorator:e=>S({maximum:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MIN).extend({decorator:e=>S({minimum:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MAX_LENGTH).extend({decorator:e=>S({maxLength:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.MIN_LENGTH).extend({decorator:e=>S({minLength:e,required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.TYPE).extend({decorator:e=>(t,r)=>("function"!=typeof(e=Array.isArray(e)?e[0]:e)||e.name||(e=e()),S({type:e,required:!1})(t,r))}).apply(),t.Decoration.for(a.ValidationKeys.DATE).extend({decorator:e=>S({type:String,format:"date-time",required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.ENUM).extend({decorator:e=>S({enum:Array.isArray(e)?e:Object.values(e),required:!1})}).apply(),t.Decoration.for(a.ValidationKeys.PATTERN).extend({decorator:e=>S({pattern:"string"==typeof e?e:e.source,required:!1})}).apply(),t.Decoration.for(s.PersistenceKeys.COLUMN).extend({decorator:e=>S({name:e,required:!1})}).apply(),t.Decoration.for(t.DecorationKeys.DESCRIPTION).extend({decorator:e=>S({description:e,required:!1})}).apply(),t.Decoration.for(s.PersistenceKeys.AUTH).extend({decorator:W}).apply();class ve extends s.ForbiddenError{constructor(e){super(e,ve.name)}}class Oe extends c.BaseError{constructor(e){super(Oe.name,e,429)}}const Pe=new Map([[o.UnauthorizedException,e=>new s.AuthorizationError(e)],[o.ForbiddenException,e=>new s.ForbiddenError(e)],[o.BadRequestException,e=>new c.BadRequestError(e)],[o.ConflictException,e=>new c.ConflictError(e)],[o.UnprocessableEntityException,e=>new c.ValidationError(e)]]);e.DecafExceptionFilter=class{constructor(e){this.moduleRef=e}async catch(e,t){const r=t.switchToHttp(),a=r.getResponse(),i=r.getRequest(),n="production"===u.LoggedEnvironment.env;let p;if(e instanceof o.NotFoundException||e instanceof s.UnsupportedError)p=(e=new o.NotAcceptableException(e.message)).getStatus();else if(!(e instanceof c.BaseError)){const t=this.decafErrorFor(e);t?e=t(e.message):429===e.status?e=new Oe(e.message):e instanceof o.HttpException?p=e.getStatus():e=new c.InternalError(e.message)}await this.logError(i,e),a.status(e.code||p).json({status:e.code||p,error:n?e.name:e.message,timestamp:(new Date).toISOString(),path:i.url,method:i.method})}decafErrorFor(e){for(const[t,r]of Pe)if(e instanceof t)return r}async logError(e,t){const r=`Unhandled error on ${e?.method} ${e?.url}`;try{(await this.resolveLogger(e)).error(r,t)}catch{try{u.Logging.get().error(r,t)}catch{}}}async resolveLogger(t){if(this.moduleRef)try{const r=d.ContextIdFactory.getByRequest(t),o=await this.moduleRef.resolve(e.DecafRequestContext,r,{strict:!1});if(o?.logger)return o.logger}catch{}return u.Logging.get()}},e.DecafExceptionFilter=p.__decorate([o.Catch(),o.Injectable(),p.__param(0,o.Optional()),p.__metadata("design:paramtypes",[d.ModuleRef])],e.DecafExceptionFilter);const _e={path:"docs",auth:{type:"http",scheme:"bearer",bearerFormat:"JWT",name:"Authorization",description:"Enter JWT token",in:"header"},topbarBgColor:"#000000"};class Se{constructor(e){this.options={...e}}customCSS(){let e="";return this.options.topbarIconPath&&(e+=`.topbar-wrapper { content: url('data:image/png;base64,${this.b64(this.options.topbarIconPath)}'); width: 200px; height: auto; }\n`),e+`\n .topbar-wrapper svg { visibility: hidden; }\n .swagger-ui .topbar { background-color: ${this.options.topbarBgColor||_e.topbarBgColor}; }\n `}getCustomOptions(){const e={};return this.options.faviconPath&&(e.customfavIcon=this.b64(this.options.faviconPath,!0)),{customSiteTitle:this.options.title,...e,customCss:this.customCSS(),swaggerOptions:{persistAuthorization:this.options.persistAuthorization}}}b64(e,t=!1){const r=A.join(this.options.assetsPath||"",e),o=h.readFileSync(r,{encoding:"base64"});return t?"data:image/png;base64,"+o:o}}class De{constructor(e,t){this.app=e,this.options=t}createDocument(){const e=this.options.path?this.options.description+""+`<br><br><a href="${this.options.openApiJsonPath}">OpenAPI JSON Spec</a> | `+`<a href="${this.options.openApiYamlPath}">OpenAPI YAML Spec</a>`:this.options.description,t=(new n.DocumentBuilder).setTitle(this.options.title).setDescription(e).setVersion(this.options.version||"0.0.1").addBearerAuth(this.options.auth||_e.auth).build();return n.SwaggerModule.createDocument(this.app,t,{extraModels:this.options.extraModels||[]})}registerOpenApiRoute(e,t,r){if(!e)return;const o=this.app.getHttpAdapter();e=e.startsWith("/")?e:"/"+e,o.get(e,(e,a)=>{o.reply(a,r(),200,{"Content-Type":t})})}setupSwagger(){const e=this.createDocument(),t=new Se({title:this.options.title,path:this.options.path||_e.path,persistAuthorization:this.options.persistAuthorization??!0,assetsPath:this.options.assetsPath,faviconPath:this.options.faviconFilePath,topbarIconPath:this.options.topbarIconFilePath,topbarBgColor:this.options.topbarBgColor});n.SwaggerModule.setup(this.options.path||_e.path,this.app,e,{...t.getCustomOptions(),jsonDocumentUrl:this.options.openApiJsonPath?""+this.options.openApiJsonPath:void 0,yamlDocumentUrl:this.options.openApiYamlPath?""+this.options.openApiYamlPath:void 0}),this.registerOpenApiRoute(this.options.openApiJsonPath,"application/json",()=>e),this.registerOpenApiRoute(this.options.openApiYamlPath,"application/x-yaml",()=>y.stringify(e))}}var Ce;e.DecafRequestHandlerInterceptor=Ce=class{constructor(e,t){this.requestContext=e,this.executor=t}async contextualize(e){oe(this.requestContext,e)}async intercept(e,t){const r=e.switchToHttp().getRequest(),o=e.switchToHttp().getResponse(),a=u.Logging.for(Ce).for(this.intercept);return a.debug(`CONTEXT ${this.requestContext.uuid} - request: ${r.method} ${r.url}`),await this.contextualize(r),a.debug(`CONTEXT ${this.requestContext.uuid} contextualized - request: ${r.method} ${r.url}`),await this.executor.exec(r,o),a.debug(`CONTEXT ${this.requestContext.uuid} executors finished - request: ${r.method} ${r.url}`),t.handle()}},e.DecafRequestHandlerInterceptor=Ce=p.__decorate([o.Injectable({scope:o.Scope.REQUEST}),p.__metadata("design:paramtypes",[e.DecafRequestContext,e.DecafHandlerExecutor])],e.DecafRequestHandlerInterceptor);const Me=new Map;function Te(){return Array.from(Me.values())}function Ie(e,t){Me.has(e)||Me.set(e,{provide:e,useFactory:t})}var xe;e.DecafCoreModule=class{static{xe=this}static get persistence(){if(!this._persistence)throw new c.InternalError("Persistence service not initialized");return this._persistence}static get log(){return this._logger||(this._logger=u.Logging.for(xe)),this._logger}constructor(e,t){this.options=e,this.moduleRef=t}static forRoot(t){const r=this.log.for(this.forRoot),o=Te();return{module:xe,providers:[{provide:N,useValue:t},{provide:F,useValue:this.persistence?.client},{provide:$,useFactory:()=>t.handlers?.map(e=>(r.info("Registered request handler: "+e.name),new e))??[]},e.DecafRequestContext,e.DecafHandlerExecutor,{provide:d.APP_INTERCEPTOR,useClass:e.DecafRequestHandlerInterceptor},...o],exports:[N,F,$,e.DecafRequestContext,e.DecafHandlerExecutor,...o.map(e=>e.provide)]}}static async bootPersistence(e){const t=this.log.for(this.bootPersistence);if(!this._persistence){const r=e.conf.map(([e,t,...r])=>r.pop()?[e,t,...r]:[e,t]);this._persistence=new s.PersistenceService,await this._persistence.boot(r);const o=this._persistence.client;for(let t=0;t<o.length;t++){const r=e.conf[t];let a=r.slice(2,r.length).pop();if(!a||!a.from){const e=s.Adapter.transformerFor(o[t].flavour);if(!e)throw new c.InternalError(`No transformer found for flavour ${o[t].flavour}. you should either @requestToContextTransformer or provide a transformer in the config`);try{a=e.from?e:new e}catch(e){throw new c.InternalError(`Failed to boot transformer for ${o[t].flavour}: ${e}`)}}l.requestToContextTransformer(o[t].flavour)(a)}if(t.info("persistence layer created successfully!"),e.initialization)try{await e.initialization()}catch(e){throw new c.InternalError("Failed to initialize application: "+e)}}return this.persistence.client}async onApplicationShutdown(){const e=xe.log.for(this.onApplicationShutdown),t=this.moduleRef.get(F);for(const r of t)try{r&&(e.info("Shutting down "+r.toString()),await r.shutdown())}catch(t){e.error("Failed to shutdown application",t)}try{await s.Service.shutdown()}catch(t){e.error("Failed to shutdown services",t)}}},e.DecafCoreModule=xe=p.__decorate([o.Global(),o.Module({}),p.__param(0,o.Inject(N)),p.__metadata("design:paramtypes",[Object,d.ModuleRef])],e.DecafCoreModule);const we=Symbol("LISTENING_ADAPTERS_FLAVOURS"),qe=Symbol("OBSERVER_EVENTS_OPTIONS");var Ne,Fe,ke,$e;e.ObserverSubscriptionRegistry=class{constructor(){this.records=new Map}upsert(e,t=[]){const r={subscriberId:e,topics:new Set(t.filter(Boolean)),updatedAt:new Date};return this.records.set(e,r),r}remove(e){return this.records.delete(e)}get(e){return this.records.get(e)}topicsFor(e){return[...this.records.get(e)?.topics??[]]}matches(e,t){const r=this.records.get(e);return!!r&&!!r.topics.size&&(r.topics.has(t)||r.topics.has("*"))}},e.ObserverSubscriptionRegistry=p.__decorate([o.Injectable()],e.ObserverSubscriptionRegistry),e.EventsController=Ne=class extends ne{constructor(e,t,r,o){super(e,Ne.name),this.options=r,this.registry=o,this.adapters=t.map(e=>s.Adapter.get(e))}listen(e){const t=u.Logging.for(Ne.name),r=!!this.options.subscriptionMode;if(r&&!e)throw new o.BadRequestException("subscriberId is required when subscriptionMode is enabled");const a=e??"",s=new f.Observable(e=>{const o=("B-"+Math.random().toString(36).slice(2,8)).toUpperCase();t.info(`Creating SSE observer: ${o} for client ${this.clientContext.uuid}`);const s=new class{constructor(){this.observerId=o}refresh(...r){return t.debug(`SSE observer ${this.observerId} received refresh event`),Promise.resolve().then(()=>{const o=(e=>{const[t,r,o,a]=e;return[t?.name??t,r,o,Array.isArray(a)?a.map(e=>{try{return"function"==typeof e.serialize?e.serialize():"string"==typeof e?e:JSON.stringify(e)}catch(e){return}}):a&&"function"==typeof a.serialize?a.serialize():"string"==typeof a?a:JSON.stringify(a)]})(r);e.next({type:"message",data:o}),t.debug(`SSE observer ${this.observerId} event pushed to client`)})}},i=r?(e,...t)=>{const r="string"==typeof e?e:e?.name??e?.constructor?.name;return!!r&&this.registry.matches(a,r)}:void 0;t.verbose(`Registering observer ${o} across ${this.adapters.length} adapter(s)`);for(const e of this.adapters){const r=e?.constructor?.name??"UnknownAdapter";try{t.debug(`Registering observer ${o} in adapter ${r}`),e.observe(s,i)}catch(e){t.debug(`Failed to register observer ${o} in adapter ${r}: ${e?.message||e}`),t.error(e)}}return()=>{t.debug("Cleaning up SSE observer "+o);for(const e of this.adapters){const r=e?.constructor?.name??"UnknownAdapter";try{t.debug(`Unregistering observer ${o} from adapter ${r}`),e.unObserve(s)}catch(e){t.debug(`Failed during cleanup of observer ${o} in adapter ${r}: ${e?.message||e}`),t.error(e)}}r&&this.registry.remove(a)}}),i=f.interval(15e3).pipe(g.tap(()=>{t.debug("Sending heartbeat")}),g.map(()=>({type:"heartbeat",data:{ts:(new Date).toISOString()}})));return f.merge(s,i)}listenForModel(e){const t=u.Logging.for(Ne.name);return new f.Observable(e=>{const r=new class{refresh(...t){return Promise.resolve().then(()=>{e.next({data:t})})}};try{for(const e of this.adapters)e.observe(r)}catch(t){e.error("Failed to observe event: "+(t.message||t))}return()=>{try{for(const e of this.adapters)e.unObserve(r)}catch(e){t.error(e)}}})}},p.__decorate([o.Sse(),p.__param(0,o.Query("subscriberId")),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[String]),p.__metadata("design:returntype",f.Observable)],e.EventsController.prototype,"listen",null),p.__decorate([o.Sse("/:model"),p.__param(0,o.Query("model")),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[String]),p.__metadata("design:returntype",f.Observable)],e.EventsController.prototype,"listenForModel",null),e.EventsController=Ne=p.__decorate([o.Controller(),p.__param(1,o.Inject(we)),p.__param(2,o.Inject(qe)),p.__metadata("design:paramtypes",[e.DecafRequestContext,Array,Object,e.ObserverSubscriptionRegistry])],e.EventsController),e.EventsSubscriptionController=Fe=class extends ne{constructor(e,t,r){super(e,Fe.name),this.options=t,this.registry=r}async subscribe(e){if(!this.options.subscriptionMode)return{enabled:!1};const t=e?.subscriberId||await Promise.resolve(s.UUID.instance.generate()),r=Array.isArray(e?.topics)?e.topics:[],o=this.registry.upsert(t,r);return{subscriberId:o.subscriberId,topics:this.registry.topicsFor(o.subscriberId)}}unsubscribe(e){if(!this.options.subscriptionMode)return{enabled:!1};const t=e?.subscriberId;return t?{unsubscribed:this.registry.remove(t),subscriberId:t}:{unsubscribed:!1}}},p.__decorate([o.Post("subscribe"),p.__param(0,o.Body()),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[Object]),p.__metadata("design:returntype",Promise)],e.EventsSubscriptionController.prototype,"subscribe",null),p.__decorate([o.Post("unsubscribe"),p.__param(0,o.Body()),p.__metadata("design:type",Function),p.__metadata("design:paramtypes",[Object]),p.__metadata("design:returntype",Object)],e.EventsSubscriptionController.prototype,"unsubscribe",null),e.EventsSubscriptionController=Fe=p.__decorate([o.Controller(),p.__param(1,o.Inject(qe)),p.__metadata("design:paramtypes",[e.DecafRequestContext,Object,e.ObserverSubscriptionRegistry])],e.EventsSubscriptionController),e.DecafStreamModule=ke=class{static forFlavours(t,r="events",o={}){const a=[e.EventsController];return o.subscriptionMode&&a.push(e.EventsSubscriptionController),{module:ke,controllers:a,imports:[d.RouterModule.register([{path:r.replace(/^\//,""),module:ke}])],providers:[e.DecafRequestContext,e.ObserverSubscriptionRegistry,{provide:we,useValue:t??[]},{provide:qe,useValue:o??{}}]}}},e.DecafStreamModule=ke=p.__decorate([o.Module({})],e.DecafStreamModule),e.DecafModule=$e=class{static async forRootAsync(t){const{autoControllers:r,autoServices:o}=t,a=(await e.DecafCoreModule.bootPersistence(t)).map(e=>e.flavour),s=[e.DecafCoreModule.forRoot(t)];return r&&a.forEach(e=>{s.push(Re(e).forRoot(e,{autoServices:o,controllerExposure:t.controllerExposure,controllerConfig:t.controllerConfig,aggregations:t.aggregations}))}),t.observerOptions?.enableObserverEvents&&s.push(e.DecafStreamModule.forFlavours(t.observerOptions.observerFlavours||a,t.observerOptions.observerApiPath??"/events",t.observerOptions)),{module:$e,imports:s}}},e.DecafModule=$e=p.__decorate([o.Module({})],e.DecafModule);const je="##VERSION##",Be="##PACKAGE##";t.Metadata.allowReregistration(!0),t.Metadata.registerLibrary(Be,je),t.Metadata.allowReregistration(!1),e.AUTH_HANDLER=U,e.AUTH_META_KEY=K,e.ApiOperationFromModel=C,e.ApiParamsFromModel=T,e.ApiProperty=S,e.Auth=W,e.BulkApiOperationFromModel=(e,r,a)=>{const i={GET:[c.BulkCrudOperationKeys.READ_ALL,o.Get],POST:[c.BulkCrudOperationKeys.CREATE_ALL,o.Post],PUT:[c.BulkCrudOperationKeys.UPDATE_ALL,o.Put],PATCH:[c.BulkCrudOperationKeys.UPDATE_ALL,o.Patch],DELETE:[c.BulkCrudOperationKeys.DELETE_ALL,o.Delete]},[p,d]=i[r],u=a?M(r,a):void 0;return u?s.isOperationBlocked(e,u.kind,u.value)?t.apply(n.ApiExcludeEndpoint()):t.apply(d(a)):s.isOperationBlocked(e,"bulk",p)?t.apply(n.ApiExcludeEndpoint()):t.apply(d(a))},e.COMMIT="612701f",e.CorsError=ve,e.DECAF_ADAPTER_ID=F,e.DECAF_CONTEXT_KEY=L,e.DECAF_CONTROLLER_CONFIG=B,e.DECAF_EXPOSE=j,e.DECAF_HANDLERS=$,e.DECAF_MODULE_OPTIONS=N,e.DECAF_ROUTE=k,e.DECAF_TASK_SERVICE_ID="DecafTaskService",e.DECORATORS=R,e.DECORATORS_PREFIX=E,e.DecafAuthHandler=ae,e.DecafBody=I,e.DecafController=ne,e.DecafModelController=ce,e.DecafParams=w,e.DecafRoleAuthHandler=class extends ae{},e.DtoFor=de,e.FULL_VERSION="0.12.2-0-612701f",e.FromModelController=Ee,e.IS_PUBLIC_KEY=H,e.LISTENING_ADAPTERS_FLAVOURS=we,e.NestBootstraper=class{static get logger(){return this._logger||(this._logger=new o.Logger("NestBootstrap")),this._logger}static initialize(e){return this.app=e,this}static enableLogger(e){return this._logger=e||new o.Logger("NestBootstrap"),this.app.useLogger(this._logger),this}static enableCors(e=[],t=["GET","POST","PUT","DELETE"]){const r="*"===e?"*":e.map(e=>e.trim().toLowerCase()),o={origin:(e,t)=>e?"*"===r||Array.isArray(r)&&r.includes(e.toLowerCase())?t(null,!0):void t(new ve(`Origin ${e} not allowed`)):t(null,!0),credentials:!0,methods:t.join(",")};return this.app.enableCors(o),this}static useHelmet(e){try{const t=require("helmet");this.app.use(t(e)),this.logger.log("Helmet middleware enabled successfully.")}catch{this.logger.warn("Helmet not installed. Skipping middleware.")}return this}static setupSwagger(e){return new De(this.app,{title:e.title,description:e.description,version:e.version,path:e.path||"api",persistAuthorization:e.persistAuthorization??!0,assetsPath:e.assetsPath,faviconFilePath:e.faviconPath,topbarIconFilePath:e.topbarIconPath,topbarBgColor:e.topbarBgColor,openApiJsonPath:e.openApiJsonPath,openApiYamlPath:e.openApiYamlPath}).setupSwagger(),this}static useGlobalPipes(...e){return e.length>0&&this.app.useGlobalPipes(...e),this}static useGlobalFilters(...t){return this.app.useGlobalFilters(...t.length>0?t:[new e.DecafExceptionFilter(this.app.get(d.ModuleRef,{strict:!1}))]),this}static useGlobalInterceptors(...e){return e.length>0&&this.app.useGlobalInterceptors(...e),this}static async start(e=Number(process.env.PORT)||3e3,t=void 0,r=!0){this.app.listen(e,t).then(async()=>{if(r){const e=await this.app.getUrl();this.logger.log("\ud83d\ude80 Application is running at: "+e)}})}},e.OBSERVER_EVENTS_OPTIONS=qe,e.PACKAGE_NAME=Be,e.Public=Y,e.REQUIRED_NAMESPACES_KEY=Q,e.REQUIRED_ROLES_KEY=G,e.Repository=(e,t)=>(r,a,i)=>{const n=((e,t)=>t?`${e.name}Repository@${t}`:e.name+"Repository")(e,t);return Ie(n,()=>s.Repository.forModel(e,t)),o.Inject(n)(r,a,i)},e.RequireNamespaces=J,e.RequireRoles=X,e.SKIP_MODEL_NAMESPACES_KEY=V,e.SKIP_MODEL_ROLES_KEY=z,e.Service=e=>(t,r,i)=>{let n=e;if(void 0===n){const e=Reflect.getMetadata("design:paramtypes",t)||[];n=e[i]}if(void 0===n)throw new c.InternalError(`@Service() could not determine an injection type for parameter ${i} of ${t.name}. Provide an explicit argument, e.g. @Service(SomeService).`);const p="string"!=typeof n&&"function"==typeof(d=n)&&d.prototype instanceof a.Model;var d;const u=p?n.name+"Service":s.injectableServiceKey(n);return Ie(u,()=>{if(p)try{return s.Service.get(n)}catch{return s.ModelService.forModel(n)}return s.Service.get(n)}),o.Inject(u)(t,r,i)},e.SwaggerBuilder=De,e.UseDecafFilter=()=>o.UseFilters(new e.DecafExceptionFilter),e.UseDecafHeaders=()=>o.UseInterceptors(e.DecafResponseInterceptor),e.VERSION=je,e.applyApiDecorators=(e,t,r,o)=>{const a=e?.prototype??e;o.method.forEach(e=>e(a,t,r)),o.params?.forEach((e,r)=>e(a,t,r))},e.contextualizeRequestContext=oe,e.controllerConfig=e=>r=>(t.Metadata.set(r,B,e),r),e.createApiPropertyDecorator=D,e.createPropertyDecorator=_,e.createRouteHandler=function(e){return async function(t,r){const o=this.log.for(e);try{o.debug(`Invoking persistence method "${e}" given parameters: ${JSON.stringify(t.valuesInOrder)}`);const{direction:a,limit:s,offset:i}=r;return await te(this.persistence(this.ctx),e,...t.valuesInOrder,a,s,i)}catch(t){throw o.error(`Custom query "${e}" failed`,t),s=`Custom query "${e}" failed`,(a=t)instanceof c.BaseError?a:new c.InternalError(a instanceof Error?`${s}: ${a.message}`:s)}var a,s}},e.defineRouteMethod=(e,t,r)=>(Object.defineProperty(e.prototype||e,t,{value:r,writable:!1}),Object.getOwnPropertyDescriptor(e.prototype||e,t)),e.expose=(...e)=>r=>(t.Metadata.set(r,j,!e.length||e),r),e.getApiDecorators=(e,t,r,a=!1)=>{const i=Z(r),c=(e=>e.split("/").filter(e=>e.startsWith(":")).map(e=>e.slice(1)))(t).map(ee),p=[];return"GET"===r&&a&&p.push(n.ApiQuery({name:"direction",required:!1,enum:s.OrderDirection,description:"the sort order when applicable"}),n.ApiQuery({name:"limit",required:!1,description:"limit or page size when applicable"}),n.ApiQuery({name:"offset",required:!1,description:"offset or bookmark when applicable"})),{method:[i(t),...c.map(n.ApiParam),...p,n.ApiOperation({summary:`Retrieve records using according to "${e}".`}),n.ApiOkResponse({description:"Result successfully retrieved."}),n.ApiNoContentResponse({description:"No content returned by the method."})],params:[w(c),o.Query()]}},e.getEnumType=P,e.getEnumValues=O,e.getModuleFor=Re,e.getRegisteredDecafProviders=Te,e.isUndefined=v,e.repoForModel=e=>{const t=a.Model.get(e);if(!t)throw new c.InternalError("Failed to find repository for "+e);return s.Repository.forModel(t)},e.resolvePersistenceMethod=te,e.runMigrations=async()=>{}},"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@decaf-ts/decoration"),require("@decaf-ts/injectable-decorators"),require("@nestjs/common"),require("@decaf-ts/decorator-validation"),require("@decaf-ts/core"),require("lodash"),require("@nestjs/swagger"),require("@decaf-ts/db-decorators"),require("tslib"),require("@nestjs/core"),require("@decaf-ts/logging"),require("@decaf-ts/for-http/server"),require("rxjs"),require("fs"),require("path"),require("yaml"),require("rxjs/operators")):"function"==typeof define&&define.amd?define(["exports","@decaf-ts/decoration","@decaf-ts/injectable-decorators","@nestjs/common","@decaf-ts/decorator-validation","@decaf-ts/core","lodash","@nestjs/swagger","@decaf-ts/db-decorators","tslib","@nestjs/core","@decaf-ts/logging","@decaf-ts/for-http/server","rxjs","fs","path","yaml","rxjs/operators"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["for-nest"]={},e.decafTsDecoration,e.decafTsInjectableDecorators,e.nestjsCommon,e.decafTsDecoratorValidation,e.decafTsCore,e.lodash,e.nestjsSwagger,e.decafTsDbDecorators,e.tslib,e.nestjsCore,e.decafTsLogging,e.server,e.rxjs,e.fs,e.path,e.yaml,e.operators);
|
|
2
2
|
//# sourceMappingURL=for-nest.cjs.map
|