equipped 5.0.26 → 5.0.27

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [5.0.27](https://github.com/kevinand11/equipped/compare/v5.0.26...v5.0.27) (2025-08-13)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * compile request and response pipes before server starts ([79fbe2d](https://github.com/kevinand11/equipped/commit/79fbe2d8c6f0a1eb2bb07d4ce5447be02d8f90fc))
11
+ * recursive fn not defined when validating queryParams ([d7b4650](https://github.com/kevinand11/equipped/commit/d7b4650b7604f0097bf8d481febc6646aec697fc))
12
+
5
13
  ### [5.0.26](https://github.com/kevinand11/equipped/compare/v5.0.25...v5.0.26) (2025-08-11)
6
14
 
7
15
 
@@ -17,24 +17,24 @@ var Conditions = /* @__PURE__ */ ((Conditions2) => {
17
17
  Conditions2["exists"] = "exists";
18
18
  return Conditions2;
19
19
  })(Conditions || {});
20
- function queryParamsPipe() {
21
- const queryKeys = _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
22
- const queryWhere = _valleyed.v.object({
23
- field: _valleyed.v.string(),
24
- value: _valleyed.v.any(),
25
- condition: _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
26
- });
27
- const queryWhereBlock = _valleyed.v.recursive(
28
- () => _valleyed.v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
29
- block: _valleyed.v.object({
30
- condition: queryKeys,
31
- value: _valleyed.v.array(queryWhereBlock)
32
- }),
33
- regular: queryWhere
20
+ const queryKeys = _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
21
+ const queryWhere = _valleyed.v.object({
22
+ field: _valleyed.v.string(),
23
+ value: _valleyed.v.any(),
24
+ condition: _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
25
+ });
26
+ const queryWhereBlock = _valleyed.v.recursive(
27
+ () => _valleyed.v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
28
+ block: _valleyed.v.object({
29
+ condition: queryKeys,
30
+ value: _valleyed.v.array(queryWhereBlock)
34
31
  }),
35
- "QueryWhereBlock"
36
- );
37
- const queryWhereClause = _valleyed.v.defaults(_valleyed.v.array(queryWhereBlock), []);
32
+ regular: queryWhere
33
+ }),
34
+ "QueryWhereBlock"
35
+ );
36
+ const queryWhereClause = _valleyed.v.defaults(_valleyed.v.array(queryWhereBlock), []);
37
+ function queryParamsPipe() {
38
38
  return _valleyed.v.meta(
39
39
  _valleyed.v.object({
40
40
  all: _valleyed.v.defaults(_valleyed.v.boolean(), false),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/dbs/pipes.ts","/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.cjs"],"names":["QueryKeys","Conditions"],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.cjs","sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nexport function queryParamsPipe() {\n\tconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\n\tconst queryWhere = v.object({\n\t\tfield: v.string(),\n\t\tvalue: v.any(),\n\t\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n\t})\n\tconst queryWhereBlock = v.recursive(\n\t\t() =>\n\t\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\t\tblock: v.object({\n\t\t\t\t\tcondition: queryKeys,\n\t\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t\t}),\n\t\t\t\tregular: queryWhere,\n\t\t\t}),\n\t\t'QueryWhereBlock',\n\t) as Pipe<\n\t\t| {\n\t\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeInput<typeof queryWhere>,\n\t\t| {\n\t\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeOutput<typeof queryWhere>\n\t>\n\n\tconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n",null]}
1
+ {"version":3,"sources":["../../../src/dbs/pipes.ts","/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.cjs"],"names":["QueryKeys","Conditions"],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.cjs","sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\nconst queryWhere = v.object({\n\tfield: v.string(),\n\tvalue: v.any(),\n\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n})\nconst queryWhereBlock = v.recursive(\n\t() =>\n\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\tblock: v.object({\n\t\t\t\tcondition: queryKeys,\n\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t}),\n\t\t\tregular: queryWhere,\n\t\t}),\n\t'QueryWhereBlock',\n) as Pipe<\n\t| {\n\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t }\n\t| PipeInput<typeof queryWhere>,\n\t| {\n\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t }\n\t| PipeOutput<typeof queryWhere>\n>\n\nconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\nexport function queryParamsPipe() {\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n",null]}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _valleyed = require('valleyed');var _indexmincjs = require('../instance/index.min.cjs');var n=(a=>(a.and="and",a.or="or",a))(n||{}),p= exports.Conditions =(t=>(t.lt="lt",t.lte="lte",t.gt="gt",t.gte="gte",t.eq="eq",t.ne="ne",t.in="in",t.nin="nin",t.exists="exists",t))(p||{});function y(){const u=_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(["and","or"]),"and"),"and"),o=_valleyed.v.object({field:_valleyed.v.string(),value:_valleyed.v.any(),condition:_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(Object.values(p)),"eq"),"eq")}),a=_valleyed.v.recursive(()=>_valleyed.v.discriminate(r=>Object.values(n).includes(r.condition)?"block":"regular",{block:_valleyed.v.object({condition:u,value:_valleyed.v.array(a)}),regular:o}),"QueryWhereBlock"),i=_valleyed.v.defaults(_valleyed.v.array(a),[]);return _valleyed.v.meta(_valleyed.v.object({all:_valleyed.v.defaults(_valleyed.v.boolean(),!1),limit:_valleyed.v.lazy(()=>{const r=_indexmincjs.Instance.get().settings.utils.paginationDefaultLimit;return _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.number().pipe(_valleyed.v.lte(r)),r),r)}),page:_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.number().pipe(_valleyed.v.gte(1)),1),1),search:_valleyed.v.defaults(_valleyed.v.nullish(_valleyed.v.object({value:_valleyed.v.string(),fields:_valleyed.v.array(_valleyed.v.string())})),null),sort:_valleyed.v.defaults(_valleyed.v.array(_valleyed.v.object({field:_valleyed.v.string(),desc:_valleyed.v.defaults(_valleyed.v.boolean(),!1)})),[]),whereType:u,where:i}).pipe(r=>({...r,auth:[],authType:"and"})),{title:"Query Params",$refId:"QueryParams"})}function g(u){return _valleyed.v.object({pages:_valleyed.v.object({current:_valleyed.v.number(),start:_valleyed.v.number(),last:_valleyed.v.number(),previous:_valleyed.v.nullable(_valleyed.v.number()),next:_valleyed.v.nullable(_valleyed.v.number())}),docs:_valleyed.v.object({limit:_valleyed.v.number(),total:_valleyed.v.number(),count:_valleyed.v.number()}),results:_valleyed.v.array(u)})}function d(u){return _valleyed.v.assert(y(),u)}const h=()=>_valleyed.v.meta(_valleyed.v.object({uri:_valleyed.v.string()}),{title:"Mongodb Config",$refId:"MongodbConfig"});exports.Conditions = p; exports.QueryKeys = n; exports.mongoDbConfigPipe = h; exports.queryParamsPipe = y; exports.queryResultsPipe = g; exports.wrapQueryParams = d;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _valleyed = require('valleyed');var _indexmincjs = require('../instance/index.min.cjs');var a=(u=>(u.and="and",u.or="or",u))(a||{}),n= exports.Conditions =(r=>(r.lt="lt",r.lte="lte",r.gt="gt",r.gte="gte",r.eq="eq",r.ne="ne",r.in="in",r.nin="nin",r.exists="exists",r))(n||{});const p=_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(["and","or"]),"and"),"and"),s=_valleyed.v.object({field:_valleyed.v.string(),value:_valleyed.v.any(),condition:_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.in(Object.values(n)),"eq"),"eq")}),o=_valleyed.v.recursive(()=>_valleyed.v.discriminate(t=>Object.values(a).includes(t.condition)?"block":"regular",{block:_valleyed.v.object({condition:p,value:_valleyed.v.array(o)}),regular:s}),"QueryWhereBlock"),y=_valleyed.v.defaults(_valleyed.v.array(o),[]);function l(){return _valleyed.v.meta(_valleyed.v.object({all:_valleyed.v.defaults(_valleyed.v.boolean(),!1),limit:_valleyed.v.lazy(()=>{const t=_indexmincjs.Instance.get().settings.utils.paginationDefaultLimit;return _valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.number().pipe(_valleyed.v.lte(t)),t),t)}),page:_valleyed.v.catch(_valleyed.v.defaults(_valleyed.v.number().pipe(_valleyed.v.gte(1)),1),1),search:_valleyed.v.defaults(_valleyed.v.nullish(_valleyed.v.object({value:_valleyed.v.string(),fields:_valleyed.v.array(_valleyed.v.string())})),null),sort:_valleyed.v.defaults(_valleyed.v.array(_valleyed.v.object({field:_valleyed.v.string(),desc:_valleyed.v.defaults(_valleyed.v.boolean(),!1)})),[]),whereType:p,where:y}).pipe(t=>({...t,auth:[],authType:"and"})),{title:"Query Params",$refId:"QueryParams"})}function d(t){return _valleyed.v.object({pages:_valleyed.v.object({current:_valleyed.v.number(),start:_valleyed.v.number(),last:_valleyed.v.number(),previous:_valleyed.v.nullable(_valleyed.v.number()),next:_valleyed.v.nullable(_valleyed.v.number())}),docs:_valleyed.v.object({limit:_valleyed.v.number(),total:_valleyed.v.number(),count:_valleyed.v.number()}),results:_valleyed.v.array(t)})}function h(t){return _valleyed.v.assert(l(),t)}const q=()=>_valleyed.v.meta(_valleyed.v.object({uri:_valleyed.v.string()}),{title:"Mongodb Config",$refId:"MongodbConfig"});exports.Conditions = n; exports.QueryKeys = a; exports.mongoDbConfigPipe = q; exports.queryParamsPipe = l; exports.queryResultsPipe = d; exports.wrapQueryParams = h;
2
2
  //# sourceMappingURL=pipes.min.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/dbs/pipes.ts"],"names":["QueryKeys","Conditions","queryParamsPipe","queryWhere","v","queryWhereBlock","d","Instance","pagLimit","queryKeys","p","model","wrapQueryParams","params","mongoDbConfigPipe"],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.min.cjs","sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nexport function queryParamsPipe() {\n\tconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\n\tconst queryWhere = v.object({\n\t\tfield: v.string(),\n\t\tvalue: v.any(),\n\t\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n\t})\n\tconst queryWhereBlock = v.recursive(\n\t\t() =>\n\t\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\t\tblock: v.object({\n\t\t\t\t\tcondition: queryKeys,\n\t\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t\t}),\n\t\t\t\tregular: queryWhere,\n\t\t\t}),\n\t\t'QueryWhereBlock',\n\t) as Pipe<\n\t\t| {\n\t\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeInput<typeof queryWhere>,\n\t\t| {\n\t\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeOutput<typeof queryWhere>\n\t>\n\n\tconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"]}
1
+ {"version":3,"sources":["../../../src/dbs/pipes.ts"],"names":["QueryKeys","Conditions","queryKeys","v","queryWhere","queryWhereBlock","d","queryParamsPipe","Instance","pagLimit","p","model","wrapQueryParams","params","mongoDbConfigPipe"],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/dbs/pipes.min.cjs","sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\nconst queryWhere = v.object({\n\tfield: v.string(),\n\tvalue: v.any(),\n\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n})\nconst queryWhereBlock = v.recursive(\n\t() =>\n\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\tblock: v.object({\n\t\t\t\tcondition: queryKeys,\n\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t}),\n\t\t\tregular: queryWhere,\n\t\t}),\n\t'QueryWhereBlock',\n) as Pipe<\n\t| {\n\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t }\n\t| PipeInput<typeof queryWhere>,\n\t| {\n\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t }\n\t| PipeOutput<typeof queryWhere>\n>\n\nconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\nexport function queryParamsPipe() {\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"]}
@@ -78,8 +78,8 @@ class Server {
78
78
  let status = defaultStatusCode;
79
79
  let contentType = defaultContentType;
80
80
  const jsonSchema = { response: {}, request: {} };
81
- const requestPipe = {};
82
- const responsePipe = {};
81
+ const requestPipeDefs = {};
82
+ const responsePipeDefs = {};
83
83
  const defs = [
84
84
  { key: "params", type: "request" },
85
85
  { key: "headers", type: "request" },
@@ -90,15 +90,14 @@ class Server {
90
90
  ];
91
91
  defs.forEach((def) => {
92
92
  const pipe = _nullishCoalesce(schema[def.key], () => ( _valleyed.v.any()));
93
- _valleyed.v.compile(pipe, { allErrors: true });
94
93
  if (def.skip) return;
95
94
  if (def.type === "request") {
96
- requestPipe[def.key] = pipe;
95
+ requestPipeDefs[def.key] = pipe;
97
96
  jsonSchema.request[def.key] = _valleyed.v.schema(pipe);
98
97
  }
99
98
  if (def.type === "response") {
100
99
  const pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe });
101
- responsePipe[def.key] = _valleyed.v.any().pipe((input) => {
100
+ responsePipeDefs[def.key] = _valleyed.v.any().pipe((input) => {
102
101
  const p = _optionalChain([pipeRecords, 'access', _9 => _9.find, 'call', _10 => _10((r) => r.status === status), 'optionalAccess', _11 => _11.pipe]);
103
102
  if (!p) throw _valleyed.PipeError.root(`schema not defined for status code: ${status}`, input);
104
103
  return _valleyed.v.assert(p, input);
@@ -110,13 +109,17 @@ class Server {
110
109
  }));
111
110
  }
112
111
  });
112
+ const requestPipe = _valleyed.v.object(requestPipeDefs);
113
+ _valleyed.v.compile(requestPipe, { allErrors: true });
114
+ const responsePipe = _valleyed.v.object(responsePipeDefs);
115
+ _valleyed.v.compile(responsePipe, { allErrors: true });
113
116
  const validateRequest = async (request) => {
114
- if (!Object.keys(requestPipe)) return request;
117
+ if (!Object.keys(requestPipeDefs)) return request;
115
118
  const context = schema.context ? await schema.context(request) : {};
116
119
  request.context = context;
117
120
  const validity = _valleyedcjs.requestLocalStorage.run(
118
121
  request,
119
- () => _valleyed.v.validate(_valleyed.v.object(requestPipe), {
122
+ () => _valleyed.v.validate(requestPipe, {
120
123
  params: request.params,
121
124
  headers: request.headers,
122
125
  query: request.query,
@@ -131,13 +134,12 @@ class Server {
131
134
  return request;
132
135
  };
133
136
  const validateResponse = async (response) => {
134
- if (!Object.keys(responsePipe)) return response;
137
+ if (!Object.keys(responsePipeDefs)) return response;
135
138
  status = response.status;
136
139
  contentType = response.contentType;
137
- contentType;
138
140
  const validity = _valleyedcjs.responseLocalStorage.run(
139
141
  response,
140
- () => _valleyed.v.validate(_valleyed.v.object(responsePipe), {
142
+ () => _valleyed.v.validate(responsePipe, {
141
143
  responseHeaders: response.headers,
142
144
  response: response.body
143
145
  })
@@ -174,7 +176,7 @@ class Server {
174
176
  throw new (0, _indexcjs.NotFoundError)(`Route ${request.path} not found`);
175
177
  });
176
178
  this.implementations.registerErrorHandler(async (error, _, res) => {
177
- _indexcjs3.Instance.get().log.error(error);
179
+ _indexcjs3.Instance.get().log.error({ error }, "Uncaught error in route handler");
178
180
  const response = error instanceof _indexcjs.RequestError ? new (0, _requestscjs.Response)({
179
181
  body: error.serializedErrors,
180
182
  status: error.statusCode
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts","/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.cjs"],"names":[],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.cjs","sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipe: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipe: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tv.compile(pipe, { allErrors: true })\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipe[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipe[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipe)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(v.object(requestPipe), {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipe)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\t\t\tcontentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(v.object(responsePipe), {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error(error)\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n",null]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts","/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.cjs"],"names":[],"mappings":"AAEA,szBAAuC;AACvC,4FAAsB;AACtB,oCAAmC;AAEnC,kDAA2D;AAC3D,qDAAyB;AACzB,wDAA2C;AAC3C,6DAA0D;AAC1D,oEAA8B;AAC9B,4CAA0C;AAE1C,8CAAuC;AAEvC,4CAA8B;AAC9B,wCAAwE;AAKxE,MAAM,cAAA,EAAgB,MAAA,CAAO,OAAA,CAAQ,qBAAW,CAAA,CAC9C,MAAA,CAAO,CAAC,CAAC,EAAE,KAAK,CAAA,EAAA,GAAM,MAAA,EAAQ,GAAG,CAAA,CACjC,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,EAAA,GAAA,CAAO;AAAA,EACvB,MAAA,EAAQ,KAAA;AAAA,EACR,WAAA,EAAa,kBAAA;AAAA,EACb,IAAA,EAAM,WAAA,CAAE,IAAA,CAAK,WAAA,CAAE,KAAA,CAAM,WAAA,CAAE,MAAA,CAAO,EAAE,OAAA,EAAS,WAAA,CAAE,MAAA,CAAO,CAAA,EAAG,KAAA,EAAO,WAAA,CAAE,QAAA,CAAS,WAAA,CAAE,MAAA,CAAO,CAAC,EAAE,CAAC,CAAC,CAAA,EAAG;AAAA,IACvF,MAAA,EAAQ,CAAA,OAAA,EAAU,GAAG,CAAA,QAAA,CAAA;AAAA,IACrB,WAAA,EAAa,CAAA,EAAA;AACb,EAAA;AACA;AAEgD;AAcjD,EAAA;AACQ,IAAA;AACA,IAAA;AASM,IAAA;AACT,IAAA;AACC,IAAA;AACQ,IAAA;AACT,IAAA;AACN,EAAA;AA7B0C,EAAA;AAC3B,EAAA;AACf,EAAA;AACA,EAAA;AACU,EAAA;AACO,iBAAA;AACR,IAAA;AACC,IAAA;AAGV,EAAA;AAqBa,EAAA;AACC,IAAA;AACd,EAAA;AAEgC,EAAA;AACxB,IAAA;AACM,MAAA;AACH,QAAA;AAEF,QAAA;AACG,QAAA;AACF,UAAA;AAEP,QAAA;AACA,QAAA;AACS,wBAAA;AAED,QAAA;AAEH,QAAA;AACC,QAAA;AACD,QAAA;AACE,UAAA;AACF,UAAA;AACH,YAAA;AACM,YAAA;AACA,YAAA;AAIN,YAAA;AACD,UAAA;AACK,YAAA;AACH,cAAA;AACA,cAAA;AAIA,cAAA;AACD,YAAA;AACM,YAAA;AACP,UAAA;AACA,QAAA;AACD,MAAA;AACD,IAAA;AACF,EAAA;AAEe,EAAA;AACR,IAAA;AACA,IAAA;AACO,IAAA;AACT,IAAA;AACE,IAAA;AACA,IAAA;AACA,IAAA;AAMA,IAAA;AACE,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACR,IAAA;AACc,IAAA;AACP,MAAA;AACE,MAAA;AAEA,MAAA;AACP,QAAA;AACA,QAAA;AACD,MAAA;AACQ,MAAA;AACD,QAAA;AACN,QAAA;AACO,UAAA;AACE,UAAA;AACD,UAAA;AACP,QAAA;AACD,QAAA;AACS,UAAA;AACR,UAAA;AACQ,UAAA;AACP,QAAA;AACH,MAAA;AACA,IAAA;AACK,IAAA;AACI,IAAA;AACJ,IAAA;AACI,IAAA;AACJ,IAAA;AACO,MAAA;AACN,MAAA;AACE,MAAA;AACF,MAAA;AAAmC,QAAA;AACtC,QAAA;AACO,UAAA;AACR,UAAA;AACO,UAAA;AACD,UAAA;AACN,QAAA;AACF,MAAA;AAEK,MAAA;AACG,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACD,MAAA;AACR,IAAA;AACM,IAAA;AACO,MAAA;AACH,MAAA;AACT,MAAA;AAEM,MAAA;AAAoC,QAAA;AACvC,QAAA;AACD,UAAA;AACA,UAAA;AACA,QAAA;AACF,MAAA;AAEK,MAAA;AACI,MAAA;AACA,MAAA;AACF,MAAA;AACR,IAAA;AACO,IAAA;AACN,MAAA;AACA,MAAA;AACA,MAAA;AACD,IAAA;AACD,EAAA;AAEO,EAAA;AACC,IAAA;AACR,EAAA;AAEc,EAAA;AACA,IAAA;AACP,IAAA;AACM,IAAA;AACH,IAAA;AACH,MAAA;AACI,QAAA;AACF,QAAA;AACG,QAAA;AAED,UAAA;AACN,UAAA;AACA,QAAA;AACF,MAAA;AAEG,IAAA;AACE,MAAA;AACI,MAAA;AACV,IAAA;AACI,IAAA;AACK,MAAA;AACH,MAAA;AAGI,QAAA;AACE,QAAA;AAEJ,MAAA;AACK,QAAA;AACD,QAAA;AACR,MAAA;AACG,MAAA;AACP,IAAA;AAEa,IAAA;AACR,IAAA;AACO,IAAA;AACN,IAAA;AACR,EAAA;AACD;ACnDkB;AACA;AACA","file":"/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.cjs","sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n",null]}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _socketio = require('socket.io');var _supertest = require('supertest'); var _supertest2 = _interopRequireDefault(_supertest);var _valleyed = require('valleyed');var _indexmincjs = require('../../errors/index.min.cjs');var _indexmincjs3 = require('../../instance/index.min.cjs');var _indexmincjs5 = require('../../validations/index.min.cjs');var _valleyedmincjs = require('../../validations/valleyed.min.cjs');var _parseAuthUsermincjs = require('../middlewares/parseAuthUser.min.cjs');var _openapimincjs = require('../openapi.min.cjs');var _requestsmincjs = require('../requests.min.cjs');var _socketsmincjs = require('../sockets.min.cjs');var _typesmincjs = require('../types.min.cjs');const M=Object.entries(_typesmincjs.StatusCodes).filter(([,f])=>f>399).map(([f,s])=>({status:s,contentType:"application/json",pipe:_valleyed.v.meta(_valleyed.v.array(_valleyed.v.object({message:_valleyed.v.string(),field:_valleyed.v.optional(_valleyed.v.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class oe{constructor(s,t,p){;oe.prototype.__init.call(this);this.config=t;this.implementations=p;this.server=s,this.#e=new (0, _openapimincjs.OpenApi)(t);const u=new (0, _socketio.Server)(s,{cors:this.cors});this.socket=new (0, _socketsmincjs.SocketEmitter)(u,t),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;__init() {this.cors={origin:"*",methods:Object.values(_typesmincjs.Methods).filter(s=>s!==_typesmincjs.Methods.options).map(s=>s.toUpperCase())}}addRouter(...s){s.map(t=>t.routes).forEach(t=>this.addRoute(...t))}addRoute(...s){s.forEach(t=>{this.#t.push(async()=>{const{method:p,path:u,schema:o={},onError:c,middlewares:m=[]}=t,d=`(${p.toUpperCase()}) ${this.#e.cleanPath(u)}`;if(this.#s.get(d))throw new (0, _indexmincjs.EquippedError)(`Route key ${d} already registered. All route keys must be unique`,{route:t,key:d});m.unshift(_parseAuthUsermincjs.parseAuthUser),m.forEach(g=>_optionalChain([g, 'access', _ => _.onSetup, 'optionalCall', _2 => _2(t)])),_optionalChain([c, 'optionalAccess', _3 => _3.onSetup, 'optionalCall', _4 => _4(t)]);const{validateRequest:R,validateResponse:w,jsonSchema:k}=this.#o(p,o);this.#s.set(d,!0),await this.#e.register(t,k),this.implementations.registerRoute(p,this.#e.cleanPath(u),async(g,e)=>{const n=await R(await this.implementations.parseRequest(g));try{for(const h of m)await h.cb(n,this.config);const r=await t.handler(n,this.config),i=r instanceof _requestsmincjs.Response?r:new (0, _requestsmincjs.Response)({body:r,status:_typesmincjs.StatusCodes.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(e,await w(i))}catch(r){if(_optionalChain([c, 'optionalAccess', _5 => _5.cb])){const i=await c.cb(n,this.config,r),h=i instanceof _requestsmincjs.Response?i:new (0, _requestsmincjs.Response)({body:i,status:_typesmincjs.StatusCodes.BadRequest,headers:{}});return await this.implementations.handleResponse(e,await w(h))}throw r}})})})}#o(s,t){const p=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _6 => _6.defaultStatusCode]), () => (_typesmincjs.StatusCodes.Ok)),u=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _7 => _7.defaultContentType]), () => ("application/json"));let o=p,c=u;const m={response:{},request:{}},d={},R={};return[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![_typesmincjs.Methods.post,_typesmincjs.Methods.put,_typesmincjs.Methods.patch].includes(s)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"}].forEach(e=>{const n=_nullishCoalesce(t[e.key], () => (_valleyed.v.any()));if(_valleyed.v.compile(n,{allErrors:!0}),!e.skip&&(e.type==="request"&&(d[e.key]=n,m.request[e.key]=_valleyed.v.schema(n)),e.type==="response")){const r=M.concat({status:p,contentType:c,pipe:n});R[e.key]=_valleyed.v.any().pipe(i=>{const h=_optionalChain([r, 'access', _8 => _8.find, 'call', _9 => _9(S=>S.status===o), 'optionalAccess', _10 => _10.pipe]);if(!h)throw _valleyed.PipeError.root(`schema not defined for status code: ${o}`,i);return _valleyed.v.assert(h,i)}),m.response[e.key]=r.map(i=>({status:i.status,contentType:i.contentType,schema:_valleyed.v.schema(i.pipe)}))}}),{jsonSchema:m,validateRequest:async e=>{if(!Object.keys(d))return e;const n=t.context?await t.context(e):{};e.context=n;const r=_valleyedmincjs.requestLocalStorage.run(e,()=>_valleyed.v.validate(_valleyed.v.object(d),{params:e.params,headers:e.headers,query:e.query,body:e.body}));if(!r.valid)throw _indexmincjs5.pipeErrorToValidationError.call(void 0, r.error);return e.params=r.value.params,e.headers=r.value.headers,e.query=r.value.query,e.body=r.value.body,e},validateResponse:async e=>{if(!Object.keys(R))return e;o=e.status,c=e.contentType;const n=_valleyedmincjs.responseLocalStorage.run(e,()=>_valleyed.v.validate(_valleyed.v.object(R),{responseHeaders:e.headers,response:e.body}));if(!n.valid)throw _indexmincjs5.pipeErrorToValidationError.call(void 0, n.error);return e.body=n.value.response,e.headers=n.value.responseHeaders,e}}}test(){return _supertest2.default.call(void 0, this.server)}async start(){const s=this.config.port,t=_indexmincjs3.Instance.get(),{app:p}=t.settings;this.config.healthPath&&this.addRoute({method:_typesmincjs.Methods.get,path:this.config.healthPath,handler:async o=>o.res({body:`${t.id}(${p.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async o=>{const c=await this.implementations.parseRequest(o);throw new (0, _indexmincjs.NotFoundError)(`Route ${c.path} not found`)}),this.implementations.registerErrorHandler(async(o,c,m)=>{_indexmincjs3.Instance.get().log.error(o);const d=o instanceof _indexmincjs.RequestError?new (0, _requestsmincjs.Response)({body:o.serializedErrors,status:o.statusCode}):new (0, _requestsmincjs.Response)({body:[{message:"Something went wrong",data:o.message}],status:_typesmincjs.StatusCodes.BadRequest});return await this.implementations.handleResponse(m,d)}),await Promise.all(this.#t.map(o=>o()));const u=await this.implementations.start(s);return u&&_indexmincjs3.Instance.get().log.info(`${t.id}(${p.name}) service listening on port ${s}`),u}}exports.Server = oe;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _socketio = require('socket.io');var _supertest = require('supertest'); var _supertest2 = _interopRequireDefault(_supertest);var _valleyed = require('valleyed');var _indexmincjs = require('../../errors/index.min.cjs');var _indexmincjs3 = require('../../instance/index.min.cjs');var _indexmincjs5 = require('../../validations/index.min.cjs');var _valleyedmincjs = require('../../validations/valleyed.min.cjs');var _parseAuthUsermincjs = require('../middlewares/parseAuthUser.min.cjs');var _openapimincjs = require('../openapi.min.cjs');var _requestsmincjs = require('../requests.min.cjs');var _socketsmincjs = require('../sockets.min.cjs');var _typesmincjs = require('../types.min.cjs');const U=Object.entries(_typesmincjs.StatusCodes).filter(([,f])=>f>399).map(([f,s])=>({status:s,contentType:"application/json",pipe:_valleyed.v.meta(_valleyed.v.array(_valleyed.v.object({message:_valleyed.v.string(),field:_valleyed.v.optional(_valleyed.v.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class ae{constructor(s,t,i){;ae.prototype.__init.call(this);this.config=t;this.implementations=i;this.server=s,this.#e=new (0, _openapimincjs.OpenApi)(t);const c=new (0, _socketio.Server)(s,{cors:this.cors});this.socket=new (0, _socketsmincjs.SocketEmitter)(c,t),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;__init() {this.cors={origin:"*",methods:Object.values(_typesmincjs.Methods).filter(s=>s!==_typesmincjs.Methods.options).map(s=>s.toUpperCase())}}addRouter(...s){s.map(t=>t.routes).forEach(t=>this.addRoute(...t))}addRoute(...s){s.forEach(t=>{this.#t.push(async()=>{const{method:i,path:c,schema:o={},onError:d,middlewares:u=[]}=t,p=`(${i.toUpperCase()}) ${this.#e.cleanPath(c)}`;if(this.#s.get(p))throw new (0, _indexmincjs.EquippedError)(`Route key ${p} already registered. All route keys must be unique`,{route:t,key:p});u.unshift(_parseAuthUsermincjs.parseAuthUser),u.forEach(m=>_optionalChain([m, 'access', _ => _.onSetup, 'optionalCall', _2 => _2(t)])),_optionalChain([d, 'optionalAccess', _3 => _3.onSetup, 'optionalCall', _4 => _4(t)]);const{validateRequest:R,validateResponse:q,jsonSchema:g}=this.#o(i,o);this.#s.set(p,!0),await this.#e.register(t,g),this.implementations.registerRoute(i,this.#e.cleanPath(c),async(m,k)=>{const w=await R(await this.implementations.parseRequest(m));try{for(const n of u)await n.cb(w,this.config);const e=await t.handler(w,this.config),a=e instanceof _requestsmincjs.Response?e:new (0, _requestsmincjs.Response)({body:e,status:_typesmincjs.StatusCodes.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(k,await q(a))}catch(e){if(_optionalChain([d, 'optionalAccess', _5 => _5.cb])){const a=await d.cb(w,this.config,e),n=a instanceof _requestsmincjs.Response?a:new (0, _requestsmincjs.Response)({body:a,status:_typesmincjs.StatusCodes.BadRequest,headers:{}});return await this.implementations.handleResponse(k,await q(n))}throw e}})})})}#o(s,t){const i=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _6 => _6.defaultStatusCode]), () => (_typesmincjs.StatusCodes.Ok)),c=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _7 => _7.defaultContentType]), () => ("application/json"));let o=i,d=c;const u={response:{},request:{}},p={},R={};[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![_typesmincjs.Methods.post,_typesmincjs.Methods.put,_typesmincjs.Methods.patch].includes(s)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"}].forEach(e=>{const a=_nullishCoalesce(t[e.key], () => (_valleyed.v.any()));if(!e.skip&&(e.type==="request"&&(p[e.key]=a,u.request[e.key]=_valleyed.v.schema(a)),e.type==="response")){const n=U.concat({status:i,contentType:d,pipe:a});R[e.key]=_valleyed.v.any().pipe(h=>{const E=_optionalChain([n, 'access', _8 => _8.find, 'call', _9 => _9(P=>P.status===o), 'optionalAccess', _10 => _10.pipe]);if(!E)throw _valleyed.PipeError.root(`schema not defined for status code: ${o}`,h);return _valleyed.v.assert(E,h)}),u.response[e.key]=n.map(h=>({status:h.status,contentType:h.contentType,schema:_valleyed.v.schema(h.pipe)}))}});const g=_valleyed.v.object(p);_valleyed.v.compile(g,{allErrors:!0});const m=_valleyed.v.object(R);return _valleyed.v.compile(m,{allErrors:!0}),{jsonSchema:u,validateRequest:async e=>{if(!Object.keys(p))return e;const a=t.context?await t.context(e):{};e.context=a;const n=_valleyedmincjs.requestLocalStorage.run(e,()=>_valleyed.v.validate(g,{params:e.params,headers:e.headers,query:e.query,body:e.body}));if(!n.valid)throw _indexmincjs5.pipeErrorToValidationError.call(void 0, n.error);return e.params=n.value.params,e.headers=n.value.headers,e.query=n.value.query,e.body=n.value.body,e},validateResponse:async e=>{if(!Object.keys(R))return e;o=e.status,d=e.contentType;const a=_valleyedmincjs.responseLocalStorage.run(e,()=>_valleyed.v.validate(m,{responseHeaders:e.headers,response:e.body}));if(!a.valid)throw _indexmincjs5.pipeErrorToValidationError.call(void 0, a.error);return e.body=a.value.response,e.headers=a.value.responseHeaders,e}}}test(){return _supertest2.default.call(void 0, this.server)}async start(){const s=this.config.port,t=_indexmincjs3.Instance.get(),{app:i}=t.settings;this.config.healthPath&&this.addRoute({method:_typesmincjs.Methods.get,path:this.config.healthPath,handler:async o=>o.res({body:`${t.id}(${i.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async o=>{const d=await this.implementations.parseRequest(o);throw new (0, _indexmincjs.NotFoundError)(`Route ${d.path} not found`)}),this.implementations.registerErrorHandler(async(o,d,u)=>{_indexmincjs3.Instance.get().log.error({error:o},"Uncaught error in route handler");const p=o instanceof _indexmincjs.RequestError?new (0, _requestsmincjs.Response)({body:o.serializedErrors,status:o.statusCode}):new (0, _requestsmincjs.Response)({body:[{message:"Something went wrong",data:o.message}],status:_typesmincjs.StatusCodes.BadRequest});return await this.implementations.handleResponse(u,p)}),await Promise.all(this.#t.map(o=>o()));const c=await this.implementations.start(s);return c&&_indexmincjs3.Instance.get().log.info(`${t.id}(${i.name}) service listening on port ${s}`),c}}exports.Server = ae;
2
2
  //# sourceMappingURL=base.min.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts"],"names":["StatusCodes","v","key","server","config","implementations"],"mappings":"AAEA,szBAAuC,4FACjB,oCACa,yDAG1B,4DACA,+DACqB,oEACA,2EAGS,mDAET,qDACWA,mDAMvB,+CAGH,MACb,CAAA,CAAA,MAAQ,CAAA,OAAO,CAAA,wBAAMC,CAAAA,CAAE,MAAA,CAAO,CAAE,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAASA,CAAAA,GAAE,CAAA,CAAA,GAAO,CAAA,CAAG,CAAA,CAAA,CAAA,CAAA,CAAA,CAAOA,EAAE,CAAA,CAAA,MAAA,CAASA,CAAAA,CAAE,WAAY,CAAA,kBAC5E,CAAUC,IAAG,CAAA,WAAA,CAAA,IAAA,CACrB,WAAA,CAAA,KAAA,CAAA,WAAA,CAAA,MAAmB,CAAA,CAAA,OAAA,CAAA,WACpB,CAAC,MAGI,CAAA,CAAA,CAAA,KAaN,CAAA,WAAA,CAAA,QAAA,CACCC,WAAAA,CACQC,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MACA,CAAA,CAAA,OAAA,EAAA,CAAA,CAAA,QAAAC,CASR,CAAA,WAAcF,CAAAA,CACd,EAAA","file":"/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.min.cjs","sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipe: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipe: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tv.compile(pipe, { allErrors: true })\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipe[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipe[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipe)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(v.object(requestPipe), {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipe)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\t\t\tcontentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(v.object(responsePipe), {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error(error)\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts"],"names":["StatusCodes","v","key","server","config","implementations"],"mappings":"AAEA,szBAAuC,4FACjB,oCACa,yDAG1B,4DACA,+DACqB,oEACA,2EAGS,mDAET,qDACWA,mDAMvB,+CAGH,MACb,CAAA,CAAA,MAAQ,CAAA,OAAO,CAAA,wBAAMC,CAAAA,CAAE,MAAA,CAAO,CAAE,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAASA,CAAAA,GAAE,CAAA,CAAA,GAAO,CAAA,CAAG,CAAA,CAAA,CAAA,CAAA,CAAA,CAAOA,EAAE,CAAA,CAAA,MAAA,CAASA,CAAAA,CAAE,WAAY,CAAA,kBAC5E,CAAUC,IAAG,CAAA,WAAA,CAAA,IAAA,CACrB,WAAA,CAAA,KAAA,CAAA,WAAA,CAAA,MAAmB,CAAA,CAAA,OAAA,CAAA,WACpB,CAAC,MAGI,CAAA,CAAA,CAAA,KAaN,CAAA,WAAA,CAAA,QAAA,CACCC,WAAAA,CACQC,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MACA,CAAA,CAAA,OAAA,EAAA,CAAA,CAAA,QAAAC,CASR,CAAA,WAAcF,CAAAA,CACd,EAAA","file":"/home/runner/work/equipped/equipped/dist/cjs/server/impls/base.min.cjs","sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"]}
@@ -1,2 +1,2 @@
1
- import{v as e}from"valleyed";import{Instance as s}from "../instance/index.min.mjs";var n=(a=>(a.and="and",a.or="or",a))(n||{}),p=(t=>(t.lt="lt",t.lte="lte",t.gt="gt",t.gte="gte",t.eq="eq",t.ne="ne",t.in="in",t.nin="nin",t.exists="exists",t))(p||{});function y(){const u=e.catch(e.defaults(e.in(["and","or"]),"and"),"and"),o=e.object({field:e.string(),value:e.any(),condition:e.catch(e.defaults(e.in(Object.values(p)),"eq"),"eq")}),a=e.recursive(()=>e.discriminate(r=>Object.values(n).includes(r.condition)?"block":"regular",{block:e.object({condition:u,value:e.array(a)}),regular:o}),"QueryWhereBlock"),i=e.defaults(e.array(a),[]);return e.meta(e.object({all:e.defaults(e.boolean(),!1),limit:e.lazy(()=>{const r=s.get().settings.utils.paginationDefaultLimit;return e.catch(e.defaults(e.number().pipe(e.lte(r)),r),r)}),page:e.catch(e.defaults(e.number().pipe(e.gte(1)),1),1),search:e.defaults(e.nullish(e.object({value:e.string(),fields:e.array(e.string())})),null),sort:e.defaults(e.array(e.object({field:e.string(),desc:e.defaults(e.boolean(),!1)})),[]),whereType:u,where:i}).pipe(r=>({...r,auth:[],authType:"and"})),{title:"Query Params",$refId:"QueryParams"})}function g(u){return e.object({pages:e.object({current:e.number(),start:e.number(),last:e.number(),previous:e.nullable(e.number()),next:e.nullable(e.number())}),docs:e.object({limit:e.number(),total:e.number(),count:e.number()}),results:e.array(u)})}function d(u){return e.assert(y(),u)}const h=()=>e.meta(e.object({uri:e.string()}),{title:"Mongodb Config",$refId:"MongodbConfig"});export{p as Conditions,n as QueryKeys,h as mongoDbConfigPipe,y as queryParamsPipe,g as queryResultsPipe,d as wrapQueryParams};
1
+ import{v as e}from"valleyed";import{Instance as i}from "../instance/index.min.mjs";var a=(u=>(u.and="and",u.or="or",u))(a||{}),n=(r=>(r.lt="lt",r.lte="lte",r.gt="gt",r.gte="gte",r.eq="eq",r.ne="ne",r.in="in",r.nin="nin",r.exists="exists",r))(n||{});const p=e.catch(e.defaults(e.in(["and","or"]),"and"),"and"),s=e.object({field:e.string(),value:e.any(),condition:e.catch(e.defaults(e.in(Object.values(n)),"eq"),"eq")}),o=e.recursive(()=>e.discriminate(t=>Object.values(a).includes(t.condition)?"block":"regular",{block:e.object({condition:p,value:e.array(o)}),regular:s}),"QueryWhereBlock"),y=e.defaults(e.array(o),[]);function l(){return e.meta(e.object({all:e.defaults(e.boolean(),!1),limit:e.lazy(()=>{const t=i.get().settings.utils.paginationDefaultLimit;return e.catch(e.defaults(e.number().pipe(e.lte(t)),t),t)}),page:e.catch(e.defaults(e.number().pipe(e.gte(1)),1),1),search:e.defaults(e.nullish(e.object({value:e.string(),fields:e.array(e.string())})),null),sort:e.defaults(e.array(e.object({field:e.string(),desc:e.defaults(e.boolean(),!1)})),[]),whereType:p,where:y}).pipe(t=>({...t,auth:[],authType:"and"})),{title:"Query Params",$refId:"QueryParams"})}function d(t){return e.object({pages:e.object({current:e.number(),start:e.number(),last:e.number(),previous:e.nullable(e.number()),next:e.nullable(e.number())}),docs:e.object({limit:e.number(),total:e.number(),count:e.number()}),results:e.array(t)})}function h(t){return e.assert(l(),t)}const q=()=>e.meta(e.object({uri:e.string()}),{title:"Mongodb Config",$refId:"MongodbConfig"});export{n as Conditions,a as QueryKeys,q as mongoDbConfigPipe,l as queryParamsPipe,d as queryResultsPipe,h as wrapQueryParams};
2
2
  //# sourceMappingURL=pipes.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/dbs/pipes.ts"],"sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nexport function queryParamsPipe() {\n\tconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\n\tconst queryWhere = v.object({\n\t\tfield: v.string(),\n\t\tvalue: v.any(),\n\t\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n\t})\n\tconst queryWhereBlock = v.recursive(\n\t\t() =>\n\t\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\t\tblock: v.object({\n\t\t\t\t\tcondition: queryKeys,\n\t\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t\t}),\n\t\t\t\tregular: queryWhere,\n\t\t\t}),\n\t\t'QueryWhereBlock',\n\t) as Pipe<\n\t\t| {\n\t\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeInput<typeof queryWhere>,\n\t\t| {\n\t\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeOutput<typeof queryWhere>\n\t>\n\n\tconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"],"mappings":"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","names":["v","Instance","QueryKeys","Conditions","queryParamsPipe","queryKeys","queryWhere","queryWhereBlock","d","queryWhereClause","pagLimit","p","queryResultsPipe","model","wrapQueryParams","params","mongoDbConfigPipe"]}
1
+ {"version":3,"sources":["../../../src/dbs/pipes.ts"],"sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\nconst queryWhere = v.object({\n\tfield: v.string(),\n\tvalue: v.any(),\n\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n})\nconst queryWhereBlock = v.recursive(\n\t() =>\n\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\tblock: v.object({\n\t\t\t\tcondition: queryKeys,\n\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t}),\n\t\t\tregular: queryWhere,\n\t\t}),\n\t'QueryWhereBlock',\n) as Pipe<\n\t| {\n\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t }\n\t| PipeInput<typeof queryWhere>,\n\t| {\n\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t }\n\t| PipeOutput<typeof queryWhere>\n>\n\nconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\nexport function queryParamsPipe() {\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"],"mappings":"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","names":["v","Instance","QueryKeys","Conditions","queryKeys","queryWhere","queryWhereBlock","d","queryWhereClause","queryParamsPipe","pagLimit","p","queryResultsPipe","model","wrapQueryParams","params","mongoDbConfigPipe"]}
@@ -17,24 +17,24 @@ var Conditions = /* @__PURE__ */ ((Conditions2) => {
17
17
  Conditions2["exists"] = "exists";
18
18
  return Conditions2;
19
19
  })(Conditions || {});
20
- function queryParamsPipe() {
21
- const queryKeys = v.catch(v.defaults(v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
22
- const queryWhere = v.object({
23
- field: v.string(),
24
- value: v.any(),
25
- condition: v.catch(v.defaults(v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
26
- });
27
- const queryWhereBlock = v.recursive(
28
- () => v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
29
- block: v.object({
30
- condition: queryKeys,
31
- value: v.array(queryWhereBlock)
32
- }),
33
- regular: queryWhere
20
+ const queryKeys = v.catch(v.defaults(v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
21
+ const queryWhere = v.object({
22
+ field: v.string(),
23
+ value: v.any(),
24
+ condition: v.catch(v.defaults(v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
25
+ });
26
+ const queryWhereBlock = v.recursive(
27
+ () => v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
28
+ block: v.object({
29
+ condition: queryKeys,
30
+ value: v.array(queryWhereBlock)
34
31
  }),
35
- "QueryWhereBlock"
36
- );
37
- const queryWhereClause = v.defaults(v.array(queryWhereBlock), []);
32
+ regular: queryWhere
33
+ }),
34
+ "QueryWhereBlock"
35
+ );
36
+ const queryWhereClause = v.defaults(v.array(queryWhereBlock), []);
37
+ function queryParamsPipe() {
38
38
  return v.meta(
39
39
  v.object({
40
40
  all: v.defaults(v.boolean(), false),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/dbs/pipes.ts"],"sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nexport function queryParamsPipe() {\n\tconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\n\tconst queryWhere = v.object({\n\t\tfield: v.string(),\n\t\tvalue: v.any(),\n\t\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n\t})\n\tconst queryWhereBlock = v.recursive(\n\t\t() =>\n\t\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\t\tblock: v.object({\n\t\t\t\t\tcondition: queryKeys,\n\t\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t\t}),\n\t\t\t\tregular: queryWhere,\n\t\t\t}),\n\t\t'QueryWhereBlock',\n\t) as Pipe<\n\t\t| {\n\t\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeInput<typeof queryWhere>,\n\t\t| {\n\t\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t\t }\n\t\t| PipeOutput<typeof queryWhere>\n\t>\n\n\tconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"],"mappings":"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","names":["QueryKeys","Conditions"]}
1
+ {"version":3,"sources":["../../../src/dbs/pipes.ts"],"sourcesContent":["import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\nconst queryWhere = v.object({\n\tfield: v.string(),\n\tvalue: v.any(),\n\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n})\nconst queryWhereBlock = v.recursive(\n\t() =>\n\t\tv.discriminate((d) => (Object.values(QueryKeys).includes(d.condition as any) ? 'block' : 'regular'), {\n\t\t\tblock: v.object({\n\t\t\t\tcondition: queryKeys,\n\t\t\t\tvalue: v.array(queryWhereBlock),\n\t\t\t}),\n\t\t\tregular: queryWhere,\n\t\t}),\n\t'QueryWhereBlock',\n) as Pipe<\n\t| {\n\t\t\tcondition: PipeInput<typeof queryKeys>\n\t\t\tvalue: PipeInput<typeof queryWhere>[]\n\t }\n\t| PipeInput<typeof queryWhere>,\n\t| {\n\t\t\tcondition: PipeOutput<typeof queryKeys>\n\t\t\tvalue: PipeOutput<typeof queryWhere>[]\n\t }\n\t| PipeOutput<typeof queryWhere>\n>\n\nconst queryWhereClause = v.defaults(v.array(queryWhereBlock), [])\n\nexport function queryParamsPipe() {\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.lazy(() => {\n\t\t\t\t\tconst pagLimit = Instance.get().settings.utils.paginationDefaultLimit\n\t\t\t\t\treturn v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit)\n\t\t\t\t}),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = () =>\n\tv.meta(\n\t\tv.object({\n\t\t\turi: v.string(),\n\t\t}),\n\t\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n\t)\n\nexport type MongoDbConfig = PipeOutput<ReturnType<typeof mongoDbConfigPipe>>\n"],"mappings":"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","names":["QueryKeys","Conditions"]}
@@ -1,2 +1,2 @@
1
- import{Server as E}from"socket.io";import P from"supertest";import{PipeError as $,v as a}from"valleyed";import{EquippedError as j,NotFoundError as O,RequestError as T}from "../../errors/index.min.mjs";import{Instance as q}from "../../instance/index.min.mjs";import{pipeErrorToValidationError as b}from "../../validations/index.min.mjs";import{requestLocalStorage as C,responseLocalStorage as x}from "../../validations/valleyed.min.mjs";import{parseAuthUser as D}from "../middlewares/parseAuthUser.min.mjs";import{OpenApi as H}from "../openapi.min.mjs";import{Response as y}from "../requests.min.mjs";import{SocketEmitter as A}from "../sockets.min.mjs";import{Methods as l,StatusCodes as v}from "../types.min.mjs";const M=Object.entries(v).filter(([,f])=>f>399).map(([f,s])=>({status:s,contentType:"application/json",pipe:a.meta(a.array(a.object({message:a.string(),field:a.optional(a.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class oe{constructor(s,t,p){this.config=t;this.implementations=p;this.server=s,this.#e=new H(t);const u=new E(s,{cors:this.cors});this.socket=new A(u,t),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;socket;server;cors={origin:"*",methods:Object.values(l).filter(s=>s!==l.options).map(s=>s.toUpperCase())};addRouter(...s){s.map(t=>t.routes).forEach(t=>this.addRoute(...t))}addRoute(...s){s.forEach(t=>{this.#t.push(async()=>{const{method:p,path:u,schema:o={},onError:c,middlewares:m=[]}=t,d=`(${p.toUpperCase()}) ${this.#e.cleanPath(u)}`;if(this.#s.get(d))throw new j(`Route key ${d} already registered. All route keys must be unique`,{route:t,key:d});m.unshift(D),m.forEach(g=>g.onSetup?.(t)),c?.onSetup?.(t);const{validateRequest:R,validateResponse:w,jsonSchema:k}=this.#o(p,o);this.#s.set(d,!0),await this.#e.register(t,k),this.implementations.registerRoute(p,this.#e.cleanPath(u),async(g,e)=>{const n=await R(await this.implementations.parseRequest(g));try{for(const h of m)await h.cb(n,this.config);const r=await t.handler(n,this.config),i=r instanceof y?r:new y({body:r,status:v.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(e,await w(i))}catch(r){if(c?.cb){const i=await c.cb(n,this.config,r),h=i instanceof y?i:new y({body:i,status:v.BadRequest,headers:{}});return await this.implementations.handleResponse(e,await w(h))}throw r}})})})}#o(s,t){const p=t?.defaultStatusCode??v.Ok,u=t?.defaultContentType??"application/json";let o=p,c=u;const m={response:{},request:{}},d={},R={};return[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![l.post,l.put,l.patch].includes(s)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"}].forEach(e=>{const n=t[e.key]??a.any();if(a.compile(n,{allErrors:!0}),!e.skip&&(e.type==="request"&&(d[e.key]=n,m.request[e.key]=a.schema(n)),e.type==="response")){const r=M.concat({status:p,contentType:c,pipe:n});R[e.key]=a.any().pipe(i=>{const h=r.find(S=>S.status===o)?.pipe;if(!h)throw $.root(`schema not defined for status code: ${o}`,i);return a.assert(h,i)}),m.response[e.key]=r.map(i=>({status:i.status,contentType:i.contentType,schema:a.schema(i.pipe)}))}}),{jsonSchema:m,validateRequest:async e=>{if(!Object.keys(d))return e;const n=t.context?await t.context(e):{};e.context=n;const r=C.run(e,()=>a.validate(a.object(d),{params:e.params,headers:e.headers,query:e.query,body:e.body}));if(!r.valid)throw b(r.error);return e.params=r.value.params,e.headers=r.value.headers,e.query=r.value.query,e.body=r.value.body,e},validateResponse:async e=>{if(!Object.keys(R))return e;o=e.status,c=e.contentType;const n=x.run(e,()=>a.validate(a.object(R),{responseHeaders:e.headers,response:e.body}));if(!n.valid)throw b(n.error);return e.body=n.value.response,e.headers=n.value.responseHeaders,e}}}test(){return P(this.server)}async start(){const s=this.config.port,t=q.get(),{app:p}=t.settings;this.config.healthPath&&this.addRoute({method:l.get,path:this.config.healthPath,handler:async o=>o.res({body:`${t.id}(${p.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async o=>{const c=await this.implementations.parseRequest(o);throw new O(`Route ${c.path} not found`)}),this.implementations.registerErrorHandler(async(o,c,m)=>{q.get().log.error(o);const d=o instanceof T?new y({body:o.serializedErrors,status:o.statusCode}):new y({body:[{message:"Something went wrong",data:o.message}],status:v.BadRequest});return await this.implementations.handleResponse(m,d)}),await Promise.all(this.#t.map(o=>o()));const u=await this.implementations.start(s);return u&&q.get().log.info(`${t.id}(${p.name}) service listening on port ${s}`),u}}export{oe as Server};
1
+ import{Server as $}from"socket.io";import j from"supertest";import{PipeError as D,v as r}from"valleyed";import{EquippedError as O,NotFoundError as T,RequestError as C}from "../../errors/index.min.mjs";import{Instance as b}from "../../instance/index.min.mjs";import{pipeErrorToValidationError as S}from "../../validations/index.min.mjs";import{requestLocalStorage as x,responseLocalStorage as H}from "../../validations/valleyed.min.mjs";import{parseAuthUser as A}from "../middlewares/parseAuthUser.min.mjs";import{OpenApi as M}from "../openapi.min.mjs";import{Response as y}from "../requests.min.mjs";import{SocketEmitter as V}from "../sockets.min.mjs";import{Methods as l,StatusCodes as v}from "../types.min.mjs";const U=Object.entries(v).filter(([,f])=>f>399).map(([f,s])=>({status:s,contentType:"application/json",pipe:r.meta(r.array(r.object({message:r.string(),field:r.optional(r.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class ae{constructor(s,t,i){this.config=t;this.implementations=i;this.server=s,this.#e=new M(t);const c=new $(s,{cors:this.cors});this.socket=new V(c,t),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;socket;server;cors={origin:"*",methods:Object.values(l).filter(s=>s!==l.options).map(s=>s.toUpperCase())};addRouter(...s){s.map(t=>t.routes).forEach(t=>this.addRoute(...t))}addRoute(...s){s.forEach(t=>{this.#t.push(async()=>{const{method:i,path:c,schema:o={},onError:d,middlewares:u=[]}=t,p=`(${i.toUpperCase()}) ${this.#e.cleanPath(c)}`;if(this.#s.get(p))throw new O(`Route key ${p} already registered. All route keys must be unique`,{route:t,key:p});u.unshift(A),u.forEach(m=>m.onSetup?.(t)),d?.onSetup?.(t);const{validateRequest:R,validateResponse:q,jsonSchema:g}=this.#o(i,o);this.#s.set(p,!0),await this.#e.register(t,g),this.implementations.registerRoute(i,this.#e.cleanPath(c),async(m,k)=>{const w=await R(await this.implementations.parseRequest(m));try{for(const n of u)await n.cb(w,this.config);const e=await t.handler(w,this.config),a=e instanceof y?e:new y({body:e,status:v.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(k,await q(a))}catch(e){if(d?.cb){const a=await d.cb(w,this.config,e),n=a instanceof y?a:new y({body:a,status:v.BadRequest,headers:{}});return await this.implementations.handleResponse(k,await q(n))}throw e}})})})}#o(s,t){const i=t?.defaultStatusCode??v.Ok,c=t?.defaultContentType??"application/json";let o=i,d=c;const u={response:{},request:{}},p={},R={};[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![l.post,l.put,l.patch].includes(s)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"}].forEach(e=>{const a=t[e.key]??r.any();if(!e.skip&&(e.type==="request"&&(p[e.key]=a,u.request[e.key]=r.schema(a)),e.type==="response")){const n=U.concat({status:i,contentType:d,pipe:a});R[e.key]=r.any().pipe(h=>{const E=n.find(P=>P.status===o)?.pipe;if(!E)throw D.root(`schema not defined for status code: ${o}`,h);return r.assert(E,h)}),u.response[e.key]=n.map(h=>({status:h.status,contentType:h.contentType,schema:r.schema(h.pipe)}))}});const g=r.object(p);r.compile(g,{allErrors:!0});const m=r.object(R);return r.compile(m,{allErrors:!0}),{jsonSchema:u,validateRequest:async e=>{if(!Object.keys(p))return e;const a=t.context?await t.context(e):{};e.context=a;const n=x.run(e,()=>r.validate(g,{params:e.params,headers:e.headers,query:e.query,body:e.body}));if(!n.valid)throw S(n.error);return e.params=n.value.params,e.headers=n.value.headers,e.query=n.value.query,e.body=n.value.body,e},validateResponse:async e=>{if(!Object.keys(R))return e;o=e.status,d=e.contentType;const a=H.run(e,()=>r.validate(m,{responseHeaders:e.headers,response:e.body}));if(!a.valid)throw S(a.error);return e.body=a.value.response,e.headers=a.value.responseHeaders,e}}}test(){return j(this.server)}async start(){const s=this.config.port,t=b.get(),{app:i}=t.settings;this.config.healthPath&&this.addRoute({method:l.get,path:this.config.healthPath,handler:async o=>o.res({body:`${t.id}(${i.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async o=>{const d=await this.implementations.parseRequest(o);throw new T(`Route ${d.path} not found`)}),this.implementations.registerErrorHandler(async(o,d,u)=>{b.get().log.error({error:o},"Uncaught error in route handler");const p=o instanceof C?new y({body:o.serializedErrors,status:o.statusCode}):new y({body:[{message:"Something went wrong",data:o.message}],status:v.BadRequest});return await this.implementations.handleResponse(u,p)}),await Promise.all(this.#t.map(o=>o()));const c=await this.implementations.start(s);return c&&b.get().log.info(`${t.id}(${i.name}) service listening on port ${s}`),c}}export{ae as Server};
2
2
  //# sourceMappingURL=base.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipe: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipe: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tv.compile(pipe, { allErrors: true })\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipe[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipe[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipe)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(v.object(requestPipe), {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipe)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\t\t\tcontentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(v.object(responsePipe), {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error(error)\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":["SocketServer","supertest","PipeError","v","EquippedError","NotFoundError","RequestError","Instance","pipeErrorToValidationError","requestLocalStorage","responseLocalStorage","parseAuthUser","OpenApi","Response","SocketEmitter","Methods","StatusCodes","errorsSchemas","value","key","Server","server","config","implementations","#openapi","socketInstance","#queue","#routesByKey","m","routers","router","routes","route","method","path","schema","onError","middlewares","validateRequest","validateResponse","jsonSchema","#resolveSchema","req","res","request","middleware","rawRes","response","error","rawResponse","defaultStatusCode","defaultContentType","status","contentType","requestPipe","responsePipe","def","pipe","pipeRecords","input","p","r","record","context","validity","port","instance","app","_","cb","started"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"AAEA,OAAS,UAAUA,MAAoB,YACvC,OAAOC,MAAe,YACtB,OAAe,aAAAC,EAAW,KAAAC,MAAS,WAEnC,OAAS,iBAAAC,EAAe,iBAAAC,EAAe,gBAAAC,MAAoB,eAC3D,OAAS,YAAAC,MAAgB,iBACzB,OAAS,8BAAAC,MAAkC,oBAC3C,OAAS,uBAAAC,EAAqB,wBAAAC,MAA4B,6BAC1D,OAAS,iBAAAC,MAAqB,+BAC9B,OAAS,WAAAC,MAAiC,aAE1C,OAAuB,YAAAC,MAAgB,cAEvC,OAAS,iBAAAC,MAAqB,aAC9B,OAAS,WAAAC,EAAgC,eAAAC,MAA+B,WAKxE,MAAMC,EAAgB,OAAO,QAAQD,CAAW,EAC9C,OAAO,CAAC,CAAC,CAAEE,CAAK,IAAMA,EAAQ,GAAG,EACjC,IAAI,CAAC,CAACC,EAAKD,CAAK,KAAO,CACvB,OAAQA,EACR,YAAa,mBACb,KAAMf,EAAE,KAAKA,EAAE,MAAMA,EAAE,OAAO,CAAE,QAASA,EAAE,OAAO,EAAG,MAAOA,EAAE,SAASA,EAAE,OAAO,CAAC,CAAE,CAAC,CAAC,EAAG,CACvF,OAAQ,UAAUgB,CAAG,WACrB,YAAa,GAAGA,CAAG,WACpB,CAAC,CACF,EAAE,EAEI,MAAeC,EAA6B,CAalD,YACCC,EACQC,EACAC,EAQP,CATO,YAAAD,EACA,qBAAAC,EASR,KAAK,OAASF,EACd,KAAKG,GAAW,IAAIZ,EAAQU,CAAM,EAClC,MAAMG,EAAiB,IAAIzB,EAAaqB,EAAQ,CAAE,KAAM,KAAK,IAAK,CAAC,EACnE,KAAK,OAAS,IAAIP,EAAcW,EAAgBH,CAAM,EACtD,KAAK,UAAU,KAAKE,GAAS,OAAO,CAAC,CACtC,CA7BAE,GAAyC,CAAC,EAC1CC,GAAe,IAAI,IACnBH,GACA,OACU,OACA,KAAO,CAChB,OAAQ,IACR,QAAS,OAAO,OAAOT,CAAO,EAC5B,OAAQa,GAAMA,IAAMb,EAAQ,OAAO,EACnC,IAAKa,GAAMA,EAAE,YAAY,CAAC,CAC7B,EAqBA,aAAaC,EAAwB,CACpCA,EAAQ,IAAKC,GAAWA,EAAO,MAAM,EAAE,QAASC,GAAW,KAAK,SAAS,GAAGA,CAAM,CAAC,CACpF,CAEA,YAAgCA,EAAoB,CACnDA,EAAO,QAASC,GAAU,CACzB,KAAKN,GAAO,KAAK,SAAY,CAC5B,KAAM,CAAE,OAAAO,EAAQ,KAAAC,EAAM,OAAAC,EAAS,CAAC,EAAG,QAAAC,EAAS,YAAAC,EAAc,CAAC,CAAE,EAAIL,EAE3Db,EAAM,IAAIc,EAAO,YAAY,CAAC,KAAK,KAAKT,GAAS,UAAUU,CAAI,CAAC,GACtE,GAAI,KAAKP,GAAa,IAAIR,CAAG,EAC5B,MAAM,IAAIf,EAAc,aAAae,CAAG,qDAAsD,CAAE,MAAAa,EAAO,IAAAb,CAAI,CAAC,EAE7GkB,EAAY,QAAQ1B,CAAoB,EACxC0B,EAAY,QAAS,GAAM,EAAE,UAAUL,CAAY,CAAC,EACpDI,GAAS,UAAUJ,CAAY,EAE/B,KAAM,CAAE,gBAAAM,EAAiB,iBAAAC,EAAkB,WAAAC,CAAW,EAAI,KAAKC,GAAeR,EAAQE,CAAM,EAE5F,KAAKR,GAAa,IAAIR,EAAK,EAAI,EAC/B,MAAM,KAAKK,GAAS,SAASQ,EAAOQ,CAAU,EAC9C,KAAK,gBAAgB,cAAcP,EAAQ,KAAKT,GAAS,UAAUU,CAAI,EAAG,MAAOQ,EAAUC,IAAa,CACvG,MAAMC,EAAU,MAAMN,EAAgB,MAAM,KAAK,gBAAgB,aAAaI,CAAG,CAAC,EAClF,GAAI,CACH,UAAWG,KAAcR,EAAa,MAAMQ,EAAW,GAAGD,EAAS,KAAK,MAAM,EAC9E,MAAME,EAAS,MAAMd,EAAM,QAAQY,EAAS,KAAK,MAAM,EACjDG,EACLD,aAAkBjC,EACfiC,EACA,IAAIjC,EAAS,CAAE,KAAMiC,EAAQ,OAAQ9B,EAAY,GAAI,QAAS,CAAC,EAAG,MAAO,EAAM,CAAC,EACpF,OAAO,MAAM,KAAK,gBAAgB,eAAe2B,EAAK,MAAMJ,EAAiBQ,CAAQ,CAAC,CACvF,OAASC,EAAO,CACf,GAAIZ,GAAS,GAAI,CAChB,MAAMa,EAAc,MAAMb,EAAQ,GAAGQ,EAAS,KAAK,OAAQI,CAAc,EACnED,EACLE,aAAuBpC,EACpBoC,EACA,IAAIpC,EAAS,CAAE,KAAMoC,EAAa,OAAQjC,EAAY,WAAY,QAAS,CAAC,CAAE,CAAC,EACnF,OAAO,MAAM,KAAK,gBAAgB,eAAe2B,EAAK,MAAMJ,EAAiBQ,CAAQ,CAAC,CACvF,CACA,MAAMC,CACP,CACD,CAAC,CACF,CAAC,CACF,CAAC,CACF,CAEAP,GAAeR,EAAqBE,EAAkB,CACrD,MAAMe,EAAoBf,GAAQ,mBAAqBnB,EAAY,GAC7DmC,EAAqBhB,GAAQ,oBAAsB,mBACzD,IAAIiB,EAASF,EACTG,EAAcF,EAClB,MAAMX,EAA+B,CAAE,SAAU,CAAC,EAAG,QAAS,CAAC,CAAE,EAC3Dc,EAA2E,CAAC,EAC5EC,EAAmE,CAAC,EAMpE,CACL,CAAE,IAAK,SAAU,KAAM,SAAU,EACjC,CAAE,IAAK,UAAW,KAAM,SAAU,EAClC,CAAE,IAAK,QAAS,KAAM,SAAU,EAChC,CAAE,IAAK,OAAQ,KAAM,UAAW,KAAM,CAAiB,CAACxC,EAAQ,KAAMA,EAAQ,IAAKA,EAAQ,KAAK,EAAG,SAASkB,CAAM,CAAE,EACpH,CAAE,IAAK,WAAY,KAAM,UAAW,EACpC,CAAE,IAAK,kBAAmB,KAAM,UAAW,CAC5C,EACK,QAASuB,GAAQ,CACrB,MAAMC,EAAOtB,EAAOqB,EAAI,GAAG,GAAKrD,EAAE,IAAI,EACtC,GAAI,CAAAqD,EAAI,OAEJA,EAAI,OAAS,YAChBF,EAAgBE,EAAI,GAAG,EAAIC,EAC3BjB,EAAW,QAAQgB,EAAI,GAAsC,EAAIrD,EAAE,OAAOsD,CAAI,GAE3ED,EAAI,OAAS,YAAY,CAC5B,MAAME,EAAczC,EAAc,OAAO,CAAE,OAAQiC,EAAmB,YAAAG,EAAa,KAAAI,CAAK,CAAC,EACzFF,EAAiBC,EAAI,GAAG,EAAIrD,EAAE,IAAI,EAAE,KAAMwD,GAAU,CACnD,MAAMC,EAAIF,EAAY,KAAMG,GAAMA,EAAE,SAAWT,CAAM,GAAG,KACxD,GAAI,CAACQ,EAAG,MAAM1D,EAAU,KAAK,uCAAuCkD,CAAM,GAAIO,CAAK,EACnF,OAAOxD,EAAE,OAAOyD,EAAGD,CAAK,CACzB,CAAC,EACDnB,EAAW,SAASgB,EAAI,GAAuC,EAAIE,EAAY,IAAKI,IAAY,CAC/F,OAAQA,EAAO,OACf,YAAaA,EAAO,YACpB,OAAQ3D,EAAE,OAAO2D,EAAO,IAAI,CAC7B,EAAE,CACH,CACD,CAAC,EACD,MAAMC,EAAc5D,EAAE,OAAOmD,CAAe,EAC5CnD,EAAE,QAAQ4D,EAAa,CAAE,UAAW,EAAK,CAAC,EAC1C,MAAMC,EAAe7D,EAAE,OAAOoD,CAAgB,EAC9C,OAAApD,EAAE,QAAQ6D,EAAc,CAAE,UAAW,EAAK,CAAC,EAsCpC,CACN,WAAAxB,EACA,gBAvCyC,MAAOI,GAAY,CAC5D,GAAI,CAAC,OAAO,KAAKU,CAAe,EAAG,OAAOV,EAC1C,MAAMqB,EAAU9B,EAAO,QAAU,MAAMA,EAAO,QAAQS,CAAO,EAAI,CAAC,EAClEA,EAAQ,QAAUqB,EAClB,MAAMC,EAAWzD,EAAoB,IAAImC,EAAS,IACjDzC,EAAE,SAAS4D,EAAa,CACvB,OAAQnB,EAAQ,OAChB,QAASA,EAAQ,QACjB,MAAOA,EAAQ,MACf,KAAMA,EAAQ,IACf,CAAC,CACF,EAEA,GAAI,CAACsB,EAAS,MAAO,MAAM1D,EAA2B0D,EAAS,KAAK,EACpE,OAAAtB,EAAQ,OAASsB,EAAS,MAAM,OAChCtB,EAAQ,QAAUsB,EAAS,MAAM,QACjCtB,EAAQ,MAAQsB,EAAS,MAAM,MAC/BtB,EAAQ,KAAOsB,EAAS,MAAM,KACvBtB,CACR,EAqBC,iBApB2C,MAAOG,GAAa,CAC/D,GAAI,CAAC,OAAO,KAAKQ,CAAgB,EAAG,OAAOR,EAC3CK,EAASL,EAAS,OAClBM,EAAcN,EAAS,YAEvB,MAAMmB,EAAWxD,EAAqB,IAAIqC,EAAU,IACnD5C,EAAE,SAAS6D,EAAc,CACxB,gBAAiBjB,EAAS,QAC1B,SAAUA,EAAS,IACpB,CAAC,CACF,EAEA,GAAI,CAACmB,EAAS,MAAO,MAAM1D,EAA2B0D,EAAS,KAAK,EACpE,OAAAnB,EAAS,KAAOmB,EAAS,MAAM,SAC/BnB,EAAS,QAAUmB,EAAS,MAAM,gBAC3BnB,CACR,CAKA,CACD,CAEA,MAAO,CACN,OAAO9C,EAAU,KAAK,MAAM,CAC7B,CAEA,MAAM,OAAQ,CACb,MAAMkE,EAAO,KAAK,OAAO,KACnBC,EAAW7D,EAAS,IAAI,EACxB,CAAE,IAAA8D,CAAI,EAAID,EAAS,SACrB,KAAK,OAAO,YACf,KAAK,SAAS,CACb,OAAQrD,EAAQ,IAChB,KAAM,KAAK,OAAO,WAClB,QAAS,MAAO2B,GACfA,EAAI,IAAI,CACP,KAAM,GAAG0B,EAAS,EAAE,IAAIC,EAAI,IAAI,oBAChC,YAAa,YACd,CAAC,CACH,CAAC,EAEF,KAAK,gBAAgB,wBAAwB,MAAO3B,GAAQ,CAC3D,MAAME,EAAU,MAAM,KAAK,gBAAgB,aAAaF,CAAG,EAC3D,MAAM,IAAIrC,EAAc,SAASuC,EAAQ,IAAI,YAAY,CAC1D,CAAC,EACD,KAAK,gBAAgB,qBAAqB,MAAOI,EAAOsB,EAAG3B,IAAQ,CAClEpC,EAAS,IAAI,EAAE,IAAI,MAAM,CAAE,MAAAyC,CAAM,EAAG,iCAAiC,EACrE,MAAMD,EACLC,aAAiB1C,EACd,IAAIO,EAAS,CACb,KAAMmC,EAAM,iBACZ,OAAQA,EAAM,UACf,CAAC,EACA,IAAInC,EAAS,CACb,KAAM,CAAC,CAAE,QAAS,uBAAwB,KAAMmC,EAAM,OAAQ,CAAC,EAC/D,OAAQhC,EAAY,UACrB,CAAC,EACJ,OAAO,MAAM,KAAK,gBAAgB,eAAe2B,EAAKI,CAAQ,CAC/D,CAAC,EAED,MAAM,QAAQ,IAAI,KAAKrB,GAAO,IAAK6C,GAAOA,EAAG,CAAC,CAAC,EAC/C,MAAMC,EAAU,MAAM,KAAK,gBAAgB,MAAML,CAAI,EACrD,OAAIK,GAASjE,EAAS,IAAI,EAAE,IAAI,KAAK,GAAG6D,EAAS,EAAE,IAAIC,EAAI,IAAI,+BAA+BF,CAAI,EAAE,EAC7FK,CACR,CACD","names":["SocketServer","supertest","PipeError","v","EquippedError","NotFoundError","RequestError","Instance","pipeErrorToValidationError","requestLocalStorage","responseLocalStorage","parseAuthUser","OpenApi","Response","SocketEmitter","Methods","StatusCodes","errorsSchemas","value","key","Server","server","config","implementations","#openapi","socketInstance","#queue","#routesByKey","m","routers","router","routes","route","method","path","schema","onError","middlewares","validateRequest","validateResponse","jsonSchema","#resolveSchema","req","res","request","middleware","rawRes","response","error","rawResponse","defaultStatusCode","defaultContentType","status","contentType","requestPipeDefs","responsePipeDefs","def","pipe","pipeRecords","input","p","r","record","requestPipe","responsePipe","context","validity","port","instance","app","_","cb","started"]}
@@ -78,8 +78,8 @@ class Server {
78
78
  let status = defaultStatusCode;
79
79
  let contentType = defaultContentType;
80
80
  const jsonSchema = { response: {}, request: {} };
81
- const requestPipe = {};
82
- const responsePipe = {};
81
+ const requestPipeDefs = {};
82
+ const responsePipeDefs = {};
83
83
  const defs = [
84
84
  { key: "params", type: "request" },
85
85
  { key: "headers", type: "request" },
@@ -90,15 +90,14 @@ class Server {
90
90
  ];
91
91
  defs.forEach((def) => {
92
92
  const pipe = schema[def.key] ?? v.any();
93
- v.compile(pipe, { allErrors: true });
94
93
  if (def.skip) return;
95
94
  if (def.type === "request") {
96
- requestPipe[def.key] = pipe;
95
+ requestPipeDefs[def.key] = pipe;
97
96
  jsonSchema.request[def.key] = v.schema(pipe);
98
97
  }
99
98
  if (def.type === "response") {
100
99
  const pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe });
101
- responsePipe[def.key] = v.any().pipe((input) => {
100
+ responsePipeDefs[def.key] = v.any().pipe((input) => {
102
101
  const p = pipeRecords.find((r) => r.status === status)?.pipe;
103
102
  if (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input);
104
103
  return v.assert(p, input);
@@ -110,13 +109,17 @@ class Server {
110
109
  }));
111
110
  }
112
111
  });
112
+ const requestPipe = v.object(requestPipeDefs);
113
+ v.compile(requestPipe, { allErrors: true });
114
+ const responsePipe = v.object(responsePipeDefs);
115
+ v.compile(responsePipe, { allErrors: true });
113
116
  const validateRequest = async (request) => {
114
- if (!Object.keys(requestPipe)) return request;
117
+ if (!Object.keys(requestPipeDefs)) return request;
115
118
  const context = schema.context ? await schema.context(request) : {};
116
119
  request.context = context;
117
120
  const validity = requestLocalStorage.run(
118
121
  request,
119
- () => v.validate(v.object(requestPipe), {
122
+ () => v.validate(requestPipe, {
120
123
  params: request.params,
121
124
  headers: request.headers,
122
125
  query: request.query,
@@ -131,13 +134,12 @@ class Server {
131
134
  return request;
132
135
  };
133
136
  const validateResponse = async (response) => {
134
- if (!Object.keys(responsePipe)) return response;
137
+ if (!Object.keys(responsePipeDefs)) return response;
135
138
  status = response.status;
136
139
  contentType = response.contentType;
137
- contentType;
138
140
  const validity = responseLocalStorage.run(
139
141
  response,
140
- () => v.validate(v.object(responsePipe), {
142
+ () => v.validate(responsePipe, {
141
143
  responseHeaders: response.headers,
142
144
  response: response.body
143
145
  })
@@ -174,7 +176,7 @@ class Server {
174
176
  throw new NotFoundError(`Route ${request.path} not found`);
175
177
  });
176
178
  this.implementations.registerErrorHandler(async (error, _, res) => {
177
- Instance.get().log.error(error);
179
+ Instance.get().log.error({ error }, "Uncaught error in route handler");
178
180
  const response = error instanceof RequestError ? new Response({
179
181
  body: error.serializedErrors,
180
182
  status: error.statusCode
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipe: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipe: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tv.compile(pipe, { allErrors: true })\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipe[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipe[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipe)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(v.object(requestPipe), {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipe)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\t\t\tcontentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(v.object(responsePipe), {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error(error)\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -17,6 +17,16 @@ declare enum Conditions {
17
17
  nin = "nin",
18
18
  exists = "exists"
19
19
  }
20
+ declare const queryKeys: Pipe<QueryKeys | undefined, QueryKeys>;
21
+ declare const queryWhere: Pipe<{
22
+ field: string;
23
+ value: any;
24
+ condition: Conditions | undefined;
25
+ }, {
26
+ field: string;
27
+ value: any;
28
+ condition: Conditions;
29
+ }>;
20
30
  declare function queryParamsPipe(): Pipe<{
21
31
  all: boolean | undefined;
22
32
  limit: number | undefined;
@@ -35,16 +45,8 @@ declare function queryParamsPipe(): Pipe<{
35
45
  value: any;
36
46
  condition: Conditions | undefined;
37
47
  } | {
38
- condition: PipeInput<Pipe<QueryKeys | undefined, QueryKeys>>;
39
- value: PipeInput<Pipe<{
40
- field: string;
41
- value: any;
42
- condition: Conditions | undefined;
43
- }, {
44
- field: string;
45
- value: any;
46
- condition: Conditions;
47
- }>>[];
48
+ condition: PipeInput<typeof queryKeys>;
49
+ value: PipeInput<typeof queryWhere>[];
48
50
  })[] | undefined;
49
51
  }, {
50
52
  auth: ({
@@ -52,16 +54,8 @@ declare function queryParamsPipe(): Pipe<{
52
54
  value: any;
53
55
  condition: Conditions;
54
56
  } | {
55
- condition: PipeOutput<Pipe<QueryKeys | undefined, QueryKeys>>;
56
- value: PipeOutput<Pipe<{
57
- field: string;
58
- value: any;
59
- condition: Conditions | undefined;
60
- }, {
61
- field: string;
62
- value: any;
63
- condition: Conditions;
64
- }>>[];
57
+ condition: PipeOutput<typeof queryKeys>;
58
+ value: PipeOutput<typeof queryWhere>[];
65
59
  })[];
66
60
  authType: QueryKeys;
67
61
  all: boolean;
@@ -81,16 +75,8 @@ declare function queryParamsPipe(): Pipe<{
81
75
  value: any;
82
76
  condition: Conditions;
83
77
  } | {
84
- condition: PipeOutput<Pipe<QueryKeys | undefined, QueryKeys>>;
85
- value: PipeOutput<Pipe<{
86
- field: string;
87
- value: any;
88
- condition: Conditions | undefined;
89
- }, {
90
- field: string;
91
- value: any;
92
- condition: Conditions;
93
- }>>[];
78
+ condition: PipeOutput<typeof queryKeys>;
79
+ value: PipeOutput<typeof queryWhere>[];
94
80
  })[];
95
81
  }>;
96
82
  declare function queryResultsPipe<T>(model: Pipe<any, T>): Pipe<{
@@ -1,5 +1,5 @@
1
1
  import { MongoClient, ObjectId, Collection } from 'mongodb';
2
- import { I as IdType$1, f as DbConfig, M as Model, E as Entity, e as Config, T as Table, a as MongoDbConfig } from './core-VE67ynvC.js';
2
+ import { I as IdType$1, f as DbConfig, M as Model, E as Entity, e as Config, T as Table, a as MongoDbConfig } from './core-BuPovjLX.js';
3
3
 
4
4
  type TableOptions = {
5
5
  skipAudit?: boolean;
@@ -1,6 +1,6 @@
1
- import { M as Model, E as Entity, D as DbChange, a as MongoDbConfig, b as DbChangeConfig, c as DbChangeCallbacks } from '../core-VE67ynvC.js';
2
- export { B as BulkWriteOperation, g as Conditions, e as Config, C as CreateInput, f as DbConfig, d as EntityInput, I as IdType, Q as QueryKeys, i as QueryParams, j as QueryParamsInput, n as QueryResults, l as QueryWhere, m as QueryWhereBlock, k as QueryWhereClause, T as Table, U as UpdateInput, o as mongoDbConfigPipe, q as queryParamsPipe, h as queryResultsPipe, w as wrapQueryParams } from '../core-VE67ynvC.js';
3
- export { D as Db, M as MongoDb, T as TableOptions } from '../db-CmGSoEjh.js';
1
+ import { M as Model, E as Entity, D as DbChange, a as MongoDbConfig, b as DbChangeConfig, c as DbChangeCallbacks } from '../core-BuPovjLX.js';
2
+ export { B as BulkWriteOperation, g as Conditions, e as Config, C as CreateInput, f as DbConfig, d as EntityInput, I as IdType, Q as QueryKeys, i as QueryParams, j as QueryParamsInput, n as QueryResults, l as QueryWhere, m as QueryWhereBlock, k as QueryWhereClause, T as Table, U as UpdateInput, o as mongoDbConfigPipe, q as queryParamsPipe, h as queryResultsPipe, w as wrapQueryParams } from '../core-BuPovjLX.js';
3
+ export { D as Db, M as MongoDb, T as TableOptions } from '../db-Gck93XBL.js';
4
4
  import { Collection } from 'mongodb';
5
5
  export { Filter } from 'mongodb';
6
6
  import 'valleyed';
@@ -17,24 +17,24 @@ var Conditions = /* @__PURE__ */ ((Conditions2) => {
17
17
  Conditions2["exists"] = "exists";
18
18
  return Conditions2;
19
19
  })(Conditions || {});
20
- function queryParamsPipe() {
21
- const queryKeys = v.catch(v.defaults(v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
22
- const queryWhere = v.object({
23
- field: v.string(),
24
- value: v.any(),
25
- condition: v.catch(v.defaults(v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
26
- });
27
- const queryWhereBlock = v.recursive(
28
- () => v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
29
- block: v.object({
30
- condition: queryKeys,
31
- value: v.array(queryWhereBlock)
32
- }),
33
- regular: queryWhere
20
+ const queryKeys = v.catch(v.defaults(v.in(["and" /* and */, "or" /* or */]), "and" /* and */), "and" /* and */);
21
+ const queryWhere = v.object({
22
+ field: v.string(),
23
+ value: v.any(),
24
+ condition: v.catch(v.defaults(v.in(Object.values(Conditions)), "eq" /* eq */), "eq" /* eq */)
25
+ });
26
+ const queryWhereBlock = v.recursive(
27
+ () => v.discriminate((d) => Object.values(QueryKeys).includes(d.condition) ? "block" : "regular", {
28
+ block: v.object({
29
+ condition: queryKeys,
30
+ value: v.array(queryWhereBlock)
34
31
  }),
35
- "QueryWhereBlock"
36
- );
37
- const queryWhereClause = v.defaults(v.array(queryWhereBlock), []);
32
+ regular: queryWhere
33
+ }),
34
+ "QueryWhereBlock"
35
+ );
36
+ const queryWhereClause = v.defaults(v.array(queryWhereBlock), []);
37
+ function queryParamsPipe() {
38
38
  return v.meta(
39
39
  v.object({
40
40
  all: v.defaults(v.boolean(), false),
@@ -5,7 +5,7 @@ import * as supertest_lib_agent from 'supertest/lib/agent';
5
5
  import http from 'http';
6
6
  import supertest from 'supertest';
7
7
  import { Server as Server$1 } from 'socket.io';
8
- import { E as Entity } from './core-VE67ynvC.js';
8
+ import { E as Entity } from './core-BuPovjLX.js';
9
9
  import { A as AuthUser } from './overrides-6Hxg764S.js';
10
10
 
11
11
  declare class Router<T extends RouteDef> {
@@ -9,16 +9,16 @@ import './requests-DblEBsI-.js';
9
9
  import 'stream';
10
10
  import './types/index.js';
11
11
  import './base-8yVXb67P.js';
12
- import './fastify-aW8KHCpj.js';
12
+ import './fastify-B7DQ55s8.js';
13
13
  import 'express';
14
14
  import 'fastify';
15
15
  import 'supertest/lib/agent';
16
16
  import 'http';
17
17
  import 'supertest';
18
18
  import 'socket.io';
19
- import './core-VE67ynvC.js';
19
+ import './core-BuPovjLX.js';
20
20
  import 'mongodb';
21
21
  import './cache/index.js';
22
22
  import 'ioredis';
23
- import './db-CmGSoEjh.js';
23
+ import './db-Gck93XBL.js';
24
24
  import './jobs/index.js';
@@ -5,9 +5,9 @@ import { E as EventBus } from '../base-CfeyC14V.js';
5
5
  import { K as KafkaEventBus } from '../kafka-zsC3c8ar.js';
6
6
  import { RabbitMQEventBus } from '../events/index.js';
7
7
  import { e as BaseTokensUtility, B as BaseApiKeysUtility, E as EquippedError } from '../requests-DblEBsI-.js';
8
- import { E as ExpressServer, F as FastifyServer } from '../fastify-aW8KHCpj.js';
8
+ import { E as ExpressServer, F as FastifyServer } from '../fastify-B7DQ55s8.js';
9
9
  import { InMemoryCache, RedisCache } from '../cache/index.js';
10
- import { M as MongoDb } from '../db-CmGSoEjh.js';
10
+ import { M as MongoDb } from '../db-Gck93XBL.js';
11
11
  import { RedisJob } from '../jobs/index.js';
12
12
  import '../overrides-6Hxg764S.js';
13
13
  import 'stream';
@@ -19,7 +19,7 @@ import 'supertest/lib/agent';
19
19
  import 'http';
20
20
  import 'supertest';
21
21
  import 'socket.io';
22
- import '../core-VE67ynvC.js';
22
+ import '../core-BuPovjLX.js';
23
23
  import 'mongodb';
24
24
  import 'ioredis';
25
25
 
@@ -78,8 +78,8 @@ class Server {
78
78
  let status = defaultStatusCode;
79
79
  let contentType = defaultContentType;
80
80
  const jsonSchema = { response: {}, request: {} };
81
- const requestPipe = {};
82
- const responsePipe = {};
81
+ const requestPipeDefs = {};
82
+ const responsePipeDefs = {};
83
83
  const defs = [
84
84
  { key: "params", type: "request" },
85
85
  { key: "headers", type: "request" },
@@ -90,15 +90,14 @@ class Server {
90
90
  ];
91
91
  defs.forEach((def) => {
92
92
  const pipe = schema[def.key] ?? v.any();
93
- v.compile(pipe, { allErrors: true });
94
93
  if (def.skip) return;
95
94
  if (def.type === "request") {
96
- requestPipe[def.key] = pipe;
95
+ requestPipeDefs[def.key] = pipe;
97
96
  jsonSchema.request[def.key] = v.schema(pipe);
98
97
  }
99
98
  if (def.type === "response") {
100
99
  const pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe });
101
- responsePipe[def.key] = v.any().pipe((input) => {
100
+ responsePipeDefs[def.key] = v.any().pipe((input) => {
102
101
  const p = pipeRecords.find((r) => r.status === status)?.pipe;
103
102
  if (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input);
104
103
  return v.assert(p, input);
@@ -110,13 +109,17 @@ class Server {
110
109
  }));
111
110
  }
112
111
  });
112
+ const requestPipe = v.object(requestPipeDefs);
113
+ v.compile(requestPipe, { allErrors: true });
114
+ const responsePipe = v.object(responsePipeDefs);
115
+ v.compile(responsePipe, { allErrors: true });
113
116
  const validateRequest = async (request) => {
114
- if (!Object.keys(requestPipe)) return request;
117
+ if (!Object.keys(requestPipeDefs)) return request;
115
118
  const context = schema.context ? await schema.context(request) : {};
116
119
  request.context = context;
117
120
  const validity = requestLocalStorage.run(
118
121
  request,
119
- () => v.validate(v.object(requestPipe), {
122
+ () => v.validate(requestPipe, {
120
123
  params: request.params,
121
124
  headers: request.headers,
122
125
  query: request.query,
@@ -131,13 +134,12 @@ class Server {
131
134
  return request;
132
135
  };
133
136
  const validateResponse = async (response) => {
134
- if (!Object.keys(responsePipe)) return response;
137
+ if (!Object.keys(responsePipeDefs)) return response;
135
138
  status = response.status;
136
139
  contentType = response.contentType;
137
- contentType;
138
140
  const validity = responseLocalStorage.run(
139
141
  response,
140
- () => v.validate(v.object(responsePipe), {
142
+ () => v.validate(responsePipe, {
141
143
  responseHeaders: response.headers,
142
144
  response: response.body
143
145
  })
@@ -174,7 +176,7 @@ class Server {
174
176
  throw new NotFoundError(`Route ${request.path} not found`);
175
177
  });
176
178
  this.implementations.registerErrorHandler(async (error, _, res) => {
177
- Instance.get().log.error(error);
179
+ Instance.get().log.error({ error }, "Uncaught error in route handler");
178
180
  const response = error instanceof RequestError ? new Response({
179
181
  body: error.serializedErrors,
180
182
  status: error.statusCode
@@ -1,4 +1,4 @@
1
- export { E as ExpressServer, F as FastifyServer, O as OnJoinFn, R as Router, S as Server, a as SocketCallbacks, b as SocketEmitter } from '../fastify-aW8KHCpj.js';
1
+ export { E as ExpressServer, F as FastifyServer, O as OnJoinFn, R as Router, S as Server, a as SocketCallbacks, b as SocketEmitter } from '../fastify-B7DQ55s8.js';
2
2
  import { R as Request, a as RouteDefToReqRes, b as RouteDef, S as ServerConfig, c as Route } from '../requests-DblEBsI-.js';
3
3
  export { B as BaseApiKeysUtility, e as BaseTokensUtility, C as CacheTokensUtility, D as DefaultHeaders, I as IncomingFile, k as MergeRouteDefs, M as Methods, g as MethodsEnum, d as Response, i as RouteConfig, l as RouteDefHandler, j as RouterConfig, f as StatusCodes, h as StatusCodesEnum, n as makeErrorMiddleware, m as makeMiddleware, s as serverConfigPipe } from '../requests-DblEBsI-.js';
4
4
  import 'express';
@@ -7,7 +7,7 @@ import 'supertest/lib/agent';
7
7
  import 'http';
8
8
  import 'supertest';
9
9
  import 'socket.io';
10
- import '../core-VE67ynvC.js';
10
+ import '../core-BuPovjLX.js';
11
11
  import 'mongodb';
12
12
  import 'valleyed';
13
13
  import '../kafka-zsC3c8ar.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "equipped",
3
- "version": "5.0.26",
3
+ "version": "5.0.27",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "type": "module",
@@ -185,7 +185,7 @@
185
185
  "redis": "5.8.0",
186
186
  "socket.io": "4.8.1",
187
187
  "supertest": "7.1.4",
188
- "valleyed": "^4.5.16"
188
+ "valleyed": "^4.5.17"
189
189
  },
190
190
  "repository": {
191
191
  "url": "git://github.com/kevinand11/equipped.git"