@seneris/nosework 0.1.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.
- package/README.md +535 -0
- package/dist/client/errors.d.ts +49 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +173 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +29 -0
- package/dist/client.js.map +1 -0
- package/dist/error.d.ts +40 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +248 -0
- package/dist/error.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/query.d.ts +48 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +471 -0
- package/dist/query.js.map +1 -0
- package/dist/track.d.ts +4 -0
- package/dist/track.d.ts.map +1 -0
- package/dist/track.js +74 -0
- package/dist/track.js.map +1 -0
- package/dist/types.d.ts +157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ua.d.ts +3 -0
- package/dist/ua.d.ts.map +1 -0
- package/dist/ua.js +40 -0
- package/dist/ua.js.map +1 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +112 -0
- package/dist/utils.js.map +1 -0
- package/package.json +54 -0
- package/prisma/schema.prisma +145 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side error capture for nosework
|
|
3
|
+
*
|
|
4
|
+
* This is a lightweight (~2KB) script that captures unhandled errors
|
|
5
|
+
* and sends them to your tracking endpoint.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { initErrorTracking } from '@seneris/nosework/client/errors'
|
|
10
|
+
*
|
|
11
|
+
* initErrorTracking({
|
|
12
|
+
* endpoint: '/api/analytics/error',
|
|
13
|
+
* siteId: process.env.NEXT_PUBLIC_ANALYTICS_SITE_ID!,
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
let config = null;
|
|
18
|
+
let errorCount = 0;
|
|
19
|
+
let lastResetTime = Date.now();
|
|
20
|
+
/**
|
|
21
|
+
* Reset rate limiter every minute
|
|
22
|
+
*/
|
|
23
|
+
function checkRateLimit() {
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
if (now - lastResetTime > 60000) {
|
|
26
|
+
errorCount = 0;
|
|
27
|
+
lastResetTime = now;
|
|
28
|
+
}
|
|
29
|
+
const limit = config?.rateLimit ?? 10;
|
|
30
|
+
if (errorCount >= limit) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
errorCount++;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Send error to the tracking endpoint
|
|
38
|
+
*/
|
|
39
|
+
async function sendError(payload) {
|
|
40
|
+
if (!config)
|
|
41
|
+
return;
|
|
42
|
+
try {
|
|
43
|
+
await fetch(config.endpoint, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/json" },
|
|
46
|
+
body: JSON.stringify(payload),
|
|
47
|
+
// Don't wait for response, fire and forget
|
|
48
|
+
keepalive: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Silently fail - we don't want error tracking to cause more errors
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Process and send an error
|
|
57
|
+
*/
|
|
58
|
+
function handleError(captured) {
|
|
59
|
+
if (!config)
|
|
60
|
+
return;
|
|
61
|
+
// Apply filter if provided
|
|
62
|
+
if (config.filter && !config.filter(captured)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Check rate limit
|
|
66
|
+
if (!checkRateLimit()) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const payload = {
|
|
70
|
+
siteId: config.siteId,
|
|
71
|
+
message: captured.message,
|
|
72
|
+
stack: captured.stack,
|
|
73
|
+
url: captured.url,
|
|
74
|
+
metadata: {
|
|
75
|
+
...config.metadata,
|
|
76
|
+
errorType: captured.type,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
sendError(payload);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Handler for window.onerror events
|
|
83
|
+
*/
|
|
84
|
+
function errorHandler(event) {
|
|
85
|
+
handleError({
|
|
86
|
+
message: event.message || "Unknown error",
|
|
87
|
+
stack: event.error?.stack,
|
|
88
|
+
url: window.location.href,
|
|
89
|
+
type: "error",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Handler for unhandled promise rejections
|
|
94
|
+
*/
|
|
95
|
+
function rejectionHandler(event) {
|
|
96
|
+
let message = "Unhandled promise rejection";
|
|
97
|
+
let stack;
|
|
98
|
+
if (event.reason instanceof Error) {
|
|
99
|
+
message = event.reason.message;
|
|
100
|
+
stack = event.reason.stack;
|
|
101
|
+
}
|
|
102
|
+
else if (typeof event.reason === "string") {
|
|
103
|
+
message = event.reason;
|
|
104
|
+
}
|
|
105
|
+
else if (event.reason && typeof event.reason === "object") {
|
|
106
|
+
message = JSON.stringify(event.reason);
|
|
107
|
+
}
|
|
108
|
+
handleError({
|
|
109
|
+
message,
|
|
110
|
+
stack,
|
|
111
|
+
url: window.location.href,
|
|
112
|
+
type: "unhandledrejection",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Initialize error tracking
|
|
117
|
+
* Call this once when your app starts
|
|
118
|
+
*/
|
|
119
|
+
export function initErrorTracking(options) {
|
|
120
|
+
if (typeof window === "undefined") {
|
|
121
|
+
// SSR - do nothing
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
config = options;
|
|
125
|
+
// Add event listeners
|
|
126
|
+
window.addEventListener("error", errorHandler);
|
|
127
|
+
window.addEventListener("unhandledrejection", rejectionHandler);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Stop error tracking and remove event listeners
|
|
131
|
+
*/
|
|
132
|
+
export function stopErrorTracking() {
|
|
133
|
+
if (typeof window === "undefined")
|
|
134
|
+
return;
|
|
135
|
+
window.removeEventListener("error", errorHandler);
|
|
136
|
+
window.removeEventListener("unhandledrejection", rejectionHandler);
|
|
137
|
+
config = null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Manually track an error
|
|
141
|
+
* Useful for caught exceptions you still want to track
|
|
142
|
+
*/
|
|
143
|
+
export function captureError(error, metadata) {
|
|
144
|
+
if (!config)
|
|
145
|
+
return;
|
|
146
|
+
const captured = {
|
|
147
|
+
message: typeof error === "string" ? error : error.message,
|
|
148
|
+
stack: typeof error === "string" ? undefined : error.stack,
|
|
149
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
150
|
+
type: "error",
|
|
151
|
+
};
|
|
152
|
+
// Apply filter
|
|
153
|
+
if (config.filter && !config.filter(captured)) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Check rate limit
|
|
157
|
+
if (!checkRateLimit()) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const payload = {
|
|
161
|
+
siteId: config.siteId,
|
|
162
|
+
message: captured.message,
|
|
163
|
+
stack: captured.stack,
|
|
164
|
+
url: captured.url,
|
|
165
|
+
metadata: {
|
|
166
|
+
...config.metadata,
|
|
167
|
+
...metadata,
|
|
168
|
+
errorType: "manual",
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
sendError(payload);
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/client/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,gBAAgB,EAAE,YAAY,GAAG,SAAS,CAAC;CAChD;AAID,wBAAgB,SAAS,IAAI,YAAY,CAoBxC;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PrismaClient } from "@prisma/client";
|
|
2
|
+
let prismaClient = null;
|
|
3
|
+
export function getClient() {
|
|
4
|
+
if (prismaClient) {
|
|
5
|
+
return prismaClient;
|
|
6
|
+
}
|
|
7
|
+
// In development, use global to preserve client across hot reloads
|
|
8
|
+
if (process.env.NODE_ENV === "development") {
|
|
9
|
+
if (!global.__noseworkPrisma) {
|
|
10
|
+
global.__noseworkPrisma = new PrismaClient({
|
|
11
|
+
datasourceUrl: process.env.ANALYTICS_DATABASE_URL,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
prismaClient = global.__noseworkPrisma;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
prismaClient = new PrismaClient({
|
|
18
|
+
datasourceUrl: process.env.ANALYTICS_DATABASE_URL,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return prismaClient;
|
|
22
|
+
}
|
|
23
|
+
export async function disconnect() {
|
|
24
|
+
if (prismaClient) {
|
|
25
|
+
await prismaClient.$disconnect();
|
|
26
|
+
prismaClient = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,IAAI,YAAY,GAAwB,IAAI,CAAC;AAE7C,MAAM,UAAU,SAAS;IACvB,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,mEAAmE;IACnE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC7B,MAAM,CAAC,gBAAgB,GAAG,IAAI,YAAY,CAAC;gBACzC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;aAClD,CAAC,CAAC;QACL,CAAC;QACD,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,IAAI,YAAY,CAAC;YAC9B,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;SAClD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,YAAY,CAAC,WAAW,EAAE,CAAC;QACjC,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;AACH,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { TrackErrorOptions, ErrorStats, ErrorGroupData, ErrorInstance, ErrorGroupStatus } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Track a JavaScript error
|
|
4
|
+
*/
|
|
5
|
+
export declare function trackError(options: TrackErrorOptions): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Get error statistics
|
|
8
|
+
*/
|
|
9
|
+
export declare function getErrorStats(siteId: string, options?: {
|
|
10
|
+
startDate?: Date;
|
|
11
|
+
endDate?: Date;
|
|
12
|
+
}): Promise<ErrorStats>;
|
|
13
|
+
/**
|
|
14
|
+
* Get error groups (aggregated errors by fingerprint)
|
|
15
|
+
*/
|
|
16
|
+
export declare function getErrorGroups(siteId: string, options?: {
|
|
17
|
+
status?: ErrorGroupStatus;
|
|
18
|
+
limit?: number;
|
|
19
|
+
offset?: number;
|
|
20
|
+
}): Promise<ErrorGroupData[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Get individual error instances for a specific error group
|
|
23
|
+
*/
|
|
24
|
+
export declare function getErrorInstances(siteId: string, fingerprint: string, options?: {
|
|
25
|
+
limit?: number;
|
|
26
|
+
offset?: number;
|
|
27
|
+
}): Promise<ErrorInstance[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Update error group status
|
|
30
|
+
*/
|
|
31
|
+
export declare function updateErrorGroupStatus(siteId: string, fingerprint: string, status: ErrorGroupStatus): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Delete errors older than a certain date
|
|
34
|
+
* Useful for manual cleanup
|
|
35
|
+
*/
|
|
36
|
+
export declare function deleteOldErrors(siteId: string, olderThan: Date): Promise<{
|
|
37
|
+
deletedErrors: number;
|
|
38
|
+
deletedGroups: number;
|
|
39
|
+
}>;
|
|
40
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAgDpB;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoD1E;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAA;CAAE,GAC7C,OAAO,CAAC,UAAU,CAAC,CA2CrB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,cAAc,EAAE,CAAC,CAyB3B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,aAAa,EAAE,CAAC,CA4B1B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,GACd,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAwC3D"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { getClient } from "./client.js";
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
/**
|
|
4
|
+
* Create a fingerprint for grouping similar errors
|
|
5
|
+
* Normalizes variable parts to group similar errors together
|
|
6
|
+
*/
|
|
7
|
+
function createFingerprint(message, stack) {
|
|
8
|
+
// Normalize message (remove variable parts)
|
|
9
|
+
const normalizedMessage = message
|
|
10
|
+
.replace(/\d+/g, "N") // Numbers → N
|
|
11
|
+
.replace(/'[^']*'/g, "'S'") // Single-quoted strings → 'S'
|
|
12
|
+
.replace(/"[^"]*"/g, '"S"') // Double-quoted strings → "S"
|
|
13
|
+
.replace(/`[^`]*`/g, "`S`") // Template strings → `S`
|
|
14
|
+
.replace(/0x[a-fA-F0-9]+/g, "0xHEX"); // Hex addresses → 0xHEX
|
|
15
|
+
// Extract top stack frame (most relevant for grouping)
|
|
16
|
+
let topFrame = "";
|
|
17
|
+
if (stack) {
|
|
18
|
+
const lines = stack.split("\n");
|
|
19
|
+
// Find first line that looks like a stack frame (starts with "at " or similar)
|
|
20
|
+
for (const line of lines.slice(1)) {
|
|
21
|
+
const trimmed = line.trim();
|
|
22
|
+
if (trimmed.startsWith("at ") || trimmed.match(/^\w+@/)) {
|
|
23
|
+
// Normalize file paths and line numbers
|
|
24
|
+
topFrame = trimmed
|
|
25
|
+
.replace(/:\d+:\d+/g, ":L:C") // Line:column → L:C
|
|
26
|
+
.replace(/\?.*/g, ""); // Remove query strings
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const hash = createHash("sha256");
|
|
32
|
+
hash.update(normalizedMessage + topFrame);
|
|
33
|
+
return hash.digest("hex").slice(0, 16);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extract pathname from URL
|
|
37
|
+
*/
|
|
38
|
+
function extractPathname(url) {
|
|
39
|
+
try {
|
|
40
|
+
return new URL(url).pathname;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return url;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Track a JavaScript error
|
|
48
|
+
*/
|
|
49
|
+
export async function trackError(options) {
|
|
50
|
+
const db = getClient();
|
|
51
|
+
const fingerprint = createFingerprint(options.message, options.stack);
|
|
52
|
+
const pathname = extractPathname(options.url);
|
|
53
|
+
const now = new Date();
|
|
54
|
+
// Create the error record
|
|
55
|
+
await db.error.create({
|
|
56
|
+
data: {
|
|
57
|
+
siteId: options.siteId,
|
|
58
|
+
message: options.message,
|
|
59
|
+
stack: options.stack,
|
|
60
|
+
fingerprint,
|
|
61
|
+
url: options.url,
|
|
62
|
+
pathname,
|
|
63
|
+
visitorHash: options.visitorHash,
|
|
64
|
+
sessionId: options.sessionId,
|
|
65
|
+
userId: options.userId,
|
|
66
|
+
browser: options.browser,
|
|
67
|
+
browserVer: options.browserVer,
|
|
68
|
+
os: options.os,
|
|
69
|
+
device: options.device,
|
|
70
|
+
metadata: options.metadata ?? undefined,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
// Upsert the error group
|
|
74
|
+
await db.errorGroup.upsert({
|
|
75
|
+
where: {
|
|
76
|
+
siteId_fingerprint: {
|
|
77
|
+
siteId: options.siteId,
|
|
78
|
+
fingerprint,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
create: {
|
|
82
|
+
siteId: options.siteId,
|
|
83
|
+
fingerprint,
|
|
84
|
+
message: options.message,
|
|
85
|
+
stack: options.stack,
|
|
86
|
+
count: 1,
|
|
87
|
+
firstSeen: now,
|
|
88
|
+
lastSeen: now,
|
|
89
|
+
status: "open",
|
|
90
|
+
},
|
|
91
|
+
update: {
|
|
92
|
+
count: { increment: 1 },
|
|
93
|
+
lastSeen: now,
|
|
94
|
+
// Update message/stack if this is a clearer example
|
|
95
|
+
...(options.stack && { stack: options.stack }),
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get error statistics
|
|
101
|
+
*/
|
|
102
|
+
export async function getErrorStats(siteId, options) {
|
|
103
|
+
const db = getClient();
|
|
104
|
+
const where = {
|
|
105
|
+
siteId,
|
|
106
|
+
...(options?.startDate || options?.endDate
|
|
107
|
+
? {
|
|
108
|
+
timestamp: {
|
|
109
|
+
...(options?.startDate && { gte: options.startDate }),
|
|
110
|
+
...(options?.endDate && { lte: options.endDate }),
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
: {}),
|
|
114
|
+
};
|
|
115
|
+
const totalErrors = await db.error.count({ where });
|
|
116
|
+
const uniqueResult = await db.error.groupBy({
|
|
117
|
+
by: ["fingerprint"],
|
|
118
|
+
where,
|
|
119
|
+
});
|
|
120
|
+
const uniqueErrors = uniqueResult.length;
|
|
121
|
+
// Errors in last 24 hours
|
|
122
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
123
|
+
const errorsToday = await db.error.count({
|
|
124
|
+
where: {
|
|
125
|
+
siteId,
|
|
126
|
+
timestamp: { gte: oneDayAgo },
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
// Open error groups
|
|
130
|
+
const openGroups = await db.errorGroup.count({
|
|
131
|
+
where: { siteId, status: "open" },
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
totalErrors,
|
|
135
|
+
uniqueErrors,
|
|
136
|
+
errorsToday,
|
|
137
|
+
openGroups,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get error groups (aggregated errors by fingerprint)
|
|
142
|
+
*/
|
|
143
|
+
export async function getErrorGroups(siteId, options) {
|
|
144
|
+
const db = getClient();
|
|
145
|
+
const limit = options?.limit ?? 50;
|
|
146
|
+
const offset = options?.offset ?? 0;
|
|
147
|
+
const groups = await db.errorGroup.findMany({
|
|
148
|
+
where: {
|
|
149
|
+
siteId,
|
|
150
|
+
...(options?.status && { status: options.status }),
|
|
151
|
+
},
|
|
152
|
+
orderBy: { lastSeen: "desc" },
|
|
153
|
+
take: limit,
|
|
154
|
+
skip: offset,
|
|
155
|
+
});
|
|
156
|
+
return groups.map((g) => ({
|
|
157
|
+
id: g.id,
|
|
158
|
+
fingerprint: g.fingerprint,
|
|
159
|
+
message: g.message,
|
|
160
|
+
stack: g.stack,
|
|
161
|
+
count: g.count,
|
|
162
|
+
firstSeen: g.firstSeen,
|
|
163
|
+
lastSeen: g.lastSeen,
|
|
164
|
+
status: g.status,
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get individual error instances for a specific error group
|
|
169
|
+
*/
|
|
170
|
+
export async function getErrorInstances(siteId, fingerprint, options) {
|
|
171
|
+
const db = getClient();
|
|
172
|
+
const limit = options?.limit ?? 50;
|
|
173
|
+
const offset = options?.offset ?? 0;
|
|
174
|
+
const errors = await db.error.findMany({
|
|
175
|
+
where: { siteId, fingerprint },
|
|
176
|
+
orderBy: { timestamp: "desc" },
|
|
177
|
+
take: limit,
|
|
178
|
+
skip: offset,
|
|
179
|
+
});
|
|
180
|
+
return errors.map((e) => ({
|
|
181
|
+
id: e.id,
|
|
182
|
+
message: e.message,
|
|
183
|
+
stack: e.stack,
|
|
184
|
+
url: e.url,
|
|
185
|
+
pathname: e.pathname,
|
|
186
|
+
visitorHash: e.visitorHash,
|
|
187
|
+
sessionId: e.sessionId,
|
|
188
|
+
userId: e.userId,
|
|
189
|
+
browser: e.browser,
|
|
190
|
+
browserVer: e.browserVer,
|
|
191
|
+
os: e.os,
|
|
192
|
+
device: e.device,
|
|
193
|
+
metadata: e.metadata,
|
|
194
|
+
timestamp: e.timestamp,
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Update error group status
|
|
199
|
+
*/
|
|
200
|
+
export async function updateErrorGroupStatus(siteId, fingerprint, status) {
|
|
201
|
+
const db = getClient();
|
|
202
|
+
await db.errorGroup.update({
|
|
203
|
+
where: {
|
|
204
|
+
siteId_fingerprint: { siteId, fingerprint },
|
|
205
|
+
},
|
|
206
|
+
data: { status },
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Delete errors older than a certain date
|
|
211
|
+
* Useful for manual cleanup
|
|
212
|
+
*/
|
|
213
|
+
export async function deleteOldErrors(siteId, olderThan) {
|
|
214
|
+
const db = getClient();
|
|
215
|
+
// Delete old error instances
|
|
216
|
+
const deletedErrors = await db.error.deleteMany({
|
|
217
|
+
where: {
|
|
218
|
+
siteId,
|
|
219
|
+
timestamp: { lt: olderThan },
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
// Delete error groups with no remaining errors
|
|
223
|
+
// First, get fingerprints that still have errors
|
|
224
|
+
const remainingFingerprints = await db.error.groupBy({
|
|
225
|
+
by: ["fingerprint"],
|
|
226
|
+
where: { siteId },
|
|
227
|
+
});
|
|
228
|
+
const activeFingerprints = new Set(remainingFingerprints.map((r) => r.fingerprint));
|
|
229
|
+
// Delete groups not in active fingerprints
|
|
230
|
+
const allGroups = await db.errorGroup.findMany({
|
|
231
|
+
where: { siteId },
|
|
232
|
+
select: { fingerprint: true },
|
|
233
|
+
});
|
|
234
|
+
const groupsToDelete = allGroups
|
|
235
|
+
.filter((g) => !activeFingerprints.has(g.fingerprint))
|
|
236
|
+
.map((g) => g.fingerprint);
|
|
237
|
+
const deletedGroups = await db.errorGroup.deleteMany({
|
|
238
|
+
where: {
|
|
239
|
+
siteId,
|
|
240
|
+
fingerprint: { in: groupsToDelete },
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
return {
|
|
244
|
+
deletedErrors: deletedErrors.count,
|
|
245
|
+
deletedGroups: deletedGroups.count,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { trackPageView, trackEvent } from "./track.js";
|
|
2
|
+
export { trackError, getErrorStats, getErrorGroups, getErrorInstances, updateErrorGroupStatus, deleteOldErrors, } from "./error.js";
|
|
3
|
+
export { getStats, getTopPages, getLocations, getReferrers, getDevices, getTimeSeries, getOrCreateSite, listSites, getSessionStats, getEntryPages, getExitPages, getPageFlows, getSessions, } from "./query.js";
|
|
4
|
+
export { getClient, disconnect } from "./client.js";
|
|
5
|
+
export { isBot, cleanupOldSalts } from "./utils.js";
|
|
6
|
+
export { parseUserAgent } from "./ua.js";
|
|
7
|
+
export type { TrackPageViewOptions, TrackEventOptions, DateRange, QueryOptions, PaginatedQueryOptions, Stats, TopPage, LocationData, ReferrerData, DeviceData, GeoLocation, ParsedUserAgent, VisitorInfo, SessionStats, SessionData, EntryExitPage, PageFlow, TrackErrorOptions, ErrorStats, ErrorGroupStatus, ErrorGroupData, ErrorInstance, } from "./types.js";
|
|
8
|
+
export type { TimeSeriesDataPoint } from "./query.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EAET,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,qBAAqB,EACrB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EAEX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,QAAQ,EAER,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Main exports for nosework analytics package
|
|
2
|
+
// Tracking functions
|
|
3
|
+
export { trackPageView, trackEvent } from "./track.js";
|
|
4
|
+
// Error tracking functions
|
|
5
|
+
export { trackError, getErrorStats, getErrorGroups, getErrorInstances, updateErrorGroupStatus, deleteOldErrors, } from "./error.js";
|
|
6
|
+
// Query functions
|
|
7
|
+
export { getStats, getTopPages, getLocations, getReferrers, getDevices, getTimeSeries, getOrCreateSite, listSites,
|
|
8
|
+
// Session analytics
|
|
9
|
+
getSessionStats, getEntryPages, getExitPages, getPageFlows, getSessions, } from "./query.js";
|
|
10
|
+
// Client utilities
|
|
11
|
+
export { getClient, disconnect } from "./client.js";
|
|
12
|
+
// Utility functions
|
|
13
|
+
export { isBot, cleanupOldSalts } from "./utils.js";
|
|
14
|
+
// User-Agent parsing (for advanced use cases)
|
|
15
|
+
export { parseUserAgent } from "./ua.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvD,2BAA2B;AAC3B,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,kBAAkB;AAClB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS;AACT,oBAAoB;AACpB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpD,oBAAoB;AACpB,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpD,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { QueryOptions, PaginatedQueryOptions, Stats, TopPage, LocationData, ReferrerData, DeviceData, SessionStats, SessionData, EntryExitPage, PageFlow } from "./types.js";
|
|
2
|
+
export declare function getStats(options: QueryOptions): Promise<Stats>;
|
|
3
|
+
export declare function getTopPages(options: PaginatedQueryOptions): Promise<TopPage[]>;
|
|
4
|
+
export declare function getLocations(options: PaginatedQueryOptions): Promise<LocationData[]>;
|
|
5
|
+
export declare function getReferrers(options: PaginatedQueryOptions): Promise<ReferrerData[]>;
|
|
6
|
+
export declare function getDevices(options: PaginatedQueryOptions): Promise<DeviceData[]>;
|
|
7
|
+
export interface TimeSeriesDataPoint {
|
|
8
|
+
date: string;
|
|
9
|
+
pageViews: number;
|
|
10
|
+
visitors: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function getTimeSeries(options: QueryOptions & {
|
|
13
|
+
interval?: "hour" | "day" | "week" | "month";
|
|
14
|
+
}): Promise<TimeSeriesDataPoint[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Get aggregate session statistics
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSessionStats(options: QueryOptions): Promise<SessionStats>;
|
|
19
|
+
/**
|
|
20
|
+
* Get entry pages (first page of each session)
|
|
21
|
+
*/
|
|
22
|
+
export declare function getEntryPages(options: PaginatedQueryOptions): Promise<EntryExitPage[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Get exit pages (last page of each session)
|
|
25
|
+
*/
|
|
26
|
+
export declare function getExitPages(options: PaginatedQueryOptions): Promise<EntryExitPage[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Get common page flow paths (sequence of pages in sessions)
|
|
29
|
+
*/
|
|
30
|
+
export declare function getPageFlows(options: PaginatedQueryOptions & {
|
|
31
|
+
maxPathLength?: number;
|
|
32
|
+
}): Promise<PageFlow[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Get individual session data (for debugging/analysis)
|
|
35
|
+
*/
|
|
36
|
+
export declare function getSessions(options: PaginatedQueryOptions): Promise<SessionData[]>;
|
|
37
|
+
export declare function getOrCreateSite(domain: string, name?: string): Promise<{
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
domain: string;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function listSites(): Promise<{
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
domain: string;
|
|
46
|
+
createdAt: Date;
|
|
47
|
+
}[]>;
|
|
48
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,QAAQ,EACT,MAAM,YAAY,CAAC;AAmBpB,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAuCpE;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,EAAE,CAAC,CA+BpB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC,CAqCzB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC,CA+BzB;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,UAAU,EAAE,CAAC,CAsCvB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,GACvE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA6BhC;AA4BD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,YAAY,CAAC,CA0DvB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,aAAa,EAAE,CAAC,CAqC1B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,aAAa,EAAE,CAAC,CAqC1B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,OAAO,CAAC,QAAQ,EAAE,CAAC,CA2CrB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,WAAW,EAAE,CAAC,CAoFxB;AAGD,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAevD;AAGD,wBAAsB,SAAS,IAAI,OAAO,CACxC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,EAAE,CAChE,CAGA"}
|