@event-driven-io/emmett-expressjs 0.5.1 → 0.5.3

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 (97) hide show
  1. package/dist/application.js +1 -44
  2. package/dist/application.js.map +1 -1
  3. package/dist/application.mjs +1 -44
  4. package/dist/application.mjs.map +1 -1
  5. package/dist/chunk-2IUXL747.mjs +2 -0
  6. package/dist/chunk-2IUXL747.mjs.map +1 -0
  7. package/dist/chunk-3ECNKSAE.mjs +2 -0
  8. package/dist/chunk-3ECNKSAE.mjs.map +1 -0
  9. package/dist/chunk-3KAYY7DS.js +2 -0
  10. package/dist/chunk-3KAYY7DS.js.map +1 -0
  11. package/dist/chunk-42BDHECF.mjs +2 -0
  12. package/dist/chunk-42BDHECF.mjs.map +1 -0
  13. package/dist/chunk-7H3QW2YD.js +1 -0
  14. package/dist/chunk-7H3QW2YD.js.map +1 -0
  15. package/dist/chunk-E4DZPUJH.js +2 -0
  16. package/dist/chunk-E4DZPUJH.js.map +1 -0
  17. package/dist/chunk-EOH3L533.mjs +2 -0
  18. package/dist/chunk-EOH3L533.mjs.map +1 -0
  19. package/dist/chunk-EP2RS6LY.js +2 -0
  20. package/dist/chunk-EP2RS6LY.js.map +1 -0
  21. package/dist/chunk-EQRLVM5S.js +5 -0
  22. package/dist/chunk-EQRLVM5S.js.map +1 -0
  23. package/dist/chunk-GEU24YU2.mjs +2 -0
  24. package/dist/chunk-GEU24YU2.mjs.map +1 -0
  25. package/dist/chunk-HKEQAT6F.mjs +1 -0
  26. package/dist/chunk-HKEQAT6F.mjs.map +1 -0
  27. package/dist/chunk-IGLFM4GN.js +2 -0
  28. package/dist/chunk-IGLFM4GN.js.map +1 -0
  29. package/dist/chunk-KVWDIWFZ.js +2 -0
  30. package/dist/chunk-KVWDIWFZ.js.map +1 -0
  31. package/dist/chunk-LKKTDHJJ.js +2 -0
  32. package/dist/chunk-LKKTDHJJ.js.map +1 -0
  33. package/dist/chunk-NDXUB3PP.js +2 -0
  34. package/dist/chunk-NDXUB3PP.js.map +1 -0
  35. package/dist/chunk-ODC4O4D7.mjs +5 -0
  36. package/dist/chunk-ODC4O4D7.mjs.map +1 -0
  37. package/dist/chunk-TRFPNOO7.mjs +2 -0
  38. package/dist/chunk-TRFPNOO7.mjs.map +1 -0
  39. package/dist/chunk-VK264KTU.js +2 -0
  40. package/dist/chunk-VK264KTU.js.map +1 -0
  41. package/dist/chunk-W4KU3SEX.mjs +2 -0
  42. package/dist/chunk-W4KU3SEX.mjs.map +1 -0
  43. package/dist/chunk-XGEKWN7Q.mjs +2 -0
  44. package/dist/chunk-XGEKWN7Q.mjs.map +1 -0
  45. package/dist/e2e/decider/api.js +1 -148
  46. package/dist/e2e/decider/api.js.map +1 -1
  47. package/dist/e2e/decider/api.mjs +1 -148
  48. package/dist/e2e/decider/api.mjs.map +1 -1
  49. package/dist/e2e/decider/businessLogic.js +1 -110
  50. package/dist/e2e/decider/businessLogic.js.map +1 -1
  51. package/dist/e2e/decider/businessLogic.mjs +1 -110
  52. package/dist/e2e/decider/businessLogic.mjs.map +1 -1
  53. package/dist/e2e/decider/shoppingCart.js +1 -96
  54. package/dist/e2e/decider/shoppingCart.js.map +1 -1
  55. package/dist/e2e/decider/shoppingCart.mjs +1 -96
  56. package/dist/e2e/decider/shoppingCart.mjs.map +1 -1
  57. package/dist/e2e/testing.js +1 -31
  58. package/dist/e2e/testing.js.map +1 -1
  59. package/dist/e2e/testing.mjs +1 -31
  60. package/dist/e2e/testing.mjs.map +1 -1
  61. package/dist/etag.js +1 -59
  62. package/dist/etag.js.map +1 -1
  63. package/dist/etag.mjs +1 -59
  64. package/dist/etag.mjs.map +1 -1
  65. package/dist/handler.js +1 -46
  66. package/dist/handler.js.map +1 -1
  67. package/dist/handler.mjs +1 -46
  68. package/dist/handler.mjs.map +1 -1
  69. package/dist/index.js +1 -6
  70. package/dist/index.js.map +1 -1
  71. package/dist/index.mjs +1 -6
  72. package/dist/index.mjs.map +1 -1
  73. package/dist/middlewares/problemDetailsMiddleware.js +1 -24
  74. package/dist/middlewares/problemDetailsMiddleware.js.map +1 -1
  75. package/dist/middlewares/problemDetailsMiddleware.mjs +1 -24
  76. package/dist/middlewares/problemDetailsMiddleware.mjs.map +1 -1
  77. package/dist/responses.js +1 -49
  78. package/dist/responses.js.map +1 -1
  79. package/dist/responses.mjs +1 -49
  80. package/dist/responses.mjs.map +1 -1
  81. package/dist/testing/apiE2ESpecification.js +1 -36
  82. package/dist/testing/apiE2ESpecification.js.map +1 -1
  83. package/dist/testing/apiE2ESpecification.mjs +1 -36
  84. package/dist/testing/apiE2ESpecification.mjs.map +1 -1
  85. package/dist/testing/apiSpecification.js +1 -78
  86. package/dist/testing/apiSpecification.js.map +1 -1
  87. package/dist/testing/apiSpecification.mjs +1 -78
  88. package/dist/testing/apiSpecification.mjs.map +1 -1
  89. package/dist/testing/index.js +1 -2
  90. package/dist/testing/index.js.map +1 -1
  91. package/dist/testing/index.mjs +1 -2
  92. package/dist/testing/index.mjs.map +1 -1
  93. package/dist/testing/utils.js +1 -31
  94. package/dist/testing/utils.js.map +1 -1
  95. package/dist/testing/utils.mjs +1 -31
  96. package/dist/testing/utils.mjs.map +1 -1
  97. package/package.json +13 -1
@@ -1,45 +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(); } }var _express = require('express'); var _express2 = _interopRequireDefault(_express);
2
- require('express-async-errors');
3
- var _http = require('http'); var _http2 = _interopRequireDefault(_http);
4
- var _problemDetailsMiddleware = require('./middlewares/problemDetailsMiddleware');
5
- const getApplication = (options) => {
6
- const app = _express2.default.call(void 0, );
7
- const {
8
- apis,
9
- mapError,
10
- enableDefaultExpressEtag,
11
- disableJsonMiddleware,
12
- disableUrlEncodingMiddleware,
13
- disableProblemDetailsMiddleware
14
- } = options;
15
- const router = _express.Router.call(void 0, );
16
- app.set("etag", _nullishCoalesce(enableDefaultExpressEtag, () => ( false)));
17
- if (!disableJsonMiddleware)
18
- app.use(_express2.default.json());
19
- if (!disableUrlEncodingMiddleware)
20
- app.use(
21
- _express2.default.urlencoded({
22
- extended: true
23
- })
24
- );
25
- for (const api of apis) {
26
- api(router);
27
- }
28
- app.use(router);
29
- if (!disableProblemDetailsMiddleware)
30
- app.use(_problemDetailsMiddleware.problemDetailsMiddleware.call(void 0, mapError));
31
- return app;
32
- };
33
- const startAPI = (app, options = { port: 3e3 }) => {
34
- const { port } = options;
35
- const server = _http2.default.createServer(app);
36
- server.on("listening", () => {
37
- console.info("server up listening");
38
- });
39
- return server.listen(port);
40
- };
41
-
42
-
43
-
44
- exports.getApplication = getApplication; exports.startAPI = startAPI;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkIGLFM4GNjs = require('./chunk-IGLFM4GN.js');require('./chunk-7H3QW2YD.js');require('./chunk-VK264KTU.js');require('./chunk-LKKTDHJJ.js');require('./chunk-KVWDIWFZ.js');require('./chunk-NDXUB3PP.js');require('./chunk-E4DZPUJH.js');require('./chunk-EQRLVM5S.js');exports.getApplication = _chunkIGLFM4GNjs.o; exports.startAPI = _chunkIGLFM4GNjs.p;
45
2
  //# sourceMappingURL=application.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/application.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,cAAgC;AAClD,OAAO;AACP,OAAO,UAAU;AACjB,SAAS,gCAAgC;AAgBlC,MAAM,iBAAiB,CAAC,YAAgC;AAC7D,QAAM,MAAmB,QAAQ;AAEjC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,SAAS,OAAO;AAItB,MAAI,IAAI,QAAQ,4BAA4B,KAAK;AAGjD,MAAI,CAAC;AAAuB,QAAI,IAAI,QAAQ,KAAK,CAAC;AAGlD,MAAI,CAAC;AACH,QAAI;AAAA,MACF,QAAQ,WAAW;AAAA,QACjB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEF,aAAW,OAAO,MAAM;AACtB,QAAI,MAAM;AAAA,EACZ;AACA,MAAI,IAAI,MAAM;AAGd,MAAI,CAAC;AACH,QAAI,IAAI,yBAAyB,QAAQ,CAAC;AAE5C,SAAO;AACT;AAMO,MAAM,WAAW,CACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;AACH,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,SAAS,KAAK,aAAa,GAAG;AAEpC,SAAO,GAAG,aAAa,MAAM;AAC3B,YAAQ,KAAK,qBAAqB;AAAA,EACpC,CAAC;AAED,SAAO,OAAO,OAAO,IAAI;AAC3B","sourcesContent":["import express, { Router, type Application } from 'express';\nimport 'express-async-errors';\nimport http from 'http';\nimport { problemDetailsMiddleware } from './middlewares/problemDetailsMiddleware';\nimport type { ErrorToProblemDetailsMapping } from './responses';\n\n// #region web-api-setup\nexport type WebApiSetup = (router: Router) => void;\n// #endregion web-api-setup\n\nexport type ApplicationOptions = {\n apis: WebApiSetup[];\n mapError?: ErrorToProblemDetailsMapping;\n enableDefaultExpressEtag?: boolean;\n disableJsonMiddleware?: boolean;\n disableUrlEncodingMiddleware?: boolean;\n disableProblemDetailsMiddleware?: boolean;\n};\n\nexport const getApplication = (options: ApplicationOptions) => {\n const app: Application = express();\n\n const {\n apis,\n mapError,\n enableDefaultExpressEtag,\n disableJsonMiddleware,\n disableUrlEncodingMiddleware,\n disableProblemDetailsMiddleware,\n } = options;\n\n const router = Router();\n\n // disabling default etag behaviour\n // to use etags in if-match and if-not-match headers\n app.set('etag', enableDefaultExpressEtag ?? false);\n\n // add json middleware\n if (!disableJsonMiddleware) app.use(express.json());\n\n // enable url encoded urls and bodies\n if (!disableUrlEncodingMiddleware)\n app.use(\n express.urlencoded({\n extended: true,\n }),\n );\n\n for (const api of apis) {\n api(router);\n }\n app.use(router);\n\n // add problem details middleware\n if (!disableProblemDetailsMiddleware)\n app.use(problemDetailsMiddleware(mapError));\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = (\n app: Application,\n options: StartApiOptions = { port: 3000 },\n) => {\n const { port } = options;\n const server = http.createServer(app);\n\n server.on('listening', () => {\n console.info('server up listening');\n });\n\n return server.listen(port);\n};\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":""}
@@ -1,45 +1,2 @@
1
- import express, { Router } from "express";
2
- import "express-async-errors";
3
- import http from "http";
4
- import { problemDetailsMiddleware } from "./middlewares/problemDetailsMiddleware";
5
- const getApplication = (options) => {
6
- const app = express();
7
- const {
8
- apis,
9
- mapError,
10
- enableDefaultExpressEtag,
11
- disableJsonMiddleware,
12
- disableUrlEncodingMiddleware,
13
- disableProblemDetailsMiddleware
14
- } = options;
15
- const router = Router();
16
- app.set("etag", enableDefaultExpressEtag ?? false);
17
- if (!disableJsonMiddleware)
18
- app.use(express.json());
19
- if (!disableUrlEncodingMiddleware)
20
- app.use(
21
- express.urlencoded({
22
- extended: true
23
- })
24
- );
25
- for (const api of apis) {
26
- api(router);
27
- }
28
- app.use(router);
29
- if (!disableProblemDetailsMiddleware)
30
- app.use(problemDetailsMiddleware(mapError));
31
- return app;
32
- };
33
- const startAPI = (app, options = { port: 3e3 }) => {
34
- const { port } = options;
35
- const server = http.createServer(app);
36
- server.on("listening", () => {
37
- console.info("server up listening");
38
- });
39
- return server.listen(port);
40
- };
41
- export {
42
- getApplication,
43
- startAPI
44
- };
1
+ import{o as a,p as b}from"./chunk-TRFPNOO7.mjs";import"./chunk-HKEQAT6F.mjs";import"./chunk-2IUXL747.mjs";import"./chunk-W4KU3SEX.mjs";import"./chunk-42BDHECF.mjs";import"./chunk-3ECNKSAE.mjs";import"./chunk-GEU24YU2.mjs";import"./chunk-ODC4O4D7.mjs";export{a as getApplication,b as startAPI};
45
2
  //# sourceMappingURL=application.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/application.ts"],"sourcesContent":["import express, { Router, type Application } from 'express';\nimport 'express-async-errors';\nimport http from 'http';\nimport { problemDetailsMiddleware } from './middlewares/problemDetailsMiddleware';\nimport type { ErrorToProblemDetailsMapping } from './responses';\n\n// #region web-api-setup\nexport type WebApiSetup = (router: Router) => void;\n// #endregion web-api-setup\n\nexport type ApplicationOptions = {\n apis: WebApiSetup[];\n mapError?: ErrorToProblemDetailsMapping;\n enableDefaultExpressEtag?: boolean;\n disableJsonMiddleware?: boolean;\n disableUrlEncodingMiddleware?: boolean;\n disableProblemDetailsMiddleware?: boolean;\n};\n\nexport const getApplication = (options: ApplicationOptions) => {\n const app: Application = express();\n\n const {\n apis,\n mapError,\n enableDefaultExpressEtag,\n disableJsonMiddleware,\n disableUrlEncodingMiddleware,\n disableProblemDetailsMiddleware,\n } = options;\n\n const router = Router();\n\n // disabling default etag behaviour\n // to use etags in if-match and if-not-match headers\n app.set('etag', enableDefaultExpressEtag ?? false);\n\n // add json middleware\n if (!disableJsonMiddleware) app.use(express.json());\n\n // enable url encoded urls and bodies\n if (!disableUrlEncodingMiddleware)\n app.use(\n express.urlencoded({\n extended: true,\n }),\n );\n\n for (const api of apis) {\n api(router);\n }\n app.use(router);\n\n // add problem details middleware\n if (!disableProblemDetailsMiddleware)\n app.use(problemDetailsMiddleware(mapError));\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = (\n app: Application,\n options: StartApiOptions = { port: 3000 },\n) => {\n const { port } = options;\n const server = http.createServer(app);\n\n server.on('listening', () => {\n console.info('server up listening');\n });\n\n return server.listen(port);\n};\n"],"mappings":"AAAA,OAAO,WAAW,cAAgC;AAClD,OAAO;AACP,OAAO,UAAU;AACjB,SAAS,gCAAgC;AAgBlC,MAAM,iBAAiB,CAAC,YAAgC;AAC7D,QAAM,MAAmB,QAAQ;AAEjC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,SAAS,OAAO;AAItB,MAAI,IAAI,QAAQ,4BAA4B,KAAK;AAGjD,MAAI,CAAC;AAAuB,QAAI,IAAI,QAAQ,KAAK,CAAC;AAGlD,MAAI,CAAC;AACH,QAAI;AAAA,MACF,QAAQ,WAAW;AAAA,QACjB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEF,aAAW,OAAO,MAAM;AACtB,QAAI,MAAM;AAAA,EACZ;AACA,MAAI,IAAI,MAAM;AAGd,MAAI,CAAC;AACH,QAAI,IAAI,yBAAyB,QAAQ,CAAC;AAE5C,SAAO;AACT;AAMO,MAAM,WAAW,CACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;AACH,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,SAAS,KAAK,aAAa,GAAG;AAEpC,SAAO,GAAG,aAAa,MAAM;AAC3B,YAAQ,KAAK,qBAAqB;AAAA,EACpC,CAAC;AAED,SAAO,OAAO,OAAO,IAAI;AAC3B;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,2 @@
1
+ import{a as s}from"./chunk-42BDHECF.mjs";import r from"supertest";import u from"assert";var v={for:(o,i)=>(...n)=>{let p=s(o()),t=i(p);return{when:a=>{let c=async()=>{for(let e of n)await e(r(t));return a(r(t))};return{then:async e=>{let f=await c();e.forEach(m=>{m(f)===!1&&u.fail()})}}}}}};export{v as a};
2
+ //# sourceMappingURL=chunk-2IUXL747.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/apiE2ESpecification.ts"],"sourcesContent":["import type { Test } from 'supertest';\nimport supertest, { type Response } from 'supertest';\nimport type TestAgent from 'supertest/lib/agent';\n\nimport type {\n DefaultStreamVersionType,\n EventStore,\n} from '@event-driven-io/emmett';\nimport assert from 'assert';\nimport type { Application } from 'express';\nimport { WrapEventStore } from './utils';\n\nexport type E2EResponseAssert = (response: Response) => boolean | void;\n\nexport type ApiE2ESpecificationAssert = [E2EResponseAssert];\n\nexport type ApiE2ESpecification = (\n ...givenRequests: ((request: TestAgent<supertest.Test>) => Test)[]\n) => {\n when: (setupRequest: (request: TestAgent<supertest.Test>) => Test) => {\n then: (verify: ApiE2ESpecificationAssert) => Promise<void>;\n };\n};\n\nexport const ApiE2ESpecification = {\n for: <StreamVersion = DefaultStreamVersionType>(\n getEventStore: () => EventStore<StreamVersion>,\n getApplication: (eventStore: EventStore<StreamVersion>) => Application,\n ): ApiE2ESpecification => {\n {\n return (\n ...givenRequests: ((request: TestAgent<supertest.Test>) => Test)[]\n ) => {\n const eventStore = WrapEventStore(getEventStore());\n const application = getApplication(eventStore);\n\n return {\n when: (\n setupRequest: (request: TestAgent<supertest.Test>) => Test,\n ) => {\n const handle = async () => {\n for (const requestFn of givenRequests) {\n await requestFn(supertest(application));\n }\n\n return setupRequest(supertest(application));\n };\n\n return {\n then: async (\n verify: ApiE2ESpecificationAssert,\n ): Promise<void> => {\n const response = await handle();\n\n verify.forEach((assertion) => {\n const succeeded = assertion(response);\n\n if (succeeded === false) assert.fail();\n });\n },\n };\n },\n };\n };\n }\n },\n};\n"],"mappings":"yCACA,OAAOA,MAAkC,YAOzC,OAAOC,MAAY,SAgBZ,IAAMC,EAAsB,CACjC,IAAK,CACHC,EACAC,IAGS,IACFC,IACA,CACH,IAAMC,EAAaC,EAAeJ,EAAc,CAAC,EAC3CK,EAAcJ,EAAeE,CAAU,EAE7C,MAAO,CACL,KACEG,GACG,CACH,IAAMC,EAAS,SAAY,CACzB,QAAWC,KAAaN,EACtB,MAAMM,EAAUC,EAAUJ,CAAW,CAAC,EAGxC,OAAOC,EAAaG,EAAUJ,CAAW,CAAC,CAC5C,EAEA,MAAO,CACL,KAAM,MACJK,GACkB,CAClB,IAAMC,EAAW,MAAMJ,EAAO,EAE9BG,EAAO,QAASE,GAAc,CACVA,EAAUD,CAAQ,IAElB,IAAOE,EAAO,KAAK,CACvC,CAAC,CACH,CACF,CACF,CACF,CACF,CAGN","names":["supertest","assert","ApiE2ESpecification","getEventStore","getApplication","givenRequests","eventStore","WrapEventStore","application","setupRequest","handle","requestFn","supertest","verify","response","assertion","assert"]}
@@ -0,0 +1,2 @@
1
+ import{i as r}from"./chunk-GEU24YU2.mjs";import"express";import{ProblemDocument as a}from"http-problem-details";var l={},m={problemDetails:"Error occured!"},R=(t,{createdId:e,urlPrefix:o,eTag:p})=>i(t,201,{location:`${o??t.req.url}/${e}`,body:{id:e},eTag:p}),H=(t,e)=>i(t,202,e),i=(t,e,o)=>{let{location:p,body:s,eTag:n}=o??l;n&&r(t,n),p&&t.setHeader("Location",p),s?(t.statusCode=e,t.send(s)):t.sendStatus(e)},O=(t,e,o)=>{o=o??m;let{location:p,eTag:s}=o,n="problem"in o?o.problem:new a({detail:o.problemDetails,status:e});s&&r(t,s),p&&t.setHeader("Location",p),t.setHeader("Content-Type","application/problem+json"),t.statusCode=e,t.json(n)};export{l as a,m as b,R as c,H as d,i as e,O as f};
2
+ //# sourceMappingURL=chunk-3ECNKSAE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/responses.ts"],"sourcesContent":["import { type Request, type Response } from 'express';\nimport { ProblemDocument } from 'http-problem-details';\nimport { setETag, type ETag } from './etag';\n\nexport type ErrorToProblemDetailsMapping = (\n error: Error,\n request: Request,\n) => ProblemDocument | undefined;\n\nexport type HttpResponseOptions = {\n body?: unknown;\n location?: string;\n eTag?: ETag;\n};\nexport const DefaultHttpResponseOptions: HttpResponseOptions = {};\n\nexport type HttpProblemResponseOptions = {\n location?: string;\n eTag?: ETag;\n} & Omit<HttpResponseOptions, 'body'> &\n (\n | {\n problem: ProblemDocument;\n }\n | { problemDetails: string }\n );\nexport const DefaultHttpProblemResponseOptions: HttpProblemResponseOptions = {\n problemDetails: 'Error occured!',\n};\n\nexport type CreatedHttpResponseOptions = {\n createdId: string;\n urlPrefix?: string;\n} & HttpResponseOptions;\n\nexport const sendCreated = (\n response: Response,\n { createdId, urlPrefix, eTag }: CreatedHttpResponseOptions,\n): void =>\n send(response, 201, {\n location: `${urlPrefix ?? response.req.url}/${createdId}`,\n body: { id: createdId },\n eTag,\n });\n\nexport type AcceptedHttpResponseOptions = {\n location: string;\n} & HttpResponseOptions;\n\nexport const sendAccepted = (\n response: Response,\n options: AcceptedHttpResponseOptions,\n): void => send(response, 202, options);\n\nexport type NoContentHttpResponseOptions = Omit<HttpResponseOptions, 'body'>;\n\nexport const send = (\n response: Response,\n statusCode: number,\n options?: HttpResponseOptions,\n): void => {\n const { location, body, eTag } = options ?? DefaultHttpResponseOptions;\n // HEADERS\n if (eTag) setETag(response, eTag);\n if (location) response.setHeader('Location', location);\n\n if (body) {\n response.statusCode = statusCode;\n response.send(body);\n } else {\n response.sendStatus(statusCode);\n }\n};\n\nexport const sendProblem = (\n response: Response,\n statusCode: number,\n options?: HttpProblemResponseOptions,\n): void => {\n options = options ?? DefaultHttpProblemResponseOptions;\n\n const { location, eTag } = options;\n\n const problemDetails =\n 'problem' in options\n ? options.problem\n : new ProblemDocument({\n detail: options.problemDetails,\n status: statusCode,\n });\n\n // HEADERS\n if (eTag) setETag(response, eTag);\n if (location) response.setHeader('Location', location);\n\n response.setHeader('Content-Type', 'application/problem+json');\n\n response.statusCode = statusCode;\n response.json(problemDetails);\n};\n"],"mappings":"yCAAA,MAA4C,UAC5C,OAAS,mBAAAA,MAAuB,uBAazB,IAAMC,EAAkD,CAAC,EAYnDC,EAAgE,CAC3E,eAAgB,gBAClB,EAOaC,EAAc,CACzBC,EACA,CAAE,UAAAC,EAAW,UAAAC,EAAW,KAAAC,CAAK,IAE7BC,EAAKJ,EAAU,IAAK,CAClB,SAAU,GAAGE,GAAaF,EAAS,IAAI,GAAG,IAAIC,CAAS,GACvD,KAAM,CAAE,GAAIA,CAAU,EACtB,KAAAE,CACF,CAAC,EAMUE,EAAe,CAC1BL,EACAM,IACSF,EAAKJ,EAAU,IAAKM,CAAO,EAIzBF,EAAO,CAClBJ,EACAO,EACAD,IACS,CACT,GAAM,CAAE,SAAAE,EAAU,KAAAC,EAAM,KAAAN,CAAK,EAAIG,GAAWT,EAExCM,GAAMO,EAAQV,EAAUG,CAAI,EAC5BK,GAAUR,EAAS,UAAU,WAAYQ,CAAQ,EAEjDC,GACFT,EAAS,WAAaO,EACtBP,EAAS,KAAKS,CAAI,GAElBT,EAAS,WAAWO,CAAU,CAElC,EAEaI,EAAc,CACzBX,EACAO,EACAD,IACS,CACTA,EAAUA,GAAWR,EAErB,GAAM,CAAE,SAAAU,EAAU,KAAAL,CAAK,EAAIG,EAErBM,EACJ,YAAaN,EACTA,EAAQ,QACR,IAAIO,EAAgB,CAClB,OAAQP,EAAQ,eAChB,OAAQC,CACV,CAAC,EAGHJ,GAAMO,EAAQV,EAAUG,CAAI,EAC5BK,GAAUR,EAAS,UAAU,WAAYQ,CAAQ,EAErDR,EAAS,UAAU,eAAgB,0BAA0B,EAE7DA,EAAS,WAAaO,EACtBP,EAAS,KAAKY,CAAc,CAC9B","names":["ProblemDocument","DefaultHttpResponseOptions","DefaultHttpProblemResponseOptions","sendCreated","response","createdId","urlPrefix","eTag","send","sendAccepted","options","statusCode","location","body","setETag","sendProblem","problemDetails","ProblemDocument"]}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkEQRLVM5Sjs = require('./chunk-EQRLVM5S.js');var o=(n=>(n.Empty="Empty",n.Pending="Pending",n.Confirmed="Confirmed",n.Canceled="Canceled",n))(o||{}),c= exports.b ={status:"Empty"},a= exports.c =(e,{type:i,data:r})=>{switch(i){case"ShoppingCartOpened":return{id:r.shoppingCartId,clientId:r.clientId,openedAt:r.openedAt,productItems:[],status:"Pending"};case"ProductItemAddedToShoppingCart":{if(e.status!=="Pending")return e;let{productItems:d}=e,{productItem:n}=r;return{...e,productItems:_chunkEQRLVM5Sjs.i.call(void 0, d,n,t=>t.productId===n.productId&&t.unitPrice===n.unitPrice,t=>({...t,quantity:t.quantity+n.quantity}),()=>n)}}case"ProductItemRemovedFromShoppingCart":{if(e.status!=="Pending")return e;let{productItems:d}=e,{productItem:n}=r;return{...e,productItems:_chunkEQRLVM5Sjs.i.call(void 0, d,n,t=>t.productId===n.productId&&t.unitPrice===n.unitPrice,t=>({...t,quantity:t.quantity-n.quantity}))}}case"ShoppingCartConfirmed":return e.status!=="Pending"?e:{...e,status:"Confirmed",confirmedAt:r.confirmedAt};case"ShoppingCartCanceled":return e.status!=="Pending"?e:{...e,status:"Canceled",canceledAt:r.canceledAt}}},s= exports.d =e=>e.reduce(a,c),u= exports.e =(t=>(t.CART_IS_ALREADY_CLOSED="CART_IS_ALREADY_CLOSED",t.PRODUCT_ITEM_NOT_FOUND="PRODUCT_ITEM_NOT_FOUND",t.CART_IS_EMPTY="CART_IS_EMPTY",t.UNKNOWN_EVENT_TYPE="UNKNOWN_EVENT_TYPE",t.UNKNOWN_COMMAND_TYPE="UNKNOWN_COMMAND_TYPE",t))(u||{});exports.a = o; exports.b = c; exports.c = a; exports.d = s; exports.e = u;
2
+ //# sourceMappingURL=chunk-3KAYY7DS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/e2e/decider/shoppingCart.ts"],"names":["ShoppingCartStatus","emptyShoppingCart","evolve","state","type","event","productItems","productItem","merge","p","getShoppingCart","events","ShoppingCartErrors"],"mappings":"wCAiDO,IAAKA,OACVA,EAAA,MAAQ,QACRA,EAAA,QAAU,UACVA,EAAA,UAAY,YACZA,EAAA,SAAW,WAJDA,OAAA,IAmCCC,EAA2B,CAAE,OAAQ,OAAyB,EAE9DC,EAAS,CACpBC,EACA,CAAE,KAAAC,EAAM,KAAMC,CAAM,IACH,CACjB,OAAQD,EAAM,CACZ,IAAK,qBACH,MAAO,CACL,GAAIC,EAAM,eACV,SAAUA,EAAM,SAChB,SAAUA,EAAM,SAChB,aAAc,CAAC,EACf,OAAQ,SACV,EACF,IAAK,iCAAkC,CACrC,GAAIF,EAAM,SAAW,UAA4B,OAAOA,EAExD,GAAM,CAAE,aAAAG,CAAa,EAAIH,EACnB,CAAE,YAAAI,CAAY,EAAIF,EAExB,MAAO,CACL,GAAGF,EACH,aAAcK,EACZF,EACAC,EACCE,GACCA,EAAE,YAAcF,EAAY,WAC5BE,EAAE,YAAcF,EAAY,UAC7BE,IACQ,CACL,GAAGA,EACH,SAAUA,EAAE,SAAWF,EAAY,QACrC,GAEF,IAAMA,CACR,CACF,CACF,CACA,IAAK,qCAAsC,CACzC,GAAIJ,EAAM,SAAW,UAA4B,OAAOA,EAExD,GAAM,CAAE,aAAAG,CAAa,EAAIH,EACnB,CAAE,YAAAI,CAAY,EAAIF,EACxB,MAAO,CACL,GAAGF,EACH,aAAcK,EACZF,EACAC,EACCE,GACCA,EAAE,YAAcF,EAAY,WAC5BE,EAAE,YAAcF,EAAY,UAC7BE,IACQ,CACL,GAAGA,EACH,SAAUA,EAAE,SAAWF,EAAY,QACrC,EAEJ,CACF,CACF,CACA,IAAK,wBACH,OAAIJ,EAAM,SAAW,UAAmCA,EAEjD,CACL,GAAGA,EACH,OAAQ,YACR,YAAaE,EAAM,WACrB,EACF,IAAK,uBACH,OAAIF,EAAM,SAAW,UAAmCA,EAEjD,CACL,GAAGA,EACH,OAAQ,WACR,WAAYE,EAAM,UACpB,CACJ,CACF,EAEaK,EAAmBC,GACvBA,EAAO,OAAqBT,EAAQD,CAAiB,EAG5CW,OAChBA,EAAA,uBAAyB,yBACzBA,EAAA,uBAAyB,yBACzBA,EAAA,cAAgB,gBAChBA,EAAA,mBAAqB,qBACrBA,EAAA,qBAAuB,uBALPA,OAAA","sourcesContent":["import { merge } from '@event-driven-io/emmett';\n\nexport interface ProductItem {\n productId: string;\n quantity: number;\n}\n\nexport type PricedProductItem = ProductItem & {\n unitPrice: number;\n};\n\nexport type ShoppingCartEvent =\n | {\n type: 'ShoppingCartOpened';\n data: {\n shoppingCartId: string;\n clientId: string;\n openedAt: Date;\n };\n }\n | {\n type: 'ProductItemAddedToShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n }\n | {\n type: 'ProductItemRemovedFromShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n }\n | {\n type: 'ShoppingCartConfirmed';\n data: {\n shoppingCartId: string;\n confirmedAt: Date;\n };\n }\n | {\n type: 'ShoppingCartCanceled';\n data: {\n shoppingCartId: string;\n canceledAt: Date;\n };\n };\n\nexport enum ShoppingCartStatus {\n Empty = 'Empty',\n Pending = 'Pending',\n Confirmed = 'Confirmed',\n Canceled = 'Canceled',\n}\n\nexport type Empty = { status: ShoppingCartStatus.Empty };\n\nexport type Pending = {\n status: ShoppingCartStatus.Pending;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n openedAt: Date;\n};\n\nexport type Confirmed = {\n status: ShoppingCartStatus.Confirmed;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n confirmedAt: Date;\n};\n\nexport type Canceled = {\n status: ShoppingCartStatus.Canceled;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n canceledAt: Date;\n};\n\nexport type ShoppingCart = Empty | Pending | Confirmed | Canceled;\n\nexport const emptyShoppingCart: Empty = { status: ShoppingCartStatus.Empty };\n\nexport const evolve = (\n state: ShoppingCart,\n { type, data: event }: ShoppingCartEvent,\n): ShoppingCart => {\n switch (type) {\n case 'ShoppingCartOpened':\n return {\n id: event.shoppingCartId,\n clientId: event.clientId,\n openedAt: event.openedAt,\n productItems: [],\n status: ShoppingCartStatus.Pending,\n };\n case 'ProductItemAddedToShoppingCart': {\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n const { productItems } = state;\n const { productItem } = event;\n\n return {\n ...state,\n productItems: merge(\n productItems,\n productItem,\n (p) =>\n p.productId === productItem.productId &&\n p.unitPrice === productItem.unitPrice,\n (p) => {\n return {\n ...p,\n quantity: p.quantity + productItem.quantity,\n };\n },\n () => productItem,\n ),\n };\n }\n case 'ProductItemRemovedFromShoppingCart': {\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n const { productItems } = state;\n const { productItem } = event;\n return {\n ...state,\n productItems: merge(\n productItems,\n productItem,\n (p) =>\n p.productId === productItem.productId &&\n p.unitPrice === productItem.unitPrice,\n (p) => {\n return {\n ...p,\n quantity: p.quantity - productItem.quantity,\n };\n },\n ),\n };\n }\n case 'ShoppingCartConfirmed':\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n return {\n ...state,\n status: ShoppingCartStatus.Confirmed,\n confirmedAt: event.confirmedAt,\n };\n case 'ShoppingCartCanceled':\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n return {\n ...state,\n status: ShoppingCartStatus.Canceled,\n canceledAt: event.canceledAt,\n };\n }\n};\n\nexport const getShoppingCart = (events: ShoppingCartEvent[]): ShoppingCart => {\n return events.reduce<ShoppingCart>(evolve, emptyShoppingCart);\n};\n\nexport const enum ShoppingCartErrors {\n CART_IS_ALREADY_CLOSED = 'CART_IS_ALREADY_CLOSED',\n PRODUCT_ITEM_NOT_FOUND = 'PRODUCT_ITEM_NOT_FOUND',\n CART_IS_EMPTY = 'CART_IS_EMPTY',\n UNKNOWN_EVENT_TYPE = 'UNKNOWN_EVENT_TYPE',\n UNKNOWN_COMMAND_TYPE = 'UNKNOWN_COMMAND_TYPE',\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var o=r=>{let n=new Map;return{async aggregateStream(e,t){return r.aggregateStream(e,t)},readStream(e,t){return r.readStream(e,t)},appendToStream:async(e,t,a)=>{let s=await r.appendToStream(e,t,a),p=n.get(e)??[e,[]];return n.set(e,[e,[...p[1],...t]]),s},appendedEvents:n,setup:async(e,t)=>r.appendToStream(e,t)}};export{o as a};
2
+ //# sourceMappingURL=chunk-42BDHECF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/utils.ts"],"sourcesContent":["import type {\n AggregateStreamOptions,\n AggregateStreamResult,\n AppendToStreamOptions,\n AppendToStreamResult,\n DefaultStreamVersionType,\n Event,\n EventStore,\n ReadStreamOptions,\n ReadStreamResult,\n} from '@event-driven-io/emmett';\n\nexport type TestEventStream<EventType extends Event = Event> = [\n string,\n EventType[],\n];\n\nexport const WrapEventStore = <StreamVersion = DefaultStreamVersionType>(\n eventStore: EventStore<StreamVersion>,\n): EventStore<StreamVersion> & {\n appendedEvents: Map<string, TestEventStream>;\n setup<EventType extends Event>(\n streamName: string,\n events: EventType[],\n ): Promise<AppendToStreamResult<StreamVersion>>;\n} => {\n const appendedEvents = new Map<string, TestEventStream>();\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType, StreamVersion>,\n ): Promise<AggregateStreamResult<State, StreamVersion> | null> {\n return eventStore.aggregateStream(streamName, options);\n },\n\n readStream<EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions<StreamVersion>,\n ): Promise<ReadStreamResult<EventType, StreamVersion>> {\n return eventStore.readStream(streamName, options);\n },\n\n appendToStream: async <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<StreamVersion>,\n ): Promise<AppendToStreamResult<StreamVersion>> => {\n const result = await eventStore.appendToStream(\n streamName,\n events,\n options,\n );\n\n const currentStream = appendedEvents.get(streamName) ?? [streamName, []];\n\n appendedEvents.set(streamName, [\n streamName,\n [...currentStream[1], ...events],\n ]);\n\n return result;\n },\n\n appendedEvents,\n\n setup: async <EventType extends Event>(\n streamName: string,\n events: EventType[],\n ): Promise<AppendToStreamResult<StreamVersion>> => {\n return eventStore.appendToStream(streamName, events);\n },\n };\n};\n"],"mappings":"AAiBO,IAAMA,EACXC,GAOG,CACH,IAAMC,EAAiB,IAAI,IAE3B,MAAO,CACL,MAAM,gBACJC,EACAC,EAC6D,CAC7D,OAAOH,EAAW,gBAAgBE,EAAYC,CAAO,CACvD,EAEA,WACED,EACAC,EACqD,CACrD,OAAOH,EAAW,WAAWE,EAAYC,CAAO,CAClD,EAEA,eAAgB,MACdD,EACAE,EACAD,IACiD,CACjD,IAAME,EAAS,MAAML,EAAW,eAC9BE,EACAE,EACAD,CACF,EAEMG,EAAgBL,EAAe,IAAIC,CAAU,GAAK,CAACA,EAAY,CAAC,CAAC,EAEvE,OAAAD,EAAe,IAAIC,EAAY,CAC7BA,EACA,CAAC,GAAGI,EAAc,CAAC,EAAG,GAAGF,CAAM,CACjC,CAAC,EAEMC,CACT,EAEA,eAAAJ,EAEA,MAAO,MACLC,EACAE,IAEOJ,EAAW,eAAeE,EAAYE,CAAM,CAEvD,CACF","names":["WrapEventStore","eventStore","appendedEvents","streamName","options","events","result","currentStream"]}
@@ -0,0 +1 @@
1
+ "use strict";//# sourceMappingURL=chunk-7H3QW2YD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var a={IF_MATCH:"if-match",IF_NOT_MATCH:"if-not-match",ETag:"etag"},s= exports.b =/W\/"(-?\d+.*)"/,n= exports.c =(r=>(r.WRONG_WEAK_ETAG_FORMAT="WRONG_WEAK_ETAG_FORMAT",r.MISSING_IF_MATCH_HEADER="MISSING_IF_MATCH_HEADER",r.MISSING_IF_NOT_MATCH_HEADER="MISSING_IF_NOT_MATCH_HEADER",r))(n||{}),g= exports.d =t=>s.test(t),E= exports.e =t=>{let e=s.exec(t);if(e===null||e.length===0)throw new Error("WRONG_WEAK_ETAG_FORMAT");return e[1]},_= exports.f =t=>`W/"${t}"`,T= exports.g =t=>{let e=t.headers[a.IF_MATCH];if(e===void 0)throw new Error("MISSING_IF_MATCH_HEADER");return e},A= exports.h =t=>{let e=t.headers[a.IF_NOT_MATCH];if(e===void 0)throw new Error("MISSING_IF_MATCH_HEADER");return Array.isArray(e)?e[0]:e},I= exports.i =(t,e)=>{t.setHeader(a.ETag,e)},i= exports.j =t=>{let e=T(t);return g(e)?E(e):e};exports.a = a; exports.b = s; exports.c = n; exports.d = g; exports.e = E; exports.f = _; exports.g = T; exports.h = A; exports.i = I; exports.j = i;
2
+ //# sourceMappingURL=chunk-E4DZPUJH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/etag.ts"],"names":["HeaderNames","WeakETagRegex","ETagErrors","isWeakETag","etag","getWeakETagValue","result","toWeakETag","value","getETagFromIfMatch","request","getETagFromIfNotMatch","setETag","response","getETagValueFromIfMatch","eTagValue"],"mappings":"AAOO,IAAMA,EAAc,CACzB,SAAU,WACV,aAAc,eACd,KAAM,MACR,EAKaC,EAAgB,iBAEXC,OAChBA,EAAA,uBAAyB,yBACzBA,EAAA,wBAA0B,0BAC1BA,EAAA,4BAA8B,8BAHdA,OAAA,IAMLC,EAAcC,GAClBH,EAAc,KAAKG,CAAc,EAG7BC,EAAoBD,GAAuB,CACtD,IAAME,EAASL,EAAc,KAAKG,CAAc,EAChD,GAAIE,IAAW,MAAQA,EAAO,SAAW,EACvC,MAAM,IAAI,MAAM,wBAAiC,EAEnD,OAAOA,EAAO,CAAC,CACjB,EAEaC,EAAcC,GAClB,MAAMA,CAAK,IAGPC,EAAsBC,GAA2B,CAC5D,IAAMN,EAAOM,EAAQ,QAAQV,EAAY,QAAQ,EAEjD,GAAII,IAAS,OACX,MAAM,IAAI,MAAM,yBAAkC,EAGpD,OAAOA,CACT,EAEaO,EAAyBD,GAA2B,CAC/D,IAAMN,EAAOM,EAAQ,QAAQV,EAAY,YAAY,EAErD,GAAII,IAAS,OACX,MAAM,IAAI,MAAM,yBAAkC,EAGpD,OAAQ,MAAM,QAAQA,CAAI,EAAIA,EAAK,CAAC,EAAIA,CAC1C,EAEaQ,EAAU,CAACC,EAAoBT,IAAqB,CAC/DS,EAAS,UAAUb,EAAY,KAAMI,CAAc,CACrD,EAEaU,EAA2BJ,GAA6B,CACnE,IAAMK,EAAkBN,EAAmBC,CAAO,EAElD,OAAOP,EAAWY,CAAS,EACvBV,EAAiBU,CAAS,EACzBA,CACP","sourcesContent":["import { type Brand } from '@event-driven-io/emmett';\nimport type { Request, Response } from 'express';\n\n//////////////////////////////////////\n/// ETAG\n//////////////////////////////////////\n\nexport const HeaderNames = {\n IF_MATCH: 'if-match',\n IF_NOT_MATCH: 'if-not-match',\n ETag: 'etag',\n};\n\nexport type WeakETag = Brand<`W/${string}`, 'ETag'>;\nexport type ETag = Brand<string, 'ETag'>;\n\nexport const WeakETagRegex = /W\\/\"(-?\\d+.*)\"/;\n\nexport const enum ETagErrors {\n WRONG_WEAK_ETAG_FORMAT = 'WRONG_WEAK_ETAG_FORMAT',\n MISSING_IF_MATCH_HEADER = 'MISSING_IF_MATCH_HEADER',\n MISSING_IF_NOT_MATCH_HEADER = 'MISSING_IF_NOT_MATCH_HEADER',\n}\n\nexport const isWeakETag = (etag: ETag): etag is WeakETag => {\n return WeakETagRegex.test(etag as string);\n};\n\nexport const getWeakETagValue = (etag: ETag): string => {\n const result = WeakETagRegex.exec(etag as string);\n if (result === null || result.length === 0) {\n throw new Error(ETagErrors.WRONG_WEAK_ETAG_FORMAT);\n }\n return result[1]!;\n};\n\nexport const toWeakETag = (value: number | bigint | string): WeakETag => {\n return `W/\"${value}\"` as WeakETag;\n};\n\nexport const getETagFromIfMatch = (request: Request): ETag => {\n const etag = request.headers[HeaderNames.IF_MATCH];\n\n if (etag === undefined) {\n throw new Error(ETagErrors.MISSING_IF_MATCH_HEADER);\n }\n\n return etag as ETag;\n};\n\nexport const getETagFromIfNotMatch = (request: Request): ETag => {\n const etag = request.headers[HeaderNames.IF_NOT_MATCH];\n\n if (etag === undefined) {\n throw new Error(ETagErrors.MISSING_IF_MATCH_HEADER);\n }\n\n return (Array.isArray(etag) ? etag[0] : etag) as ETag;\n};\n\nexport const setETag = (response: Response, etag: ETag): void => {\n response.setHeader(HeaderNames.ETag, etag as string);\n};\n\nexport const getETagValueFromIfMatch = (request: Request): string => {\n const eTagValue: ETag = getETagFromIfMatch(request);\n\n return isWeakETag(eTagValue)\n ? getWeakETagValue(eTagValue)\n : (eTagValue as string);\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import{b as C,c as d}from"./chunk-XGEKWN7Q.mjs";import{d as a,e}from"./chunk-ODC4O4D7.mjs";var S=(p=>(p.CART_ALREADY_EXISTS="CART_ALREADY_EXISTS",p.CART_IS_ALREADY_CLOSED="CART_IS_ALREADY_CLOSED",p.PRODUCT_ITEM_NOT_FOUND="PRODUCT_ITEM_NOT_FOUND",p.CART_IS_EMPTY="CART_IS_EMPTY",p.UNKNOWN_EVENT_TYPE="UNKNOWN_EVENT_TYPE",p.UNKNOWN_COMMAND_TYPE="UNKNOWN_COMMAND_TYPE",p))(S||{}),I=(o,{productId:t,quantity:r,unitPrice:n})=>{if((o.find(i=>i.productId===t&&i.unitPrice==n)?.quantity??0)<r)throw new e("PRODUCT_ITEM_NOT_FOUND")},g=({type:o,data:t},r)=>{switch(o){case"OpenShoppingCart":{if(r.status!=="Empty")throw new e("CART_ALREADY_EXISTS");return{type:"ShoppingCartOpened",data:{shoppingCartId:t.shoppingCartId,clientId:t.clientId,openedAt:t.now}}}case"AddProductItemToShoppingCart":{if(r.status!=="Pending")throw new e("CART_IS_ALREADY_CLOSED");return{type:"ProductItemAddedToShoppingCart",data:{shoppingCartId:t.shoppingCartId,productItem:t.productItem}}}case"RemoveProductItemFromShoppingCart":{if(r.status!=="Pending")throw new e("CART_IS_ALREADY_CLOSED");return I(r.productItems,t.productItem),{type:"ProductItemRemovedFromShoppingCart",data:{shoppingCartId:t.shoppingCartId,productItem:t.productItem}}}case"ConfirmShoppingCart":{if(r.status!=="Pending")throw new e("CART_IS_ALREADY_CLOSED");if(r.productItems.length===0)throw new e("CART_IS_EMPTY");return{type:"ShoppingCartConfirmed",data:{shoppingCartId:t.shoppingCartId,confirmedAt:t.now}}}case"CancelShoppingCart":{if(r.status!=="Pending")throw new e("CART_IS_ALREADY_CLOSED");return{type:"ShoppingCartCanceled",data:{shoppingCartId:t.shoppingCartId,canceledAt:t.now}}}default:{let n=t;throw new a("UNKNOWN_COMMAND_TYPE")}}},u={decide:g,evolve:d,getInitialState:()=>C};export{S as a,I as b,g as c,u as d};
2
+ //# sourceMappingURL=chunk-EOH3L533.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/e2e/decider/businessLogic.ts"],"sourcesContent":["import {\n EmmettError,\n IllegalStateError,\n type Decider,\n} from '@event-driven-io/emmett';\n\nimport {\n ShoppingCartStatus,\n emptyShoppingCart,\n evolve,\n type PricedProductItem,\n type ShoppingCart,\n type ShoppingCartEvent,\n} from './shoppingCart';\n\n//////////////////////////////////////\n/// Commands\n//////////////////////////////////////\n\nexport type OpenShoppingCart = {\n type: 'OpenShoppingCart';\n data: {\n shoppingCartId: string;\n clientId: string;\n now: Date;\n };\n};\n\nexport type AddProductItemToShoppingCart = {\n type: 'AddProductItemToShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n};\n\nexport type RemoveProductItemFromShoppingCart = {\n type: 'RemoveProductItemFromShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n};\n\nexport type ConfirmShoppingCart = {\n type: 'ConfirmShoppingCart';\n data: {\n shoppingCartId: string;\n now: Date;\n };\n};\n\nexport type CancelShoppingCart = {\n type: 'CancelShoppingCart';\n data: {\n shoppingCartId: string;\n now: Date;\n };\n};\n\nexport type ShoppingCartCommand =\n | OpenShoppingCart\n | AddProductItemToShoppingCart\n | RemoveProductItemFromShoppingCart\n | ConfirmShoppingCart\n | CancelShoppingCart;\n\n//////////////////////////////////////\n/// Decide\n//////////////////////////////////////\n\nexport const enum ShoppingCartErrors {\n CART_ALREADY_EXISTS = 'CART_ALREADY_EXISTS',\n CART_IS_ALREADY_CLOSED = 'CART_IS_ALREADY_CLOSED',\n PRODUCT_ITEM_NOT_FOUND = 'PRODUCT_ITEM_NOT_FOUND',\n CART_IS_EMPTY = 'CART_IS_EMPTY',\n UNKNOWN_EVENT_TYPE = 'UNKNOWN_EVENT_TYPE',\n UNKNOWN_COMMAND_TYPE = 'UNKNOWN_COMMAND_TYPE',\n}\n\nexport const assertProductItemExists = (\n productItems: PricedProductItem[],\n { productId, quantity, unitPrice }: PricedProductItem,\n): void => {\n const currentQuantity =\n productItems.find(\n (p) => p.productId === productId && p.unitPrice == unitPrice,\n )?.quantity ?? 0;\n\n if (currentQuantity < quantity) {\n throw new IllegalStateError(ShoppingCartErrors.PRODUCT_ITEM_NOT_FOUND);\n }\n};\n\nexport const decide = (\n { type, data: command }: ShoppingCartCommand,\n shoppingCart: ShoppingCart,\n): ShoppingCartEvent => {\n switch (type) {\n case 'OpenShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Empty) {\n throw new IllegalStateError(ShoppingCartErrors.CART_ALREADY_EXISTS);\n }\n return {\n type: 'ShoppingCartOpened',\n data: {\n shoppingCartId: command.shoppingCartId,\n clientId: command.clientId,\n openedAt: command.now,\n },\n };\n }\n\n case 'AddProductItemToShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n return {\n type: 'ProductItemAddedToShoppingCart',\n data: {\n shoppingCartId: command.shoppingCartId,\n productItem: command.productItem,\n },\n };\n }\n\n case 'RemoveProductItemFromShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n assertProductItemExists(shoppingCart.productItems, command.productItem);\n\n return {\n type: 'ProductItemRemovedFromShoppingCart',\n data: {\n shoppingCartId: command.shoppingCartId,\n productItem: command.productItem,\n },\n };\n }\n\n case 'ConfirmShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n if (shoppingCart.productItems.length === 0) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_EMPTY);\n }\n\n return {\n type: 'ShoppingCartConfirmed',\n data: {\n shoppingCartId: command.shoppingCartId,\n confirmedAt: command.now,\n },\n };\n }\n\n case 'CancelShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n return {\n type: 'ShoppingCartCanceled',\n data: {\n shoppingCartId: command.shoppingCartId,\n canceledAt: command.now,\n },\n };\n }\n default: {\n const _: never = command;\n throw new EmmettError(ShoppingCartErrors.UNKNOWN_COMMAND_TYPE);\n }\n }\n};\n\nexport const decider: Decider<\n ShoppingCart,\n ShoppingCartCommand,\n ShoppingCartEvent\n> = {\n decide,\n evolve,\n getInitialState: () => emptyShoppingCart,\n};\n"],"mappings":"2FAuEO,IAAWA,OAChBA,EAAA,oBAAsB,sBACtBA,EAAA,uBAAyB,yBACzBA,EAAA,uBAAyB,yBACzBA,EAAA,cAAgB,gBAChBA,EAAA,mBAAqB,qBACrBA,EAAA,qBAAuB,uBANPA,OAAA,IASLC,EAA0B,CACrCC,EACA,CAAE,UAAAC,EAAW,SAAAC,EAAU,UAAAC,CAAU,IACxB,CAMT,IAJEH,EAAa,KACVI,GAAMA,EAAE,YAAcH,GAAaG,EAAE,WAAaD,CACrD,GAAG,UAAY,GAEKD,EACpB,MAAM,IAAIG,EAAkB,wBAAyC,CAEzE,EAEaC,EAAS,CACpB,CAAE,KAAAC,EAAM,KAAMC,CAAQ,EACtBC,IACsB,CACtB,OAAQF,EAAM,CACZ,IAAK,mBAAoB,CACvB,GAAIE,EAAa,iBACf,MAAM,IAAIJ,EAAkB,qBAAsC,EAEpE,MAAO,CACL,KAAM,qBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,SAAUA,EAAQ,SAClB,SAAUA,EAAQ,GACpB,CACF,CACF,CAEA,IAAK,+BAAgC,CACnC,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAEvE,MAAO,CACL,KAAM,iCACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,YAAaA,EAAQ,WACvB,CACF,CACF,CAEA,IAAK,oCAAqC,CACxC,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,OAAAN,EAAwBU,EAAa,aAAcD,EAAQ,WAAW,EAE/D,CACL,KAAM,qCACN,KAAM,CACJ,eAAgBA,EAAQ,eACxB,YAAaA,EAAQ,WACvB,CACF,CACF,CAEA,IAAK,sBAAuB,CAC1B,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,GAAII,EAAa,aAAa,SAAW,EACvC,MAAM,IAAIJ,EAAkB,eAAgC,EAG9D,MAAO,CACL,KAAM,wBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,YAAaA,EAAQ,GACvB,CACF,CACF,CAEA,IAAK,qBAAsB,CACzB,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,MAAO,CACL,KAAM,uBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,WAAYA,EAAQ,GACtB,CACF,CACF,CACA,QAAS,CACP,IAAME,EAAWF,EACjB,MAAM,IAAIG,EAAY,sBAAuC,CAC/D,CACF,CACF,EAEaC,EAIT,CACF,OAAAN,EACA,OAAAO,EACA,gBAAiB,IAAMC,CACzB","names":["ShoppingCartErrors","assertProductItemExists","productItems","productId","quantity","unitPrice","p","IllegalStateError","decide","type","command","shoppingCart","_","EmmettError","decider","evolve","emptyShoppingCart"]}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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 _chunk3KAYY7DSjs = require('./chunk-3KAYY7DS.js');var _chunkEQRLVM5Sjs = require('./chunk-EQRLVM5S.js');var S=(p=>(p.CART_ALREADY_EXISTS="CART_ALREADY_EXISTS",p.CART_IS_ALREADY_CLOSED="CART_IS_ALREADY_CLOSED",p.PRODUCT_ITEM_NOT_FOUND="PRODUCT_ITEM_NOT_FOUND",p.CART_IS_EMPTY="CART_IS_EMPTY",p.UNKNOWN_EVENT_TYPE="UNKNOWN_EVENT_TYPE",p.UNKNOWN_COMMAND_TYPE="UNKNOWN_COMMAND_TYPE",p))(S||{}),I= exports.b =(o,{productId:t,quantity:r,unitPrice:n})=>{if((_nullishCoalesce(_optionalChain([o, 'access', _ => _.find, 'call', _2 => _2(i=>i.productId===t&&i.unitPrice==n), 'optionalAccess', _3 => _3.quantity]), () => (0)))<r)throw new (0, _chunkEQRLVM5Sjs.e)("PRODUCT_ITEM_NOT_FOUND")},g= exports.c =({type:o,data:t},r)=>{switch(o){case"OpenShoppingCart":{if(r.status!=="Empty")throw new (0, _chunkEQRLVM5Sjs.e)("CART_ALREADY_EXISTS");return{type:"ShoppingCartOpened",data:{shoppingCartId:t.shoppingCartId,clientId:t.clientId,openedAt:t.now}}}case"AddProductItemToShoppingCart":{if(r.status!=="Pending")throw new (0, _chunkEQRLVM5Sjs.e)("CART_IS_ALREADY_CLOSED");return{type:"ProductItemAddedToShoppingCart",data:{shoppingCartId:t.shoppingCartId,productItem:t.productItem}}}case"RemoveProductItemFromShoppingCart":{if(r.status!=="Pending")throw new (0, _chunkEQRLVM5Sjs.e)("CART_IS_ALREADY_CLOSED");return I(r.productItems,t.productItem),{type:"ProductItemRemovedFromShoppingCart",data:{shoppingCartId:t.shoppingCartId,productItem:t.productItem}}}case"ConfirmShoppingCart":{if(r.status!=="Pending")throw new (0, _chunkEQRLVM5Sjs.e)("CART_IS_ALREADY_CLOSED");if(r.productItems.length===0)throw new (0, _chunkEQRLVM5Sjs.e)("CART_IS_EMPTY");return{type:"ShoppingCartConfirmed",data:{shoppingCartId:t.shoppingCartId,confirmedAt:t.now}}}case"CancelShoppingCart":{if(r.status!=="Pending")throw new (0, _chunkEQRLVM5Sjs.e)("CART_IS_ALREADY_CLOSED");return{type:"ShoppingCartCanceled",data:{shoppingCartId:t.shoppingCartId,canceledAt:t.now}}}default:{let n=t;throw new (0, _chunkEQRLVM5Sjs.d)("UNKNOWN_COMMAND_TYPE")}}},u= exports.d ={decide:g,evolve:_chunk3KAYY7DSjs.c,getInitialState:()=>_chunk3KAYY7DSjs.b};exports.a = S; exports.b = I; exports.c = g; exports.d = u;
2
+ //# sourceMappingURL=chunk-EP2RS6LY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/e2e/decider/businessLogic.ts"],"names":["ShoppingCartErrors","assertProductItemExists","productItems","productId","quantity","unitPrice","p","IllegalStateError","decide","type","command","shoppingCart","_","EmmettError","decider","evolve","emptyShoppingCart"],"mappings":"yFAuEO,IAAWA,OAChBA,EAAA,oBAAsB,sBACtBA,EAAA,uBAAyB,yBACzBA,EAAA,uBAAyB,yBACzBA,EAAA,cAAgB,gBAChBA,EAAA,mBAAqB,qBACrBA,EAAA,qBAAuB,uBANPA,OAAA,IASLC,EAA0B,CACrCC,EACA,CAAE,UAAAC,EAAW,SAAAC,EAAU,UAAAC,CAAU,IACxB,CAMT,IAJEH,EAAa,KACVI,GAAMA,EAAE,YAAcH,GAAaG,EAAE,WAAaD,CACrD,GAAG,UAAY,GAEKD,EACpB,MAAM,IAAIG,EAAkB,wBAAyC,CAEzE,EAEaC,EAAS,CACpB,CAAE,KAAAC,EAAM,KAAMC,CAAQ,EACtBC,IACsB,CACtB,OAAQF,EAAM,CACZ,IAAK,mBAAoB,CACvB,GAAIE,EAAa,iBACf,MAAM,IAAIJ,EAAkB,qBAAsC,EAEpE,MAAO,CACL,KAAM,qBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,SAAUA,EAAQ,SAClB,SAAUA,EAAQ,GACpB,CACF,CACF,CAEA,IAAK,+BAAgC,CACnC,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAEvE,MAAO,CACL,KAAM,iCACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,YAAaA,EAAQ,WACvB,CACF,CACF,CAEA,IAAK,oCAAqC,CACxC,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,OAAAN,EAAwBU,EAAa,aAAcD,EAAQ,WAAW,EAE/D,CACL,KAAM,qCACN,KAAM,CACJ,eAAgBA,EAAQ,eACxB,YAAaA,EAAQ,WACvB,CACF,CACF,CAEA,IAAK,sBAAuB,CAC1B,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,GAAII,EAAa,aAAa,SAAW,EACvC,MAAM,IAAIJ,EAAkB,eAAgC,EAG9D,MAAO,CACL,KAAM,wBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,YAAaA,EAAQ,GACvB,CACF,CACF,CAEA,IAAK,qBAAsB,CACzB,GAAIC,EAAa,mBACf,MAAM,IAAIJ,EAAkB,wBAAyC,EAGvE,MAAO,CACL,KAAM,uBACN,KAAM,CACJ,eAAgBG,EAAQ,eACxB,WAAYA,EAAQ,GACtB,CACF,CACF,CACA,QAAS,CACP,IAAME,EAAWF,EACjB,MAAM,IAAIG,EAAY,sBAAuC,CAC/D,CACF,CACF,EAEaC,EAIT,CACF,OAAAN,EACA,OAAAO,EACA,gBAAiB,IAAMC,CACzB","sourcesContent":["import {\n EmmettError,\n IllegalStateError,\n type Decider,\n} from '@event-driven-io/emmett';\n\nimport {\n ShoppingCartStatus,\n emptyShoppingCart,\n evolve,\n type PricedProductItem,\n type ShoppingCart,\n type ShoppingCartEvent,\n} from './shoppingCart';\n\n//////////////////////////////////////\n/// Commands\n//////////////////////////////////////\n\nexport type OpenShoppingCart = {\n type: 'OpenShoppingCart';\n data: {\n shoppingCartId: string;\n clientId: string;\n now: Date;\n };\n};\n\nexport type AddProductItemToShoppingCart = {\n type: 'AddProductItemToShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n};\n\nexport type RemoveProductItemFromShoppingCart = {\n type: 'RemoveProductItemFromShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n};\n\nexport type ConfirmShoppingCart = {\n type: 'ConfirmShoppingCart';\n data: {\n shoppingCartId: string;\n now: Date;\n };\n};\n\nexport type CancelShoppingCart = {\n type: 'CancelShoppingCart';\n data: {\n shoppingCartId: string;\n now: Date;\n };\n};\n\nexport type ShoppingCartCommand =\n | OpenShoppingCart\n | AddProductItemToShoppingCart\n | RemoveProductItemFromShoppingCart\n | ConfirmShoppingCart\n | CancelShoppingCart;\n\n//////////////////////////////////////\n/// Decide\n//////////////////////////////////////\n\nexport const enum ShoppingCartErrors {\n CART_ALREADY_EXISTS = 'CART_ALREADY_EXISTS',\n CART_IS_ALREADY_CLOSED = 'CART_IS_ALREADY_CLOSED',\n PRODUCT_ITEM_NOT_FOUND = 'PRODUCT_ITEM_NOT_FOUND',\n CART_IS_EMPTY = 'CART_IS_EMPTY',\n UNKNOWN_EVENT_TYPE = 'UNKNOWN_EVENT_TYPE',\n UNKNOWN_COMMAND_TYPE = 'UNKNOWN_COMMAND_TYPE',\n}\n\nexport const assertProductItemExists = (\n productItems: PricedProductItem[],\n { productId, quantity, unitPrice }: PricedProductItem,\n): void => {\n const currentQuantity =\n productItems.find(\n (p) => p.productId === productId && p.unitPrice == unitPrice,\n )?.quantity ?? 0;\n\n if (currentQuantity < quantity) {\n throw new IllegalStateError(ShoppingCartErrors.PRODUCT_ITEM_NOT_FOUND);\n }\n};\n\nexport const decide = (\n { type, data: command }: ShoppingCartCommand,\n shoppingCart: ShoppingCart,\n): ShoppingCartEvent => {\n switch (type) {\n case 'OpenShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Empty) {\n throw new IllegalStateError(ShoppingCartErrors.CART_ALREADY_EXISTS);\n }\n return {\n type: 'ShoppingCartOpened',\n data: {\n shoppingCartId: command.shoppingCartId,\n clientId: command.clientId,\n openedAt: command.now,\n },\n };\n }\n\n case 'AddProductItemToShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n return {\n type: 'ProductItemAddedToShoppingCart',\n data: {\n shoppingCartId: command.shoppingCartId,\n productItem: command.productItem,\n },\n };\n }\n\n case 'RemoveProductItemFromShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n assertProductItemExists(shoppingCart.productItems, command.productItem);\n\n return {\n type: 'ProductItemRemovedFromShoppingCart',\n data: {\n shoppingCartId: command.shoppingCartId,\n productItem: command.productItem,\n },\n };\n }\n\n case 'ConfirmShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n if (shoppingCart.productItems.length === 0) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_EMPTY);\n }\n\n return {\n type: 'ShoppingCartConfirmed',\n data: {\n shoppingCartId: command.shoppingCartId,\n confirmedAt: command.now,\n },\n };\n }\n\n case 'CancelShoppingCart': {\n if (shoppingCart.status !== ShoppingCartStatus.Pending) {\n throw new IllegalStateError(ShoppingCartErrors.CART_IS_ALREADY_CLOSED);\n }\n\n return {\n type: 'ShoppingCartCanceled',\n data: {\n shoppingCartId: command.shoppingCartId,\n canceledAt: command.now,\n },\n };\n }\n default: {\n const _: never = command;\n throw new EmmettError(ShoppingCartErrors.UNKNOWN_COMMAND_TYPE);\n }\n }\n};\n\nexport const decider: Decider<\n ShoppingCart,\n ShoppingCartCommand,\n ShoppingCartEvent\n> = {\n decide,\n evolve,\n getInitialState: () => emptyShoppingCart,\n};\n"]}
@@ -0,0 +1,5 @@
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 p=class e extends Error{constructor(r){let s=r&&typeof r=="object"&&"errorCode"in r?r.errorCode:f(r)?r:500,t=r&&typeof r=="object"&&"message"in r?r.message:x(r)?r:`Error with status code '${s}' ocurred during Emmett processing`;super(t),this.errorCode=s,Object.setPrototypeOf(this,e.prototype)}};var u=class e extends p{constructor(r){super({errorCode:400,message:_nullishCoalesce(r, () => ("Validation Error ocurred during Emmett processing"))}),Object.setPrototypeOf(this,e.prototype)}},l= exports.e =class e extends p{constructor(r){super({errorCode:403,message:_nullishCoalesce(r, () => ("Illegal State ocurred during Emmett processing"))}),Object.setPrototypeOf(this,e.prototype)}};var m;(function(e){e.NOT_A_NONEMPTY_STRING="NOT_A_NONEMPTY_STRING",e.NOT_A_POSITIVE_NUMBER="NOT_A_POSITIVE_NUMBER",e.NOT_AN_UNSIGNED_BIGINT="NOT_AN_UNSIGNED_BIGINT"})(m||(m={}));var f=e=>typeof e=="number"&&e===e,x=e=>typeof e=="string",A= exports.a =e=>{if(!x(e)||e.length===0)throw new u(m.NOT_A_NONEMPTY_STRING);return e},b= exports.b =e=>{if(!f(e)||e<=0)throw new u(m.NOT_A_POSITIVE_NUMBER);return e},R= exports.c =e=>{let r=BigInt(e);if(r<0)throw new u(m.NOT_AN_UNSIGNED_BIGINT);return r};var N="STREAM_DOES_NOT_EXIST",E="NO_CONCURRENCY_CHECK";var _uuid = require('uuid');var h=(e,r,s=t=>t)=>async(t,n,c,a)=>{let o=s(n),i=await t.aggregateStream(o,{evolve:e,getInitialState:r,read:{expectedStreamVersion:_nullishCoalesce(_optionalChain([a, 'optionalAccess', _ => _.expectedStreamVersion]), () => (E))}}),g=_nullishCoalesce(_optionalChain([i, 'optionalAccess', _2 => _2.state]), () => (r())),O=_optionalChain([i, 'optionalAccess', _3 => _3.currentStreamVersion]),d=c(g),S=Array.isArray(d)?d:[d],T=_nullishCoalesce(_nullishCoalesce(_optionalChain([a, 'optionalAccess', _4 => _4.expectedStreamVersion]), () => (O)), () => (N));return{...await t.appendToStream(o,S,{expectedStreamVersion:T}),newState:S.reduce(e,g)}};var L=({decide:e,evolve:r,getInitialState:s},t=n=>n)=>async(n,c,a,o)=>h(r,s,t)(n,c,i=>e(a,i),o);var y=(e,r)=>{let s=e,t=r;return Object.keys(t).every(n=>typeof t[n]=="object"?y(s[n],t[n]):t[n]===s[n])},F= exports.h =(e,r)=>{if(!y(e,r))throw Error(`subObj:
2
+ ${JSON.stringify(r)}
3
+ is not subset of
4
+ ${JSON.stringify(e)}`)};var W=(e,r,s,t,n=()=>{})=>{let c=!1,a=e.map(o=>s(o)?(c=!0,t(o)):o).filter(o=>o!==void 0).map(o=>{if(!o)throw Error("That should not happen");return o});return!c&&n()!==void 0?[...e,r]:a};var _assert = require('assert'); var _assert2 = _interopRequireDefault(_assert);exports.a = A; exports.b = b; exports.c = R; exports.d = p; exports.e = l; exports.f = N; exports.g = L; exports.h = F; exports.i = W;
5
+ //# sourceMappingURL=chunk-EQRLVM5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/@event-driven-io/emmett/src/errors/index.ts","../node_modules/@event-driven-io/emmett/src/validation/index.ts","../node_modules/@event-driven-io/emmett/src/eventStore/expectedVersion.ts","../node_modules/@event-driven-io/emmett/src/eventStore/inMemoryEventStore.ts","../node_modules/@event-driven-io/emmett/src/commandHandling/handleCommand.ts","../node_modules/@event-driven-io/emmett/src/commandHandling/handleCommandWithDecider.ts","../node_modules/@event-driven-io/emmett/src/testing/assertions.ts","../node_modules/@event-driven-io/emmett/src/utils/merge.ts","../node_modules/@event-driven-io/emmett/src/testing/deciderSpecification.ts"],"names":["EmmettError","_EmmettError","options","errorCode","isNumber","message","isString","ValidationError","_ValidationError","IllegalStateError","_IllegalStateError","ValidationErrors","val","assertNotEmptyString","value","assertPositiveNumber","assertUnsignedBigInt","number","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","uuid","CommandHandler","evolve","getInitialState","mapToStreamId","id","eventStore","handle","streamName","aggregationResult","state","currentStreamVersion","result","newEvents","expectedStreamVersion","DeciderCommandHandler","decide","command","isSubset","superObj","subObj","sup","sub","ele","assertMatches","actual","expected","merge","array","item","where","onExisting","onNotFound","wasFound","p","assert"],"mappings":"AAEM,IAAOA,EAAP,MAAOC,UAAoB,KAAK,CAC7B,UAEP,YACEC,EAAmE,CAEnE,IAAMC,EACJD,GAAW,OAAOA,GAAY,UAAY,cAAeA,EACrDA,EAAQ,UACRE,EAASF,CAAO,EACdA,EACA,IACFG,EACJH,GAAW,OAAOA,GAAY,UAAY,YAAaA,EACnDA,EAAQ,QACRI,EAASJ,CAAO,EACdA,EACA,2BAA2BC,CAAS,qCAE5C,MAAME,CAAO,EACb,KAAK,UAAYF,EAGjB,OAAO,eAAe,KAAMF,EAAY,SAAS,CACnD,GAqBI,IAAOM,EAAP,MAAOC,UAAwBR,CAAW,CAC9C,YAAYK,EAAgB,CAC1B,MAAM,CACJ,UAAW,IACX,QAASA,GAAW,oDACrB,EAGD,OAAO,eAAe,KAAMG,EAAgB,SAAS,CACvD,GAGWC,EAAP,MAAOC,UAA0BV,CAAW,CAChD,YAAYK,EAAgB,CAC1B,MAAM,CACJ,UAAW,IACX,QAASA,GAAW,iDACrB,EAGD,OAAO,eAAe,KAAMK,EAAkB,SAAS,CACzD,GClEF,IAAkBC,GAAlB,SAAkBA,EAAgB,CAChCA,EAAA,sBAAA,wBACAA,EAAA,sBAAA,wBACAA,EAAA,uBAAA,wBACF,GAJkBA,IAAAA,EAAgB,CAAA,EAAA,EAM3B,IAAMP,EAAYQ,GACvB,OAAOA,GAAQ,UAAYA,IAAQA,EAExBN,EAAYM,GACvB,OAAOA,GAAQ,SAEJC,EAAwBC,GAA0B,CAC7D,GAAI,CAACR,EAASQ,CAAK,GAAKA,EAAM,SAAW,EACvC,MAAM,IAAIP,EAAgBI,EAAiB,qBAAqB,EAElE,OAAOG,CACT,EAEaC,EAAwBD,GAA0B,CAC7D,GAAI,CAACV,EAASU,CAAK,GAAKA,GAAS,EAC/B,MAAM,IAAIP,EAAgBI,EAAiB,qBAAqB,EAElE,OAAOG,CACT,EAEaE,EAAwBF,GAAyB,CAC5D,IAAMG,EAAS,OAAOH,CAAK,EAC3B,GAAIG,EAAS,EACX,MAAM,IAAIV,EAAgBI,EAAiB,sBAAsB,EAEnE,OAAOM,CACT,EChBO,IAAMC,EACX,wBACWC,EACX,uBCrBF,OAAS,MAAMC,MAAY,OCgBpB,IAAMC,EACX,CACEC,EACAC,EACAC,EAAyCC,GAAOA,IAElD,MACEC,EACAD,EACAE,EACAzB,IAGuD,CACvD,IAAM0B,EAAaJ,EAAcC,CAAE,EAG7BI,EAAoB,MAAMH,EAAW,gBAGzCE,EAAY,CACZ,OAAAN,EACA,gBAAAC,EACA,KAAM,CAGJ,sBACErB,GAAS,uBAAyBiB,GAEvC,EAGKW,EAAQD,GAAmB,OAASN,EAAe,EACnDQ,EAAuBF,GAAmB,qBAG1CG,EAASL,EAAOG,CAAK,EAErBG,EAAY,MAAM,QAAQD,CAAM,EAAIA,EAAS,CAACA,CAAM,EAMpDE,EACJhC,GAAS,uBACT6B,GACAb,EAYF,MAAO,CAAE,GATY,MAAMQ,EAAW,eACpCE,EACAK,EACA,CACE,sBAAAC,EACD,EAIuB,SAAUD,EAAU,OAAOX,EAAQQ,CAAK,CAAC,CACrE,EClEK,IAAMK,EACX,CAME,CACE,OAAAC,EACA,OAAAd,EACA,gBAAAC,CAAe,EAEjBC,EAAyCC,GAAOA,IAElD,MACEC,EACAD,EACAY,EACAnC,IAIAmB,EACEC,EACAC,EACAC,CAAa,EACbE,EAAYD,EAAKK,GAAUM,EAAOC,EAASP,CAAK,EAAG5B,CAAO,ECpCzD,IAAMoC,EAAW,CAACC,EAAmBC,IAA4B,CACtE,IAAMC,EAAMF,EACNG,EAAMF,EAEZ,OAAO,OAAO,KAAKE,CAAG,EAAE,MAAOC,GACzB,OAAOD,EAAIC,CAAG,GAAK,SACdL,EACLG,EAAIE,CAAG,EACPD,EAAIC,CAAG,CAA4B,EAGhCD,EAAIC,CAAG,IAAMF,EAAIE,CAAG,CAC5B,CACH,EAEaC,EAAgB,CAACC,EAAiBC,IAAqB,CAClE,GAAI,CAACR,EAASO,EAAQC,CAAQ,EAC5B,MAAM,MACJ;EAAY,KAAK,UAAUA,CAAQ,CAAC;;EAAuB,KAAK,UAAUD,CAAM,CAAC,EAAE,CAEzF,ECpBO,IAAME,EAAQ,CACnBC,EACAC,EACAC,EACAC,EACAC,EAAkC,IAAG,KACnC,CACF,IAAIC,EAAW,GAETrB,EAASgB,EAEZ,IAAKM,GACCJ,EAAMI,CAAC,GAEZD,EAAW,GACJF,EAAWG,CAAC,GAHGA,CAIvB,EAGA,OAAQA,GAAMA,IAAM,MAAS,EAE7B,IAAKA,GAAK,CACT,GAAI,CAACA,EAAG,MAAM,MAAM,wBAAwB,EAE5C,OAAOA,CACT,CAAC,EAIH,MAAI,CAACD,GACYD,EAAU,IAEV,OAAkB,CAAC,GAAGJ,EAAOC,CAAI,EAG3CjB,CACT,ECpCA,OAAOuB,OAAY"}
@@ -0,0 +1,2 @@
1
+ var a={IF_MATCH:"if-match",IF_NOT_MATCH:"if-not-match",ETag:"etag"},s=/W\/"(-?\d+.*)"/,n=(r=>(r.WRONG_WEAK_ETAG_FORMAT="WRONG_WEAK_ETAG_FORMAT",r.MISSING_IF_MATCH_HEADER="MISSING_IF_MATCH_HEADER",r.MISSING_IF_NOT_MATCH_HEADER="MISSING_IF_NOT_MATCH_HEADER",r))(n||{}),g=t=>s.test(t),E=t=>{let e=s.exec(t);if(e===null||e.length===0)throw new Error("WRONG_WEAK_ETAG_FORMAT");return e[1]},_=t=>`W/"${t}"`,T=t=>{let e=t.headers[a.IF_MATCH];if(e===void 0)throw new Error("MISSING_IF_MATCH_HEADER");return e},A=t=>{let e=t.headers[a.IF_NOT_MATCH];if(e===void 0)throw new Error("MISSING_IF_MATCH_HEADER");return Array.isArray(e)?e[0]:e},I=(t,e)=>{t.setHeader(a.ETag,e)},i=t=>{let e=T(t);return g(e)?E(e):e};export{a,s as b,n as c,g as d,E as e,_ as f,T as g,A as h,I as i,i as j};
2
+ //# sourceMappingURL=chunk-GEU24YU2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/etag.ts"],"sourcesContent":["import { type Brand } from '@event-driven-io/emmett';\nimport type { Request, Response } from 'express';\n\n//////////////////////////////////////\n/// ETAG\n//////////////////////////////////////\n\nexport const HeaderNames = {\n IF_MATCH: 'if-match',\n IF_NOT_MATCH: 'if-not-match',\n ETag: 'etag',\n};\n\nexport type WeakETag = Brand<`W/${string}`, 'ETag'>;\nexport type ETag = Brand<string, 'ETag'>;\n\nexport const WeakETagRegex = /W\\/\"(-?\\d+.*)\"/;\n\nexport const enum ETagErrors {\n WRONG_WEAK_ETAG_FORMAT = 'WRONG_WEAK_ETAG_FORMAT',\n MISSING_IF_MATCH_HEADER = 'MISSING_IF_MATCH_HEADER',\n MISSING_IF_NOT_MATCH_HEADER = 'MISSING_IF_NOT_MATCH_HEADER',\n}\n\nexport const isWeakETag = (etag: ETag): etag is WeakETag => {\n return WeakETagRegex.test(etag as string);\n};\n\nexport const getWeakETagValue = (etag: ETag): string => {\n const result = WeakETagRegex.exec(etag as string);\n if (result === null || result.length === 0) {\n throw new Error(ETagErrors.WRONG_WEAK_ETAG_FORMAT);\n }\n return result[1]!;\n};\n\nexport const toWeakETag = (value: number | bigint | string): WeakETag => {\n return `W/\"${value}\"` as WeakETag;\n};\n\nexport const getETagFromIfMatch = (request: Request): ETag => {\n const etag = request.headers[HeaderNames.IF_MATCH];\n\n if (etag === undefined) {\n throw new Error(ETagErrors.MISSING_IF_MATCH_HEADER);\n }\n\n return etag as ETag;\n};\n\nexport const getETagFromIfNotMatch = (request: Request): ETag => {\n const etag = request.headers[HeaderNames.IF_NOT_MATCH];\n\n if (etag === undefined) {\n throw new Error(ETagErrors.MISSING_IF_MATCH_HEADER);\n }\n\n return (Array.isArray(etag) ? etag[0] : etag) as ETag;\n};\n\nexport const setETag = (response: Response, etag: ETag): void => {\n response.setHeader(HeaderNames.ETag, etag as string);\n};\n\nexport const getETagValueFromIfMatch = (request: Request): string => {\n const eTagValue: ETag = getETagFromIfMatch(request);\n\n return isWeakETag(eTagValue)\n ? getWeakETagValue(eTagValue)\n : (eTagValue as string);\n};\n"],"mappings":"AAOO,IAAMA,EAAc,CACzB,SAAU,WACV,aAAc,eACd,KAAM,MACR,EAKaC,EAAgB,iBAEXC,OAChBA,EAAA,uBAAyB,yBACzBA,EAAA,wBAA0B,0BAC1BA,EAAA,4BAA8B,8BAHdA,OAAA,IAMLC,EAAcC,GAClBH,EAAc,KAAKG,CAAc,EAG7BC,EAAoBD,GAAuB,CACtD,IAAME,EAASL,EAAc,KAAKG,CAAc,EAChD,GAAIE,IAAW,MAAQA,EAAO,SAAW,EACvC,MAAM,IAAI,MAAM,wBAAiC,EAEnD,OAAOA,EAAO,CAAC,CACjB,EAEaC,EAAcC,GAClB,MAAMA,CAAK,IAGPC,EAAsBC,GAA2B,CAC5D,IAAMN,EAAOM,EAAQ,QAAQV,EAAY,QAAQ,EAEjD,GAAII,IAAS,OACX,MAAM,IAAI,MAAM,yBAAkC,EAGpD,OAAOA,CACT,EAEaO,EAAyBD,GAA2B,CAC/D,IAAMN,EAAOM,EAAQ,QAAQV,EAAY,YAAY,EAErD,GAAII,IAAS,OACX,MAAM,IAAI,MAAM,yBAAkC,EAGpD,OAAQ,MAAM,QAAQA,CAAI,EAAIA,EAAK,CAAC,EAAIA,CAC1C,EAEaQ,EAAU,CAACC,EAAoBT,IAAqB,CAC/DS,EAAS,UAAUb,EAAY,KAAMI,CAAc,CACrD,EAEaU,EAA2BJ,GAA6B,CACnE,IAAMK,EAAkBN,EAAmBC,CAAO,EAElD,OAAOP,EAAWY,CAAS,EACvBV,EAAiBU,CAAS,EACzBA,CACP","names":["HeaderNames","WeakETagRegex","ETagErrors","isWeakETag","etag","getWeakETagValue","result","toWeakETag","value","getETagFromIfMatch","request","getETagFromIfNotMatch","setETag","response","getETagValueFromIfMatch","eTagValue"]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-HKEQAT6F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +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(); } }var _chunkNDXUB3PPjs = require('./chunk-NDXUB3PP.js');var _chunkEQRLVM5Sjs = require('./chunk-EQRLVM5S.js');var _express = require('express'); var _express2 = _interopRequireDefault(_express);require('express-async-errors');var _http = require('http'); var _http2 = _interopRequireDefault(_http);var _httpproblemdetails = require('http-problem-details');var u=e=>(t,o,s,i)=>{let p;e&&(p=e(t,o)),p=_nullishCoalesce(p, () => (P(t))),_chunkNDXUB3PPjs.f.call(void 0, s,p.status,{problem:p})},P= exports.n =e=>{let t=500;return e instanceof _chunkEQRLVM5Sjs.d&&(t=e.errorCode),new (0, _httpproblemdetails.ProblemDocument)({detail:e.message,status:t})};var v=e=>{let t=_express2.default.call(void 0, ),{apis:o,mapError:s,enableDefaultExpressEtag:i,disableJsonMiddleware:p,disableUrlEncodingMiddleware:b,disableProblemDetailsMiddleware:x}=e,m=_express.Router.call(void 0, );t.set("etag",_nullishCoalesce(i, () => (!1))),p||t.use(_express2.default.json()),b||t.use(_express2.default.urlencoded({extended:!0}));for(let H of o)H(m);return t.use(m),x||t.use(u(s)),t},N= exports.p =(e,t={port:3e3})=>{let{port:o}=t,s=_http2.default.createServer(e);return s.on("listening",()=>{console.info("server up listening")}),s.listen(o)};var K=e=>async(t,o,s)=>(await Promise.resolve(e(t)))(o),k= exports.b =e=>t=>{_chunkNDXUB3PPjs.e.call(void 0, t,200,e)},z= exports.c =e=>t=>{_chunkNDXUB3PPjs.c.call(void 0, t,e)},G= exports.d =e=>t=>{_chunkNDXUB3PPjs.d.call(void 0, t,e)},L= exports.e =e=>E(204,e),E= exports.f =(e,t)=>o=>{_chunkNDXUB3PPjs.e.call(void 0, o,e,t)},Q= exports.g =e=>n(400,e),V= exports.h =e=>n(403,e),X= exports.i =e=>n(404,e),Y= exports.j =e=>n(409,e),Z= exports.k =e=>n(412,e),n= exports.l =(e,t)=>o=>{_chunkNDXUB3PPjs.f.call(void 0, o,e,t)};exports.a = K; exports.b = k; exports.c = z; exports.d = G; exports.e = L; exports.f = E; exports.g = Q; exports.h = V; exports.i = X; exports.j = Y; exports.k = Z; exports.l = n; exports.m = u; exports.n = P; exports.o = v; exports.p = N;
2
+ //# sourceMappingURL=chunk-IGLFM4GN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/handler.ts","../src/index.ts","../src/application.ts","../src/middlewares/problemDetailsMiddleware.ts"],"names":["express","Router","http","ProblemDocument","problemDetailsMiddleware","mapError","error","request","response","_next","problemDetails","defaulErrorToProblemDetailsMapping","sendProblem","statusCode","EmmettError","getApplication","options","app","apis","enableDefaultExpressEtag","disableJsonMiddleware","disableUrlEncodingMiddleware","disableProblemDetailsMiddleware","router","api","startAPI","port","server","on","handle","OK","send","Created","sendCreated","Accepted","sendAccepted","NoContent","HttpResponse","BadRequest","HttpProblem","Forbidden","NotFound","Conflict","PreconditionFailed"],"mappings":"gGAAA,MAA+D,UCA/D,MAAO,uBCAP,OAAOA,GAAW,UAAAC,MAAgC,UAClD,MAAO,uBACP,OAAOC,MAAU,OCAjB,OAAS,mBAAAC,MAAuB,uBAGzB,IAAMC,EACVC,GACD,CACEC,EACAC,EACAC,EACAC,IACS,CACT,IAAIC,EAEAL,IAAUK,EAAiBL,EAASC,EAAOC,CAAO,GAEtDG,EACEA,GAAkBC,EAAmCL,CAAK,EAE5DM,EAAYJ,EAAUE,EAAe,OAAQ,CAAE,QAASA,CAAe,CAAC,CAC1E,EAEWC,EACXL,GACoB,CACpB,IAAIO,EAAa,IAEjB,OAAIP,aAAiBQ,IACnBD,EAAaP,EAAM,WAGd,IAAIH,EAAgB,CACzB,OAAQG,EAAM,QACd,OAAQO,CACV,CAAC,CACH,EDjBO,IAAME,EAAkBC,GAAgC,CAC7D,IAAMC,EAAmBjB,EAAQ,EAE3B,CACJ,KAAAkB,EACA,SAAAb,EACA,yBAAAc,EACA,sBAAAC,EACA,6BAAAC,EACA,gCAAAC,CACF,EAAIN,EAEEO,EAAStB,EAAO,EAItBgB,EAAI,IAAI,OAAQE,GAA4B,EAAK,EAG5CC,GAAuBH,EAAI,IAAIjB,EAAQ,KAAK,CAAC,EAG7CqB,GACHJ,EAAI,IACFjB,EAAQ,WAAW,CACjB,SAAU,EACZ,CAAC,CACH,EAEF,QAAWwB,KAAON,EAChBM,EAAID,CAAM,EAEZ,OAAAN,EAAI,IAAIM,CAAM,EAGTD,GACHL,EAAI,IAAIb,EAAyBC,CAAQ,CAAC,EAErCY,CACT,EAMaQ,EAAW,CACtBR,EACAD,EAA2B,CAAE,KAAM,GAAK,IACrC,CACH,GAAM,CAAE,KAAAU,CAAK,EAAIV,EACXW,EAASzB,EAAK,aAAae,CAAG,EAEpC,OAAAU,EAAO,GAAG,YAAa,IAAM,CAC3B,QAAQ,KAAK,qBAAqB,CACpC,CAAC,EAEMA,EAAO,OAAOD,CAAI,CAC3B,EFxDO,IAAME,EACmBC,GAC9B,MACEtB,EACAC,EACAC,KAEoB,MAAM,QAAQ,QAAQoB,EAAOtB,CAAO,CAAC,GAEtCC,CAAQ,EAIlBsB,EACVd,GACAR,GAAuB,CACtBuB,EAAKvB,EAAU,IAAKQ,CAAO,CAC7B,EAEWgB,EACVhB,GACAR,GAAuB,CACtByB,EAAYzB,EAAUQ,CAAO,CAC/B,EAEWkB,EACVlB,GACAR,GAAuB,CACtB2B,EAAa3B,EAAUQ,CAAO,CAChC,EAEWoB,EACXpB,GACiBqB,EAAa,IAAKrB,CAAO,EAE/BqB,EACX,CAACxB,EAAoBG,IACpBR,GAAuB,CACtBuB,EAAKvB,EAAUK,EAAYG,CAAO,CACpC,EAMWsB,EACXtB,GACiBuB,EAAY,IAAKvB,CAAO,EAE9BwB,EAAaxB,GACxBuB,EAAY,IAAKvB,CAAO,EAEbyB,EAAYzB,GACvBuB,EAAY,IAAKvB,CAAO,EAEb0B,EAAY1B,GACvBuB,EAAY,IAAKvB,CAAO,EAEb2B,EACX3B,GACiBuB,EAAY,IAAKvB,CAAO,EAE9BuB,EACX,CAAC1B,EAAoBG,IACpBR,GAAuB,CACtBI,EAAYJ,EAAUK,EAAYG,CAAO,CAC3C","sourcesContent":["import { type NextFunction, type Request, type Response } from 'express';\nimport {\n send,\n sendAccepted,\n sendCreated,\n sendProblem,\n type AcceptedHttpResponseOptions,\n type CreatedHttpResponseOptions,\n type HttpProblemResponseOptions,\n type HttpResponseOptions,\n type NoContentHttpResponseOptions,\n} from '.';\n\n// #region httpresponse-on\nexport type HttpResponse = (response: Response) => void;\n\nexport type HttpHandler<RequestType extends Request> = (\n request: RequestType,\n) => Promise<HttpResponse> | HttpResponse;\n\nexport const on =\n <RequestType extends Request>(handle: HttpHandler<RequestType>) =>\n async (\n request: RequestType,\n response: Response,\n _next: NextFunction,\n ): Promise<void> => {\n const setResponse = await Promise.resolve(handle(request));\n\n return setResponse(response);\n };\n// #endregion httpresponse-on\n\nexport const OK =\n (options?: HttpResponseOptions): HttpResponse =>\n (response: Response) => {\n send(response, 200, options);\n };\n\nexport const Created =\n (options: CreatedHttpResponseOptions): HttpResponse =>\n (response: Response) => {\n sendCreated(response, options);\n };\n\nexport const Accepted =\n (options: AcceptedHttpResponseOptions): HttpResponse =>\n (response: Response) => {\n sendAccepted(response, options);\n };\n\nexport const NoContent = (\n options?: NoContentHttpResponseOptions,\n): HttpResponse => HttpResponse(204, options);\n\nexport const HttpResponse =\n (statusCode: number, options?: HttpResponseOptions): HttpResponse =>\n (response: Response) => {\n send(response, statusCode, options);\n };\n\n/////////////////////\n// ERRORS\n/////////////////////\n\nexport const BadRequest = (\n options?: HttpProblemResponseOptions,\n): HttpResponse => HttpProblem(400, options);\n\nexport const Forbidden = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(403, options);\n\nexport const NotFound = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(404, options);\n\nexport const Conflict = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(409, options);\n\nexport const PreconditionFailed = (\n options: HttpProblemResponseOptions,\n): HttpResponse => HttpProblem(412, options);\n\nexport const HttpProblem =\n (statusCode: number, options?: HttpProblemResponseOptions): HttpResponse =>\n (response: Response) => {\n sendProblem(response, statusCode, options);\n };\n","import 'express-async-errors';\n\nexport * from './application';\nexport * from './etag';\nexport * from './handler';\nexport * from './responses';\nexport * from './testing';\n","import express, { Router, type Application } from 'express';\nimport 'express-async-errors';\nimport http from 'http';\nimport { problemDetailsMiddleware } from './middlewares/problemDetailsMiddleware';\nimport type { ErrorToProblemDetailsMapping } from './responses';\n\n// #region web-api-setup\nexport type WebApiSetup = (router: Router) => void;\n// #endregion web-api-setup\n\nexport type ApplicationOptions = {\n apis: WebApiSetup[];\n mapError?: ErrorToProblemDetailsMapping;\n enableDefaultExpressEtag?: boolean;\n disableJsonMiddleware?: boolean;\n disableUrlEncodingMiddleware?: boolean;\n disableProblemDetailsMiddleware?: boolean;\n};\n\nexport const getApplication = (options: ApplicationOptions) => {\n const app: Application = express();\n\n const {\n apis,\n mapError,\n enableDefaultExpressEtag,\n disableJsonMiddleware,\n disableUrlEncodingMiddleware,\n disableProblemDetailsMiddleware,\n } = options;\n\n const router = Router();\n\n // disabling default etag behaviour\n // to use etags in if-match and if-not-match headers\n app.set('etag', enableDefaultExpressEtag ?? false);\n\n // add json middleware\n if (!disableJsonMiddleware) app.use(express.json());\n\n // enable url encoded urls and bodies\n if (!disableUrlEncodingMiddleware)\n app.use(\n express.urlencoded({\n extended: true,\n }),\n );\n\n for (const api of apis) {\n api(router);\n }\n app.use(router);\n\n // add problem details middleware\n if (!disableProblemDetailsMiddleware)\n app.use(problemDetailsMiddleware(mapError));\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = (\n app: Application,\n options: StartApiOptions = { port: 3000 },\n) => {\n const { port } = options;\n const server = http.createServer(app);\n\n server.on('listening', () => {\n console.info('server up listening');\n });\n\n return server.listen(port);\n};\n","import { EmmettError } from '@event-driven-io/emmett';\nimport type { NextFunction, Request, Response } from 'express';\nimport { ProblemDocument } from 'http-problem-details';\nimport { sendProblem, type ErrorToProblemDetailsMapping } from '..';\n\nexport const problemDetailsMiddleware =\n (mapError?: ErrorToProblemDetailsMapping) =>\n (\n error: Error,\n request: Request,\n response: Response,\n _next: NextFunction,\n ): void => {\n let problemDetails: ProblemDocument | undefined;\n\n if (mapError) problemDetails = mapError(error, request);\n\n problemDetails =\n problemDetails ?? defaulErrorToProblemDetailsMapping(error);\n\n sendProblem(response, problemDetails.status, { problem: problemDetails });\n };\n\nexport const defaulErrorToProblemDetailsMapping = (\n error: Error,\n): ProblemDocument => {\n let statusCode = 500;\n\n if (error instanceof EmmettError) {\n statusCode = error.errorCode;\n }\n\n return new ProblemDocument({\n detail: error.message,\n status: statusCode,\n });\n};\n"]}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var o=r=>{let n=new Map;return{async aggregateStream(e,t){return r.aggregateStream(e,t)},readStream(e,t){return r.readStream(e,t)},appendToStream:async(e,t,a)=>{let s=await r.appendToStream(e,t,a),p=_nullishCoalesce(n.get(e), () => ([e,[]]));return n.set(e,[e,[...p[1],...t]]),s},appendedEvents:n,setup:async(e,t)=>r.appendToStream(e,t)}};exports.a = o;
2
+ //# sourceMappingURL=chunk-KVWDIWFZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/utils.ts"],"names":["WrapEventStore","eventStore","appendedEvents","streamName","options","events","result","currentStream"],"mappings":"AAiBO,IAAMA,EACXC,GAOG,CACH,IAAMC,EAAiB,IAAI,IAE3B,MAAO,CACL,MAAM,gBACJC,EACAC,EAC6D,CAC7D,OAAOH,EAAW,gBAAgBE,EAAYC,CAAO,CACvD,EAEA,WACED,EACAC,EACqD,CACrD,OAAOH,EAAW,WAAWE,EAAYC,CAAO,CAClD,EAEA,eAAgB,MACdD,EACAE,EACAD,IACiD,CACjD,IAAME,EAAS,MAAML,EAAW,eAC9BE,EACAE,EACAD,CACF,EAEMG,EAAgBL,EAAe,IAAIC,CAAU,GAAK,CAACA,EAAY,CAAC,CAAC,EAEvE,OAAAD,EAAe,IAAIC,EAAY,CAC7BA,EACA,CAAC,GAAGI,EAAc,CAAC,EAAG,GAAGF,CAAM,CACjC,CAAC,EAEMC,CACT,EAEA,eAAAJ,EAEA,MAAO,MACLC,EACAE,IAEOJ,EAAW,eAAeE,EAAYE,CAAM,CAEvD,CACF","sourcesContent":["import type {\n AggregateStreamOptions,\n AggregateStreamResult,\n AppendToStreamOptions,\n AppendToStreamResult,\n DefaultStreamVersionType,\n Event,\n EventStore,\n ReadStreamOptions,\n ReadStreamResult,\n} from '@event-driven-io/emmett';\n\nexport type TestEventStream<EventType extends Event = Event> = [\n string,\n EventType[],\n];\n\nexport const WrapEventStore = <StreamVersion = DefaultStreamVersionType>(\n eventStore: EventStore<StreamVersion>,\n): EventStore<StreamVersion> & {\n appendedEvents: Map<string, TestEventStream>;\n setup<EventType extends Event>(\n streamName: string,\n events: EventType[],\n ): Promise<AppendToStreamResult<StreamVersion>>;\n} => {\n const appendedEvents = new Map<string, TestEventStream>();\n\n return {\n async aggregateStream<State, EventType extends Event>(\n streamName: string,\n options: AggregateStreamOptions<State, EventType, StreamVersion>,\n ): Promise<AggregateStreamResult<State, StreamVersion> | null> {\n return eventStore.aggregateStream(streamName, options);\n },\n\n readStream<EventType extends Event>(\n streamName: string,\n options?: ReadStreamOptions<StreamVersion>,\n ): Promise<ReadStreamResult<EventType, StreamVersion>> {\n return eventStore.readStream(streamName, options);\n },\n\n appendToStream: async <EventType extends Event>(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<StreamVersion>,\n ): Promise<AppendToStreamResult<StreamVersion>> => {\n const result = await eventStore.appendToStream(\n streamName,\n events,\n options,\n );\n\n const currentStream = appendedEvents.get(streamName) ?? [streamName, []];\n\n appendedEvents.set(streamName, [\n streamName,\n [...currentStream[1], ...events],\n ]);\n\n return result;\n },\n\n appendedEvents,\n\n setup: async <EventType extends Event>(\n streamName: string,\n events: EventType[],\n ): Promise<AppendToStreamResult<StreamVersion>> => {\n return eventStore.appendToStream(streamName, events);\n },\n };\n};\n"]}
@@ -0,0 +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(); } }var _chunkKVWDIWFZjs = require('./chunk-KVWDIWFZ.js');var _chunkEQRLVM5Sjs = require('./chunk-EQRLVM5S.js');require('express');var _strict = require('assert/strict'); var _strict2 = _interopRequireDefault(_strict);var _supertest = require('supertest'); var _supertest2 = _interopRequireDefault(_supertest);var b=(t,e)=>[t,e],h= exports.b =(t,e)=>[t,e],R= exports.c =(t,e)=>[t,e],d= exports.d =(t,e)=>r=>{let{body:s,headers:o}=_nullishCoalesce(e, () => ({}));_strict2.default.equal(r.statusCode,t),s&&_chunkEQRLVM5Sjs.h.call(void 0, r.body,s),o&&_chunkEQRLVM5Sjs.h.call(void 0, r.headers,o)},w= exports.e =(t,e)=>d(t,e?{body:e}:void 0),V= exports.f ={for:(t,e)=>(...r)=>{let s=_chunkKVWDIWFZjs.a.call(void 0, t()),o=e(s);return{when:E=>{let y=async()=>{for(let[n,p]of r)await s.setup(n,p);return E(_supertest2.default.call(void 0, o))};return{then:async n=>{let p=await y();if(typeof n=="function")n(p)===!1&&_strict2.default.fail();else if(Array.isArray(n)){let[i,...m]=n;typeof i=="function"&&i(p)===!1&&_strict2.default.fail();let T=typeof i=="function"?m:n;_chunkEQRLVM5Sjs.h.call(void 0, Array.from(s.appendedEvents.values()),T)}}}}}}};exports.a = b; exports.b = h; exports.c = R; exports.d = d; exports.e = w; exports.f = V;
2
+ //# sourceMappingURL=chunk-LKKTDHJJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/apiSpecification.ts"],"names":["assert","supertest","existingStream","streamId","events","expect","expectNewEvents","expectResponse","statusCode","options","response","body","headers","assertMatches","expectError","errorCode","problemDetails","ApiSpecification","getEventStore","getApplication","givenStreams","eventStore","WrapEventStore","application","setupRequest","handle","streamName","verify","first","rest"],"mappings":"gFAMA,MAAiC,UAEjC,OAAOA,MAAY,gBAEnB,OAAOC,MAAe,YAQf,IAAMC,EAAiB,CAC5BC,EACAC,IAEO,CAACD,EAAUC,CAAM,EAcbC,EAAS,CACpBF,EACAC,IAEO,CAACD,EAAUC,CAAM,EAGbE,EAAkB,CAC7BH,EACAC,IAEO,CAACD,EAAUC,CAAM,EAGbG,EACX,CACEC,EACAC,IAEDC,GAA6B,CAC5B,GAAM,CAAE,KAAAC,EAAM,QAAAC,CAAQ,EAAIH,GAAW,CAAC,EACtCT,EAAO,MAAMU,EAAS,WAAYF,CAAU,EACxCG,GAAME,EAAcH,EAAS,KAAMC,CAAI,EACvCC,GAASC,EAAcH,EAAS,QAASE,CAAO,CACtD,EAEWE,EAAc,CACzBC,EACAC,IAEAT,EACEQ,EACAC,EAAiB,CAAE,KAAMA,CAAe,EAAI,MAC9C,EAcWC,EAAmB,CAC9B,IAAK,CAIHC,EACAC,IAGS,IAAIC,IAA+C,CACxD,IAAMC,EAAaC,EAAeJ,EAAc,CAAC,EAC3CK,EAAcJ,EAAeE,CAAU,EAE7C,MAAO,CACL,KACEG,GACG,CACH,IAAMC,EAAS,SAAY,CACzB,OAAW,CAACC,EAAYtB,CAAM,IAAKgB,EACjC,MAAMC,EAAW,MAAMK,EAAYtB,CAAM,EAG3C,OAAOoB,EAAavB,EAAUsB,CAAW,CAAC,CAC5C,EAEA,MAAO,CACL,KAAM,MACJI,GACkB,CAClB,IAAMjB,EAAW,MAAMe,EAAO,EAE9B,GAAI,OAAOE,GAAW,WACFA,EAAOjB,CAAQ,IAEf,IAAOV,EAAO,KAAK,UAC5B,MAAM,QAAQ2B,CAAM,EAAG,CAChC,GAAM,CAACC,EAAO,GAAGC,CAAI,EAAIF,EAErB,OAAOC,GAAU,YACDA,EAAMlB,CAAQ,IAEd,IAAOV,EAAO,KAAK,EAGvC,IAAMI,EAAS,OAAOwB,GAAU,WAAaC,EAAOF,EAEpDd,EACE,MAAM,KAAKQ,EAAW,eAAe,OAAO,CAAC,EAC7CjB,CACF,CACF,CACF,CACF,CACF,CACF,CACF,CAGN","sourcesContent":["import {\n assertMatches,\n type DefaultStreamVersionType,\n type Event,\n type EventStore,\n} from '@event-driven-io/emmett';\nimport { type Application } from 'express';\nimport type { ProblemDocument } from 'http-problem-details';\nimport assert from 'node:assert/strict';\nimport type { Response, Test } from 'supertest';\nimport supertest from 'supertest';\nimport type TestAgent from 'supertest/lib/agent';\nimport { WrapEventStore, type TestEventStream } from './utils';\n\n////////////////////////////////\n/////////// Setup\n////////////////////////////////\n\nexport const existingStream = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\n////////////////////////////////\n/////////// Asserts\n////////////////////////////////\n\nexport type ResponseAssert = (response: Response) => boolean | void;\n\nexport type ApiSpecificationAssert<EventType extends Event = Event> =\n | TestEventStream<EventType>[]\n | ResponseAssert\n | [ResponseAssert, ...TestEventStream<EventType>[]];\n\nexport const expect = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\nexport const expectNewEvents = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\nexport const expectResponse =\n <Body = unknown>(\n statusCode: number,\n options?: { body?: Body; headers?: { [index: string]: string } },\n ) =>\n (response: Response): void => {\n const { body, headers } = options ?? {};\n assert.equal(response.statusCode, statusCode);\n if (body) assertMatches(response.body, body);\n if (headers) assertMatches(response.headers, headers);\n };\n\nexport const expectError = (\n errorCode: number,\n problemDetails?: ProblemDocument,\n) =>\n expectResponse(\n errorCode,\n problemDetails ? { body: problemDetails } : undefined,\n );\n\n////////////////////////////////\n/////////// Api Specification\n////////////////////////////////\n\nexport type ApiSpecification<EventType extends Event = Event> = (\n ...givenStreams: TestEventStream<EventType>[]\n) => {\n when: (setupRequest: (request: TestAgent<supertest.Test>) => Test) => {\n then: (verify: ApiSpecificationAssert<EventType>) => Promise<void>;\n };\n};\n\nexport const ApiSpecification = {\n for: <\n EventType extends Event = Event,\n StreamVersion = DefaultStreamVersionType,\n >(\n getEventStore: () => EventStore<StreamVersion>,\n getApplication: (eventStore: EventStore<StreamVersion>) => Application,\n ): ApiSpecification<EventType> => {\n {\n return (...givenStreams: TestEventStream<EventType>[]) => {\n const eventStore = WrapEventStore(getEventStore());\n const application = getApplication(eventStore);\n\n return {\n when: (\n setupRequest: (request: TestAgent<supertest.Test>) => Test,\n ) => {\n const handle = async () => {\n for (const [streamName, events] of givenStreams) {\n await eventStore.setup(streamName, events);\n }\n\n return setupRequest(supertest(application));\n };\n\n return {\n then: async (\n verify: ApiSpecificationAssert<EventType>,\n ): Promise<void> => {\n const response = await handle();\n\n if (typeof verify === 'function') {\n const succeeded = verify(response);\n\n if (succeeded === false) assert.fail();\n } else if (Array.isArray(verify)) {\n const [first, ...rest] = verify;\n\n if (typeof first === 'function') {\n const succeeded = first(response);\n\n if (succeeded === false) assert.fail();\n }\n\n const events = typeof first === 'function' ? rest : verify;\n\n assertMatches(\n Array.from(eventStore.appendedEvents.values()),\n events,\n );\n }\n },\n };\n },\n };\n };\n }\n },\n};\n"]}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var _chunkE4DZPUJHjs = require('./chunk-E4DZPUJH.js');require('express');var _httpproblemdetails = require('http-problem-details');var l={},m= exports.b ={problemDetails:"Error occured!"},R= exports.c =(t,{createdId:e,urlPrefix:o,eTag:p})=>i(t,201,{location:`${_nullishCoalesce(o, () => (t.req.url))}/${e}`,body:{id:e},eTag:p}),H= exports.d =(t,e)=>i(t,202,e),i= exports.e =(t,e,o)=>{let{location:p,body:s,eTag:n}=_nullishCoalesce(o, () => (l));n&&_chunkE4DZPUJHjs.i.call(void 0, t,n),p&&t.setHeader("Location",p),s?(t.statusCode=e,t.send(s)):t.sendStatus(e)},O= exports.f =(t,e,o)=>{o=_nullishCoalesce(o, () => (m));let{location:p,eTag:s}=o,n="problem"in o?o.problem:new (0, _httpproblemdetails.ProblemDocument)({detail:o.problemDetails,status:e});s&&_chunkE4DZPUJHjs.i.call(void 0, t,s),p&&t.setHeader("Location",p),t.setHeader("Content-Type","application/problem+json"),t.statusCode=e,t.json(n)};exports.a = l; exports.b = m; exports.c = R; exports.d = H; exports.e = i; exports.f = O;
2
+ //# sourceMappingURL=chunk-NDXUB3PP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/responses.ts"],"names":["ProblemDocument","DefaultHttpResponseOptions","DefaultHttpProblemResponseOptions","sendCreated","response","createdId","urlPrefix","eTag","send","sendAccepted","options","statusCode","location","body","setETag","sendProblem","problemDetails"],"mappings":"wCAAA,MAA4C,UAC5C,OAAS,mBAAAA,MAAuB,uBAazB,IAAMC,EAAkD,CAAC,EAYnDC,EAAgE,CAC3E,eAAgB,gBAClB,EAOaC,EAAc,CACzBC,EACA,CAAE,UAAAC,EAAW,UAAAC,EAAW,KAAAC,CAAK,IAE7BC,EAAKJ,EAAU,IAAK,CAClB,SAAU,GAAGE,GAAaF,EAAS,IAAI,GAAG,IAAIC,CAAS,GACvD,KAAM,CAAE,GAAIA,CAAU,EACtB,KAAAE,CACF,CAAC,EAMUE,EAAe,CAC1BL,EACAM,IACSF,EAAKJ,EAAU,IAAKM,CAAO,EAIzBF,EAAO,CAClBJ,EACAO,EACAD,IACS,CACT,GAAM,CAAE,SAAAE,EAAU,KAAAC,EAAM,KAAAN,CAAK,EAAIG,GAAWT,EAExCM,GAAMO,EAAQV,EAAUG,CAAI,EAC5BK,GAAUR,EAAS,UAAU,WAAYQ,CAAQ,EAEjDC,GACFT,EAAS,WAAaO,EACtBP,EAAS,KAAKS,CAAI,GAElBT,EAAS,WAAWO,CAAU,CAElC,EAEaI,EAAc,CACzBX,EACAO,EACAD,IACS,CACTA,EAAUA,GAAWR,EAErB,GAAM,CAAE,SAAAU,EAAU,KAAAL,CAAK,EAAIG,EAErBM,EACJ,YAAaN,EACTA,EAAQ,QACR,IAAIV,EAAgB,CAClB,OAAQU,EAAQ,eAChB,OAAQC,CACV,CAAC,EAGHJ,GAAMO,EAAQV,EAAUG,CAAI,EAC5BK,GAAUR,EAAS,UAAU,WAAYQ,CAAQ,EAErDR,EAAS,UAAU,eAAgB,0BAA0B,EAE7DA,EAAS,WAAaO,EACtBP,EAAS,KAAKY,CAAc,CAC9B","sourcesContent":["import { type Request, type Response } from 'express';\nimport { ProblemDocument } from 'http-problem-details';\nimport { setETag, type ETag } from './etag';\n\nexport type ErrorToProblemDetailsMapping = (\n error: Error,\n request: Request,\n) => ProblemDocument | undefined;\n\nexport type HttpResponseOptions = {\n body?: unknown;\n location?: string;\n eTag?: ETag;\n};\nexport const DefaultHttpResponseOptions: HttpResponseOptions = {};\n\nexport type HttpProblemResponseOptions = {\n location?: string;\n eTag?: ETag;\n} & Omit<HttpResponseOptions, 'body'> &\n (\n | {\n problem: ProblemDocument;\n }\n | { problemDetails: string }\n );\nexport const DefaultHttpProblemResponseOptions: HttpProblemResponseOptions = {\n problemDetails: 'Error occured!',\n};\n\nexport type CreatedHttpResponseOptions = {\n createdId: string;\n urlPrefix?: string;\n} & HttpResponseOptions;\n\nexport const sendCreated = (\n response: Response,\n { createdId, urlPrefix, eTag }: CreatedHttpResponseOptions,\n): void =>\n send(response, 201, {\n location: `${urlPrefix ?? response.req.url}/${createdId}`,\n body: { id: createdId },\n eTag,\n });\n\nexport type AcceptedHttpResponseOptions = {\n location: string;\n} & HttpResponseOptions;\n\nexport const sendAccepted = (\n response: Response,\n options: AcceptedHttpResponseOptions,\n): void => send(response, 202, options);\n\nexport type NoContentHttpResponseOptions = Omit<HttpResponseOptions, 'body'>;\n\nexport const send = (\n response: Response,\n statusCode: number,\n options?: HttpResponseOptions,\n): void => {\n const { location, body, eTag } = options ?? DefaultHttpResponseOptions;\n // HEADERS\n if (eTag) setETag(response, eTag);\n if (location) response.setHeader('Location', location);\n\n if (body) {\n response.statusCode = statusCode;\n response.send(body);\n } else {\n response.sendStatus(statusCode);\n }\n};\n\nexport const sendProblem = (\n response: Response,\n statusCode: number,\n options?: HttpProblemResponseOptions,\n): void => {\n options = options ?? DefaultHttpProblemResponseOptions;\n\n const { location, eTag } = options;\n\n const problemDetails =\n 'problem' in options\n ? options.problem\n : new ProblemDocument({\n detail: options.problemDetails,\n status: statusCode,\n });\n\n // HEADERS\n if (eTag) setETag(response, eTag);\n if (location) response.setHeader('Location', location);\n\n response.setHeader('Content-Type', 'application/problem+json');\n\n response.statusCode = statusCode;\n response.json(problemDetails);\n};\n"]}
@@ -0,0 +1,5 @@
1
+ var p=class e extends Error{errorCode;constructor(r){let s=r&&typeof r=="object"&&"errorCode"in r?r.errorCode:f(r)?r:500,t=r&&typeof r=="object"&&"message"in r?r.message:x(r)?r:`Error with status code '${s}' ocurred during Emmett processing`;super(t),this.errorCode=s,Object.setPrototypeOf(this,e.prototype)}};var u=class e extends p{constructor(r){super({errorCode:400,message:r??"Validation Error ocurred during Emmett processing"}),Object.setPrototypeOf(this,e.prototype)}},l=class e extends p{constructor(r){super({errorCode:403,message:r??"Illegal State ocurred during Emmett processing"}),Object.setPrototypeOf(this,e.prototype)}};var m;(function(e){e.NOT_A_NONEMPTY_STRING="NOT_A_NONEMPTY_STRING",e.NOT_A_POSITIVE_NUMBER="NOT_A_POSITIVE_NUMBER",e.NOT_AN_UNSIGNED_BIGINT="NOT_AN_UNSIGNED_BIGINT"})(m||(m={}));var f=e=>typeof e=="number"&&e===e,x=e=>typeof e=="string",A=e=>{if(!x(e)||e.length===0)throw new u(m.NOT_A_NONEMPTY_STRING);return e},b=e=>{if(!f(e)||e<=0)throw new u(m.NOT_A_POSITIVE_NUMBER);return e},R=e=>{let r=BigInt(e);if(r<0)throw new u(m.NOT_AN_UNSIGNED_BIGINT);return r};var N="STREAM_DOES_NOT_EXIST",E="NO_CONCURRENCY_CHECK";import{v4 as k}from"uuid";var h=(e,r,s=t=>t)=>async(t,n,c,a)=>{let o=s(n),i=await t.aggregateStream(o,{evolve:e,getInitialState:r,read:{expectedStreamVersion:a?.expectedStreamVersion??E}}),g=i?.state??r(),O=i?.currentStreamVersion,d=c(g),S=Array.isArray(d)?d:[d],T=a?.expectedStreamVersion??O??N;return{...await t.appendToStream(o,S,{expectedStreamVersion:T}),newState:S.reduce(e,g)}};var L=({decide:e,evolve:r,getInitialState:s},t=n=>n)=>async(n,c,a,o)=>h(r,s,t)(n,c,i=>e(a,i),o);var y=(e,r)=>{let s=e,t=r;return Object.keys(t).every(n=>typeof t[n]=="object"?y(s[n],t[n]):t[n]===s[n])},F=(e,r)=>{if(!y(e,r))throw Error(`subObj:
2
+ ${JSON.stringify(r)}
3
+ is not subset of
4
+ ${JSON.stringify(e)}`)};var W=(e,r,s,t,n=()=>{})=>{let c=!1,a=e.map(o=>s(o)?(c=!0,t(o)):o).filter(o=>o!==void 0).map(o=>{if(!o)throw Error("That should not happen");return o});return!c&&n()!==void 0?[...e,r]:a};import me from"assert";export{A as a,b,R as c,p as d,l as e,N as f,L as g,F as h,W as i};
5
+ //# sourceMappingURL=chunk-ODC4O4D7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/@event-driven-io/emmett/src/errors/index.ts","../node_modules/@event-driven-io/emmett/src/validation/index.ts","../node_modules/@event-driven-io/emmett/src/eventStore/expectedVersion.ts","../node_modules/@event-driven-io/emmett/src/eventStore/inMemoryEventStore.ts","../node_modules/@event-driven-io/emmett/src/commandHandling/handleCommand.ts","../node_modules/@event-driven-io/emmett/src/commandHandling/handleCommandWithDecider.ts","../node_modules/@event-driven-io/emmett/src/testing/assertions.ts","../node_modules/@event-driven-io/emmett/src/utils/merge.ts","../node_modules/@event-driven-io/emmett/src/testing/deciderSpecification.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null],"mappings":"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","names":["EmmettError","_EmmettError","options","errorCode","isNumber","message","isString","ValidationError","_ValidationError","EmmettError","message","IllegalStateError","_IllegalStateError","ValidationErrors","isNumber","val","isString","assertNotEmptyString","value","ValidationError","assertPositiveNumber","assertUnsignedBigInt","number","STREAM_DOES_NOT_EXIST","NO_CONCURRENCY_CHECK","uuid","CommandHandler","evolve","getInitialState","mapToStreamId","id","eventStore","handle","options","streamName","aggregationResult","NO_CONCURRENCY_CHECK","state","currentStreamVersion","result","newEvents","expectedStreamVersion","STREAM_DOES_NOT_EXIST","DeciderCommandHandler","decide","evolve","getInitialState","mapToStreamId","id","eventStore","command","options","CommandHandler","state","isSubset","superObj","subObj","sup","sub","ele","assertMatches","actual","expected","merge","array","item","where","onExisting","onNotFound","wasFound","result","p","assert"]}
@@ -0,0 +1,2 @@
1
+ import{c as R,d as c,e as l,f as r}from"./chunk-3ECNKSAE.mjs";import{d}from"./chunk-ODC4O4D7.mjs";import"express";import"express-async-errors";import a,{Router as y}from"express";import"express-async-errors";import O from"http";import{ProblemDocument as f}from"http-problem-details";var u=e=>(t,o,s,i)=>{let p;e&&(p=e(t,o)),p=p??P(t),r(s,p.status,{problem:p})},P=e=>{let t=500;return e instanceof d&&(t=e.errorCode),new f({detail:e.message,status:t})};var v=e=>{let t=a(),{apis:o,mapError:s,enableDefaultExpressEtag:i,disableJsonMiddleware:p,disableUrlEncodingMiddleware:b,disableProblemDetailsMiddleware:x}=e,m=y();t.set("etag",i??!1),p||t.use(a.json()),b||t.use(a.urlencoded({extended:!0}));for(let H of o)H(m);return t.use(m),x||t.use(u(s)),t},N=(e,t={port:3e3})=>{let{port:o}=t,s=O.createServer(e);return s.on("listening",()=>{console.info("server up listening")}),s.listen(o)};var K=e=>async(t,o,s)=>(await Promise.resolve(e(t)))(o),k=e=>t=>{l(t,200,e)},z=e=>t=>{R(t,e)},G=e=>t=>{c(t,e)},L=e=>E(204,e),E=(e,t)=>o=>{l(o,e,t)},Q=e=>n(400,e),V=e=>n(403,e),X=e=>n(404,e),Y=e=>n(409,e),Z=e=>n(412,e),n=(e,t)=>o=>{r(o,e,t)};export{K as a,k as b,z as c,G as d,L as e,E as f,Q as g,V as h,X as i,Y as j,Z as k,n as l,u as m,P as n,v as o,N as p};
2
+ //# sourceMappingURL=chunk-TRFPNOO7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/handler.ts","../src/index.ts","../src/application.ts","../src/middlewares/problemDetailsMiddleware.ts"],"sourcesContent":["import { type NextFunction, type Request, type Response } from 'express';\nimport {\n send,\n sendAccepted,\n sendCreated,\n sendProblem,\n type AcceptedHttpResponseOptions,\n type CreatedHttpResponseOptions,\n type HttpProblemResponseOptions,\n type HttpResponseOptions,\n type NoContentHttpResponseOptions,\n} from '.';\n\n// #region httpresponse-on\nexport type HttpResponse = (response: Response) => void;\n\nexport type HttpHandler<RequestType extends Request> = (\n request: RequestType,\n) => Promise<HttpResponse> | HttpResponse;\n\nexport const on =\n <RequestType extends Request>(handle: HttpHandler<RequestType>) =>\n async (\n request: RequestType,\n response: Response,\n _next: NextFunction,\n ): Promise<void> => {\n const setResponse = await Promise.resolve(handle(request));\n\n return setResponse(response);\n };\n// #endregion httpresponse-on\n\nexport const OK =\n (options?: HttpResponseOptions): HttpResponse =>\n (response: Response) => {\n send(response, 200, options);\n };\n\nexport const Created =\n (options: CreatedHttpResponseOptions): HttpResponse =>\n (response: Response) => {\n sendCreated(response, options);\n };\n\nexport const Accepted =\n (options: AcceptedHttpResponseOptions): HttpResponse =>\n (response: Response) => {\n sendAccepted(response, options);\n };\n\nexport const NoContent = (\n options?: NoContentHttpResponseOptions,\n): HttpResponse => HttpResponse(204, options);\n\nexport const HttpResponse =\n (statusCode: number, options?: HttpResponseOptions): HttpResponse =>\n (response: Response) => {\n send(response, statusCode, options);\n };\n\n/////////////////////\n// ERRORS\n/////////////////////\n\nexport const BadRequest = (\n options?: HttpProblemResponseOptions,\n): HttpResponse => HttpProblem(400, options);\n\nexport const Forbidden = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(403, options);\n\nexport const NotFound = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(404, options);\n\nexport const Conflict = (options?: HttpProblemResponseOptions): HttpResponse =>\n HttpProblem(409, options);\n\nexport const PreconditionFailed = (\n options: HttpProblemResponseOptions,\n): HttpResponse => HttpProblem(412, options);\n\nexport const HttpProblem =\n (statusCode: number, options?: HttpProblemResponseOptions): HttpResponse =>\n (response: Response) => {\n sendProblem(response, statusCode, options);\n };\n","import 'express-async-errors';\n\nexport * from './application';\nexport * from './etag';\nexport * from './handler';\nexport * from './responses';\nexport * from './testing';\n","import express, { Router, type Application } from 'express';\nimport 'express-async-errors';\nimport http from 'http';\nimport { problemDetailsMiddleware } from './middlewares/problemDetailsMiddleware';\nimport type { ErrorToProblemDetailsMapping } from './responses';\n\n// #region web-api-setup\nexport type WebApiSetup = (router: Router) => void;\n// #endregion web-api-setup\n\nexport type ApplicationOptions = {\n apis: WebApiSetup[];\n mapError?: ErrorToProblemDetailsMapping;\n enableDefaultExpressEtag?: boolean;\n disableJsonMiddleware?: boolean;\n disableUrlEncodingMiddleware?: boolean;\n disableProblemDetailsMiddleware?: boolean;\n};\n\nexport const getApplication = (options: ApplicationOptions) => {\n const app: Application = express();\n\n const {\n apis,\n mapError,\n enableDefaultExpressEtag,\n disableJsonMiddleware,\n disableUrlEncodingMiddleware,\n disableProblemDetailsMiddleware,\n } = options;\n\n const router = Router();\n\n // disabling default etag behaviour\n // to use etags in if-match and if-not-match headers\n app.set('etag', enableDefaultExpressEtag ?? false);\n\n // add json middleware\n if (!disableJsonMiddleware) app.use(express.json());\n\n // enable url encoded urls and bodies\n if (!disableUrlEncodingMiddleware)\n app.use(\n express.urlencoded({\n extended: true,\n }),\n );\n\n for (const api of apis) {\n api(router);\n }\n app.use(router);\n\n // add problem details middleware\n if (!disableProblemDetailsMiddleware)\n app.use(problemDetailsMiddleware(mapError));\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = (\n app: Application,\n options: StartApiOptions = { port: 3000 },\n) => {\n const { port } = options;\n const server = http.createServer(app);\n\n server.on('listening', () => {\n console.info('server up listening');\n });\n\n return server.listen(port);\n};\n","import { EmmettError } from '@event-driven-io/emmett';\nimport type { NextFunction, Request, Response } from 'express';\nimport { ProblemDocument } from 'http-problem-details';\nimport { sendProblem, type ErrorToProblemDetailsMapping } from '..';\n\nexport const problemDetailsMiddleware =\n (mapError?: ErrorToProblemDetailsMapping) =>\n (\n error: Error,\n request: Request,\n response: Response,\n _next: NextFunction,\n ): void => {\n let problemDetails: ProblemDocument | undefined;\n\n if (mapError) problemDetails = mapError(error, request);\n\n problemDetails =\n problemDetails ?? defaulErrorToProblemDetailsMapping(error);\n\n sendProblem(response, problemDetails.status, { problem: problemDetails });\n };\n\nexport const defaulErrorToProblemDetailsMapping = (\n error: Error,\n): ProblemDocument => {\n let statusCode = 500;\n\n if (error instanceof EmmettError) {\n statusCode = error.errorCode;\n }\n\n return new ProblemDocument({\n detail: error.message,\n status: statusCode,\n });\n};\n"],"mappings":"kGAAA,MAA+D,UCA/D,MAAO,uBCAP,OAAOA,GAAW,UAAAC,MAAgC,UAClD,MAAO,uBACP,OAAOC,MAAU,OCAjB,OAAS,mBAAAC,MAAuB,uBAGzB,IAAMC,EACVC,GACD,CACEC,EACAC,EACAC,EACAC,IACS,CACT,IAAIC,EAEAL,IAAUK,EAAiBL,EAASC,EAAOC,CAAO,GAEtDG,EACEA,GAAkBC,EAAmCL,CAAK,EAE5DM,EAAYJ,EAAUE,EAAe,OAAQ,CAAE,QAASA,CAAe,CAAC,CAC1E,EAEWC,EACXL,GACoB,CACpB,IAAIO,EAAa,IAEjB,OAAIP,aAAiBQ,IACnBD,EAAaP,EAAM,WAGd,IAAIS,EAAgB,CACzB,OAAQT,EAAM,QACd,OAAQO,CACV,CAAC,CACH,EDjBO,IAAMG,EAAkBC,GAAgC,CAC7D,IAAMC,EAAmBC,EAAQ,EAE3B,CACJ,KAAAC,EACA,SAAAC,EACA,yBAAAC,EACA,sBAAAC,EACA,6BAAAC,EACA,gCAAAC,CACF,EAAIR,EAEES,EAASC,EAAO,EAItBT,EAAI,IAAI,OAAQI,GAA4B,EAAK,EAG5CC,GAAuBL,EAAI,IAAIC,EAAQ,KAAK,CAAC,EAG7CK,GACHN,EAAI,IACFC,EAAQ,WAAW,CACjB,SAAU,EACZ,CAAC,CACH,EAEF,QAAWS,KAAOR,EAChBQ,EAAIF,CAAM,EAEZ,OAAAR,EAAI,IAAIQ,CAAM,EAGTD,GACHP,EAAI,IAAIW,EAAyBR,CAAQ,CAAC,EAErCH,CACT,EAMaY,EAAW,CACtBZ,EACAD,EAA2B,CAAE,KAAM,GAAK,IACrC,CACH,GAAM,CAAE,KAAAc,CAAK,EAAId,EACXe,EAASC,EAAK,aAAaf,CAAG,EAEpC,OAAAc,EAAO,GAAG,YAAa,IAAM,CAC3B,QAAQ,KAAK,qBAAqB,CACpC,CAAC,EAEMA,EAAO,OAAOD,CAAI,CAC3B,EFxDO,IAAMG,EACmBC,GAC9B,MACEC,EACAC,EACAC,KAEoB,MAAM,QAAQ,QAAQH,EAAOC,CAAO,CAAC,GAEtCC,CAAQ,EAIlBE,EACVC,GACAH,GAAuB,CACtBI,EAAKJ,EAAU,IAAKG,CAAO,CAC7B,EAEWE,EACVF,GACAH,GAAuB,CACtBM,EAAYN,EAAUG,CAAO,CAC/B,EAEWI,EACVJ,GACAH,GAAuB,CACtBQ,EAAaR,EAAUG,CAAO,CAChC,EAEWM,EACXN,GACiBO,EAAa,IAAKP,CAAO,EAE/BO,EACX,CAACC,EAAoBR,IACpBH,GAAuB,CACtBI,EAAKJ,EAAUW,EAAYR,CAAO,CACpC,EAMWS,EACXT,GACiBU,EAAY,IAAKV,CAAO,EAE9BW,EAAaX,GACxBU,EAAY,IAAKV,CAAO,EAEbY,EAAYZ,GACvBU,EAAY,IAAKV,CAAO,EAEba,EAAYb,GACvBU,EAAY,IAAKV,CAAO,EAEbc,EACXd,GACiBU,EAAY,IAAKV,CAAO,EAE9BU,EACX,CAACF,EAAoBR,IACpBH,GAAuB,CACtBkB,EAAYlB,EAAUW,EAAYR,CAAO,CAC3C","names":["express","Router","http","ProblemDocument","problemDetailsMiddleware","mapError","error","request","response","_next","problemDetails","defaulErrorToProblemDetailsMapping","sendProblem","statusCode","EmmettError","ProblemDocument","getApplication","options","app","express","apis","mapError","enableDefaultExpressEtag","disableJsonMiddleware","disableUrlEncodingMiddleware","disableProblemDetailsMiddleware","router","Router","api","problemDetailsMiddleware","startAPI","port","server","http","on","handle","request","response","_next","OK","options","send","Created","sendCreated","Accepted","sendAccepted","NoContent","HttpResponse","statusCode","BadRequest","HttpProblem","Forbidden","NotFound","Conflict","PreconditionFailed","sendProblem"]}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunkKVWDIWFZjs = require('./chunk-KVWDIWFZ.js');var _supertest = require('supertest'); var _supertest2 = _interopRequireDefault(_supertest);var _assert = require('assert'); var _assert2 = _interopRequireDefault(_assert);var v={for:(o,i)=>(...n)=>{let p=_chunkKVWDIWFZjs.a.call(void 0, o()),t=i(p);return{when:a=>{let c=async()=>{for(let e of n)await e(_supertest2.default.call(void 0, t));return a(_supertest2.default.call(void 0, t))};return{then:async e=>{let f=await c();e.forEach(m=>{m(f)===!1&&_assert2.default.fail()})}}}}}};exports.a = v;
2
+ //# sourceMappingURL=chunk-VK264KTU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/apiE2ESpecification.ts"],"names":["supertest","assert","ApiE2ESpecification","getEventStore","getApplication","givenRequests","eventStore","WrapEventStore","application","setupRequest","handle","requestFn","verify","response","assertion"],"mappings":"wCACA,OAAOA,MAAkC,YAOzC,OAAOC,MAAY,SAgBZ,IAAMC,EAAsB,CACjC,IAAK,CACHC,EACAC,IAGS,IACFC,IACA,CACH,IAAMC,EAAaC,EAAeJ,EAAc,CAAC,EAC3CK,EAAcJ,EAAeE,CAAU,EAE7C,MAAO,CACL,KACEG,GACG,CACH,IAAMC,EAAS,SAAY,CACzB,QAAWC,KAAaN,EACtB,MAAMM,EAAUX,EAAUQ,CAAW,CAAC,EAGxC,OAAOC,EAAaT,EAAUQ,CAAW,CAAC,CAC5C,EAEA,MAAO,CACL,KAAM,MACJI,GACkB,CAClB,IAAMC,EAAW,MAAMH,EAAO,EAE9BE,EAAO,QAASE,GAAc,CACVA,EAAUD,CAAQ,IAElB,IAAOZ,EAAO,KAAK,CACvC,CAAC,CACH,CACF,CACF,CACF,CACF,CAGN","sourcesContent":["import type { Test } from 'supertest';\nimport supertest, { type Response } from 'supertest';\nimport type TestAgent from 'supertest/lib/agent';\n\nimport type {\n DefaultStreamVersionType,\n EventStore,\n} from '@event-driven-io/emmett';\nimport assert from 'assert';\nimport type { Application } from 'express';\nimport { WrapEventStore } from './utils';\n\nexport type E2EResponseAssert = (response: Response) => boolean | void;\n\nexport type ApiE2ESpecificationAssert = [E2EResponseAssert];\n\nexport type ApiE2ESpecification = (\n ...givenRequests: ((request: TestAgent<supertest.Test>) => Test)[]\n) => {\n when: (setupRequest: (request: TestAgent<supertest.Test>) => Test) => {\n then: (verify: ApiE2ESpecificationAssert) => Promise<void>;\n };\n};\n\nexport const ApiE2ESpecification = {\n for: <StreamVersion = DefaultStreamVersionType>(\n getEventStore: () => EventStore<StreamVersion>,\n getApplication: (eventStore: EventStore<StreamVersion>) => Application,\n ): ApiE2ESpecification => {\n {\n return (\n ...givenRequests: ((request: TestAgent<supertest.Test>) => Test)[]\n ) => {\n const eventStore = WrapEventStore(getEventStore());\n const application = getApplication(eventStore);\n\n return {\n when: (\n setupRequest: (request: TestAgent<supertest.Test>) => Test,\n ) => {\n const handle = async () => {\n for (const requestFn of givenRequests) {\n await requestFn(supertest(application));\n }\n\n return setupRequest(supertest(application));\n };\n\n return {\n then: async (\n verify: ApiE2ESpecificationAssert,\n ): Promise<void> => {\n const response = await handle();\n\n verify.forEach((assertion) => {\n const succeeded = assertion(response);\n\n if (succeeded === false) assert.fail();\n });\n },\n };\n },\n };\n };\n }\n },\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import{a as c}from"./chunk-42BDHECF.mjs";import{h as a}from"./chunk-ODC4O4D7.mjs";import"express";import v from"node:assert/strict";import f from"supertest";var b=(t,e)=>[t,e],h=(t,e)=>[t,e],R=(t,e)=>[t,e],d=(t,e)=>r=>{let{body:s,headers:o}=e??{};v.equal(r.statusCode,t),s&&a(r.body,s),o&&a(r.headers,o)},w=(t,e)=>d(t,e?{body:e}:void 0),V={for:(t,e)=>(...r)=>{let s=c(t()),o=e(s);return{when:E=>{let y=async()=>{for(let[n,p]of r)await s.setup(n,p);return E(f(o))};return{then:async n=>{let p=await y();if(typeof n=="function")n(p)===!1&&v.fail();else if(Array.isArray(n)){let[i,...m]=n;typeof i=="function"&&i(p)===!1&&v.fail();let T=typeof i=="function"?m:n;a(Array.from(s.appendedEvents.values()),T)}}}}}}};export{b as a,h as b,R as c,d,w as e,V as f};
2
+ //# sourceMappingURL=chunk-W4KU3SEX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/apiSpecification.ts"],"sourcesContent":["import {\n assertMatches,\n type DefaultStreamVersionType,\n type Event,\n type EventStore,\n} from '@event-driven-io/emmett';\nimport { type Application } from 'express';\nimport type { ProblemDocument } from 'http-problem-details';\nimport assert from 'node:assert/strict';\nimport type { Response, Test } from 'supertest';\nimport supertest from 'supertest';\nimport type TestAgent from 'supertest/lib/agent';\nimport { WrapEventStore, type TestEventStream } from './utils';\n\n////////////////////////////////\n/////////// Setup\n////////////////////////////////\n\nexport const existingStream = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\n////////////////////////////////\n/////////// Asserts\n////////////////////////////////\n\nexport type ResponseAssert = (response: Response) => boolean | void;\n\nexport type ApiSpecificationAssert<EventType extends Event = Event> =\n | TestEventStream<EventType>[]\n | ResponseAssert\n | [ResponseAssert, ...TestEventStream<EventType>[]];\n\nexport const expect = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\nexport const expectNewEvents = <EventType extends Event = Event>(\n streamId: string,\n events: EventType[],\n): TestEventStream<EventType> => {\n return [streamId, events];\n};\n\nexport const expectResponse =\n <Body = unknown>(\n statusCode: number,\n options?: { body?: Body; headers?: { [index: string]: string } },\n ) =>\n (response: Response): void => {\n const { body, headers } = options ?? {};\n assert.equal(response.statusCode, statusCode);\n if (body) assertMatches(response.body, body);\n if (headers) assertMatches(response.headers, headers);\n };\n\nexport const expectError = (\n errorCode: number,\n problemDetails?: ProblemDocument,\n) =>\n expectResponse(\n errorCode,\n problemDetails ? { body: problemDetails } : undefined,\n );\n\n////////////////////////////////\n/////////// Api Specification\n////////////////////////////////\n\nexport type ApiSpecification<EventType extends Event = Event> = (\n ...givenStreams: TestEventStream<EventType>[]\n) => {\n when: (setupRequest: (request: TestAgent<supertest.Test>) => Test) => {\n then: (verify: ApiSpecificationAssert<EventType>) => Promise<void>;\n };\n};\n\nexport const ApiSpecification = {\n for: <\n EventType extends Event = Event,\n StreamVersion = DefaultStreamVersionType,\n >(\n getEventStore: () => EventStore<StreamVersion>,\n getApplication: (eventStore: EventStore<StreamVersion>) => Application,\n ): ApiSpecification<EventType> => {\n {\n return (...givenStreams: TestEventStream<EventType>[]) => {\n const eventStore = WrapEventStore(getEventStore());\n const application = getApplication(eventStore);\n\n return {\n when: (\n setupRequest: (request: TestAgent<supertest.Test>) => Test,\n ) => {\n const handle = async () => {\n for (const [streamName, events] of givenStreams) {\n await eventStore.setup(streamName, events);\n }\n\n return setupRequest(supertest(application));\n };\n\n return {\n then: async (\n verify: ApiSpecificationAssert<EventType>,\n ): Promise<void> => {\n const response = await handle();\n\n if (typeof verify === 'function') {\n const succeeded = verify(response);\n\n if (succeeded === false) assert.fail();\n } else if (Array.isArray(verify)) {\n const [first, ...rest] = verify;\n\n if (typeof first === 'function') {\n const succeeded = first(response);\n\n if (succeeded === false) assert.fail();\n }\n\n const events = typeof first === 'function' ? rest : verify;\n\n assertMatches(\n Array.from(eventStore.appendedEvents.values()),\n events,\n );\n }\n },\n };\n },\n };\n };\n }\n },\n};\n"],"mappings":"kFAMA,MAAiC,UAEjC,OAAOA,MAAY,qBAEnB,OAAOC,MAAe,YAQf,IAAMC,EAAiB,CAC5BC,EACAC,IAEO,CAACD,EAAUC,CAAM,EAcbC,EAAS,CACpBF,EACAC,IAEO,CAACD,EAAUC,CAAM,EAGbE,EAAkB,CAC7BH,EACAC,IAEO,CAACD,EAAUC,CAAM,EAGbG,EACX,CACEC,EACAC,IAEDC,GAA6B,CAC5B,GAAM,CAAE,KAAAC,EAAM,QAAAC,CAAQ,EAAIH,GAAW,CAAC,EACtCI,EAAO,MAAMH,EAAS,WAAYF,CAAU,EACxCG,GAAMG,EAAcJ,EAAS,KAAMC,CAAI,EACvCC,GAASE,EAAcJ,EAAS,QAASE,CAAO,CACtD,EAEWG,EAAc,CACzBC,EACAC,IAEAV,EACES,EACAC,EAAiB,CAAE,KAAMA,CAAe,EAAI,MAC9C,EAcWC,EAAmB,CAC9B,IAAK,CAIHC,EACAC,IAGS,IAAIC,IAA+C,CACxD,IAAMC,EAAaC,EAAeJ,EAAc,CAAC,EAC3CK,EAAcJ,EAAeE,CAAU,EAE7C,MAAO,CACL,KACEG,GACG,CACH,IAAMC,EAAS,SAAY,CACzB,OAAW,CAACC,EAAYvB,CAAM,IAAKiB,EACjC,MAAMC,EAAW,MAAMK,EAAYvB,CAAM,EAG3C,OAAOqB,EAAaG,EAAUJ,CAAW,CAAC,CAC5C,EAEA,MAAO,CACL,KAAM,MACJK,GACkB,CAClB,IAAMnB,EAAW,MAAMgB,EAAO,EAE9B,GAAI,OAAOG,GAAW,WACFA,EAAOnB,CAAQ,IAEf,IAAOG,EAAO,KAAK,UAC5B,MAAM,QAAQgB,CAAM,EAAG,CAChC,GAAM,CAACC,EAAO,GAAGC,CAAI,EAAIF,EAErB,OAAOC,GAAU,YACDA,EAAMpB,CAAQ,IAEd,IAAOG,EAAO,KAAK,EAGvC,IAAMT,EAAS,OAAO0B,GAAU,WAAaC,EAAOF,EAEpDf,EACE,MAAM,KAAKQ,EAAW,eAAe,OAAO,CAAC,EAC7ClB,CACF,CACF,CACF,CACF,CACF,CACF,CACF,CAGN","names":["assert","supertest","existingStream","streamId","events","expect","expectNewEvents","expectResponse","statusCode","options","response","body","headers","assert","assertMatches","expectError","errorCode","problemDetails","ApiSpecification","getEventStore","getApplication","givenStreams","eventStore","WrapEventStore","application","setupRequest","handle","streamName","supertest","verify","first","rest"]}
@@ -0,0 +1,2 @@
1
+ import{i as p}from"./chunk-ODC4O4D7.mjs";var o=(n=>(n.Empty="Empty",n.Pending="Pending",n.Confirmed="Confirmed",n.Canceled="Canceled",n))(o||{}),c={status:"Empty"},a=(e,{type:i,data:r})=>{switch(i){case"ShoppingCartOpened":return{id:r.shoppingCartId,clientId:r.clientId,openedAt:r.openedAt,productItems:[],status:"Pending"};case"ProductItemAddedToShoppingCart":{if(e.status!=="Pending")return e;let{productItems:d}=e,{productItem:n}=r;return{...e,productItems:p(d,n,t=>t.productId===n.productId&&t.unitPrice===n.unitPrice,t=>({...t,quantity:t.quantity+n.quantity}),()=>n)}}case"ProductItemRemovedFromShoppingCart":{if(e.status!=="Pending")return e;let{productItems:d}=e,{productItem:n}=r;return{...e,productItems:p(d,n,t=>t.productId===n.productId&&t.unitPrice===n.unitPrice,t=>({...t,quantity:t.quantity-n.quantity}))}}case"ShoppingCartConfirmed":return e.status!=="Pending"?e:{...e,status:"Confirmed",confirmedAt:r.confirmedAt};case"ShoppingCartCanceled":return e.status!=="Pending"?e:{...e,status:"Canceled",canceledAt:r.canceledAt}}},s=e=>e.reduce(a,c),u=(t=>(t.CART_IS_ALREADY_CLOSED="CART_IS_ALREADY_CLOSED",t.PRODUCT_ITEM_NOT_FOUND="PRODUCT_ITEM_NOT_FOUND",t.CART_IS_EMPTY="CART_IS_EMPTY",t.UNKNOWN_EVENT_TYPE="UNKNOWN_EVENT_TYPE",t.UNKNOWN_COMMAND_TYPE="UNKNOWN_COMMAND_TYPE",t))(u||{});export{o as a,c as b,a as c,s as d,u as e};
2
+ //# sourceMappingURL=chunk-XGEKWN7Q.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/e2e/decider/shoppingCart.ts"],"sourcesContent":["import { merge } from '@event-driven-io/emmett';\n\nexport interface ProductItem {\n productId: string;\n quantity: number;\n}\n\nexport type PricedProductItem = ProductItem & {\n unitPrice: number;\n};\n\nexport type ShoppingCartEvent =\n | {\n type: 'ShoppingCartOpened';\n data: {\n shoppingCartId: string;\n clientId: string;\n openedAt: Date;\n };\n }\n | {\n type: 'ProductItemAddedToShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n }\n | {\n type: 'ProductItemRemovedFromShoppingCart';\n data: {\n shoppingCartId: string;\n productItem: PricedProductItem;\n };\n }\n | {\n type: 'ShoppingCartConfirmed';\n data: {\n shoppingCartId: string;\n confirmedAt: Date;\n };\n }\n | {\n type: 'ShoppingCartCanceled';\n data: {\n shoppingCartId: string;\n canceledAt: Date;\n };\n };\n\nexport enum ShoppingCartStatus {\n Empty = 'Empty',\n Pending = 'Pending',\n Confirmed = 'Confirmed',\n Canceled = 'Canceled',\n}\n\nexport type Empty = { status: ShoppingCartStatus.Empty };\n\nexport type Pending = {\n status: ShoppingCartStatus.Pending;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n openedAt: Date;\n};\n\nexport type Confirmed = {\n status: ShoppingCartStatus.Confirmed;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n confirmedAt: Date;\n};\n\nexport type Canceled = {\n status: ShoppingCartStatus.Canceled;\n id: string;\n clientId: string;\n productItems: PricedProductItem[];\n canceledAt: Date;\n};\n\nexport type ShoppingCart = Empty | Pending | Confirmed | Canceled;\n\nexport const emptyShoppingCart: Empty = { status: ShoppingCartStatus.Empty };\n\nexport const evolve = (\n state: ShoppingCart,\n { type, data: event }: ShoppingCartEvent,\n): ShoppingCart => {\n switch (type) {\n case 'ShoppingCartOpened':\n return {\n id: event.shoppingCartId,\n clientId: event.clientId,\n openedAt: event.openedAt,\n productItems: [],\n status: ShoppingCartStatus.Pending,\n };\n case 'ProductItemAddedToShoppingCart': {\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n const { productItems } = state;\n const { productItem } = event;\n\n return {\n ...state,\n productItems: merge(\n productItems,\n productItem,\n (p) =>\n p.productId === productItem.productId &&\n p.unitPrice === productItem.unitPrice,\n (p) => {\n return {\n ...p,\n quantity: p.quantity + productItem.quantity,\n };\n },\n () => productItem,\n ),\n };\n }\n case 'ProductItemRemovedFromShoppingCart': {\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n const { productItems } = state;\n const { productItem } = event;\n return {\n ...state,\n productItems: merge(\n productItems,\n productItem,\n (p) =>\n p.productId === productItem.productId &&\n p.unitPrice === productItem.unitPrice,\n (p) => {\n return {\n ...p,\n quantity: p.quantity - productItem.quantity,\n };\n },\n ),\n };\n }\n case 'ShoppingCartConfirmed':\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n return {\n ...state,\n status: ShoppingCartStatus.Confirmed,\n confirmedAt: event.confirmedAt,\n };\n case 'ShoppingCartCanceled':\n if (state.status !== ShoppingCartStatus.Pending) return state;\n\n return {\n ...state,\n status: ShoppingCartStatus.Canceled,\n canceledAt: event.canceledAt,\n };\n }\n};\n\nexport const getShoppingCart = (events: ShoppingCartEvent[]): ShoppingCart => {\n return events.reduce<ShoppingCart>(evolve, emptyShoppingCart);\n};\n\nexport const enum ShoppingCartErrors {\n CART_IS_ALREADY_CLOSED = 'CART_IS_ALREADY_CLOSED',\n PRODUCT_ITEM_NOT_FOUND = 'PRODUCT_ITEM_NOT_FOUND',\n CART_IS_EMPTY = 'CART_IS_EMPTY',\n UNKNOWN_EVENT_TYPE = 'UNKNOWN_EVENT_TYPE',\n UNKNOWN_COMMAND_TYPE = 'UNKNOWN_COMMAND_TYPE',\n}\n"],"mappings":"yCAiDO,IAAKA,OACVA,EAAA,MAAQ,QACRA,EAAA,QAAU,UACVA,EAAA,UAAY,YACZA,EAAA,SAAW,WAJDA,OAAA,IAmCCC,EAA2B,CAAE,OAAQ,OAAyB,EAE9DC,EAAS,CACpBC,EACA,CAAE,KAAAC,EAAM,KAAMC,CAAM,IACH,CACjB,OAAQD,EAAM,CACZ,IAAK,qBACH,MAAO,CACL,GAAIC,EAAM,eACV,SAAUA,EAAM,SAChB,SAAUA,EAAM,SAChB,aAAc,CAAC,EACf,OAAQ,SACV,EACF,IAAK,iCAAkC,CACrC,GAAIF,EAAM,SAAW,UAA4B,OAAOA,EAExD,GAAM,CAAE,aAAAG,CAAa,EAAIH,EACnB,CAAE,YAAAI,CAAY,EAAIF,EAExB,MAAO,CACL,GAAGF,EACH,aAAcK,EACZF,EACAC,EACCE,GACCA,EAAE,YAAcF,EAAY,WAC5BE,EAAE,YAAcF,EAAY,UAC7BE,IACQ,CACL,GAAGA,EACH,SAAUA,EAAE,SAAWF,EAAY,QACrC,GAEF,IAAMA,CACR,CACF,CACF,CACA,IAAK,qCAAsC,CACzC,GAAIJ,EAAM,SAAW,UAA4B,OAAOA,EAExD,GAAM,CAAE,aAAAG,CAAa,EAAIH,EACnB,CAAE,YAAAI,CAAY,EAAIF,EACxB,MAAO,CACL,GAAGF,EACH,aAAcK,EACZF,EACAC,EACCE,GACCA,EAAE,YAAcF,EAAY,WAC5BE,EAAE,YAAcF,EAAY,UAC7BE,IACQ,CACL,GAAGA,EACH,SAAUA,EAAE,SAAWF,EAAY,QACrC,EAEJ,CACF,CACF,CACA,IAAK,wBACH,OAAIJ,EAAM,SAAW,UAAmCA,EAEjD,CACL,GAAGA,EACH,OAAQ,YACR,YAAaE,EAAM,WACrB,EACF,IAAK,uBACH,OAAIF,EAAM,SAAW,UAAmCA,EAEjD,CACL,GAAGA,EACH,OAAQ,WACR,WAAYE,EAAM,UACpB,CACJ,CACF,EAEaK,EAAmBC,GACvBA,EAAO,OAAqBT,EAAQD,CAAiB,EAG5CW,OAChBA,EAAA,uBAAyB,yBACzBA,EAAA,uBAAyB,yBACzBA,EAAA,cAAgB,gBAChBA,EAAA,mBAAqB,qBACrBA,EAAA,qBAAuB,uBALPA,OAAA","names":["ShoppingCartStatus","emptyShoppingCart","evolve","state","type","event","productItems","productItem","merge","p","getShoppingCart","events","ShoppingCartErrors"]}