@loggerjs/browser 0.4.0 → 0.5.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.
- package/dist/broadcast-channel-transport.cjs +115 -0
- package/dist/broadcast-channel-transport.cjs.map +1 -0
- package/dist/broadcast-channel-transport.js +114 -0
- package/dist/broadcast-channel-transport.js.map +1 -0
- package/dist/console-integration.cjs +98 -0
- package/dist/console-integration.cjs.map +1 -0
- package/dist/console-integration.js +97 -0
- package/dist/console-integration.js.map +1 -0
- package/dist/context-propagation-integration.cjs +78 -0
- package/dist/context-propagation-integration.cjs.map +1 -0
- package/dist/context-propagation-integration.js +77 -0
- package/dist/context-propagation-integration.js.map +1 -0
- package/dist/error-integration.cjs +128 -0
- package/dist/error-integration.cjs.map +1 -0
- package/dist/error-integration.js +127 -0
- package/dist/error-integration.js.map +1 -0
- package/dist/fetch-integration.cjs +120 -0
- package/dist/fetch-integration.cjs.map +1 -0
- package/dist/fetch-integration.js +119 -0
- package/dist/fetch-integration.js.map +1 -0
- package/dist/framework-error-integration.cjs +102 -0
- package/dist/framework-error-integration.cjs.map +1 -0
- package/dist/framework-error-integration.js +101 -0
- package/dist/framework-error-integration.js.map +1 -0
- package/dist/framework-router-integrations.cjs +88 -0
- package/dist/framework-router-integrations.cjs.map +1 -0
- package/dist/framework-router-integrations.js +84 -0
- package/dist/framework-router-integrations.js.map +1 -0
- package/dist/http-transport.cjs +301 -0
- package/dist/http-transport.cjs.map +1 -0
- package/dist/http-transport.js +299 -0
- package/dist/http-transport.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-offline-queue.cjs +105 -0
- package/dist/indexeddb-offline-queue.cjs.map +1 -0
- package/dist/indexeddb-offline-queue.js +104 -0
- package/dist/indexeddb-offline-queue.js.map +1 -0
- package/dist/indexeddb-transport.cjs +531 -0
- package/dist/indexeddb-transport.cjs.map +1 -0
- package/dist/indexeddb-transport.js +530 -0
- package/dist/indexeddb-transport.js.map +1 -0
- package/dist/offline-first-transport.cjs +675 -0
- package/dist/offline-first-transport.cjs.map +1 -0
- package/dist/offline-first-transport.js +674 -0
- package/dist/offline-first-transport.js.map +1 -0
- package/dist/page-lifecycle.cjs +39 -0
- package/dist/page-lifecycle.cjs.map +1 -0
- package/dist/page-lifecycle.js +38 -0
- package/dist/page-lifecycle.js.map +1 -0
- package/dist/payload-transforms.cjs +30 -0
- package/dist/payload-transforms.cjs.map +1 -0
- package/dist/payload-transforms.js +29 -0
- package/dist/payload-transforms.js.map +1 -0
- package/dist/performance-integration.cjs +135 -0
- package/dist/performance-integration.cjs.map +1 -0
- package/dist/performance-integration.js +133 -0
- package/dist/performance-integration.js.map +1 -0
- package/dist/reporting-integration.cjs +110 -0
- package/dist/reporting-integration.cjs.map +1 -0
- package/dist/reporting-integration.js +109 -0
- package/dist/reporting-integration.js.map +1 -0
- package/dist/router-integration.cjs +97 -0
- package/dist/router-integration.cjs.map +1 -0
- package/dist/router-integration.js +96 -0
- package/dist/router-integration.js.map +1 -0
- package/dist/runtime-host-integration.cjs +181 -0
- package/dist/runtime-host-integration.cjs.map +1 -0
- package/dist/runtime-host-integration.js +180 -0
- package/dist/runtime-host-integration.js.map +1 -0
- package/dist/service-worker-integration.cjs +109 -0
- package/dist/service-worker-integration.cjs.map +1 -0
- package/dist/service-worker-integration.js +108 -0
- package/dist/service-worker-integration.js.map +1 -0
- package/dist/service-worker-transport.cjs +184 -0
- package/dist/service-worker-transport.cjs.map +1 -0
- package/dist/service-worker-transport.js +183 -0
- package/dist/service-worker-transport.js.map +1 -0
- package/dist/user-action-integration.cjs +100 -0
- package/dist/user-action-integration.cjs.map +1 -0
- package/dist/user-action-integration.js +99 -0
- package/dist/user-action-integration.js.map +1 -0
- package/dist/web-vitals-integration.cjs +157 -0
- package/dist/web-vitals-integration.cjs.map +1 -0
- package/dist/web-vitals-integration.js +156 -0
- package/dist/web-vitals-integration.js.map +1 -0
- package/dist/websocket-integration.cjs +158 -0
- package/dist/websocket-integration.cjs.map +1 -0
- package/dist/websocket-integration.js +157 -0
- package/dist/websocket-integration.js.map +1 -0
- package/dist/websocket-transport.cjs +187 -0
- package/dist/websocket-transport.cjs.map +1 -0
- package/dist/websocket-transport.js +186 -0
- package/dist/websocket-transport.js.map +1 -0
- package/dist/xhr-integration.cjs +107 -0
- package/dist/xhr-integration.cjs.map +1 -0
- package/dist/xhr-integration.js +106 -0
- package/dist/xhr-integration.js.map +1 -0
- package/dist/zip-export.cjs +241 -0
- package/dist/zip-export.cjs.map +1 -0
- package/dist/zip-export.js +238 -0
- package/dist/zip-export.js.map +1 -0
- package/package.json +104 -77
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
3
|
+
//#region src/framework-error-integration.ts
|
|
4
|
+
function errorMessage(error) {
|
|
5
|
+
return error instanceof Error ? error.message : "Framework error";
|
|
6
|
+
}
|
|
7
|
+
function instanceComponentName(instance) {
|
|
8
|
+
const record = instance;
|
|
9
|
+
return record?.$options?.name ?? record?.type?.displayName ?? record?.type?.name ?? record?.constructor?.name;
|
|
10
|
+
}
|
|
11
|
+
function normalizeFrameworkInfo(input, fallbackFramework) {
|
|
12
|
+
if (typeof input === "string") return {
|
|
13
|
+
framework: fallbackFramework,
|
|
14
|
+
info: input
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
framework: fallbackFramework,
|
|
18
|
+
...input
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function captureFrameworkErrorsIntegration(options = {}) {
|
|
22
|
+
const integrationName = options.name ?? "capture-framework-errors";
|
|
23
|
+
const fallbackFramework = options.framework ?? "framework";
|
|
24
|
+
const level = options.level ?? "error";
|
|
25
|
+
const maxPending = Math.max(0, Math.floor(options.maxPending ?? 10));
|
|
26
|
+
const infoMaxDepth = options.infoMaxDepth ?? 6;
|
|
27
|
+
const pending = [];
|
|
28
|
+
let api;
|
|
29
|
+
let started = false;
|
|
30
|
+
let disposed = false;
|
|
31
|
+
const emit = (error, rawInfo) => {
|
|
32
|
+
const info = normalizeFrameworkInfo(rawInfo, fallbackFramework);
|
|
33
|
+
const message = options.getMessage?.(error, info) ?? errorMessage(error);
|
|
34
|
+
api?.capture({
|
|
35
|
+
level,
|
|
36
|
+
message,
|
|
37
|
+
error,
|
|
38
|
+
props: { browser: {
|
|
39
|
+
kind: "framework-error",
|
|
40
|
+
framework: info.framework,
|
|
41
|
+
componentName: info.componentName,
|
|
42
|
+
componentStack: info.componentStack,
|
|
43
|
+
info: (0, _loggerjs_core.normalizeValue)(info.info, {
|
|
44
|
+
maxDepth: infoMaxDepth,
|
|
45
|
+
maxObjectKeys: 80
|
|
46
|
+
}),
|
|
47
|
+
props: (0, _loggerjs_core.normalizeValue)(info.props, {
|
|
48
|
+
maxDepth: infoMaxDepth,
|
|
49
|
+
maxObjectKeys: 80
|
|
50
|
+
})
|
|
51
|
+
} }
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
const capture = (error, info) => {
|
|
55
|
+
if (api) {
|
|
56
|
+
emit(error, info);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (started || disposed || pending.length >= maxPending) return;
|
|
60
|
+
pending.push({
|
|
61
|
+
error,
|
|
62
|
+
info
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
name: integrationName,
|
|
67
|
+
setup(nextApi) {
|
|
68
|
+
api = nextApi;
|
|
69
|
+
started = true;
|
|
70
|
+
disposed = false;
|
|
71
|
+
for (const item of pending.splice(0)) emit(item.error, item.info);
|
|
72
|
+
return () => {
|
|
73
|
+
api = void 0;
|
|
74
|
+
disposed = true;
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
capture,
|
|
78
|
+
reactComponentDidCatch(error, errorInfo) {
|
|
79
|
+
capture(error, {
|
|
80
|
+
framework: "react",
|
|
81
|
+
componentStack: errorInfo?.componentStack
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
vueErrorHandler(error, instance, info) {
|
|
85
|
+
capture(error, {
|
|
86
|
+
framework: "vue",
|
|
87
|
+
componentName: instanceComponentName(instance),
|
|
88
|
+
info
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
solidErrorHandler(error) {
|
|
92
|
+
capture(error, { framework: "solid" });
|
|
93
|
+
},
|
|
94
|
+
svelteErrorHandler(error, info) {
|
|
95
|
+
capture(error, normalizeFrameworkInfo(info, "svelte"));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
exports.captureFrameworkErrorsIntegration = captureFrameworkErrorsIntegration;
|
|
101
|
+
|
|
102
|
+
//# sourceMappingURL=framework-error-integration.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-error-integration.cjs","names":[],"sources":["../src/framework-error-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport type BrowserFrameworkName = \"angular\" | \"react\" | \"solid\" | \"svelte\" | \"vue\" | string;\n\nexport interface BrowserFrameworkErrorInfo {\n framework?: BrowserFrameworkName;\n componentName?: string;\n componentStack?: string;\n info?: unknown;\n props?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface CaptureFrameworkErrorsOptions {\n name?: string;\n framework?: BrowserFrameworkName;\n level?: LoggerLevel;\n maxPending?: number;\n infoMaxDepth?: number;\n getMessage?: (error: unknown, info: BrowserFrameworkErrorInfo) => string;\n}\n\nexport interface BrowserFrameworkErrorIntegration extends Integration {\n capture: (error: unknown, info?: BrowserFrameworkErrorInfo | string) => void;\n reactComponentDidCatch: (error: unknown, errorInfo?: { componentStack?: string }) => void;\n vueErrorHandler: (error: unknown, instance?: unknown, info?: string) => void;\n solidErrorHandler: (error: unknown) => void;\n svelteErrorHandler: (error: unknown, info?: BrowserFrameworkErrorInfo | string) => void;\n}\n\ninterface PendingFrameworkError {\n error: unknown;\n info?: BrowserFrameworkErrorInfo | string;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : \"Framework error\";\n}\n\nfunction instanceComponentName(instance: unknown): string | undefined {\n const record = instance as\n | {\n constructor?: { name?: string };\n $options?: { name?: string };\n type?: { name?: string; displayName?: string };\n }\n | undefined;\n return (\n record?.$options?.name ??\n record?.type?.displayName ??\n record?.type?.name ??\n record?.constructor?.name\n );\n}\n\nfunction normalizeFrameworkInfo(\n input: BrowserFrameworkErrorInfo | string | undefined,\n fallbackFramework: BrowserFrameworkName,\n): BrowserFrameworkErrorInfo {\n if (typeof input === \"string\") return { framework: fallbackFramework, info: input };\n return { framework: fallbackFramework, ...input };\n}\n\nexport function captureFrameworkErrorsIntegration(\n options: CaptureFrameworkErrorsOptions = {},\n): BrowserFrameworkErrorIntegration {\n const integrationName = options.name ?? \"capture-framework-errors\";\n const fallbackFramework = options.framework ?? \"framework\";\n const level = options.level ?? \"error\";\n const maxPending = Math.max(0, Math.floor(options.maxPending ?? 10));\n const infoMaxDepth = options.infoMaxDepth ?? 6;\n const pending: PendingFrameworkError[] = [];\n let api: IntegrationSetupContext | undefined;\n let started = false;\n let disposed = false;\n\n const emit = (error: unknown, rawInfo?: BrowserFrameworkErrorInfo | string) => {\n const info = normalizeFrameworkInfo(rawInfo, fallbackFramework);\n const message = options.getMessage?.(error, info) ?? errorMessage(error);\n api?.capture({\n level,\n message,\n error,\n props: {\n browser: {\n kind: \"framework-error\",\n framework: info.framework,\n componentName: info.componentName,\n componentStack: info.componentStack,\n info: normalizeValue(info.info, { maxDepth: infoMaxDepth, maxObjectKeys: 80 }),\n props: normalizeValue(info.props, { maxDepth: infoMaxDepth, maxObjectKeys: 80 }),\n },\n },\n });\n };\n\n const capture = (error: unknown, info?: BrowserFrameworkErrorInfo | string) => {\n if (api) {\n emit(error, info);\n return;\n }\n if (started || disposed || pending.length >= maxPending) return;\n pending.push({ error, info });\n };\n\n const integration: BrowserFrameworkErrorIntegration = {\n name: integrationName,\n setup(nextApi) {\n api = nextApi;\n started = true;\n disposed = false;\n for (const item of pending.splice(0)) emit(item.error, item.info);\n return () => {\n api = undefined;\n disposed = true;\n };\n },\n capture,\n reactComponentDidCatch(error, errorInfo) {\n capture(error, {\n framework: \"react\",\n componentStack: errorInfo?.componentStack,\n });\n },\n vueErrorHandler(error, instance, info) {\n capture(error, {\n framework: \"vue\",\n componentName: instanceComponentName(instance),\n info,\n });\n },\n solidErrorHandler(error) {\n capture(error, { framework: \"solid\" });\n },\n svelteErrorHandler(error, info) {\n capture(error, normalizeFrameworkInfo(info, \"svelte\"));\n },\n };\n\n return integration;\n}\n"],"mappings":";;;AAwCA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAEA,SAAS,sBAAsB,UAAuC;CACpE,MAAM,SAAS;CAOf,OACE,QAAQ,UAAU,QAClB,QAAQ,MAAM,eACd,QAAQ,MAAM,QACd,QAAQ,aAAa;AAEzB;AAEA,SAAS,uBACP,OACA,mBAC2B;CAC3B,IAAI,OAAO,UAAU,UAAU,OAAO;EAAE,WAAW;EAAmB,MAAM;CAAM;CAClF,OAAO;EAAE,WAAW;EAAmB,GAAG;CAAM;AAClD;AAEA,SAAgB,kCACd,UAAyC,CAAC,GACR;CAClC,MAAM,kBAAkB,QAAQ,QAAQ;CACxC,MAAM,oBAAoB,QAAQ,aAAa;CAC/C,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,cAAc,EAAE,CAAC;CACnE,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,UAAmC,CAAC;CAC1C,IAAI;CACJ,IAAI,UAAU;CACd,IAAI,WAAW;CAEf,MAAM,QAAQ,OAAgB,YAAiD;EAC7E,MAAM,OAAO,uBAAuB,SAAS,iBAAiB;EAC9D,MAAM,UAAU,QAAQ,aAAa,OAAO,IAAI,KAAK,aAAa,KAAK;EACvE,KAAK,QAAQ;GACX;GACA;GACA;GACA,OAAO,EACL,SAAS;IACP,MAAM;IACN,WAAW,KAAK;IAChB,eAAe,KAAK;IACpB,gBAAgB,KAAK;IACrB,OAAA,GAAA,eAAA,eAAA,CAAqB,KAAK,MAAM;KAAE,UAAU;KAAc,eAAe;IAAG,CAAC;IAC7E,QAAA,GAAA,eAAA,eAAA,CAAsB,KAAK,OAAO;KAAE,UAAU;KAAc,eAAe;IAAG,CAAC;GACjF,EACF;EACF,CAAC;CACH;CAEA,MAAM,WAAW,OAAgB,SAA8C;EAC7E,IAAI,KAAK;GACP,KAAK,OAAO,IAAI;GAChB;EACF;EACA,IAAI,WAAW,YAAY,QAAQ,UAAU,YAAY;EACzD,QAAQ,KAAK;GAAE;GAAO;EAAK,CAAC;CAC9B;CAoCA,OAAO;EAjCL,MAAM;EACN,MAAM,SAAS;GACb,MAAM;GACN,UAAU;GACV,WAAW;GACX,KAAK,MAAM,QAAQ,QAAQ,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,KAAK,IAAI;GAChE,aAAa;IACX,MAAM,KAAA;IACN,WAAW;GACb;EACF;EACA;EACA,uBAAuB,OAAO,WAAW;GACvC,QAAQ,OAAO;IACb,WAAW;IACX,gBAAgB,WAAW;GAC7B,CAAC;EACH;EACA,gBAAgB,OAAO,UAAU,MAAM;GACrC,QAAQ,OAAO;IACb,WAAW;IACX,eAAe,sBAAsB,QAAQ;IAC7C;GACF,CAAC;EACH;EACA,kBAAkB,OAAO;GACvB,QAAQ,OAAO,EAAE,WAAW,QAAQ,CAAC;EACvC;EACA,mBAAmB,OAAO,MAAM;GAC9B,QAAQ,OAAO,uBAAuB,MAAM,QAAQ,CAAC;EACvD;CAGe;AACnB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { normalizeValue } from "@loggerjs/core";
|
|
2
|
+
//#region src/framework-error-integration.ts
|
|
3
|
+
function errorMessage(error) {
|
|
4
|
+
return error instanceof Error ? error.message : "Framework error";
|
|
5
|
+
}
|
|
6
|
+
function instanceComponentName(instance) {
|
|
7
|
+
const record = instance;
|
|
8
|
+
return record?.$options?.name ?? record?.type?.displayName ?? record?.type?.name ?? record?.constructor?.name;
|
|
9
|
+
}
|
|
10
|
+
function normalizeFrameworkInfo(input, fallbackFramework) {
|
|
11
|
+
if (typeof input === "string") return {
|
|
12
|
+
framework: fallbackFramework,
|
|
13
|
+
info: input
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
framework: fallbackFramework,
|
|
17
|
+
...input
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function captureFrameworkErrorsIntegration(options = {}) {
|
|
21
|
+
const integrationName = options.name ?? "capture-framework-errors";
|
|
22
|
+
const fallbackFramework = options.framework ?? "framework";
|
|
23
|
+
const level = options.level ?? "error";
|
|
24
|
+
const maxPending = Math.max(0, Math.floor(options.maxPending ?? 10));
|
|
25
|
+
const infoMaxDepth = options.infoMaxDepth ?? 6;
|
|
26
|
+
const pending = [];
|
|
27
|
+
let api;
|
|
28
|
+
let started = false;
|
|
29
|
+
let disposed = false;
|
|
30
|
+
const emit = (error, rawInfo) => {
|
|
31
|
+
const info = normalizeFrameworkInfo(rawInfo, fallbackFramework);
|
|
32
|
+
const message = options.getMessage?.(error, info) ?? errorMessage(error);
|
|
33
|
+
api?.capture({
|
|
34
|
+
level,
|
|
35
|
+
message,
|
|
36
|
+
error,
|
|
37
|
+
props: { browser: {
|
|
38
|
+
kind: "framework-error",
|
|
39
|
+
framework: info.framework,
|
|
40
|
+
componentName: info.componentName,
|
|
41
|
+
componentStack: info.componentStack,
|
|
42
|
+
info: normalizeValue(info.info, {
|
|
43
|
+
maxDepth: infoMaxDepth,
|
|
44
|
+
maxObjectKeys: 80
|
|
45
|
+
}),
|
|
46
|
+
props: normalizeValue(info.props, {
|
|
47
|
+
maxDepth: infoMaxDepth,
|
|
48
|
+
maxObjectKeys: 80
|
|
49
|
+
})
|
|
50
|
+
} }
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const capture = (error, info) => {
|
|
54
|
+
if (api) {
|
|
55
|
+
emit(error, info);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (started || disposed || pending.length >= maxPending) return;
|
|
59
|
+
pending.push({
|
|
60
|
+
error,
|
|
61
|
+
info
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
name: integrationName,
|
|
66
|
+
setup(nextApi) {
|
|
67
|
+
api = nextApi;
|
|
68
|
+
started = true;
|
|
69
|
+
disposed = false;
|
|
70
|
+
for (const item of pending.splice(0)) emit(item.error, item.info);
|
|
71
|
+
return () => {
|
|
72
|
+
api = void 0;
|
|
73
|
+
disposed = true;
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
capture,
|
|
77
|
+
reactComponentDidCatch(error, errorInfo) {
|
|
78
|
+
capture(error, {
|
|
79
|
+
framework: "react",
|
|
80
|
+
componentStack: errorInfo?.componentStack
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
vueErrorHandler(error, instance, info) {
|
|
84
|
+
capture(error, {
|
|
85
|
+
framework: "vue",
|
|
86
|
+
componentName: instanceComponentName(instance),
|
|
87
|
+
info
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
solidErrorHandler(error) {
|
|
91
|
+
capture(error, { framework: "solid" });
|
|
92
|
+
},
|
|
93
|
+
svelteErrorHandler(error, info) {
|
|
94
|
+
capture(error, normalizeFrameworkInfo(info, "svelte"));
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { captureFrameworkErrorsIntegration };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=framework-error-integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-error-integration.js","names":[],"sources":["../src/framework-error-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport type BrowserFrameworkName = \"angular\" | \"react\" | \"solid\" | \"svelte\" | \"vue\" | string;\n\nexport interface BrowserFrameworkErrorInfo {\n framework?: BrowserFrameworkName;\n componentName?: string;\n componentStack?: string;\n info?: unknown;\n props?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface CaptureFrameworkErrorsOptions {\n name?: string;\n framework?: BrowserFrameworkName;\n level?: LoggerLevel;\n maxPending?: number;\n infoMaxDepth?: number;\n getMessage?: (error: unknown, info: BrowserFrameworkErrorInfo) => string;\n}\n\nexport interface BrowserFrameworkErrorIntegration extends Integration {\n capture: (error: unknown, info?: BrowserFrameworkErrorInfo | string) => void;\n reactComponentDidCatch: (error: unknown, errorInfo?: { componentStack?: string }) => void;\n vueErrorHandler: (error: unknown, instance?: unknown, info?: string) => void;\n solidErrorHandler: (error: unknown) => void;\n svelteErrorHandler: (error: unknown, info?: BrowserFrameworkErrorInfo | string) => void;\n}\n\ninterface PendingFrameworkError {\n error: unknown;\n info?: BrowserFrameworkErrorInfo | string;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : \"Framework error\";\n}\n\nfunction instanceComponentName(instance: unknown): string | undefined {\n const record = instance as\n | {\n constructor?: { name?: string };\n $options?: { name?: string };\n type?: { name?: string; displayName?: string };\n }\n | undefined;\n return (\n record?.$options?.name ??\n record?.type?.displayName ??\n record?.type?.name ??\n record?.constructor?.name\n );\n}\n\nfunction normalizeFrameworkInfo(\n input: BrowserFrameworkErrorInfo | string | undefined,\n fallbackFramework: BrowserFrameworkName,\n): BrowserFrameworkErrorInfo {\n if (typeof input === \"string\") return { framework: fallbackFramework, info: input };\n return { framework: fallbackFramework, ...input };\n}\n\nexport function captureFrameworkErrorsIntegration(\n options: CaptureFrameworkErrorsOptions = {},\n): BrowserFrameworkErrorIntegration {\n const integrationName = options.name ?? \"capture-framework-errors\";\n const fallbackFramework = options.framework ?? \"framework\";\n const level = options.level ?? \"error\";\n const maxPending = Math.max(0, Math.floor(options.maxPending ?? 10));\n const infoMaxDepth = options.infoMaxDepth ?? 6;\n const pending: PendingFrameworkError[] = [];\n let api: IntegrationSetupContext | undefined;\n let started = false;\n let disposed = false;\n\n const emit = (error: unknown, rawInfo?: BrowserFrameworkErrorInfo | string) => {\n const info = normalizeFrameworkInfo(rawInfo, fallbackFramework);\n const message = options.getMessage?.(error, info) ?? errorMessage(error);\n api?.capture({\n level,\n message,\n error,\n props: {\n browser: {\n kind: \"framework-error\",\n framework: info.framework,\n componentName: info.componentName,\n componentStack: info.componentStack,\n info: normalizeValue(info.info, { maxDepth: infoMaxDepth, maxObjectKeys: 80 }),\n props: normalizeValue(info.props, { maxDepth: infoMaxDepth, maxObjectKeys: 80 }),\n },\n },\n });\n };\n\n const capture = (error: unknown, info?: BrowserFrameworkErrorInfo | string) => {\n if (api) {\n emit(error, info);\n return;\n }\n if (started || disposed || pending.length >= maxPending) return;\n pending.push({ error, info });\n };\n\n const integration: BrowserFrameworkErrorIntegration = {\n name: integrationName,\n setup(nextApi) {\n api = nextApi;\n started = true;\n disposed = false;\n for (const item of pending.splice(0)) emit(item.error, item.info);\n return () => {\n api = undefined;\n disposed = true;\n };\n },\n capture,\n reactComponentDidCatch(error, errorInfo) {\n capture(error, {\n framework: \"react\",\n componentStack: errorInfo?.componentStack,\n });\n },\n vueErrorHandler(error, instance, info) {\n capture(error, {\n framework: \"vue\",\n componentName: instanceComponentName(instance),\n info,\n });\n },\n solidErrorHandler(error) {\n capture(error, { framework: \"solid\" });\n },\n svelteErrorHandler(error, info) {\n capture(error, normalizeFrameworkInfo(info, \"svelte\"));\n },\n };\n\n return integration;\n}\n"],"mappings":";;AAwCA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAEA,SAAS,sBAAsB,UAAuC;CACpE,MAAM,SAAS;CAOf,OACE,QAAQ,UAAU,QAClB,QAAQ,MAAM,eACd,QAAQ,MAAM,QACd,QAAQ,aAAa;AAEzB;AAEA,SAAS,uBACP,OACA,mBAC2B;CAC3B,IAAI,OAAO,UAAU,UAAU,OAAO;EAAE,WAAW;EAAmB,MAAM;CAAM;CAClF,OAAO;EAAE,WAAW;EAAmB,GAAG;CAAM;AAClD;AAEA,SAAgB,kCACd,UAAyC,CAAC,GACR;CAClC,MAAM,kBAAkB,QAAQ,QAAQ;CACxC,MAAM,oBAAoB,QAAQ,aAAa;CAC/C,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,cAAc,EAAE,CAAC;CACnE,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,UAAmC,CAAC;CAC1C,IAAI;CACJ,IAAI,UAAU;CACd,IAAI,WAAW;CAEf,MAAM,QAAQ,OAAgB,YAAiD;EAC7E,MAAM,OAAO,uBAAuB,SAAS,iBAAiB;EAC9D,MAAM,UAAU,QAAQ,aAAa,OAAO,IAAI,KAAK,aAAa,KAAK;EACvE,KAAK,QAAQ;GACX;GACA;GACA;GACA,OAAO,EACL,SAAS;IACP,MAAM;IACN,WAAW,KAAK;IAChB,eAAe,KAAK;IACpB,gBAAgB,KAAK;IACrB,MAAM,eAAe,KAAK,MAAM;KAAE,UAAU;KAAc,eAAe;IAAG,CAAC;IAC7E,OAAO,eAAe,KAAK,OAAO;KAAE,UAAU;KAAc,eAAe;IAAG,CAAC;GACjF,EACF;EACF,CAAC;CACH;CAEA,MAAM,WAAW,OAAgB,SAA8C;EAC7E,IAAI,KAAK;GACP,KAAK,OAAO,IAAI;GAChB;EACF;EACA,IAAI,WAAW,YAAY,QAAQ,UAAU,YAAY;EACzD,QAAQ,KAAK;GAAE;GAAO;EAAK,CAAC;CAC9B;CAoCA,OAAO;EAjCL,MAAM;EACN,MAAM,SAAS;GACb,MAAM;GACN,UAAU;GACV,WAAW;GACX,KAAK,MAAM,QAAQ,QAAQ,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,KAAK,IAAI;GAChE,aAAa;IACX,MAAM,KAAA;IACN,WAAW;GACb;EACF;EACA;EACA,uBAAuB,OAAO,WAAW;GACvC,QAAQ,OAAO;IACb,WAAW;IACX,gBAAgB,WAAW;GAC7B,CAAC;EACH;EACA,gBAAgB,OAAO,UAAU,MAAM;GACrC,QAAQ,OAAO;IACb,WAAW;IACX,eAAe,sBAAsB,QAAQ;IAC7C;GACF,CAAC;EACH;EACA,kBAAkB,OAAO;GACvB,QAAQ,OAAO,EAAE,WAAW,QAAQ,CAAC;EACvC;EACA,mBAAmB,OAAO,MAAM;GAC9B,QAAQ,OAAO,uBAAuB,MAAM,QAAQ,CAAC;EACvD;CAGe;AACnB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _loggerjs_core = require("@loggerjs/core");
|
|
3
|
+
//#region src/framework-router-integrations.ts
|
|
4
|
+
function routePath(input) {
|
|
5
|
+
if (typeof input === "string") return input;
|
|
6
|
+
if (input && typeof input === "object") {
|
|
7
|
+
const route = input;
|
|
8
|
+
if (typeof route.fullPath === "string") return route.fullPath;
|
|
9
|
+
if (typeof route.pathname === "string") return route.pathname;
|
|
10
|
+
if (typeof route.path === "string") return route.path;
|
|
11
|
+
if (route.location) return routePath(route.location);
|
|
12
|
+
}
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
function emitRouteChange(api, framework, level, to, from, options) {
|
|
16
|
+
const sanitize = options.sanitizeUrl;
|
|
17
|
+
const toPath = sanitize ? sanitize(routePath(to)) : routePath(to);
|
|
18
|
+
const fromPath = from === void 0 ? void 0 : sanitize ? sanitize(routePath(from)) : routePath(from);
|
|
19
|
+
api.capture({
|
|
20
|
+
level,
|
|
21
|
+
message: `${framework} route ${toPath}`,
|
|
22
|
+
props: { browser: {
|
|
23
|
+
kind: "framework-route-change",
|
|
24
|
+
framework,
|
|
25
|
+
route: {
|
|
26
|
+
to: toPath,
|
|
27
|
+
from: fromPath,
|
|
28
|
+
state: options.includeState ? (0, _loggerjs_core.normalizeValue)(to, { maxDepth: 4 }) : void 0
|
|
29
|
+
}
|
|
30
|
+
} }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function nextRouterIntegration(options) {
|
|
34
|
+
const level = options.level ?? "info";
|
|
35
|
+
return {
|
|
36
|
+
name: "next-router",
|
|
37
|
+
setup(api) {
|
|
38
|
+
const router = options.router;
|
|
39
|
+
if (!router.events?.on || !router.events.off) return;
|
|
40
|
+
const onRoute = api.guard((url) => emitRouteChange(api, "next", level, url, router.asPath, options));
|
|
41
|
+
router.events.on("routeChangeComplete", onRoute);
|
|
42
|
+
router.events.on("hashChangeComplete", onRoute);
|
|
43
|
+
return () => {
|
|
44
|
+
router.events?.off?.("routeChangeComplete", onRoute);
|
|
45
|
+
router.events?.off?.("hashChangeComplete", onRoute);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function reactRouterIntegration(options) {
|
|
51
|
+
const level = options.level ?? "info";
|
|
52
|
+
return {
|
|
53
|
+
name: "react-router",
|
|
54
|
+
setup(api) {
|
|
55
|
+
let previous = options.history.location;
|
|
56
|
+
const dispose = options.history.listen?.(api.guard((update) => {
|
|
57
|
+
const next = update?.location ?? update;
|
|
58
|
+
emitRouteChange(api, "react-router", level, next, previous, options);
|
|
59
|
+
previous = next;
|
|
60
|
+
}));
|
|
61
|
+
return typeof dispose === "function" ? dispose : void 0;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function vueRouterIntegration(options) {
|
|
66
|
+
const level = options.level ?? "info";
|
|
67
|
+
const framework = options.framework ?? "vue-router";
|
|
68
|
+
return {
|
|
69
|
+
name: framework,
|
|
70
|
+
setup(api) {
|
|
71
|
+
const dispose = options.router.afterEach?.(api.guard((to, from) => emitRouteChange(api, framework, level, to, from, options)));
|
|
72
|
+
return typeof dispose === "function" ? dispose : void 0;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function nuxtRouterIntegration(options) {
|
|
77
|
+
return vueRouterIntegration({
|
|
78
|
+
...options,
|
|
79
|
+
framework: "nuxt"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
exports.nextRouterIntegration = nextRouterIntegration;
|
|
84
|
+
exports.nuxtRouterIntegration = nuxtRouterIntegration;
|
|
85
|
+
exports.reactRouterIntegration = reactRouterIntegration;
|
|
86
|
+
exports.vueRouterIntegration = vueRouterIntegration;
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=framework-router-integrations.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-router-integrations.cjs","names":[],"sources":["../src/framework-router-integrations.ts"],"sourcesContent":["import {\n normalizeValue,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport interface FrameworkRouterIntegrationOptions {\n level?: LoggerLevel;\n sanitizeUrl?: (url: string) => string;\n includeState?: boolean;\n}\n\nexport interface NextRouterLike {\n asPath?: string;\n events?: {\n on?: (event: string, listener: (url: string) => void) => void;\n off?: (event: string, listener: (url: string) => void) => void;\n };\n}\n\nexport interface ReactRouterHistoryLike {\n location?: unknown;\n listen?: (listener: (update: unknown) => void) => void | (() => void);\n}\n\nexport interface VueRouterLike {\n currentRoute?: unknown;\n afterEach?: (listener: (to: unknown, from: unknown) => void) => void | (() => void);\n}\n\nexport interface NextRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n router: NextRouterLike;\n}\n\nexport interface ReactRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n history: ReactRouterHistoryLike;\n}\n\nexport interface VueRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n router: VueRouterLike;\n framework?: \"vue-router\" | \"nuxt\";\n}\n\nfunction routePath(input: unknown): string {\n if (typeof input === \"string\") return input;\n if (input && typeof input === \"object\") {\n const route = input as {\n fullPath?: string;\n pathname?: string;\n path?: string;\n location?: unknown;\n };\n if (typeof route.fullPath === \"string\") return route.fullPath;\n if (typeof route.pathname === \"string\") return route.pathname;\n if (typeof route.path === \"string\") return route.path;\n if (route.location) return routePath(route.location);\n }\n return \"\";\n}\n\nfunction emitRouteChange(\n api: IntegrationSetupContext,\n framework: string,\n level: LoggerLevel,\n to: unknown,\n from: unknown,\n options: FrameworkRouterIntegrationOptions,\n) {\n const sanitize = options.sanitizeUrl;\n const toPath = sanitize ? sanitize(routePath(to)) : routePath(to);\n const fromPath =\n from === undefined ? undefined : sanitize ? sanitize(routePath(from)) : routePath(from);\n api.capture({\n level,\n message: `${framework} route ${toPath}`,\n props: {\n browser: {\n kind: \"framework-route-change\",\n framework,\n route: {\n to: toPath,\n from: fromPath,\n state: options.includeState ? normalizeValue(to, { maxDepth: 4 }) : undefined,\n },\n },\n },\n });\n}\n\nexport function nextRouterIntegration(options: NextRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n return {\n name: \"next-router\",\n setup(api) {\n const router = options.router;\n if (!router.events?.on || !router.events.off) return;\n const onRoute = api.guard((url: string) =>\n emitRouteChange(api, \"next\", level, url, router.asPath, options),\n );\n router.events.on(\"routeChangeComplete\", onRoute);\n router.events.on(\"hashChangeComplete\", onRoute);\n return () => {\n router.events?.off?.(\"routeChangeComplete\", onRoute);\n router.events?.off?.(\"hashChangeComplete\", onRoute);\n };\n },\n };\n}\n\nexport function reactRouterIntegration(options: ReactRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n return {\n name: \"react-router\",\n setup(api) {\n let previous = options.history.location;\n const dispose = options.history.listen?.(\n api.guard((update: unknown) => {\n const next = (update as { location?: unknown })?.location ?? update;\n emitRouteChange(api, \"react-router\", level, next, previous, options);\n previous = next;\n }),\n );\n return typeof dispose === \"function\" ? dispose : undefined;\n },\n };\n}\n\nexport function vueRouterIntegration(options: VueRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n const framework = options.framework ?? \"vue-router\";\n return {\n name: framework,\n setup(api) {\n const dispose = options.router.afterEach?.(\n api.guard((to: unknown, from: unknown) =>\n emitRouteChange(api, framework, level, to, from, options),\n ),\n );\n return typeof dispose === \"function\" ? dispose : undefined;\n },\n };\n}\n\nexport function nuxtRouterIntegration(\n options: Omit<VueRouterIntegrationOptions, \"framework\">,\n): Integration {\n return vueRouterIntegration({ ...options, framework: \"nuxt\" });\n}\n"],"mappings":";;;AA4CA,SAAS,UAAU,OAAwB;CACzC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,QAAQ;EAMd,IAAI,OAAO,MAAM,aAAa,UAAU,OAAO,MAAM;EACrD,IAAI,OAAO,MAAM,aAAa,UAAU,OAAO,MAAM;EACrD,IAAI,OAAO,MAAM,SAAS,UAAU,OAAO,MAAM;EACjD,IAAI,MAAM,UAAU,OAAO,UAAU,MAAM,QAAQ;CACrD;CACA,OAAO;AACT;AAEA,SAAS,gBACP,KACA,WACA,OACA,IACA,MACA,SACA;CACA,MAAM,WAAW,QAAQ;CACzB,MAAM,SAAS,WAAW,SAAS,UAAU,EAAE,CAAC,IAAI,UAAU,EAAE;CAChE,MAAM,WACJ,SAAS,KAAA,IAAY,KAAA,IAAY,WAAW,SAAS,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI;CACxF,IAAI,QAAQ;EACV;EACA,SAAS,GAAG,UAAU,SAAS;EAC/B,OAAO,EACL,SAAS;GACP,MAAM;GACN;GACA,OAAO;IACL,IAAI;IACJ,MAAM;IACN,OAAO,QAAQ,gBAAA,GAAA,eAAA,eAAA,CAA8B,IAAI,EAAE,UAAU,EAAE,CAAC,IAAI,KAAA;GACtE;EACF,EACF;CACF,CAAC;AACH;AAEA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,MAAM,SAAS,QAAQ;GACvB,IAAI,CAAC,OAAO,QAAQ,MAAM,CAAC,OAAO,OAAO,KAAK;GAC9C,MAAM,UAAU,IAAI,OAAO,QACzB,gBAAgB,KAAK,QAAQ,OAAO,KAAK,OAAO,QAAQ,OAAO,CACjE;GACA,OAAO,OAAO,GAAG,uBAAuB,OAAO;GAC/C,OAAO,OAAO,GAAG,sBAAsB,OAAO;GAC9C,aAAa;IACX,OAAO,QAAQ,MAAM,uBAAuB,OAAO;IACnD,OAAO,QAAQ,MAAM,sBAAsB,OAAO;GACpD;EACF;CACF;AACF;AAEA,SAAgB,uBAAuB,SAAqD;CAC1F,MAAM,QAAQ,QAAQ,SAAS;CAC/B,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,IAAI,WAAW,QAAQ,QAAQ;GAC/B,MAAM,UAAU,QAAQ,QAAQ,SAC9B,IAAI,OAAO,WAAoB;IAC7B,MAAM,OAAQ,QAAmC,YAAY;IAC7D,gBAAgB,KAAK,gBAAgB,OAAO,MAAM,UAAU,OAAO;IACnE,WAAW;GACb,CAAC,CACH;GACA,OAAO,OAAO,YAAY,aAAa,UAAU,KAAA;EACnD;CACF;AACF;AAEA,SAAgB,qBAAqB,SAAmD;CACtF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,YAAY,QAAQ,aAAa;CACvC,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,MAAM,UAAU,QAAQ,OAAO,YAC7B,IAAI,OAAO,IAAa,SACtB,gBAAgB,KAAK,WAAW,OAAO,IAAI,MAAM,OAAO,CAC1D,CACF;GACA,OAAO,OAAO,YAAY,aAAa,UAAU,KAAA;EACnD;CACF;AACF;AAEA,SAAgB,sBACd,SACa;CACb,OAAO,qBAAqB;EAAE,GAAG;EAAS,WAAW;CAAO,CAAC;AAC/D"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { normalizeValue } from "@loggerjs/core";
|
|
2
|
+
//#region src/framework-router-integrations.ts
|
|
3
|
+
function routePath(input) {
|
|
4
|
+
if (typeof input === "string") return input;
|
|
5
|
+
if (input && typeof input === "object") {
|
|
6
|
+
const route = input;
|
|
7
|
+
if (typeof route.fullPath === "string") return route.fullPath;
|
|
8
|
+
if (typeof route.pathname === "string") return route.pathname;
|
|
9
|
+
if (typeof route.path === "string") return route.path;
|
|
10
|
+
if (route.location) return routePath(route.location);
|
|
11
|
+
}
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
function emitRouteChange(api, framework, level, to, from, options) {
|
|
15
|
+
const sanitize = options.sanitizeUrl;
|
|
16
|
+
const toPath = sanitize ? sanitize(routePath(to)) : routePath(to);
|
|
17
|
+
const fromPath = from === void 0 ? void 0 : sanitize ? sanitize(routePath(from)) : routePath(from);
|
|
18
|
+
api.capture({
|
|
19
|
+
level,
|
|
20
|
+
message: `${framework} route ${toPath}`,
|
|
21
|
+
props: { browser: {
|
|
22
|
+
kind: "framework-route-change",
|
|
23
|
+
framework,
|
|
24
|
+
route: {
|
|
25
|
+
to: toPath,
|
|
26
|
+
from: fromPath,
|
|
27
|
+
state: options.includeState ? normalizeValue(to, { maxDepth: 4 }) : void 0
|
|
28
|
+
}
|
|
29
|
+
} }
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function nextRouterIntegration(options) {
|
|
33
|
+
const level = options.level ?? "info";
|
|
34
|
+
return {
|
|
35
|
+
name: "next-router",
|
|
36
|
+
setup(api) {
|
|
37
|
+
const router = options.router;
|
|
38
|
+
if (!router.events?.on || !router.events.off) return;
|
|
39
|
+
const onRoute = api.guard((url) => emitRouteChange(api, "next", level, url, router.asPath, options));
|
|
40
|
+
router.events.on("routeChangeComplete", onRoute);
|
|
41
|
+
router.events.on("hashChangeComplete", onRoute);
|
|
42
|
+
return () => {
|
|
43
|
+
router.events?.off?.("routeChangeComplete", onRoute);
|
|
44
|
+
router.events?.off?.("hashChangeComplete", onRoute);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function reactRouterIntegration(options) {
|
|
50
|
+
const level = options.level ?? "info";
|
|
51
|
+
return {
|
|
52
|
+
name: "react-router",
|
|
53
|
+
setup(api) {
|
|
54
|
+
let previous = options.history.location;
|
|
55
|
+
const dispose = options.history.listen?.(api.guard((update) => {
|
|
56
|
+
const next = update?.location ?? update;
|
|
57
|
+
emitRouteChange(api, "react-router", level, next, previous, options);
|
|
58
|
+
previous = next;
|
|
59
|
+
}));
|
|
60
|
+
return typeof dispose === "function" ? dispose : void 0;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function vueRouterIntegration(options) {
|
|
65
|
+
const level = options.level ?? "info";
|
|
66
|
+
const framework = options.framework ?? "vue-router";
|
|
67
|
+
return {
|
|
68
|
+
name: framework,
|
|
69
|
+
setup(api) {
|
|
70
|
+
const dispose = options.router.afterEach?.(api.guard((to, from) => emitRouteChange(api, framework, level, to, from, options)));
|
|
71
|
+
return typeof dispose === "function" ? dispose : void 0;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function nuxtRouterIntegration(options) {
|
|
76
|
+
return vueRouterIntegration({
|
|
77
|
+
...options,
|
|
78
|
+
framework: "nuxt"
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { nextRouterIntegration, nuxtRouterIntegration, reactRouterIntegration, vueRouterIntegration };
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=framework-router-integrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-router-integrations.js","names":[],"sources":["../src/framework-router-integrations.ts"],"sourcesContent":["import {\n normalizeValue,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport interface FrameworkRouterIntegrationOptions {\n level?: LoggerLevel;\n sanitizeUrl?: (url: string) => string;\n includeState?: boolean;\n}\n\nexport interface NextRouterLike {\n asPath?: string;\n events?: {\n on?: (event: string, listener: (url: string) => void) => void;\n off?: (event: string, listener: (url: string) => void) => void;\n };\n}\n\nexport interface ReactRouterHistoryLike {\n location?: unknown;\n listen?: (listener: (update: unknown) => void) => void | (() => void);\n}\n\nexport interface VueRouterLike {\n currentRoute?: unknown;\n afterEach?: (listener: (to: unknown, from: unknown) => void) => void | (() => void);\n}\n\nexport interface NextRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n router: NextRouterLike;\n}\n\nexport interface ReactRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n history: ReactRouterHistoryLike;\n}\n\nexport interface VueRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {\n router: VueRouterLike;\n framework?: \"vue-router\" | \"nuxt\";\n}\n\nfunction routePath(input: unknown): string {\n if (typeof input === \"string\") return input;\n if (input && typeof input === \"object\") {\n const route = input as {\n fullPath?: string;\n pathname?: string;\n path?: string;\n location?: unknown;\n };\n if (typeof route.fullPath === \"string\") return route.fullPath;\n if (typeof route.pathname === \"string\") return route.pathname;\n if (typeof route.path === \"string\") return route.path;\n if (route.location) return routePath(route.location);\n }\n return \"\";\n}\n\nfunction emitRouteChange(\n api: IntegrationSetupContext,\n framework: string,\n level: LoggerLevel,\n to: unknown,\n from: unknown,\n options: FrameworkRouterIntegrationOptions,\n) {\n const sanitize = options.sanitizeUrl;\n const toPath = sanitize ? sanitize(routePath(to)) : routePath(to);\n const fromPath =\n from === undefined ? undefined : sanitize ? sanitize(routePath(from)) : routePath(from);\n api.capture({\n level,\n message: `${framework} route ${toPath}`,\n props: {\n browser: {\n kind: \"framework-route-change\",\n framework,\n route: {\n to: toPath,\n from: fromPath,\n state: options.includeState ? normalizeValue(to, { maxDepth: 4 }) : undefined,\n },\n },\n },\n });\n}\n\nexport function nextRouterIntegration(options: NextRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n return {\n name: \"next-router\",\n setup(api) {\n const router = options.router;\n if (!router.events?.on || !router.events.off) return;\n const onRoute = api.guard((url: string) =>\n emitRouteChange(api, \"next\", level, url, router.asPath, options),\n );\n router.events.on(\"routeChangeComplete\", onRoute);\n router.events.on(\"hashChangeComplete\", onRoute);\n return () => {\n router.events?.off?.(\"routeChangeComplete\", onRoute);\n router.events?.off?.(\"hashChangeComplete\", onRoute);\n };\n },\n };\n}\n\nexport function reactRouterIntegration(options: ReactRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n return {\n name: \"react-router\",\n setup(api) {\n let previous = options.history.location;\n const dispose = options.history.listen?.(\n api.guard((update: unknown) => {\n const next = (update as { location?: unknown })?.location ?? update;\n emitRouteChange(api, \"react-router\", level, next, previous, options);\n previous = next;\n }),\n );\n return typeof dispose === \"function\" ? dispose : undefined;\n },\n };\n}\n\nexport function vueRouterIntegration(options: VueRouterIntegrationOptions): Integration {\n const level = options.level ?? \"info\";\n const framework = options.framework ?? \"vue-router\";\n return {\n name: framework,\n setup(api) {\n const dispose = options.router.afterEach?.(\n api.guard((to: unknown, from: unknown) =>\n emitRouteChange(api, framework, level, to, from, options),\n ),\n );\n return typeof dispose === \"function\" ? dispose : undefined;\n },\n };\n}\n\nexport function nuxtRouterIntegration(\n options: Omit<VueRouterIntegrationOptions, \"framework\">,\n): Integration {\n return vueRouterIntegration({ ...options, framework: \"nuxt\" });\n}\n"],"mappings":";;AA4CA,SAAS,UAAU,OAAwB;CACzC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,QAAQ;EAMd,IAAI,OAAO,MAAM,aAAa,UAAU,OAAO,MAAM;EACrD,IAAI,OAAO,MAAM,aAAa,UAAU,OAAO,MAAM;EACrD,IAAI,OAAO,MAAM,SAAS,UAAU,OAAO,MAAM;EACjD,IAAI,MAAM,UAAU,OAAO,UAAU,MAAM,QAAQ;CACrD;CACA,OAAO;AACT;AAEA,SAAS,gBACP,KACA,WACA,OACA,IACA,MACA,SACA;CACA,MAAM,WAAW,QAAQ;CACzB,MAAM,SAAS,WAAW,SAAS,UAAU,EAAE,CAAC,IAAI,UAAU,EAAE;CAChE,MAAM,WACJ,SAAS,KAAA,IAAY,KAAA,IAAY,WAAW,SAAS,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI;CACxF,IAAI,QAAQ;EACV;EACA,SAAS,GAAG,UAAU,SAAS;EAC/B,OAAO,EACL,SAAS;GACP,MAAM;GACN;GACA,OAAO;IACL,IAAI;IACJ,MAAM;IACN,OAAO,QAAQ,eAAe,eAAe,IAAI,EAAE,UAAU,EAAE,CAAC,IAAI,KAAA;GACtE;EACF,EACF;CACF,CAAC;AACH;AAEA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,MAAM,SAAS,QAAQ;GACvB,IAAI,CAAC,OAAO,QAAQ,MAAM,CAAC,OAAO,OAAO,KAAK;GAC9C,MAAM,UAAU,IAAI,OAAO,QACzB,gBAAgB,KAAK,QAAQ,OAAO,KAAK,OAAO,QAAQ,OAAO,CACjE;GACA,OAAO,OAAO,GAAG,uBAAuB,OAAO;GAC/C,OAAO,OAAO,GAAG,sBAAsB,OAAO;GAC9C,aAAa;IACX,OAAO,QAAQ,MAAM,uBAAuB,OAAO;IACnD,OAAO,QAAQ,MAAM,sBAAsB,OAAO;GACpD;EACF;CACF;AACF;AAEA,SAAgB,uBAAuB,SAAqD;CAC1F,MAAM,QAAQ,QAAQ,SAAS;CAC/B,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,IAAI,WAAW,QAAQ,QAAQ;GAC/B,MAAM,UAAU,QAAQ,QAAQ,SAC9B,IAAI,OAAO,WAAoB;IAC7B,MAAM,OAAQ,QAAmC,YAAY;IAC7D,gBAAgB,KAAK,gBAAgB,OAAO,MAAM,UAAU,OAAO;IACnE,WAAW;GACb,CAAC,CACH;GACA,OAAO,OAAO,YAAY,aAAa,UAAU,KAAA;EACnD;CACF;AACF;AAEA,SAAgB,qBAAqB,SAAmD;CACtF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,YAAY,QAAQ,aAAa;CACvC,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,MAAM,UAAU,QAAQ,OAAO,YAC7B,IAAI,OAAO,IAAa,SACtB,gBAAgB,KAAK,WAAW,OAAO,IAAI,MAAM,OAAO,CAC1D,CACF;GACA,OAAO,OAAO,YAAY,aAAa,UAAU,KAAA;EACnD;CACF;AACF;AAEA,SAAgB,sBACd,SACa;CACb,OAAO,qBAAqB;EAAE,GAAG;EAAS,WAAW;CAAO,CAAC;AAC/D"}
|