temba 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +58 -10
  2. package/package.json +17 -17
  3. package/{config → src/config}/index.d.ts +15 -8
  4. package/src/config/index.d.ts.map +1 -0
  5. package/{config → src/config}/index.js +23 -28
  6. package/src/config/index.js.map +1 -0
  7. package/src/delay/delayMiddleware.d.ts +3 -0
  8. package/src/delay/delayMiddleware.d.ts.map +1 -0
  9. package/src/delay/delayMiddleware.js +13 -0
  10. package/src/delay/delayMiddleware.js.map +1 -0
  11. package/src/index.d.ts +6 -0
  12. package/src/index.d.ts.map +1 -0
  13. package/src/index.js +83 -0
  14. package/src/index.js.map +1 -0
  15. package/src/queries/in-memory.d.ts +3 -0
  16. package/src/queries/in-memory.d.ts.map +1 -0
  17. package/src/queries/in-memory.js +61 -0
  18. package/src/queries/in-memory.js.map +1 -0
  19. package/src/queries/mongo.d.ts +3 -0
  20. package/src/queries/mongo.d.ts.map +1 -0
  21. package/src/queries/mongo.js +75 -0
  22. package/src/queries/mongo.js.map +1 -0
  23. package/src/queries/queries.d.ts +2 -0
  24. package/src/queries/queries.d.ts.map +1 -0
  25. package/src/queries/queries.js +10 -0
  26. package/src/queries/queries.js.map +1 -0
  27. package/src/queries/types.d.ts +15 -0
  28. package/src/queries/types.d.ts.map +1 -0
  29. package/src/queries/types.js +2 -0
  30. package/src/queries/types.js.map +1 -0
  31. package/src/requestBodyInterceptor/interceptRequestBody.d.ts +3 -0
  32. package/src/requestBodyInterceptor/interceptRequestBody.d.ts.map +1 -0
  33. package/src/requestBodyInterceptor/interceptRequestBody.js +14 -0
  34. package/src/requestBodyInterceptor/interceptRequestBody.js.map +1 -0
  35. package/src/requestBodyInterceptor/types.d.ts +12 -0
  36. package/src/requestBodyInterceptor/types.d.ts.map +1 -0
  37. package/src/requestBodyInterceptor/types.js +2 -0
  38. package/src/requestBodyInterceptor/types.js.map +1 -0
  39. package/src/requestHandlers/delete.d.ts +12 -0
  40. package/src/requestHandlers/delete.d.ts.map +1 -0
  41. package/src/requestHandlers/delete.js +22 -0
  42. package/src/requestHandlers/delete.js.map +1 -0
  43. package/src/requestHandlers/get.d.ts +22 -0
  44. package/src/requestHandlers/get.d.ts.map +1 -0
  45. package/src/requestHandlers/get.js +47 -0
  46. package/src/requestHandlers/get.js.map +1 -0
  47. package/src/requestHandlers/index.d.ts +54 -0
  48. package/src/requestHandlers/index.d.ts.map +1 -0
  49. package/src/requestHandlers/index.js +21 -0
  50. package/src/requestHandlers/index.js.map +1 -0
  51. package/src/requestHandlers/patch.d.ts +9 -0
  52. package/src/requestHandlers/patch.d.ts.map +1 -0
  53. package/src/requestHandlers/patch.js +35 -0
  54. package/src/requestHandlers/patch.js.map +1 -0
  55. package/src/requestHandlers/post.d.ts +18 -0
  56. package/src/requestHandlers/post.d.ts.map +1 -0
  57. package/src/requestHandlers/post.js +37 -0
  58. package/src/requestHandlers/post.js.map +1 -0
  59. package/src/requestHandlers/put.d.ts +9 -0
  60. package/src/requestHandlers/put.d.ts.map +1 -0
  61. package/src/requestHandlers/put.js +35 -0
  62. package/src/requestHandlers/put.js.map +1 -0
  63. package/src/requestHandlers/types.d.ts +38 -0
  64. package/src/requestHandlers/types.d.ts.map +1 -0
  65. package/src/requestHandlers/types.js +2 -0
  66. package/src/requestHandlers/types.js.map +1 -0
  67. package/src/requestHandlers/utils.d.ts +2 -0
  68. package/src/requestHandlers/utils.d.ts.map +1 -0
  69. package/src/requestHandlers/utils.js +6 -0
  70. package/src/requestHandlers/utils.js.map +1 -0
  71. package/src/resourceRouter.d.ts +5 -0
  72. package/src/resourceRouter.d.ts.map +1 -0
  73. package/src/resourceRouter.js +95 -0
  74. package/src/resourceRouter.js.map +1 -0
  75. package/src/responseBodyInterceptor/interceptResponseBody.d.ts +3 -0
  76. package/src/responseBodyInterceptor/interceptResponseBody.d.ts.map +1 -0
  77. package/src/responseBodyInterceptor/interceptResponseBody.js +7 -0
  78. package/src/responseBodyInterceptor/interceptResponseBody.js.map +1 -0
  79. package/src/responseBodyInterceptor/types.d.ts +11 -0
  80. package/src/responseBodyInterceptor/types.d.ts.map +1 -0
  81. package/src/responseBodyInterceptor/types.js +2 -0
  82. package/src/responseBodyInterceptor/types.js.map +1 -0
  83. package/src/schema/compile.d.ts +3 -0
  84. package/src/schema/compile.d.ts.map +1 -0
  85. package/src/schema/compile.js +26 -0
  86. package/src/schema/compile.js.map +1 -0
  87. package/src/schema/types.d.ts +25 -0
  88. package/src/schema/types.d.ts.map +1 -0
  89. package/src/schema/types.js +2 -0
  90. package/{routes → src/schema}/types.js.map +1 -1
  91. package/src/schema/validate.d.ts +4 -0
  92. package/src/schema/validate.d.ts.map +1 -0
  93. package/src/schema/validate.js +14 -0
  94. package/src/schema/validate.js.map +1 -0
  95. package/src/urls/urlParser.d.ts +5 -0
  96. package/src/urls/urlParser.d.ts.map +1 -0
  97. package/src/urls/urlParser.js +9 -0
  98. package/src/urls/urlParser.js.map +1 -0
  99. package/test/integration/api-prefix.test.d.ts +2 -0
  100. package/test/integration/api-prefix.test.d.ts.map +1 -0
  101. package/test/integration/api-prefix.test.js +69 -0
  102. package/test/integration/api-prefix.test.js.map +1 -0
  103. package/test/integration/createServer.d.ts +4 -0
  104. package/test/integration/createServer.d.ts.map +1 -0
  105. package/test/integration/createServer.js +4 -0
  106. package/test/integration/createServer.js.map +1 -0
  107. package/test/integration/crud.test.d.ts +2 -0
  108. package/test/integration/crud.test.d.ts.map +1 -0
  109. package/test/integration/crud.test.js +173 -0
  110. package/test/integration/crud.test.js.map +1 -0
  111. package/test/integration/custom-router.test.d.ts +2 -0
  112. package/test/integration/custom-router.test.d.ts.map +1 -0
  113. package/test/integration/custom-router.test.js +74 -0
  114. package/test/integration/custom-router.test.js.map +1 -0
  115. package/test/integration/head-method.test.d.ts +2 -0
  116. package/test/integration/head-method.test.d.ts.map +1 -0
  117. package/test/integration/head-method.test.js +38 -0
  118. package/test/integration/head-method.test.js.map +1 -0
  119. package/test/integration/options-method.test.d.ts +2 -0
  120. package/test/integration/options-method.test.d.ts.map +1 -0
  121. package/test/integration/options-method.test.js +30 -0
  122. package/test/integration/options-method.test.js.map +1 -0
  123. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-change-requestBody.test.d.ts +2 -0
  124. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-change-requestBody.test.d.ts.map +1 -0
  125. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-change-requestBody.test.js +76 -0
  126. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-change-requestBody.test.js.map +1 -0
  127. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-error-string.test.d.ts +2 -0
  128. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-error-string.test.d.ts.map +1 -0
  129. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-error-string.test.js +60 -0
  130. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-error-string.test.js.map +1 -0
  131. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-invalid-return-types.test.d.ts +2 -0
  132. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-invalid-return-types.test.d.ts.map +1 -0
  133. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-invalid-return-types.test.js +89 -0
  134. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-invalid-return-types.test.js.map +1 -0
  135. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-void.test.d.ts +2 -0
  136. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-void.test.d.ts.map +1 -0
  137. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-void.test.js +47 -0
  138. package/test/integration/requestBodyInterceptor/requestBodyInterceptor-void.test.js.map +1 -0
  139. package/test/integration/responseBodyInterceptor.test.d.ts +2 -0
  140. package/test/integration/responseBodyInterceptor.test.d.ts.map +1 -0
  141. package/test/integration/responseBodyInterceptor.test.js +107 -0
  142. package/test/integration/responseBodyInterceptor.test.js.map +1 -0
  143. package/test/integration/returnNullFields.test.d.ts +2 -0
  144. package/test/integration/returnNullFields.test.d.ts.map +1 -0
  145. package/test/integration/returnNullFields.test.js +51 -0
  146. package/test/integration/returnNullFields.test.js.map +1 -0
  147. package/test/integration/root-url.test.d.ts +2 -0
  148. package/test/integration/root-url.test.d.ts.map +1 -0
  149. package/test/integration/root-url.test.js +29 -0
  150. package/test/integration/root-url.test.js.map +1 -0
  151. package/test/integration/schema-validation.test.d.ts +2 -0
  152. package/test/integration/schema-validation.test.d.ts.map +1 -0
  153. package/test/integration/schema-validation.test.js +169 -0
  154. package/test/integration/schema-validation.test.js.map +1 -0
  155. package/test/unit/config/config.test.d.ts +2 -0
  156. package/test/unit/config/config.test.d.ts.map +1 -0
  157. package/test/unit/config/config.test.js +121 -0
  158. package/test/unit/config/config.test.js.map +1 -0
  159. package/test/unit/urls/urlParser.test.d.ts +2 -0
  160. package/test/unit/urls/urlParser.test.d.ts.map +1 -0
  161. package/test/unit/urls/urlParser.test.js +43 -0
  162. package/test/unit/urls/urlParser.test.js.map +1 -0
  163. package/tsconfig.tsbuildinfo +1 -0
  164. package/vitest.config.d.ts +3 -0
  165. package/vitest.config.d.ts.map +1 -0
  166. package/vitest.config.js +10 -0
  167. package/vitest.config.js.map +1 -0
  168. package/config/index.js.map +0 -1
  169. package/delay/delayMiddleware.d.ts +0 -2
  170. package/delay/delayMiddleware.js +0 -16
  171. package/delay/delayMiddleware.js.map +0 -1
  172. package/index.d.ts +0 -5
  173. package/index.js +0 -94
  174. package/index.js.map +0 -1
  175. package/queries/in-memory.d.ts +0 -19
  176. package/queries/in-memory.js +0 -66
  177. package/queries/in-memory.js.map +0 -1
  178. package/queries/mongo.d.ts +0 -19
  179. package/queries/mongo.js +0 -106
  180. package/queries/mongo.js.map +0 -1
  181. package/queries/queries.d.ts +0 -20
  182. package/queries/queries.js +0 -17
  183. package/queries/queries.js.map +0 -1
  184. package/routes/delete.d.ts +0 -4
  185. package/routes/delete.js +0 -39
  186. package/routes/delete.js.map +0 -1
  187. package/routes/get.d.ts +0 -4
  188. package/routes/get.js +0 -71
  189. package/routes/get.js.map +0 -1
  190. package/routes/interceptors.d.ts +0 -3
  191. package/routes/interceptors.js +0 -22
  192. package/routes/interceptors.js.map +0 -1
  193. package/routes/patch.d.ts +0 -4
  194. package/routes/patch.js +0 -47
  195. package/routes/patch.js.map +0 -1
  196. package/routes/post.d.ts +0 -4
  197. package/routes/post.js +0 -47
  198. package/routes/post.js.map +0 -1
  199. package/routes/put.d.ts +0 -4
  200. package/routes/put.js +0 -47
  201. package/routes/put.js.map +0 -1
  202. package/routes/routes.d.ts +0 -6
  203. package/routes/routes.js +0 -61
  204. package/routes/routes.js.map +0 -1
  205. package/routes/types.d.ts +0 -17
  206. package/routes/types.js +0 -3
  207. package/routes/utils.d.ts +0 -3
  208. package/routes/utils.js +0 -8
  209. package/routes/utils.js.map +0 -1
  210. package/urls/urlMiddleware.d.ts +0 -3
  211. package/urls/urlMiddleware.js +0 -30
  212. package/urls/urlMiddleware.js.map +0 -1
  213. package/urls/urlParser.d.ts +0 -5
  214. package/urls/urlParser.js +0 -13
  215. package/urls/urlParser.js.map +0 -1
@@ -0,0 +1,95 @@
1
+ import express from 'express';
2
+ import { getRequestHandler } from './requestHandlers';
3
+ import { parseUrl } from './urls/urlParser';
4
+ export const createResourceRouter = (queries, schemas, routerConfig) => {
5
+ const getUrlInfo = (baseUrl) => {
6
+ const url = routerConfig.apiPrefix ? baseUrl.replace(routerConfig.apiPrefix, '') : baseUrl;
7
+ return parseUrl(url);
8
+ };
9
+ const parseGetRequest = (req) => {
10
+ const urlInfo = getUrlInfo(req.baseUrl);
11
+ if (!urlInfo.resource)
12
+ return null;
13
+ return {
14
+ id: urlInfo.id,
15
+ resource: urlInfo.resource,
16
+ };
17
+ };
18
+ const parsePostRequest = (req) => {
19
+ const urlInfo = getUrlInfo(req.baseUrl);
20
+ if (!urlInfo.resource)
21
+ return null;
22
+ const host = req.get('host') || null;
23
+ const protocol = host ? req.protocol : null;
24
+ return {
25
+ id: urlInfo.id,
26
+ resource: urlInfo.resource,
27
+ body: req.body,
28
+ host,
29
+ protocol,
30
+ };
31
+ };
32
+ const parsePutRequest = (req) => {
33
+ const urlInfo = getUrlInfo(req.baseUrl);
34
+ if (!urlInfo.resource)
35
+ return null;
36
+ if (!urlInfo.id)
37
+ return null;
38
+ return {
39
+ id: urlInfo.id,
40
+ resource: urlInfo.resource,
41
+ body: req.body,
42
+ };
43
+ };
44
+ const parsePatchRequest = parsePutRequest;
45
+ const parseDeleteRequest = (req) => {
46
+ const urlInfo = getUrlInfo(req.baseUrl);
47
+ if (!urlInfo.resource)
48
+ return null;
49
+ return {
50
+ id: urlInfo.id,
51
+ resource: urlInfo.resource,
52
+ };
53
+ };
54
+ const sendResponse = (tembaResponse, res) => {
55
+ res.status(tembaResponse.status);
56
+ if (tembaResponse.headers) {
57
+ for (const [key, value] of Object.entries(tembaResponse.headers)) {
58
+ res.set(key, value);
59
+ }
60
+ }
61
+ res.json(tembaResponse.body);
62
+ res.end();
63
+ };
64
+ const handle = async (expressRequest, expressResponse, parseRequest, handleRequest) => {
65
+ const requestInfo = parseRequest(expressRequest);
66
+ if (!requestInfo ||
67
+ (routerConfig.validateResources &&
68
+ !routerConfig.resources.includes(requestInfo.resource.toLowerCase()))) {
69
+ return expressResponse.status(404).json({
70
+ message: 'Unknown resource',
71
+ });
72
+ }
73
+ const response = await handleRequest(requestInfo);
74
+ sendResponse(response, expressResponse);
75
+ };
76
+ const requestHandler = getRequestHandler(queries, schemas, routerConfig);
77
+ const resourceRouter = express.Router();
78
+ resourceRouter.get('*', async (expressRequest, expressResponse) => {
79
+ await handle(expressRequest, expressResponse, parseGetRequest, requestHandler.handleGet);
80
+ });
81
+ resourceRouter.post('*', async (expressRequest, expressResponse) => {
82
+ await handle(expressRequest, expressResponse, parsePostRequest, requestHandler.handlePost);
83
+ });
84
+ resourceRouter.put('*', async (expressRequest, expressResponse) => {
85
+ await handle(expressRequest, expressResponse, parsePutRequest, requestHandler.handlePut);
86
+ });
87
+ resourceRouter.patch('*', async (expressRequest, expressResponse) => {
88
+ await handle(expressRequest, expressResponse, parsePatchRequest, requestHandler.handlePatch);
89
+ });
90
+ resourceRouter.delete('*', async (expressRequest, expressResponse) => {
91
+ await handle(expressRequest, expressResponse, parseDeleteRequest, requestHandler.handleDelete);
92
+ });
93
+ return resourceRouter;
94
+ };
95
+ //# sourceMappingURL=resourceRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceRouter.js","sourceRoot":"","sources":["../../src/resourceRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { InterceptedResponse, ResponseBodyInterceptor } from './types';
2
+ export declare const interceptResponseBody: (interceptor: ResponseBodyInterceptor, info: InterceptedResponse) => {};
3
+ //# sourceMappingURL=interceptResponseBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptResponseBody.d.ts","sourceRoot":"","sources":["../../../src/responseBodyInterceptor/interceptResponseBody.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAEtE,eAAO,MAAM,qBAAqB,gBACnB,uBAAuB,QAC9B,mBAAmB,OAO1B,CAAA"}
@@ -0,0 +1,7 @@
1
+ export const interceptResponseBody = (interceptor, info) => {
2
+ if (!interceptor)
3
+ return info.body;
4
+ const intercepted = interceptor(info);
5
+ return intercepted ? intercepted : info.body;
6
+ };
7
+ //# sourceMappingURL=interceptResponseBody.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptResponseBody.js","sourceRoot":"","sources":["../../../src/responseBodyInterceptor/interceptResponseBody.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,WAAoC,EACpC,IAAyB,EACzB,EAAE;IACF,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC,IAAI,CAAA;IAElC,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;AAC9C,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { Item } from '../queries/types';
2
+ export type InterceptedResponse = {
3
+ body: Item;
4
+ resource: string;
5
+ id: string;
6
+ } | {
7
+ body: Item[];
8
+ resource: string;
9
+ };
10
+ export type ResponseBodyInterceptor = (info: InterceptedResponse) => unknown;
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/responseBodyInterceptor/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEvC,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;CACX,GACD;IACE,IAAI,EAAE,IAAI,EAAE,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAEL,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/responseBodyInterceptor/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { CompiledSchemas, ConfiguredSchemas } from './types';
2
+ export declare const compileSchemas: (configuredSchemas: ConfiguredSchemas | null) => CompiledSchemas;
3
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/schema/compile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE5D,eAAO,MAAM,cAAc,sBAAuB,iBAAiB,GAAG,IAAI,oBA4BzE,CAAA"}
@@ -0,0 +1,26 @@
1
+ import Ajv from 'ajv';
2
+ export const compileSchemas = (configuredSchemas) => {
3
+ // Turn the configured schemas into compiled schemas
4
+ const compiledSchemas = {
5
+ post: {},
6
+ put: {},
7
+ patch: {},
8
+ };
9
+ if (!configuredSchemas)
10
+ return compiledSchemas;
11
+ // Use a single Ajv instance in the whole app
12
+ const ajv = new Ajv();
13
+ Object.keys(configuredSchemas).forEach((resource) => {
14
+ if (configuredSchemas[resource]?.post) {
15
+ compiledSchemas.post[resource] = ajv.compile(configuredSchemas[resource]?.post);
16
+ }
17
+ if (configuredSchemas[resource]?.put) {
18
+ compiledSchemas.put[resource] = ajv.compile(configuredSchemas[resource]?.put);
19
+ }
20
+ if (configuredSchemas[resource]?.patch) {
21
+ compiledSchemas.patch[resource] = ajv.compile(configuredSchemas[resource]?.patch);
22
+ }
23
+ });
24
+ return compiledSchemas;
25
+ };
26
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/schema/compile.ts"],"names":[],"mappings":"AAAA,OAAO,GAAkB,MAAM,KAAK,CAAA;AAGpC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,iBAA2C,EAAE,EAAE;IAC5E,oDAAoD;IACpD,MAAM,eAAe,GAAoB;QACvC,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,EAAE;KACV,CAAA;IAED,IAAI,CAAC,iBAAiB;QAAE,OAAO,eAAe,CAAA;IAE9C,6CAA6C;IAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;IAErB,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAClD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;YACtC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,IAAiB,CAAC,CAAA;QAC9F,CAAC;QAED,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;YACrC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,GAAgB,CAAC,CAAA;QAC5F,CAAC;QAED,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;YACvC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,KAAkB,CAAC,CAAA;QAChG,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,eAAe,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { ValidateFunction } from 'ajv';
2
+ export type ConfiguredSchemas = {
3
+ [resource: string]: ConfiguredResourceSchema;
4
+ };
5
+ type ConfiguredResourceSchema = {
6
+ post?: unknown;
7
+ put?: unknown;
8
+ patch?: unknown;
9
+ };
10
+ export type ValidateFunctionPerResource = {
11
+ [resource: string]: ValidateFunction<unknown>;
12
+ };
13
+ export type CompiledSchemas = {
14
+ post: ValidateFunctionPerResource;
15
+ put: ValidateFunctionPerResource;
16
+ patch: ValidateFunctionPerResource;
17
+ };
18
+ export type ValidationResult = {
19
+ isValid: false;
20
+ errorMessage: string;
21
+ } | {
22
+ isValid: true;
23
+ };
24
+ export {};
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAEtC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,QAAQ,EAAE,MAAM,GAAG,wBAAwB,CAAA;CAC7C,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;CAC9C,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,2BAA2B,CAAA;IACjC,GAAG,EAAE,2BAA2B,CAAA;IAChC,KAAK,EAAE,2BAA2B,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,gBAAgB,GACxB;IACE,OAAO,EAAE,KAAK,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB,GACD;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/routes/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schema/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { ValidateFunction } from 'ajv';
2
+ import { ValidationResult } from './types';
3
+ export declare const validate: (body: unknown, validate?: ValidateFunction<unknown>) => ValidationResult;
4
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/schema/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE1C,eAAO,MAAM,QAAQ,SAAU,OAAO,aAAa,iBAAiB,OAAO,CAAC,KAAG,gBAW9E,CAAA"}
@@ -0,0 +1,14 @@
1
+ export const validate = (body, validate) => {
2
+ if (!validate)
3
+ return { isValid: true };
4
+ if (validate(body)) {
5
+ return { isValid: true };
6
+ }
7
+ else {
8
+ return {
9
+ isValid: false,
10
+ errorMessage: validate.errors?.[0]?.message ?? 'Unknown schema validation error',
11
+ };
12
+ }
13
+ };
14
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/schema/validate.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAa,EAAE,QAAoC,EAAoB,EAAE;IAChG,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAEvC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,iCAAiC;SACjF,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export declare const parseUrl: (url: string) => {
2
+ resource: string | null;
3
+ id: string | null;
4
+ };
5
+ //# sourceMappingURL=urlParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlParser.d.ts","sourceRoot":"","sources":["../../../src/urls/urlParser.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,QAAS,MAAM;;;CASnC,CAAA"}
@@ -0,0 +1,9 @@
1
+ export const parseUrl = (url) => {
2
+ if (!url || (url && !url.trim()))
3
+ return { resource: null, id: null };
4
+ const urlSegments = url.split('/').filter((i) => i);
5
+ const resource = (urlSegments.length > 0 ? urlSegments[0] : null) ?? null;
6
+ const id = (urlSegments.length > 1 ? urlSegments[1] : null) ?? null;
7
+ return { resource, id };
8
+ };
9
+ //# sourceMappingURL=urlParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlParser.js","sourceRoot":"","sources":["../../../src/urls/urlParser.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE;IACtC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;IAErE,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAEnD,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;IACzE,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;IAEnE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;AACzB,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=api-prefix.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-prefix.test.d.ts","sourceRoot":"","sources":["../../../test/integration/api-prefix.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { test, expect } from 'vitest';
2
+ import request from 'supertest';
3
+ import createServer from './createServer';
4
+ /*
5
+ Tests when configuring the apiPrefix.
6
+ */
7
+ // This Temba server is created with an apiPrefix configured
8
+ const apiPrefix = 'api';
9
+ const tembaServer = createServer({ apiPrefix });
10
+ test('GET on root URL returns 404 Not Found error', async () => {
11
+ const response = await request(tembaServer).get('/');
12
+ expect(response.statusCode).toEqual(404);
13
+ expect(response.body.message).toEqual('Not Found');
14
+ });
15
+ test('GET on apiPrefix URL returns welcome text', async () => {
16
+ const response = await request(tembaServer).get('/' + apiPrefix);
17
+ expect(response.statusCode).toEqual(200);
18
+ expect(response.text).toEqual('It works! ツ');
19
+ });
20
+ test('GET on apiPrefix and resource URL returns empty array', async () => {
21
+ const movies = '/' + apiPrefix + '/movies/';
22
+ expect((await request(tembaServer).get(movies)).statusCode).toEqual(200);
23
+ const post = await request(tembaServer).post(movies);
24
+ expect(post.statusCode).toEqual(201);
25
+ const movie = movies + post.body.id;
26
+ expect((await request(tembaServer).get(movie)).statusCode).toEqual(200);
27
+ expect((await request(tembaServer).get(movies)).statusCode).toEqual(200);
28
+ expect((await request(tembaServer).put(movie)).statusCode).toEqual(200);
29
+ expect((await request(tembaServer).patch(movie)).statusCode).toEqual(200);
30
+ expect((await request(tembaServer).delete(movie)).statusCode).toEqual(204);
31
+ });
32
+ test('GET on resource URL without apiPrefix returns 404 Not Found', async () => {
33
+ const response = await request(tembaServer).get('/movies');
34
+ expect(response.statusCode).toEqual(404);
35
+ });
36
+ test('POST on resource URL without apiPrefix returns 404 Not Found', async () => {
37
+ const response = await request(tembaServer).post('/movies');
38
+ expect(response.statusCode).toEqual(404);
39
+ });
40
+ test('PUT on resource URL without apiPrefix returns 404 Not Found', async () => {
41
+ const response = await request(tembaServer).put('/movies');
42
+ expect(response.statusCode).toEqual(404);
43
+ });
44
+ test('DELETE on resource URL without apiPrefix returns 404 Not Found', async () => {
45
+ const response = await request(tembaServer).delete('/movies');
46
+ expect(response.statusCode).toEqual(404);
47
+ });
48
+ test('PATCH on resource URL without apiPrefix returns 404 Not Found', async () => {
49
+ const response = await request(tembaServer).patch('/movies');
50
+ expect(response.statusCode).toEqual(404);
51
+ });
52
+ test('HEAD on resource URL without apiPrefix returns 404 Not Found', async () => {
53
+ const response = await request(tembaServer).head('/movies');
54
+ expect(response.statusCode).toEqual(404);
55
+ });
56
+ test('apiPrefix is equal to resource name', async () => {
57
+ const apiPrefix = 'movies';
58
+ const server = createServer({ apiPrefix });
59
+ const moviesUrl = `/${apiPrefix}/movies/`;
60
+ // Create a movie
61
+ const postResponse = await request(server).post(moviesUrl).send({ title: 'Inception' });
62
+ expect(postResponse.statusCode).toEqual(201);
63
+ const id = postResponse.header.location?.split('/').pop();
64
+ // Check if we can get the movie
65
+ const getResponse = await request(server).get(moviesUrl + id);
66
+ expect(getResponse.statusCode).toEqual(200);
67
+ expect(getResponse.body.title).toEqual('Inception');
68
+ });
69
+ //# sourceMappingURL=api-prefix.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-prefix.test.js","sourceRoot":"","sources":["../../../test/integration/api-prefix.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UserConfig } from '../../src/config';
2
+ declare const createServer: (config?: UserConfig) => import("express-serve-static-core").Express | undefined;
3
+ export default createServer;
4
+ //# sourceMappingURL=createServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../../../test/integration/createServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAGlD,QAAA,MAAM,YAAY,YAAa,UAAU,4DAC+B,CAAA;AAExE,eAAe,YAAY,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { create } from '../../src/index';
2
+ const createServer = (config) => create({ ...(config || {}), isTesting: true }).Express;
3
+ export default createServer;
4
+ //# sourceMappingURL=createServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createServer.js","sourceRoot":"","sources":["../../../test/integration/createServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,MAAM,YAAY,GAAG,CAAC,MAAmB,EAAE,EAAE,CAC3C,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,IAAK,EAAiB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAA;AAExE,eAAe,YAAY,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=crud.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.test.d.ts","sourceRoot":"","sources":["../../../test/integration/crud.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,173 @@
1
+ import { describe, beforeEach, test, expect } from 'vitest';
2
+ import request from 'supertest';
3
+ import createServer from './createServer';
4
+ /*
5
+ Tests for a CRUD roundtrip along all supported HTTP methods.
6
+ */
7
+ describe('CRUD', () => {
8
+ // This Temba server is created with the default configuration, i.e. no config object is supplied.
9
+ const tembaServer = createServer();
10
+ const resource = '/articles/';
11
+ beforeEach(async () => {
12
+ // Delete all items.
13
+ await request(tembaServer).delete(resource);
14
+ });
15
+ test('Read, create, replace, update and delete resources', async () => {
16
+ // Initially, there are no items so a get all returns an empty array.
17
+ const getAllResponse = await request(tembaServer).get(resource);
18
+ expect(getAllResponse.status).toBe(200);
19
+ expect(getAllResponse.body.length).toBe(0);
20
+ // Initially, there are no items so a getting an id returns a 404.
21
+ const getOneResponse = await request(tembaServer).get(resource + 'id_does_not_exist');
22
+ expect(getOneResponse.status).toBe(404);
23
+ // Initially, there are no items so a replacing something by id returns a 404.
24
+ const nonExistingItem = {
25
+ id: 'id_does_not_exist',
26
+ name: 'this should fail',
27
+ };
28
+ const replaceNonExistingResponse = await request(tembaServer)
29
+ .put(resource + 'id_does_not_exist')
30
+ .send(nonExistingItem);
31
+ expect(replaceNonExistingResponse.status).toBe(404);
32
+ // Initially, there are no items so a updating something by id returns a 404.
33
+ const updateNonExistingResponse = await request(tembaServer)
34
+ .patch(resource + 'id_does_not_exist')
35
+ .send(nonExistingItem);
36
+ expect(updateNonExistingResponse.status).toBe(404);
37
+ // Initially, there are no items, but deleting an id always returns a 204 anyway.
38
+ const deleteNonExistingResponse = await request(tembaServer).delete(resource + 'id_does_not_exist');
39
+ expect(deleteNonExistingResponse.status).toBe(204);
40
+ // Check again there are still no items.
41
+ const getAllResponse2 = await request(tembaServer).get(resource);
42
+ expect(getAllResponse2.status).toBe(200);
43
+ expect(getAllResponse2.body.length).toBe(0);
44
+ // Create a new item.
45
+ const newItem = { name: 'newItem', done: false };
46
+ const createNewResponse = await request(tembaServer).post(resource).send(newItem);
47
+ const createdNewItem = createNewResponse.body;
48
+ expect(createNewResponse.status).toBe(201);
49
+ expect(createdNewItem.name).toBe('newItem');
50
+ expect(createdNewItem.done).toBe(false);
51
+ expect(createNewResponse.header.location?.endsWith(resource + createdNewItem.id)).toBe(true);
52
+ // Now there is one item. Get all items.
53
+ const getAllOneItemResponse = await request(tembaServer).get(resource);
54
+ expect(getAllOneItemResponse.status).toBe(200);
55
+ expect(getAllOneItemResponse.body.length).toBe(1);
56
+ expect(getAllOneItemResponse.body[0].name).toBe('newItem');
57
+ expect(getAllOneItemResponse.body[0].id).toBe(createdNewItem.id);
58
+ // Get one item by ID.
59
+ const getJustOneItemResponse = await request(tembaServer).get(resource + createdNewItem.id);
60
+ expect(getJustOneItemResponse.status).toBe(200);
61
+ expect(getJustOneItemResponse.body.name).toBe('newItem');
62
+ expect(getJustOneItemResponse.body.id).toBe(createdNewItem.id);
63
+ // Replace (PUT) one item by ID.
64
+ // Here we add the field "hello" and "foo", and remove the field "done"
65
+ const replacedItem = { name: 'replacedItem', hello: 'world', foo: 'bar' };
66
+ const replaceResponse = await request(tembaServer)
67
+ .put(resource + createdNewItem.id)
68
+ .send(replacedItem);
69
+ expect(replaceResponse.status).toBe(200);
70
+ expect(replaceResponse.body.name).toBe('replacedItem');
71
+ expect(replaceResponse.body.hello).toEqual('world');
72
+ expect(replaceResponse.body.foo).toEqual('bar');
73
+ expect(replaceResponse.body.done).toBeUndefined();
74
+ expect(replaceResponse.body.id).toEqual(createdNewItem.id);
75
+ // Get one item by ID.
76
+ const getJustOneReplacedItemResponse = await request(tembaServer).get(resource + createdNewItem.id);
77
+ expect(getJustOneReplacedItemResponse.status).toBe(200);
78
+ expect(getJustOneReplacedItemResponse.body.name).toBe('replacedItem');
79
+ expect(getJustOneReplacedItemResponse.body.hello).toEqual('world');
80
+ expect(getJustOneReplacedItemResponse.body.foo).toEqual('bar');
81
+ expect(getJustOneReplacedItemResponse.body.id).toBe(createdNewItem.id);
82
+ // Update (PATCH) one item by ID.
83
+ // Here we update the "name", add the "something" field, clear the "foo" field, and leave all other properties unchanged.
84
+ const updatedItem = { name: 'updatedItem', something: 'in the way', foo: null };
85
+ const updateResponse = await request(tembaServer)
86
+ .patch(resource + createdNewItem.id)
87
+ .send(updatedItem);
88
+ expect(updateResponse.status).toBe(200);
89
+ expect(updateResponse.body.name).toBe('updatedItem');
90
+ expect(updateResponse.body.hello).toEqual('world');
91
+ expect(updateResponse.body.something).toEqual('in the way');
92
+ expect(updateResponse.body.foo).toBeNull();
93
+ expect(updateResponse.body.id).toEqual(createdNewItem.id);
94
+ // Get one item by ID.
95
+ const getJustOneUpdatedItemResponse = await request(tembaServer).get(resource + createdNewItem.id);
96
+ expect(getJustOneUpdatedItemResponse.status).toBe(200);
97
+ expect(getJustOneUpdatedItemResponse.body.name).toBe('updatedItem');
98
+ expect(getJustOneUpdatedItemResponse.body.hello).toEqual('world');
99
+ expect(getJustOneUpdatedItemResponse.body.something).toEqual('in the way');
100
+ expect(getJustOneUpdatedItemResponse.body.foo).toBeNull();
101
+ expect(getJustOneUpdatedItemResponse.body.id).toBe(createdNewItem.id);
102
+ // Delete one item by ID.
103
+ const deleteResponse = await request(tembaServer).delete(resource + createdNewItem.id);
104
+ expect(deleteResponse.status).toBe(204);
105
+ // Get one item by ID.
106
+ const getJustDeletedItemResponse = await request(tembaServer).get(resource + createdNewItem.id);
107
+ expect(getJustDeletedItemResponse.status).toBe(404);
108
+ // Check there are no items anymore.
109
+ const getAllResponse3 = await request(tembaServer).get(resource);
110
+ expect(getAllResponse3.status).toBe(200);
111
+ expect(getAllResponse2.body.length).toBe(0);
112
+ });
113
+ test('When POSTing and PUTting with ID in request body, ignore ID in body', async () => {
114
+ const hardCodedIdToIgnore = 'myID';
115
+ // Initially, there are no items so a get all returns an empty array.
116
+ const getAllResponse = await request(tembaServer).get(resource);
117
+ expect(getAllResponse.status).toBe(200);
118
+ expect(getAllResponse.body.length).toBe(0);
119
+ // Create a new item, but ignore the ID in the request body.
120
+ const newItem = { id: hardCodedIdToIgnore, name: 'newItem' };
121
+ const createNewResponse = await request(tembaServer).post(resource).send(newItem);
122
+ const newCreatedItem = createNewResponse.body;
123
+ expect(createNewResponse.status).toBe(201);
124
+ expect(newCreatedItem.name).toBe('newItem');
125
+ expect(newCreatedItem.id.length).toBeGreaterThan(0);
126
+ expect(newCreatedItem.id).not.toEqual(hardCodedIdToIgnore);
127
+ // Replace one item by ID in the URI and ignore the ID in the request body.
128
+ const replacedItem = { id: hardCodedIdToIgnore, name: 'replacedItem' };
129
+ const replaceResponse = await request(tembaServer)
130
+ .put(resource + newCreatedItem.id)
131
+ .send(replacedItem);
132
+ expect(replaceResponse.status).toBe(200);
133
+ expect(replaceResponse.body.name).toBe('replacedItem');
134
+ expect(replaceResponse.body.id).toEqual(newCreatedItem.id);
135
+ // Update one item by ID in the URI and ignore the ID in the request body.
136
+ const updatedItem = { id: hardCodedIdToIgnore, name: 'updatedItem' };
137
+ const updateResponse = await request(tembaServer)
138
+ .put(resource + newCreatedItem.id)
139
+ .send(updatedItem);
140
+ expect(updateResponse.status).toBe(200);
141
+ expect(updateResponse.body.name).toBe('updatedItem');
142
+ expect(updateResponse.body.id).toEqual(newCreatedItem.id);
143
+ // Now there is one item. Get all items.
144
+ const getAllOneItemResponse = await request(tembaServer).get(resource);
145
+ expect(getAllOneItemResponse.status).toBe(200);
146
+ expect(getAllOneItemResponse.body.length).toBe(1);
147
+ expect(getAllOneItemResponse.body[0].name).toBe('updatedItem');
148
+ expect(getAllOneItemResponse.body[0].id).toBe(newCreatedItem.id);
149
+ });
150
+ test('DELETE on resource URL (without ID) deletes all resources', async () => {
151
+ // Create 2 new items.
152
+ const createNewResponse1 = await request(tembaServer).post(resource).send({ name: 'item 1' });
153
+ expect(createNewResponse1.status).toBe(201);
154
+ const item1Id = createNewResponse1.body.id;
155
+ const createNewResponse2 = await request(tembaServer).post(resource).send({ name: 'item 2' });
156
+ expect(createNewResponse2.status).toBe(201);
157
+ const item2Id = createNewResponse2.body.id;
158
+ // Get all items, there should be 2.
159
+ const getAllResponse = await request(tembaServer).get(resource);
160
+ expect(getAllResponse.status).toBe(200);
161
+ expect(getAllResponse.body.length).toBe(2);
162
+ expect(getAllResponse.body[0].id).toBe(item1Id);
163
+ expect(getAllResponse.body[1].id).toBe(item2Id);
164
+ // Delete all items with a DELETE call on the resource URL instead of an ID.
165
+ const deleteResponse = await request(tembaServer).delete(resource);
166
+ expect(deleteResponse.status).toBe(204);
167
+ // Get all items, there should be 0.
168
+ const getAllResponse2 = await request(tembaServer).get(resource);
169
+ expect(getAllResponse2.status).toBe(200);
170
+ expect(getAllResponse2.body.length).toBe(0);
171
+ });
172
+ });
173
+ //# sourceMappingURL=crud.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.test.js","sourceRoot":"","sources":["../../../test/integration/crud.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC3D,OAAO,OAAO,MAAM,WAAW,CAAA;AAC/B,OAAO,YAAY,MAAM,gBAAgB,CAAA;AAEzC;;EAEE;AAEF,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,kGAAkG;IAClG,MAAM,WAAW,GAAG,YAAY,EAAE,CAAA;IAElC,MAAM,QAAQ,GAAG,YAAY,CAAA;IAE7B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,oBAAoB;QACpB,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,qEAAqE;QACrE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC/D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1C,kEAAkE;QAClE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,mBAAmB,CAAC,CAAA;QACrF,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEvC,8EAA8E;QAC9E,MAAM,eAAe,GAAG;YACtB,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,kBAAkB;SACzB,CAAA;QACD,MAAM,0BAA0B,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aAC1D,GAAG,CAAC,QAAQ,GAAG,mBAAmB,CAAC;aACnC,IAAI,CAAC,eAAe,CAAC,CAAA;QACxB,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEnD,6EAA6E;QAC7E,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aACzD,KAAK,CAAC,QAAQ,GAAG,mBAAmB,CAAC;aACrC,IAAI,CAAC,eAAe,CAAC,CAAA;QACxB,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAElD,iFAAiF;QACjF,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CACjE,QAAQ,GAAG,mBAAmB,CAC/B,CAAA;QACD,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAElD,wCAAwC;QACxC,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAChE,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE3C,qBAAqB;QACrB,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;QAChD,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjF,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAA;QAC7C,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAE5F,wCAAwC;QACxC,MAAM,qBAAqB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACtE,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC9C,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC1D,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAEhE,sBAAsB;QACtB,MAAM,sBAAsB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC,CAAA;QAC3F,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC/C,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxD,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAE9D,gCAAgC;QAChC,uEAAuE;QACvE,MAAM,YAAY,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;QACzE,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aAC/C,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC;aACjC,IAAI,CAAC,YAAY,CAAC,CAAA;QAErB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACtD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACnD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAA;QACjD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAE1D,sBAAsB;QACtB,MAAM,8BAA8B,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CACnE,QAAQ,GAAG,cAAc,CAAC,EAAE,CAC7B,CAAA;QACD,MAAM,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvD,MAAM,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACrE,MAAM,CAAC,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,CAAC,8BAA8B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC9D,MAAM,CAAC,8BAA8B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAEtE,iCAAiC;QACjC,yHAAyH;QACzH,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QAC/E,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aAC9C,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC;aACnC,IAAI,CAAC,WAAW,CAAC,CAAA;QACpB,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QACpD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAC3D,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC1C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAEzD,sBAAsB;QACtB,MAAM,6BAA6B,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAClE,QAAQ,GAAG,cAAc,CAAC,EAAE,CAC7B,CAAA;QACD,MAAM,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtD,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QACnE,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACjE,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAC1E,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACzD,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAErE,yBAAyB;QACzB,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC,CAAA;QACtF,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEvC,sBAAsB;QACtB,MAAM,0BAA0B,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC,CAAA;QAC/F,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEnD,oCAAoC;QACpC,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAChE,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,mBAAmB,GAAG,MAAM,CAAA;QAElC,qEAAqE;QACrE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC/D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE1C,4DAA4D;QAC5D,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAC5D,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjF,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAA;QAC7C,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3C,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QACnD,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;QAE1D,2EAA2E;QAC3E,MAAM,YAAY,GAAG,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAA;QACtE,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aAC/C,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC;aACjC,IAAI,CAAC,YAAY,CAAC,CAAA;QACrB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACtD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAE1D,0EAA0E;QAC1E,MAAM,WAAW,GAAG,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;QACpE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;aAC9C,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC;aACjC,IAAI,CAAC,WAAW,CAAC,CAAA;QACpB,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QACpD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAEzD,wCAAwC;QACxC,MAAM,qBAAqB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACtE,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC9C,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAC9D,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,sBAAsB;QACtB,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC7F,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAA;QAC1C,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC7F,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAA;QAE1C,oCAAoC;QACpC,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC/D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/C,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAE/C,4EAA4E;QAC5E,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAClE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEvC,oCAAoC;QACpC,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAChE,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=custom-router.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-router.test.d.ts","sourceRoot":"","sources":["../../../test/integration/custom-router.test.ts"],"names":[],"mappings":""}