@prosopo/api-express-router 3.2.9 → 3.3.1

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 (40) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +10 -9
  2. package/.turbo/turbo-build$colon$tsc.log +20 -20
  3. package/.turbo/turbo-build.log +10 -9
  4. package/CHANGELOG.md +65 -0
  5. package/dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs +13 -11
  6. package/dist/cjs/errorHandler.cjs +2 -7
  7. package/dist/cjs/errorResponse.cjs +29 -0
  8. package/dist/cjs/index.cjs +2 -0
  9. package/dist/cjs/middlewares/authMiddleware.cjs +34 -27
  10. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts.map +1 -1
  11. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js +14 -12
  12. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js.map +1 -1
  13. package/dist/errorHandler.d.ts +6 -6
  14. package/dist/errorHandler.d.ts.map +1 -1
  15. package/dist/errorHandler.js +2 -7
  16. package/dist/errorHandler.js.map +1 -1
  17. package/dist/errorResponse.d.ts +14 -0
  18. package/dist/errorResponse.d.ts.map +1 -0
  19. package/dist/errorResponse.js +27 -0
  20. package/dist/errorResponse.js.map +1 -0
  21. package/dist/errorSites.d.ts +14 -0
  22. package/dist/errorSites.d.ts.map +1 -0
  23. package/dist/errorSites.js +2 -0
  24. package/dist/errorSites.js.map +1 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/middlewares/authMiddleware.d.ts.map +1 -1
  30. package/dist/middlewares/authMiddleware.js +35 -28
  31. package/dist/middlewares/authMiddleware.js.map +1 -1
  32. package/dist/tests/apiExpressRouter.test-d.js +12 -1
  33. package/dist/tests/apiExpressRouter.test-d.js.map +1 -1
  34. package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.js +15 -9
  35. package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.js.map +1 -1
  36. package/dist/tests/unit/errorHandler.unit.test.js +151 -113
  37. package/dist/tests/unit/errorHandler.unit.test.js.map +1 -1
  38. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js +22 -33
  39. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js.map +1 -1
  40. package/package.json +16 -16
@@ -6,8 +6,8 @@ ViteCommonJSConfig: .
6
6
  '/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
7
7
  '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
8
8
  '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
9
- '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
10
9
  '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
11
11
  '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
12
12
  '/home/runner/work/captcha/captcha/packages/env/tsconfig.json',
13
13
  '/home/runner/work/captcha/captcha/packages/ipinfo/tsconfig.json',
@@ -26,8 +26,8 @@ ViteCommonJSConfig: .
26
26
  '@prosopo/logger',
27
27
  '@prosopo/util',
28
28
  '@prosopo/common',
29
- '@prosopo/locale',
30
29
  '@prosopo/types',
30
+ '@prosopo/locale',
31
31
  '@prosopo/util-crypto',
32
32
  '@prosopo/env',
33
33
  '@prosopo/ipinfo',
@@ -41,18 +41,19 @@ ViteCommonJSConfig: .
41
41
  ]
42
42
  }
43
43
  The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
44
- vite v8.1.5 building ssr environment for production...
44
+ vite v8.1.6 building ssr environment for production...
45
45
  Bundle build started
46
46
  
47
- ✓ 8 modules transformed.
47
+ ✓ 9 modules transformed.
48
48
  rendering chunks...
49
49
  computing gzip size...
50
- dist/cjs/errorHandler.cjs 0.45 kB │ gzip: 0.25 kB
50
+ dist/cjs/errorHandler.cjs 0.28 kB │ gzip: 0.18 kB
51
51
  dist/cjs/apiExpressRouterFactory.cjs 0.78 kB │ gzip: 0.35 kB
52
52
  dist/cjs/middlewares/jwtReplayGuard.cjs 0.97 kB │ gzip: 0.53 kB
53
- dist/cjs/index.cjs 1.42 kB │ gzip: 0.41 kB
54
- dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs 1.49 kB │ gzip: 0.62 kB
53
+ dist/cjs/errorResponse.cjs 1.20 kB │ gzip: 0.56 kB
54
+ dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs 1.36 kB │ gzip: 0.56 kB
55
+ dist/cjs/index.cjs 1.55 kB │ gzip: 0.44 kB
55
56
  dist/cjs/middlewares/requestLoggerMiddleware.cjs 1.81 kB │ gzip: 0.78 kB
56
- dist/cjs/middlewares/authMiddleware.cjs 2.47 kB │ gzip: 1.01 kB
57
+ dist/cjs/middlewares/authMiddleware.cjs 2.45 kB │ gzip: 0.95 kB
57
58
 
58
- ✓ built in 28ms
59
+ ✓ built in 32ms
@@ -1,5 +1,5 @@
1
1
  $ tsc --build --verbose
2
- 2:44:12 PM - Projects in this build:
2
+ 7:41:14 PM - Projects in this build:
3
3
  * ../../dev/config/tsconfig.json
4
4
  * ../util/tsconfig.json
5
5
  * ../logger/tsconfig.json
@@ -19,41 +19,41 @@ $ tsc --build --verbose
19
19
  * ../env/tsconfig.json
20
20
  * tsconfig.json
21
21
 
22
- 2:44:12 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
22
+ 7:41:14 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
23
23
 
24
- 2:44:12 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
24
+ 7:41:14 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
25
25
 
26
- 2:44:12 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
26
+ 7:41:14 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/tests/loggerBrowser.unit.test.ts' is older than output '../logger/tsconfig.tsbuildinfo'
27
27
 
28
- 2:44:12 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
28
+ 7:41:14 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/tests/apiRoute.unit.test.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
29
29
 
30
- 2:44:12 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/process.ts' is older than output '../locale/tsconfig.tsbuildinfo'
30
+ 7:41:14 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/process.ts' is older than output '../locale/tsconfig.tsbuildinfo'
31
31
 
32
- 2:44:12 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
32
+ 7:41:14 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
33
33
 
34
- 2:44:12 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
34
+ 7:41:14 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
35
35
 
36
- 2:44:12 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
36
+ 7:41:14 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/objectUtils.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
37
37
 
38
- 2:44:12 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/IpInfoService.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
38
+ 7:41:14 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/types.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
39
39
 
40
- 2:44:12 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
40
+ 7:41:14 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
41
41
 
42
- 2:44:12 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/tests/apiHarness.ts' is older than output '../api/tsconfig.tsbuildinfo'
42
+ 7:41:14 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
43
43
 
44
- 2:44:12 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
44
+ 7:41:14 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
45
45
 
46
- 2:44:12 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
46
+ 7:41:15 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
47
47
 
48
- 2:44:12 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/mongoGlobalSetup.ts' is older than output '../database/tsconfig.tsbuildinfo'
48
+ 7:41:15 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/unit/captchaLabel.unit.test.ts' is older than output '../database/tsconfig.tsbuildinfo'
49
49
 
50
- 2:44:12 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.test.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
50
+ 7:41:15 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.test.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
51
51
 
52
- 2:44:12 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
52
+ 7:41:15 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
53
53
 
54
- 2:44:12 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/tests/env.maintenance.unit.test.ts' is older than output '../env/tsconfig.tsbuildinfo'
54
+ 7:41:15 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/tests/env.maintenance.unit.test.ts' is older than output '../env/tsconfig.tsbuildinfo'
55
55
 
56
- 2:44:12 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
56
+ 7:41:15 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
57
57
 
58
- 2:44:12 PM - Building project '/home/runner/work/captcha/captcha/packages/api-express-router/tsconfig.json'...
58
+ 7:41:15 PM - Building project '/home/runner/work/captcha/captcha/packages/api-express-router/tsconfig.json'...
59
59
 
@@ -7,8 +7,8 @@ ViteEsmConfig: .
7
7
  '/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
8
8
  '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
9
9
  '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
10
- '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
11
10
  '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
12
12
  '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
13
13
  '/home/runner/work/captcha/captcha/packages/env/tsconfig.json',
14
14
  '/home/runner/work/captcha/captcha/packages/ipinfo/tsconfig.json',
@@ -27,8 +27,8 @@ ViteEsmConfig: .
27
27
  '@prosopo/logger',
28
28
  '@prosopo/util',
29
29
  '@prosopo/common',
30
- '@prosopo/locale',
31
30
  '@prosopo/types',
31
+ '@prosopo/locale',
32
32
  '@prosopo/util-crypto',
33
33
  '@prosopo/env',
34
34
  '@prosopo/ipinfo',
@@ -42,19 +42,20 @@ ViteEsmConfig: .
42
42
  ]
43
43
  }
44
44
  The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
45
- vite v8.1.5 building ssr environment for production...
45
+ vite v8.1.6 building ssr environment for production...
46
46
  Bundle build started
47
47
  
48
- ✓ 8 modules transformed.
48
+ ✓ 9 modules transformed.
49
49
  rendering chunks...
50
50
  computing gzip size...
51
51
  dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
52
- dist/errorHandler.js 0.42 kB │ gzip: 0.24 kB
52
+ dist/errorHandler.js 0.24 kB │ gzip: 0.17 kB
53
53
  dist/apiExpressRouterFactory.js 0.71 kB │ gzip: 0.34 kB
54
- dist/index.js 0.94 kB │ gzip: 0.34 kB
55
54
  dist/middlewares/jwtReplayGuard.js 0.95 kB │ gzip: 0.53 kB
56
- dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js 1.30 kB │ gzip: 0.59 kB
55
+ dist/index.js 1.02 kB │ gzip: 0.36 kB
56
+ dist/errorResponse.js 1.08 kB │ gzip: 0.55 kB
57
+ dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js 1.15 kB │ gzip: 0.52 kB
57
58
  dist/middlewares/requestLoggerMiddleware.js 1.75 kB │ gzip: 0.76 kB
58
- dist/middlewares/authMiddleware.js 2.34 kB │ gzip: 0.98 kB
59
+ dist/middlewares/authMiddleware.js 2.31 kB │ gzip: 0.92 kB
59
60
 
60
- ✓ built in 37ms
61
+ ✓ built in 45ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # @prosopo/api-express-router
2
2
 
3
+ ## 3.3.1
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [49892fc]
7
+ - @prosopo/locale@3.12.1
8
+ - @prosopo/types@5.17.1
9
+ - @prosopo/common@3.3.0
10
+ - @prosopo/env@3.6.79
11
+
12
+ ## 3.3.0
13
+ ### Minor Changes
14
+
15
+ - d2148c8: Errors now carry a fixed code and a site instead of a translation key.
16
+
17
+ Every error is a `ProsopoError` with a `code` from one list in
18
+ `@prosopo/common` (`ERROR_CODES`) and an `errorSite` such as `PROV-12`, which
19
+ names the one place it was thrown. Together they make the `errorId`, e.g.
20
+ `SITE_KEY_INVALID:PROV-31`, which the widget shows after the message so a
21
+ screenshot is enough to find the throw.
22
+
23
+ What a client sees:
24
+
25
+ - A public error (bad site key, blocked network, and so on) sends its code,
26
+ English message, data and errorId.
27
+ - Anything else sends only `BACKEND_ERROR:<site>` (or `FRONTEND_ERROR:<site>`
28
+ from the widget) and a status. Internal details never leave the server.
29
+
30
+ The provider no longer translates errors. The widget looks up
31
+ `ERRORS.<CODE>` in its catalogue and falls back to the English message. The
32
+ old error classes (`ProsopoApiError`, `ProsopoEnvError` and the rest), the
33
+ `key`/`messageEn` fields and `localiseErrorMessage` are gone.
34
+
35
+ Other changes in behaviour:
36
+
37
+ - An error with no specific code is a hidden 500.
38
+ - Errors no longer log themselves when they are created. The server logs each
39
+ unhandled one once: 5xx as errors, 4xx at debug.
40
+ - An invalid PoW signature is a 401 instead of a 500.
41
+ - `stringifyBigInts` returns a copy instead of changing its input, so frozen
42
+ error context can be logged.
43
+ - The provider's last hand-written error replies now use the same error body.
44
+ These were the missing-header 401s, the access-policy block, autoBan, the
45
+ metrics 401/403 and the rate limiter. The rate limiter answers with a new
46
+ public `RATE_LIMITED` (429) code.
47
+
48
+ ### Patch Changes
49
+
50
+ - 46b97b7: Roll up the open Dependabot updates: express 5 (with `@types/express` 5), dotenv 18, undici 8, geolib 4, vitest 5, vite 8.1.6 everywhere, 17 minor and patch bumps (Babel, mongoose, i18next, ip-address, turbo and others), `@angular/router` in the Angular demo, and a GitHub Actions bump.
51
+
52
+ The whole vitest family moves to 5.0.4, including `@vitest/coverage-v8`, because `@vitest/browser-playwright` 5 only works with vitest 5. The `@types/express-serve-static-core` override moves to 5.1.3 to match `@types/express` 5.
53
+
54
+ `@prosopo/dotenv` now loads env files with `quiet: true`. Since dotenv 17, every load prints an "injected env" line to stderr unless told not to.
55
+ - Updated dependencies [46b97b7]
56
+ - Updated dependencies [d2148c8]
57
+ - Updated dependencies [2bcf2fe]
58
+ - Updated dependencies [860948c]
59
+ - @prosopo/api-route@2.6.65
60
+ - @prosopo/common@3.3.0
61
+ - @prosopo/env@3.6.78
62
+ - @prosopo/locale@3.12.0
63
+ - @prosopo/logger@2.1.5
64
+ - @prosopo/types@5.17.0
65
+ - @prosopo/util@3.3.16
66
+ - @prosopo/util-crypto@13.6.1
67
+
3
68
  ## 3.2.9
4
69
  ### Patch Changes
5
70
 
@@ -1,3 +1,4 @@
1
+ const require_errorResponse = require("../errorResponse.cjs");
1
2
  let _prosopo_common = require("@prosopo/common");
2
3
  let _prosopo_util = require("@prosopo/util");
3
4
  //#region src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts
@@ -11,24 +12,25 @@ var ApiExpressDefaultEndpointAdapter = class {
11
12
  try {
12
13
  args = endpoint.getRequestArgsSchema()?.parse(request.body);
13
14
  } catch (error) {
14
- return next(new _prosopo_common.ProsopoApiError("API.PARSE_ERROR", { context: {
15
- code: 400,
16
- error
17
- } }));
15
+ return next(new _prosopo_common.ProsopoError({
16
+ code: "INVALID_REQUEST",
17
+ errorSite: "APIX-1",
18
+ message: "Error parsing request",
19
+ cause: error
20
+ }));
18
21
  }
19
22
  try {
20
23
  const apiEndpointResponse = await endpoint.processRequest(args, request.logger);
21
24
  const responseObject = (0, _prosopo_util.stringifyBigInts)(apiEndpointResponse);
22
25
  response.json(responseObject);
23
26
  } catch (error) {
24
- request.logger.error(() => ({ err: error }));
25
- const responseError = error instanceof _prosopo_common.ProsopoApiError || error instanceof _prosopo_common.ProsopoBaseError && typeof error.context?.code === "number" ? error : new _prosopo_common.ProsopoApiError("API.UNKNOWN", {
26
- context: { code: this.errorStatusCode },
27
- silent: true
27
+ const responseError = (0, _prosopo_common.isProsopoError)(error) ? error : new _prosopo_common.ProsopoError({
28
+ code: "UNEXPECTED",
29
+ errorSite: "APIX-2",
30
+ cause: error,
31
+ status: this.errorStatusCode
28
32
  });
29
- const { code, statusMessage, jsonError } = (0, _prosopo_common.unwrapError)(responseError, request.i18n);
30
- response.statusMessage = statusMessage;
31
- response.status(code).json({ error: jsonError });
33
+ require_errorResponse.sendErrorResponse(responseError, "APIX-6", response, request.logger);
32
34
  }
33
35
  }
34
36
  };
@@ -1,12 +1,7 @@
1
- let _prosopo_common = require("@prosopo/common");
1
+ const require_errorResponse = require("./errorResponse.cjs");
2
2
  //#region src/errorHandler.ts
3
3
  var handleErrors = (err, request, response, next) => {
4
- const { code, statusMessage, jsonError } = (0, _prosopo_common.unwrapError)(err, request.i18n);
5
- response.statusMessage = statusMessage;
6
- response.set("content-type", "application/json");
7
- response.status(code);
8
- response.send({ error: jsonError });
9
- response.end();
4
+ require_errorResponse.sendErrorResponse(err, "APIX-7", response, request.logger);
10
5
  };
11
6
  //#endregion
12
7
  exports.handleErrors = handleErrors;
@@ -0,0 +1,29 @@
1
+ let _prosopo_common = require("@prosopo/common");
2
+ //#region src/errorResponse.ts
3
+ /**
4
+ * Answers with an error the handler raised on purpose. Not logged: the
5
+ * handler already knows what happened and logs the decision itself.
6
+ */
7
+ var sendProsopoError = (response, error) => response.status(error.status).json({ error: (0, _prosopo_common.toPublicError)(error, "BACKEND_ERROR") });
8
+ /**
9
+ * Errors are only logged where nobody handled them. A fault (5xx) is logged as
10
+ * an error; a client's mistake (4xx) only at debug, since logging every bad
11
+ * request is noise.
12
+ */
13
+ var logUnhandledError = (logger, error) => {
14
+ const record = () => ({
15
+ msg: error.errorId,
16
+ data: { error: (0, _prosopo_common.describeError)(error) }
17
+ });
18
+ if ((0, _prosopo_common.isSevereError)(error)) logger?.error(record);
19
+ else logger?.debug(record);
20
+ };
21
+ var sendErrorResponse = (err, fallbackSite, response, logger) => {
22
+ const { error, status, body } = (0, _prosopo_common.toApiError)(err, fallbackSite);
23
+ logUnhandledError(logger, error);
24
+ response.status(status).json(body);
25
+ };
26
+ //#endregion
27
+ exports.logUnhandledError = logUnhandledError;
28
+ exports.sendErrorResponse = sendErrorResponse;
29
+ exports.sendProsopoError = sendProsopoError;
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_errorResponse = require("./errorResponse.cjs");
2
3
  const require_errorHandler = require("./errorHandler.cjs");
3
4
  const require_apiExpressRouterFactory = require("./apiExpressRouterFactory.cjs");
4
5
  const require_apiExpressDefaultEndpointAdapter = require("./endpointAdapter/apiExpressDefaultEndpointAdapter.cjs");
@@ -17,4 +18,5 @@ exports.createApiExpressDefaultEndpointAdapter = createApiExpressDefaultEndpoint
17
18
  exports.createMemoryJwtReplayGuard = require_jwtReplayGuard.createMemoryJwtReplayGuard;
18
19
  exports.handleErrors = require_errorHandler.handleErrors;
19
20
  exports.requestLoggerMiddleware = require_requestLoggerMiddleware.requestLoggerMiddleware;
21
+ exports.sendProsopoError = require_errorResponse.sendProsopoError;
20
22
  exports.verifySignature = require_authMiddleware.verifySignature;
@@ -1,6 +1,5 @@
1
1
  let _prosopo_common = require("@prosopo/common");
2
2
  let _polkadot_util = require("@polkadot/util");
3
- let _prosopo_locale = require("@prosopo/locale");
4
3
  //#region src/middlewares/authMiddleware.ts
5
4
  var verifyWith = (key, jwt, options) => {
6
5
  if (!key) return void 0;
@@ -21,49 +20,57 @@ var authMiddleware = (pair, authAccount, options = {}) => {
21
20
  next();
22
21
  return;
23
22
  }
24
- unauthorized(req, res, "API.UNAUTHORIZED");
23
+ unauthorized(res);
25
24
  return;
26
25
  } catch (err) {
27
- req.logger.error(() => ({
26
+ req.logger.debug(() => ({
28
27
  err,
29
28
  msg: "Auth Middleware Error"
30
29
  }));
31
- unauthorized(req, res, translationKeyOf(err));
30
+ unauthorized(res, err);
32
31
  return;
33
32
  }
34
33
  };
35
34
  };
36
- var translationKeyOf = (err) => err instanceof _prosopo_common.ProsopoBaseError && err.translationKey !== void 0 && (0, _prosopo_locale.isTranslationKey)(err.translationKey) ? err.translationKey : "API.UNAUTHORIZED";
37
- var unauthorized = (req, res, key) => {
38
- const body = { error: {
39
- code: 401,
40
- key,
41
- message: req.i18n ? req.i18n.t(key) : key
42
- } };
43
- res.status(401).json(body);
35
+ var unauthorized = (res, cause) => {
36
+ const error = (0, _prosopo_common.isProsopoError)(cause, "UNAUTHORIZED") ? cause : new _prosopo_common.ProsopoError({
37
+ code: "UNAUTHORIZED",
38
+ errorSite: "APIX-8",
39
+ cause
40
+ });
41
+ const body = { error: (0, _prosopo_common.toPublicError)(error, "BACKEND_ERROR") };
42
+ res.status(error.status).json(body);
44
43
  };
45
44
  var extractJWT = (req) => {
46
45
  const authHeader = req.headers.Authorization || req.headers.authorization;
47
- if (!authHeader || typeof authHeader !== "string") throw new _prosopo_common.ProsopoApiError("GENERAL.MISSING_AUTH_HEADER", { context: {
48
- error: "Missing Authorization header",
49
- code: 401
50
- } });
46
+ if (!authHeader || typeof authHeader !== "string") throw new _prosopo_common.ProsopoError({
47
+ code: "UNAUTHORIZED",
48
+ errorSite: "APIX-3",
49
+ message: "Missing authorization header",
50
+ context: { error: "Missing Authorization header" }
51
+ });
51
52
  const jwt = authHeader.replace("Bearer ", "");
52
- if (!jwt) throw new _prosopo_common.ProsopoApiError("GENERAL.INVALID_JWT", { context: {
53
- error: "Missing JWT",
54
- code: 400
55
- } });
53
+ if (!jwt) throw new _prosopo_common.ProsopoError({
54
+ code: "UNAUTHORIZED",
55
+ errorSite: "APIX-4",
56
+ message: "Invalid JWT",
57
+ context: { error: "Missing JWT" }
58
+ });
56
59
  return jwt;
57
60
  };
58
61
  var verifySignature = (signature, message, pair) => {
59
62
  const u8Sig = (0, _polkadot_util.hexToU8a)(signature);
60
- if (!pair.verify(message, u8Sig, pair.publicKey)) throw new _prosopo_common.ProsopoApiError("GENERAL.INVALID_SIGNATURE", { context: {
61
- error: "Signature verification failed",
62
- code: 401,
63
- account: pair.address,
64
- message,
65
- signature
66
- } });
63
+ if (!pair.verify(message, u8Sig, pair.publicKey)) throw new _prosopo_common.ProsopoError({
64
+ code: "UNAUTHORIZED",
65
+ errorSite: "APIX-5",
66
+ message: "Invalid signature",
67
+ context: {
68
+ error: "Signature verification failed",
69
+ account: pair.address,
70
+ message,
71
+ signature
72
+ }
73
+ });
67
74
  };
68
75
  //#endregion
69
76
  exports.authMiddleware = authMiddleware;
@@ -1 +1 @@
1
- {"version":3,"file":"apiExpressDefaultEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,cAAM,gCAAiC,YAAW,yBAAyB;IAEzE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM;IAG5B,aAAa,CACzB,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC;CAoDhB;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
1
+ {"version":3,"file":"apiExpressDefaultEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,cAAM,gCAAiC,YAAW,yBAAyB;IAEzE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM;IAG5B,aAAa,CACzB,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC;CAuChB;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
- import { ProsopoApiError, ProsopoBaseError, unwrapError } from "@prosopo/common";
1
+ import { sendErrorResponse } from "../errorResponse.js";
2
+ import { ProsopoError, isProsopoError } from "@prosopo/common";
2
3
  import { stringifyBigInts } from "@prosopo/util";
3
4
  //#region src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts
4
5
  var ApiExpressDefaultEndpointAdapter = class {
@@ -11,22 +12,23 @@ var ApiExpressDefaultEndpointAdapter = class {
11
12
  try {
12
13
  args = endpoint.getRequestArgsSchema()?.parse(request.body);
13
14
  } catch (error) {
14
- return next(new ProsopoApiError("API.PARSE_ERROR", { context: {
15
- code: 400,
16
- error
17
- } }));
15
+ return next(new ProsopoError({
16
+ code: "INVALID_REQUEST",
17
+ errorSite: "APIX-1",
18
+ message: "Error parsing request",
19
+ cause: error
20
+ }));
18
21
  }
19
22
  try {
20
23
  const responseObject = stringifyBigInts(await endpoint.processRequest(args, request.logger));
21
24
  response.json(responseObject);
22
25
  } catch (error) {
23
- request.logger.error(() => ({ err: error }));
24
- const { code, statusMessage, jsonError } = unwrapError(error instanceof ProsopoApiError || error instanceof ProsopoBaseError && typeof error.context?.code === "number" ? error : new ProsopoApiError("API.UNKNOWN", {
25
- context: { code: this.errorStatusCode },
26
- silent: true
27
- }), request.i18n);
28
- response.statusMessage = statusMessage;
29
- response.status(code).json({ error: jsonError });
26
+ sendErrorResponse(isProsopoError(error) ? error : new ProsopoError({
27
+ code: "UNEXPECTED",
28
+ errorSite: "APIX-2",
29
+ cause: error,
30
+ status: this.errorStatusCode
31
+ }), "APIX-6", response, request.logger);
30
32
  }
31
33
  }
32
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"apiExpressDefaultEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAeA,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,WAAW,GACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKjD,MAAM,gCAAgC;IACrC,YACkB,QAAkB,EAClB,eAAuB;QADvB,aAAQ,GAAR,QAAQ,CAAU;QAClB,oBAAe,GAAf,eAAe,CAAQ;IACtC,CAAC;IAEG,KAAK,CAAC,aAAa,CACzB,QAA0C,EAC1C,OAAgB,EAChB,QAAkB,EAClB,IAAkB;QAElB,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACJ,IAAI,GAAG,QAAQ,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CACV,IAAI,eAAe,CAAC,iBAAiB,EAAE;gBACtC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;aACpC,CAAC,CACF,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,cAAc,CACxD,IAAI,EACJ,OAAO,CAAC,MAAM,CACd,CAAC;YAGF,MAAM,cAAc,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YAE7D,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC3B,GAAG,EAAE,KAAK;aACV,CAAC,CAAC,CAAC;YASJ,MAAM,aAAa,GAClB,KAAK,YAAY,eAAe;gBAChC,CAAC,KAAK,YAAY,gBAAgB;oBACjC,OAAO,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,QAAQ,CAAC;gBACxC,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,eAAe,CAAC,aAAa,EAAE;oBACnC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE;oBACvC,MAAM,EAAE,IAAI;iBACZ,CAAC,CAAC;YAEN,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,WAAW,CACrD,aAAa,EACb,OAAO,CAAC,IAAI,CACZ,CAAC;YACF,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;YACvC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
1
+ {"version":3,"file":"apiExpressDefaultEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,gCAAgC;IACrC,YACkB,QAAkB,EAClB,eAAuB;QADvB,aAAQ,GAAR,QAAQ,CAAU;QAClB,oBAAe,GAAf,eAAe,CAAQ;IACtC,CAAC;IAEG,KAAK,CAAC,aAAa,CACzB,QAA0C,EAC1C,OAAgB,EAChB,QAAkB,EAClB,IAAkB;QAElB,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACJ,IAAI,GAAG,QAAQ,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CACV,IAAI,YAAY,CAAC;gBAChB,IAAI,EAAE,iBAAiB;gBACvB,SAAS,EAAE,QAAQ;gBACnB,OAAO,EAAE,uBAAuB;gBAChC,KAAK,EAAE,KAAK;aACZ,CAAC,CACF,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,cAAc,CACxD,IAAI,EACJ,OAAO,CAAC,MAAM,CACd,CAAC;YAGF,MAAM,cAAc,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YAE7D,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAGhB,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC;gBAC1C,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,YAAY,CAAC;oBACjB,IAAI,EAAE,YAAY;oBAClB,SAAS,EAAE,QAAQ;oBACnB,KAAK,EAAE,KAAK;oBACZ,MAAM,EAAE,IAAI,CAAC,eAAe;iBAC5B,CAAC,CAAC;YACL,iBAAiB,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
- import { type ProsopoApiError } from "@prosopo/common";
2
- import type { NextFunction, Request, Response } from "express";
3
- import type { ZodError } from "zod";
4
- type ErrorResponse = Pick<Response, "statusMessage" | "set" | "status" | "send" | "end">;
5
- export declare const handleErrors: (err: ProsopoApiError | SyntaxError | ZodError, request: Pick<Request, "i18n">, response: ErrorResponse, next: NextFunction) => void;
6
- export {};
1
+ import type { Logger } from "@prosopo/logger";
2
+ import type { NextFunction, Request } from "express";
3
+ import { type ErrorResponse } from "./errorResponse.js";
4
+ export declare const handleErrors: (err: unknown, request: Request | {
5
+ logger?: Logger;
6
+ }, response: ErrorResponse, next: NextFunction) => void;
7
7
  //# sourceMappingURL=errorHandler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,eAAe,EAAe,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,KAAK,aAAa,GAAG,IAAI,CACxB,QAAQ,EACR,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CACnD,CAAC;AAEF,eAAO,MAAM,YAAY,QACnB,eAAe,GAAG,WAAW,GAAG,QAAQ,WACpC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YACpB,aAAa,QACjB,YAAY,KAChB,IAOF,CAAC"}
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,oBAAoB,CAAC;AAM3E,eAAO,MAAM,YAAY,QACnB,OAAO,WACH,OAAO,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,YAC5B,aAAa,QACjB,YAAY,KAChB,IAEF,CAAC"}
@@ -1,12 +1,7 @@
1
- import { unwrapError } from "@prosopo/common";
1
+ import { sendErrorResponse } from "./errorResponse.js";
2
2
  //#region src/errorHandler.ts
3
3
  var handleErrors = (err, request, response, next) => {
4
- const { code, statusMessage, jsonError } = unwrapError(err, request.i18n);
5
- response.statusMessage = statusMessage;
6
- response.set("content-type", "application/json");
7
- response.status(code);
8
- response.send({ error: jsonError });
9
- response.end();
4
+ sendErrorResponse(err, "APIX-7", response, request.logger);
10
5
  };
11
6
  //#endregion
12
7
  export { handleErrors };
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAwB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AASpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,GAA6C,EAC7C,OAA8B,EAC9B,QAAuB,EACvB,IAAkB,EACX,EAAE;IACT,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAM3E,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,GAAY,EACZ,OAAsC,EACtC,QAAuB,EACvB,IAAkB,EACX,EAAE;IACT,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC5D,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type ErrorSite, type ProsopoError } from "@prosopo/common";
2
+ import type { Logger } from "@prosopo/logger";
3
+ export interface ErrorResponse {
4
+ status(code: number): ErrorResponse;
5
+ json(body: unknown): unknown;
6
+ }
7
+ export interface ChainableResponse<R> {
8
+ status(code: number): R;
9
+ json(body: unknown): R;
10
+ }
11
+ export declare const sendProsopoError: <R extends ChainableResponse<R>>(response: R, error: ProsopoError) => R;
12
+ export declare const logUnhandledError: (logger: Logger | undefined, error: ProsopoError) => void;
13
+ export declare const sendErrorResponse: (err: unknown, fallbackSite: ErrorSite, response: ErrorResponse, logger: Logger | undefined) => void;
14
+ //# sourceMappingURL=errorResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorResponse.d.ts","sourceRoot":"","sources":["../src/errorResponse.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,SAAS,EACd,KAAK,YAAY,EAKjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC;CACvB;AAMD,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,iBAAiB,CAAC,CAAC,CAAC,YACpD,CAAC,SACJ,YAAY,KACjB,CAGsD,CAAC;AAO1D,eAAO,MAAM,iBAAiB,WACrB,MAAM,GAAG,SAAS,SACnB,YAAY,KACjB,IAOF,CAAC;AAEF,eAAO,MAAM,iBAAiB,QACxB,OAAO,gBACE,SAAS,YACb,aAAa,UACf,MAAM,GAAG,SAAS,KACxB,IAIF,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { describeError, isSevereError, toApiError, toPublicError } from "@prosopo/common";
2
+ //#region src/errorResponse.ts
3
+ /**
4
+ * Answers with an error the handler raised on purpose. Not logged: the
5
+ * handler already knows what happened and logs the decision itself.
6
+ */
7
+ var sendProsopoError = (response, error) => response.status(error.status).json({ error: toPublicError(error, "BACKEND_ERROR") });
8
+ /**
9
+ * Errors are only logged where nobody handled them. A fault (5xx) is logged as
10
+ * an error; a client's mistake (4xx) only at debug, since logging every bad
11
+ * request is noise.
12
+ */
13
+ var logUnhandledError = (logger, error) => {
14
+ const record = () => ({
15
+ msg: error.errorId,
16
+ data: { error: describeError(error) }
17
+ });
18
+ if (isSevereError(error)) logger?.error(record);
19
+ else logger?.debug(record);
20
+ };
21
+ var sendErrorResponse = (err, fallbackSite, response, logger) => {
22
+ const { error, status, body } = toApiError(err, fallbackSite);
23
+ logUnhandledError(logger, error);
24
+ response.status(status).json(body);
25
+ };
26
+ //#endregion
27
+ export { logUnhandledError, sendErrorResponse, sendProsopoError };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorResponse.js","sourceRoot":"","sources":["../src/errorResponse.ts"],"names":[],"mappings":"AAcA,OAAO,EAGN,aAAa,EACb,aAAa,EACb,UAAU,EACV,aAAa,GACb,MAAM,iBAAiB,CAAC;AAiBzB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,QAAW,EACX,KAAmB,EACf,EAAE,CACN,QAAQ;KACN,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;KACpB,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;AAO1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAChC,MAA0B,EAC1B,KAAmB,EACZ,EAAE;IACT,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC;QACrB,GAAG,EAAE,KAAK,CAAC,OAAO;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE;KACrC,CAAC,CAAC;IACH,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;;QAC3C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAChC,GAAY,EACZ,YAAuB,EACvB,QAAuB,EACvB,MAA0B,EACnB,EAAE;IACT,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC9D,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ declare module "@prosopo/common" {
2
+ interface ErrorSites {
3
+ "APIX-1": true;
4
+ "APIX-2": true;
5
+ "APIX-3": true;
6
+ "APIX-4": true;
7
+ "APIX-5": true;
8
+ "APIX-6": true;
9
+ "APIX-7": true;
10
+ "APIX-8": true;
11
+ }
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=errorSites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorSites.d.ts","sourceRoot":"","sources":["../src/errorSites.ts"],"names":[],"mappings":"AAcA,OAAO,QAAQ,iBAAiB,CAAC;IAChC,UAAU,UAAU;QACnB,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;KACf;CACD;AAED,OAAO,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errorSites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorSites.js","sourceRoot":"","sources":["../src/errorSites.ts"],"names":[],"mappings":""}