@hartl-services/medusa-base 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.withSentryErrorReporting = withSentryErrorReporting;
|
|
37
|
+
const Sentry = __importStar(require("@sentry/node"));
|
|
38
|
+
/**
|
|
39
|
+
* Medusa's own HTTP error-handler middleware fully "handles" every thrown
|
|
40
|
+
* route/workflow error via logger.error(...) before it can ever reach an
|
|
41
|
+
* uncaught-exception process hook, so Sentry's default Node integrations
|
|
42
|
+
* never see it. Bridging logger.error(...) itself is the only place that
|
|
43
|
+
* reliably captures every error Medusa's framework already logs internally.
|
|
44
|
+
* Errors that Medusa logs through logger.warn(err) (failing event
|
|
45
|
+
* subscribers) are reported too, at warning level.
|
|
46
|
+
*/
|
|
47
|
+
function withSentryErrorReporting(logger) {
|
|
48
|
+
const originalError = logger.error.bind(logger);
|
|
49
|
+
const originalWarn = logger.warn.bind(logger);
|
|
50
|
+
return {
|
|
51
|
+
panic: logger.panic.bind(logger),
|
|
52
|
+
shouldLog: logger.shouldLog.bind(logger),
|
|
53
|
+
setLogLevel: logger.setLogLevel.bind(logger),
|
|
54
|
+
unsetLogLevel: logger.unsetLogLevel.bind(logger),
|
|
55
|
+
activity: logger.activity.bind(logger),
|
|
56
|
+
progress: logger.progress.bind(logger),
|
|
57
|
+
failure: logger.failure.bind(logger),
|
|
58
|
+
success: logger.success.bind(logger),
|
|
59
|
+
silly: logger.silly.bind(logger),
|
|
60
|
+
debug: logger.debug.bind(logger),
|
|
61
|
+
verbose: logger.verbose.bind(logger),
|
|
62
|
+
http: logger.http.bind(logger),
|
|
63
|
+
info: logger.info.bind(logger),
|
|
64
|
+
// Medusa's Redis Event Bus logs a failing subscriber's exception with
|
|
65
|
+
// warn(err), even on the final retry, so an Error passed to warn is a real
|
|
66
|
+
// failure too. Plain warning messages stay out of Sentry.
|
|
67
|
+
warn: (message) => {
|
|
68
|
+
if (message instanceof Error) {
|
|
69
|
+
Sentry.captureException(message, { level: "warning" });
|
|
70
|
+
}
|
|
71
|
+
return originalWarn(message);
|
|
72
|
+
},
|
|
73
|
+
log: logger.log.bind(logger),
|
|
74
|
+
error: (messageOrError, error) => {
|
|
75
|
+
const exception = error ?? (messageOrError instanceof Error ? messageOrError : new Error(messageOrError));
|
|
76
|
+
const loggerMessage = error && typeof messageOrError === "string" ? messageOrError : undefined;
|
|
77
|
+
Sentry.captureException(exception, loggerMessage ? { extra: { loggerMessage } } : undefined);
|
|
78
|
+
return originalError(messageOrError, error);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VudHJ5LWxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wdWJsaWMvc2VudHJ5LWxvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVlBLDREQTBDQztBQXRERCxxREFBc0M7QUFHdEM7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQix3QkFBd0IsQ0FBQyxNQUFjO0lBQ3JELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQy9DLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRTdDLE9BQU87UUFDTCxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2hDLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDeEMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM1QyxhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2hELFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDdEMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN0QyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3BDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNoQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2hDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM5QixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLHNFQUFzRTtRQUN0RSwyRUFBMkU7UUFDM0UsMERBQTBEO1FBQzFELElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2hCLElBQUssT0FBbUIsWUFBWSxLQUFLLEVBQUUsQ0FBQztnQkFDMUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO1lBQ3hELENBQUM7WUFDRCxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUM5QixDQUFDO1FBQ0QsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM1QixLQUFLLEVBQUUsQ0FBQyxjQUFjLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDL0IsTUFBTSxTQUFTLEdBQ2IsS0FBSyxJQUFJLENBQUMsY0FBYyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFBO1lBQ3pGLE1BQU0sYUFBYSxHQUNqQixLQUFLLElBQUksT0FBTyxjQUFjLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtZQUUxRSxNQUFNLENBQUMsZ0JBQWdCLENBQ3JCLFNBQVMsRUFDVCxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUN6RCxDQUFBO1lBRUQsT0FBTyxhQUFhLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFBO1FBQzdDLENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQyJ9
|
package/README.md
CHANGED
|
@@ -230,3 +230,26 @@ Affiliate 100 (`affiliate-validate-complete-cart`,
|
|
|
230
230
|
instead of silently leaving partial state.
|
|
231
231
|
- The base never swallows a participant error and never reads toggles here.
|
|
232
232
|
|
|
233
|
+
|
|
234
|
+
## Sentry logger wrapper
|
|
235
|
+
|
|
236
|
+
`@hartl-services/medusa-base/sentry-logger` exports `withSentryErrorReporting(logger)`,
|
|
237
|
+
formerly published as `@hartl-services/medusa-sentry-logger`. Medusa's HTTP
|
|
238
|
+
error handler catches thrown route and workflow errors and only logs them, so
|
|
239
|
+
Sentry's default Node integrations never see them; wrapping the logger reports
|
|
240
|
+
every `logger.error(...)` and every `Error` passed to `logger.warn(...)` (at
|
|
241
|
+
level `warning`). It is a plain library import for `medusa-config.ts`, not a
|
|
242
|
+
Medusa plugin feature, and needs `@sentry/node` (an optional peer dependency):
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import { logger } from "@medusajs/framework/logger";
|
|
246
|
+
import { withSentryErrorReporting } from "@hartl-services/medusa-base/sentry-logger";
|
|
247
|
+
|
|
248
|
+
module.exports = defineConfig({
|
|
249
|
+
logger: withSentryErrorReporting(logger),
|
|
250
|
+
// ...
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Initialize Sentry in `instrumentation.ts` as usual; without a `SENTRY_DSN` the
|
|
255
|
+
wrapper is inert.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Logger } from "@medusajs/framework/types";
|
|
2
|
+
/**
|
|
3
|
+
* Medusa's own HTTP error-handler middleware fully "handles" every thrown
|
|
4
|
+
* route/workflow error via logger.error(...) before it can ever reach an
|
|
5
|
+
* uncaught-exception process hook, so Sentry's default Node integrations
|
|
6
|
+
* never see it. Bridging logger.error(...) itself is the only place that
|
|
7
|
+
* reliably captures every error Medusa's framework already logs internally.
|
|
8
|
+
* Errors that Medusa logs through logger.warn(err) (failing event
|
|
9
|
+
* subscribers) are reported too, at warning level.
|
|
10
|
+
*/
|
|
11
|
+
export declare function withSentryErrorReporting(logger: Logger): Logger;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.withSentryErrorReporting = withSentryErrorReporting;
|
|
37
|
+
const Sentry = __importStar(require("@sentry/node"));
|
|
38
|
+
/**
|
|
39
|
+
* Medusa's own HTTP error-handler middleware fully "handles" every thrown
|
|
40
|
+
* route/workflow error via logger.error(...) before it can ever reach an
|
|
41
|
+
* uncaught-exception process hook, so Sentry's default Node integrations
|
|
42
|
+
* never see it. Bridging logger.error(...) itself is the only place that
|
|
43
|
+
* reliably captures every error Medusa's framework already logs internally.
|
|
44
|
+
* Errors that Medusa logs through logger.warn(err) (failing event
|
|
45
|
+
* subscribers) are reported too, at warning level.
|
|
46
|
+
*/
|
|
47
|
+
function withSentryErrorReporting(logger) {
|
|
48
|
+
const originalError = logger.error.bind(logger);
|
|
49
|
+
const originalWarn = logger.warn.bind(logger);
|
|
50
|
+
return {
|
|
51
|
+
panic: logger.panic.bind(logger),
|
|
52
|
+
shouldLog: logger.shouldLog.bind(logger),
|
|
53
|
+
setLogLevel: logger.setLogLevel.bind(logger),
|
|
54
|
+
unsetLogLevel: logger.unsetLogLevel.bind(logger),
|
|
55
|
+
activity: logger.activity.bind(logger),
|
|
56
|
+
progress: logger.progress.bind(logger),
|
|
57
|
+
failure: logger.failure.bind(logger),
|
|
58
|
+
success: logger.success.bind(logger),
|
|
59
|
+
silly: logger.silly.bind(logger),
|
|
60
|
+
debug: logger.debug.bind(logger),
|
|
61
|
+
verbose: logger.verbose.bind(logger),
|
|
62
|
+
http: logger.http.bind(logger),
|
|
63
|
+
info: logger.info.bind(logger),
|
|
64
|
+
// Medusa's Redis Event Bus logs a failing subscriber's exception with
|
|
65
|
+
// warn(err), even on the final retry, so an Error passed to warn is a real
|
|
66
|
+
// failure too. Plain warning messages stay out of Sentry.
|
|
67
|
+
warn: (message) => {
|
|
68
|
+
if (message instanceof Error) {
|
|
69
|
+
Sentry.captureException(message, { level: "warning" });
|
|
70
|
+
}
|
|
71
|
+
return originalWarn(message);
|
|
72
|
+
},
|
|
73
|
+
log: logger.log.bind(logger),
|
|
74
|
+
error: (messageOrError, error) => {
|
|
75
|
+
const exception = error ?? (messageOrError instanceof Error ? messageOrError : new Error(messageOrError));
|
|
76
|
+
const loggerMessage = error && typeof messageOrError === "string" ? messageOrError : undefined;
|
|
77
|
+
Sentry.captureException(exception, loggerMessage ? { extra: { loggerMessage } } : undefined);
|
|
78
|
+
return originalError(messageOrError, error);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hartl-services/medusa-base",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts,
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, enforcement helpers, the complete-cart hook composition, and the Sentry logger wrapper.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
7
7
|
".medusa/server",
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"import": "./dist/public/index.js",
|
|
29
29
|
"require": "./dist/public/index.js"
|
|
30
30
|
},
|
|
31
|
+
"./sentry-logger": {
|
|
32
|
+
"types": "./dist/public/sentry-logger.d.ts",
|
|
33
|
+
"import": "./dist/public/sentry-logger.js",
|
|
34
|
+
"require": "./dist/public/sentry-logger.js"
|
|
35
|
+
},
|
|
31
36
|
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
32
37
|
"./.medusa/server/src/*": "./.medusa/server/src/*",
|
|
33
38
|
"./admin": {
|
|
@@ -41,6 +46,7 @@
|
|
|
41
46
|
"@medusajs/js-sdk": "^2.19.0",
|
|
42
47
|
"@medusajs/medusa": "^2.19.0",
|
|
43
48
|
"@medusajs/ui": "^4.2.1",
|
|
49
|
+
"@sentry/node": "^10.74.0",
|
|
44
50
|
"@tanstack/react-query": "^5.64.2",
|
|
45
51
|
"react": "^18.3.1",
|
|
46
52
|
"react-router-dom": "^7.18.2"
|
|
@@ -55,6 +61,7 @@
|
|
|
55
61
|
"@medusajs/js-sdk": "2.19.0",
|
|
56
62
|
"@medusajs/medusa": "2.19.0",
|
|
57
63
|
"@medusajs/ui": "4.2.1",
|
|
64
|
+
"@sentry/node": "^10.74.0",
|
|
58
65
|
"@swc/core": "^1.7.28",
|
|
59
66
|
"@swc/jest": "^0.2.39",
|
|
60
67
|
"@tanstack/react-query": "5.64.2",
|
|
@@ -72,6 +79,11 @@
|
|
|
72
79
|
"engines": {
|
|
73
80
|
"node": ">=20"
|
|
74
81
|
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"@sentry/node": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
75
87
|
"scripts": {
|
|
76
88
|
"build": "medusa plugin:build && tsc -p tsconfig.public.json",
|
|
77
89
|
"dev": "medusa plugin:develop",
|