@dasasian/firebase-structured-logger 0.1.1 → 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.
- package/dist/client/errorHandler.d.ts.map +1 -1
- package/dist/client/errorHandler.js +35 -3
- package/dist/client/errorHandler.js.map +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/logger.d.ts +5 -5
- package/dist/client/logger.d.ts.map +1 -1
- package/dist/client/logger.js +13 -12
- package/dist/client/logger.js.map +1 -1
- package/dist/client/rateLimiter.d.ts +26 -4
- package/dist/client/rateLimiter.d.ts.map +1 -1
- package/dist/client/rateLimiter.js +37 -38
- package/dist/client/rateLimiter.js.map +1 -1
- package/dist/functions/logHandler.d.ts.map +1 -1
- package/dist/functions/logHandler.js +3 -3
- package/dist/functions/logHandler.js.map +1 -1
- package/dist/functions/sourceMapCache.d.ts +10 -3
- package/dist/functions/sourceMapCache.d.ts.map +1 -1
- package/dist/functions/sourceMapCache.js +22 -10
- package/dist/functions/sourceMapCache.js.map +1 -1
- package/package.json +8 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/client/errorHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/client/errorHandler.ts"],"names":[],"mappings":"AAqBA,wBAAgB,uBAAuB,IAAI,IAAI,CA8B9C;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GACpC,IAAI,CAMN"}
|
|
@@ -3,14 +3,46 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.setupGlobalErrorHandler = setupGlobalErrorHandler;
|
|
4
4
|
exports.handleReactError = handleReactError;
|
|
5
5
|
const logger_1 = require("./logger");
|
|
6
|
+
/**
|
|
7
|
+
* A script loaded cross-origin without CORS has its error withheld by the
|
|
8
|
+
* browser: the event fires with `error === null` and only `message`
|
|
9
|
+
* (classically `"Script error."`), `filename`, `lineno` and `colno` are set.
|
|
10
|
+
*
|
|
11
|
+
* Passing that null straight to the logger produced an entry whose message was
|
|
12
|
+
* the literal string "null" — less information than the event carried, and
|
|
13
|
+
* identical for every such error, so they were indistinguishable in Cloud
|
|
14
|
+
* Logging and collapsed into a single signature that duplicate suppression
|
|
15
|
+
* then swallowed. The locator is folded into the message so the entries stay
|
|
16
|
+
* distinct as well as readable.
|
|
17
|
+
*/
|
|
18
|
+
function errorFromEvent(event) {
|
|
19
|
+
const where = event.filename
|
|
20
|
+
? ` (${event.filename}:${event.lineno ?? 0}:${event.colno ?? 0})`
|
|
21
|
+
: '';
|
|
22
|
+
return new Error(`${event.message || 'Cross-origin script error'}${where}`);
|
|
23
|
+
}
|
|
6
24
|
function setupGlobalErrorHandler() {
|
|
7
25
|
window.addEventListener('error', (event) => {
|
|
8
|
-
|
|
9
|
-
|
|
26
|
+
if (event.error != null) {
|
|
27
|
+
console.error('[fsl] Uncaught error:', event.error);
|
|
28
|
+
(0, logger_1.getClientLogger)().error(event.error, {
|
|
29
|
+
errorCategory: 'crash',
|
|
30
|
+
errorType: 'UncaughtError',
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.error('[fsl] Cross-origin script error:', event.message);
|
|
35
|
+
(0, logger_1.getClientLogger)().error(errorFromEvent(event), { errorCategory: 'crash', errorType: 'CrossOriginError' }, { filename: event.filename, lineno: event.lineno, colno: event.colno });
|
|
10
36
|
});
|
|
11
37
|
window.addEventListener('unhandledrejection', (event) => {
|
|
12
38
|
console.error('[fsl] Unhandled rejection:', event.reason);
|
|
13
|
-
|
|
39
|
+
// A rejection can carry any value, including none at all. `toError` would
|
|
40
|
+
// turn that into Error("undefined"), which says nothing.
|
|
41
|
+
const reason = event.reason ?? new Error('Unhandled promise rejection with no reason');
|
|
42
|
+
(0, logger_1.getClientLogger)().error(reason, {
|
|
43
|
+
errorCategory: 'crash',
|
|
44
|
+
errorType: 'UnhandledRejection',
|
|
45
|
+
});
|
|
14
46
|
});
|
|
15
47
|
}
|
|
16
48
|
function handleReactError(error, errorInfo) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/client/errorHandler.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/client/errorHandler.ts"],"names":[],"mappings":";;AAqBA,0DA8BC;AAED,4CASC;AA9DD,qCAA0C;AAE1C;;;;;;;;;;;GAWG;AACH,SAAS,cAAc,CAAC,KAAiB;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ;QAC1B,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG;QACjE,CAAC,CAAC,EAAE,CAAA;IACN,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,2BAA2B,GAAG,KAAK,EAAE,CAAC,CAAA;AAC7E,CAAC;AAED,SAAgB,uBAAuB;IACrC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACzC,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;YACnD,IAAA,wBAAe,GAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE;gBACnC,aAAa,EAAE,OAAO;gBACtB,SAAS,EAAE,eAAe;aAC3B,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;QAChE,IAAA,wBAAe,GAAE,CAAC,KAAK,CACrB,cAAc,CAAC,KAAK,CAAC,EACrB,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,EACzD,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CACvE,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;QACtD,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QACzD,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;QACzE,IAAA,wBAAe,GAAE,CAAC,KAAK,CAAC,MAAM,EAAE;YAC9B,aAAa,EAAE,OAAO;YACtB,SAAS,EAAE,oBAAoB;SAChC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAC9B,KAAY,EACZ,SAAqC;IAErC,IAAA,wBAAe,GAAE,CAAC,KAAK,CACrB,KAAK,EACL,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,EACnD,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,CAC7C,CAAA;AACH,CAAC"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { initLogger, getClientLogger,
|
|
2
|
-
export type { InitLoggerConfig, RateLimitConfig } from './logger';
|
|
1
|
+
export { initLogger, getClientLogger, triggerTestLog } from './logger';
|
|
2
|
+
export type { Logger, InitLoggerConfig, RateLimitConfig } from './logger';
|
|
3
3
|
export { setupGlobalErrorHandler, handleReactError } from './errorHandler';
|
|
4
4
|
export { addBreadcrumb, setActiveActivity, bc } from './breadcrumbs';
|
|
5
5
|
export type { LogSeverity, LogPayload, BreadcrumbEntry, BaseLabels } from '../shared/types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAMtE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AACzE,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AACpE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/client/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.bc = exports.setActiveActivity = exports.addBreadcrumb = exports.handleReactError = exports.setupGlobalErrorHandler = exports.triggerTestLog = exports.
|
|
3
|
+
exports.bc = exports.setActiveActivity = exports.addBreadcrumb = exports.handleReactError = exports.setupGlobalErrorHandler = exports.triggerTestLog = exports.getClientLogger = exports.initLogger = void 0;
|
|
4
4
|
var logger_1 = require("./logger");
|
|
5
5
|
Object.defineProperty(exports, "initLogger", { enumerable: true, get: function () { return logger_1.initLogger; } });
|
|
6
6
|
Object.defineProperty(exports, "getClientLogger", { enumerable: true, get: function () { return logger_1.getClientLogger; } });
|
|
7
|
-
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
|
|
8
7
|
Object.defineProperty(exports, "triggerTestLog", { enumerable: true, get: function () { return logger_1.triggerTestLog; } });
|
|
9
8
|
var errorHandler_1 = require("./errorHandler");
|
|
10
9
|
Object.defineProperty(exports, "setupGlobalErrorHandler", { enumerable: true, get: function () { return errorHandler_1.setupGlobalErrorHandler; } });
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;AAAA,mCAAsE;AAA7D,oGAAA,UAAU,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,wGAAA,cAAc,OAAA;AAOpD,+CAA0E;AAAjE,uHAAA,uBAAuB,OAAA;AAAE,gHAAA,gBAAgB,OAAA;AAClD,6CAAoE;AAA3D,4GAAA,aAAa,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAAE,iGAAA,EAAE,OAAA"}
|
package/dist/client/logger.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LogSeverity, LogPayload } from '../shared/types';
|
|
1
|
+
import type { LogSeverity, LogPayload, BaseLabels } from '../shared/types';
|
|
2
2
|
import { type RateLimitConfig } from './rateLimiter';
|
|
3
3
|
export type { RateLimitConfig };
|
|
4
4
|
type LogCallable = (data: LogPayload) => Promise<unknown>;
|
|
@@ -19,10 +19,10 @@ export declare class Logger<AppLabels extends Record<string, string | undefined>
|
|
|
19
19
|
clearUser(): void;
|
|
20
20
|
setScreen(screen: string): void;
|
|
21
21
|
addBreadcrumb(type: 'action' | 'state' | 'nav' | 'error', name: string, data?: Record<string, unknown>): void;
|
|
22
|
-
error(raw: unknown, labels?: Partial<AppLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
23
|
-
info(message: string, labels?: Partial<AppLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
24
|
-
warning(message: string, labels?: Partial<AppLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
25
|
-
debug(message: string, labels?: Partial<AppLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
22
|
+
error(raw: unknown, labels?: Partial<AppLabels & BaseLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
23
|
+
info(message: string, labels?: Partial<AppLabels & BaseLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
24
|
+
warning(message: string, labels?: Partial<AppLabels & BaseLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
25
|
+
debug(message: string, labels?: Partial<AppLabels & BaseLabels>, context?: Record<string, unknown>, attachments?: Record<string, Blob | File | string>): void;
|
|
26
26
|
private send;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/client/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/client/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/client/logger.js
CHANGED
|
@@ -82,18 +82,11 @@ class Logger {
|
|
|
82
82
|
}
|
|
83
83
|
error(raw, labels, context, attachments) {
|
|
84
84
|
const error = (0, error_1.toError)(raw);
|
|
85
|
-
const screen = (0, breadcrumbs_1.getCurrentScreen)();
|
|
86
|
-
const activity = (0, breadcrumbs_1.getActiveActivity)();
|
|
87
|
-
if (!(0, rateLimiter_1.canLogError)(error, screen, activity)) {
|
|
88
|
-
console.error('[fsl] Error suppressed:', error.message);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
(0, rateLimiter_1.recordError)(error, screen, activity);
|
|
92
85
|
const errorLabels = {
|
|
93
86
|
errorType: error.name || 'UnknownError',
|
|
94
87
|
...labels,
|
|
95
88
|
};
|
|
96
|
-
void this.send(error.message, 'ERROR', errorLabels, context, attachments, (0, error_1.toErrorPayload)(error));
|
|
89
|
+
void this.send(error.message, 'ERROR', errorLabels, context, attachments, (0, error_1.toErrorPayload)(error), (0, rateLimiter_1.signatureFor)(error, (0, breadcrumbs_1.getCurrentScreen)(), (0, breadcrumbs_1.getActiveActivity)()));
|
|
97
90
|
}
|
|
98
91
|
info(message, labels, context, attachments) {
|
|
99
92
|
void this.send(message, 'INFO', labels, context, attachments);
|
|
@@ -104,11 +97,20 @@ class Logger {
|
|
|
104
97
|
debug(message, labels, context, attachments) {
|
|
105
98
|
void this.send(message, 'DEBUG', labels, context, attachments);
|
|
106
99
|
}
|
|
107
|
-
async send(message, severity, labels, context, attachments, error) {
|
|
100
|
+
async send(message, severity, labels, context, attachments, error, signature) {
|
|
108
101
|
if (severity_1.SEVERITY_ORDER[severity] > this.minLevel)
|
|
109
102
|
return;
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
// One gate for every severity. Passing a signature opts this log into
|
|
104
|
+
// duplicate suppression; the check and the budget spend are one operation,
|
|
105
|
+
// so a log can neither be counted twice nor checked without being counted.
|
|
106
|
+
const decision = (0, rateLimiter_1.allow)(signature);
|
|
107
|
+
if (!decision.allowed) {
|
|
108
|
+
if (decision.reason === 'duplicate') {
|
|
109
|
+
console.warn(`[fsl] Duplicate suppressed: ${decision.signature}`);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.warn('[fsl] Session log limit reached');
|
|
113
|
+
}
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
114
116
|
try {
|
|
@@ -140,7 +142,6 @@ class Logger {
|
|
|
140
142
|
},
|
|
141
143
|
...(base64Attachments ? { attachments: base64Attachments } : {}),
|
|
142
144
|
};
|
|
143
|
-
(0, rateLimiter_1.recordLog)();
|
|
144
145
|
await this.config.logFunction(payload);
|
|
145
146
|
}
|
|
146
147
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/client/logger.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/client/logger.ts"],"names":[],"mappings":";;;AAmPA,wCAWC;AAKD,gCAKC;AAED,0CAKC;AA9QD,iDAAmD;AACnD,2CAAyD;AACzD,+CAOsB;AACtB,+CAKsB;AAgBtB,SAAS,eAAe;IACtB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,YAAY;QAAE,OAAO,SAAS,CAAA;IAC9F,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,oCAAoC;AACpC,MAAM,SAAS,GAAuB;IACpC,CAAC,kBAAkB,EAAE,KAAK,CAAC;IAC3B,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,CAAC,KAAK,EAAE,OAAO,CAAC;IAChB,CAAC,KAAK,EAAE,SAAS,CAAC;IAClB,CAAC,OAAO,EAAE,OAAO,CAAC;CACnB,CAAA;AAED,MAAM,QAAQ,GAAuB;IACnC,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,CAAC,KAAK,EAAE,MAAM,CAAC;IACf,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACpB,CAAC,QAAQ,EAAE,QAAQ,CAAC;CACrB,CAAA;AAED,SAAS,cAAc,CAAC,KAAyB,EAAE,QAAgB;IACjE,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IACtD,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAA;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAA;AACrE,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;AACjD,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;AAEnD,KAAK,UAAU,YAAY,CAAC,IAAU;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAA;QAC/B,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACnB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgB,CAAA;YACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAA;QACzC,CAAC,CAAA;QACD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAA;QACvB,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAA2B;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,OAAO,YAAY,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED,MAAa,MAAM;IAGA,MAAM,CAA6B;IACnC,QAAQ,CAAQ;IACzB,MAAM,CAAoB;IAC1B,UAAU,GAAuB,EAAE,CAAA;IAE3C,YAAY,MAAmC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,yBAAc,CAAC,MAAM,CAAC,WAAW,IAAI,eAAe,EAAE,CAAC,CAAA;QACvE,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC5B,IAAA,kCAAoB,EAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,WAAgC;QACnD,IAAI,CAAC,MAAM,GAAG,GAAG,CAAA;QACjB,IAAI,CAAC,UAAU,GAAG,WAAW,IAAI,EAAE,CAAA;IACrC,CAAC;IAED,SAAS;QACP,IAAI,CAAC,MAAM,GAAG,SAAS,CAAA;QACvB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACpB,IAAA,8BAAgB,GAAE,CAAA;IACpB,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,IAAA,8BAAgB,EAAC,MAAM,CAAC,CAAA;IAC1B,CAAC;IAED,aAAa,CACX,IAA0C,EAC1C,IAAY,EACZ,IAA8B;QAE9B,IAAA,2BAAa,EAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CACH,GAAY,EACZ,MAAwC,EACxC,OAAiC,EACjC,WAAkD;QAElD,MAAM,KAAK,GAAG,IAAA,eAAO,EAAC,GAAG,CAAC,CAAA;QAE1B,MAAM,WAAW,GAAuC;YACtD,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,cAAc;YACvC,GAAI,MAA6C;SAClD,CAAA;QAED,KAAK,IAAI,CAAC,IAAI,CACZ,KAAK,CAAC,OAAO,EACb,OAAO,EACP,WAAW,EACX,OAAO,EACP,WAAW,EACX,IAAA,sBAAc,EAAC,KAAK,CAAC,EACrB,IAAA,0BAAY,EAAC,KAAK,EAAE,IAAA,8BAAgB,GAAE,EAAE,IAAA,+BAAiB,GAAE,CAAC,CAC7D,CAAA;IACH,CAAC;IAED,IAAI,CACF,OAAe,EACf,MAAwC,EACxC,OAAiC,EACjC,WAAkD;QAElD,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAA4C,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;IACrG,CAAC;IAED,OAAO,CACL,OAAe,EACf,MAAwC,EACxC,OAAiC,EACjC,WAAkD;QAElD,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,MAA4C,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;IACxG,CAAC;IAED,KAAK,CACH,OAAe,EACf,MAAwC,EACxC,OAAiC,EACjC,WAAkD;QAElD,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAA4C,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;IACtG,CAAC;IAEO,KAAK,CAAC,IAAI,CAChB,OAAe,EACf,QAAqB,EACrB,MAA2C,EAC3C,OAAiC,EACjC,WAAkD,EAClD,KAAoB,EACpB,SAAkB;QAElB,IAAI,yBAAc,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAM;QAEpD,sEAAsE;QACtE,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,IAAA,mBAAK,EAAC,SAAS,CAAC,CAAA;QACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACpC,OAAO,CAAC,IAAI,CAAC,+BAA+B,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;YACnE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;YACjD,CAAC;YACD,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAyB;gBACtC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;gBACxB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;gBAChC,MAAM,EAAE,IAAA,8BAAgB,GAAE;gBAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,OAAO;gBAChB,GAAG,IAAI,CAAC,UAAU;gBAClB,GAAG,MAAM;aACV,CAAA;YAED,IAAI,iBAAqD,CAAA;YACzD,IAAI,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvD,iBAAiB,GAAG,EAAE,CAAA;gBACtB,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC7D,iBAAiB,CAAC,IAAI,CAAC,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAA;gBAC3D,CAAC;YACH,CAAC;YAED,MAAM,OAAO,GAAe;gBAC1B,OAAO;gBACP,QAAQ;gBACR,MAAM,EAAE,SAAS;gBACjB,WAAW,EAAE;oBACX,WAAW,EAAE,IAAA,gCAAkB,EAAC,EAAE,CAAC;oBACnC,OAAO;oBACP,KAAK;iBACN;gBACD,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAA;YAED,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACtF,CAAC;IACH,CAAC;CACF;AAvJD,wBAuJC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc;IAC5B,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAA;IAC3C,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;IAChC,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IAC/E,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;IAC1C,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACpE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;IAC5C,MAAM,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;IACxE,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;IACzC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;IAClE,OAAO,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAA;AACtG,CAAC;AAED,yBAAyB;AACzB,IAAI,QAAQ,GAAsD,IAAI,CAAA;AAEtE,SAAgB,UAAU,CAExB,MAAmC;IACnC,QAAQ,GAAG,IAAI,MAAM,CAAC,MAAM,CAA+C,CAAA;IAC3E,OAAO,QAA6B,CAAA;AACtC,CAAC;AAED,SAAgB,eAAe;IAG7B,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAC/D,OAAO,QAA6B,CAAA;AACtC,CAAC"}
|
|
@@ -4,9 +4,31 @@ export interface RateLimitConfig {
|
|
|
4
4
|
storageKey?: string;
|
|
5
5
|
}
|
|
6
6
|
export declare function configureRateLimiter(options: RateLimitConfig): void;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Build the key used to recognise a repeat of the same problem. Two occurrences
|
|
9
|
+
* count as duplicates only if the message, the screen and the activity all match,
|
|
10
|
+
* so the same error from two different places is not collapsed into one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function signatureFor(error: Error | string, screen?: string, activity?: string): string;
|
|
13
|
+
export type RateLimitDecision = {
|
|
14
|
+
allowed: true;
|
|
15
|
+
} | {
|
|
16
|
+
allowed: false;
|
|
17
|
+
reason: 'session-limit' | 'duplicate';
|
|
18
|
+
signature?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Decide whether one log may be sent, and consume its budget if so.
|
|
22
|
+
*
|
|
23
|
+
* Check and consume are one operation on purpose. They used to be separate
|
|
24
|
+
* exports called from two different layers, which meant an error was checked
|
|
25
|
+
* against the session limit twice and counted against it twice — a configured
|
|
26
|
+
* limit of 50 was really 25 for errors. A single call cannot double-count, and
|
|
27
|
+
* cannot be checked without consuming.
|
|
28
|
+
*
|
|
29
|
+
* Pass a `signature` to opt this log into duplicate suppression. Any severity
|
|
30
|
+
* may do so; it is not reserved for errors.
|
|
31
|
+
*/
|
|
32
|
+
export declare function allow(signature?: string): RateLimitDecision;
|
|
11
33
|
export declare function resetRateLimiter(): void;
|
|
12
34
|
//# sourceMappingURL=rateLimiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;
|
|
1
|
+
{"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAeD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEnE;AAmBD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAGR;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjF;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAkB3D;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.configureRateLimiter = configureRateLimiter;
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.recordLog = recordLog;
|
|
7
|
-
exports.recordError = recordError;
|
|
4
|
+
exports.signatureFor = signatureFor;
|
|
5
|
+
exports.allow = allow;
|
|
8
6
|
exports.resetRateLimiter = resetRateLimiter;
|
|
9
7
|
const DEFAULT_SESSION_LIMIT = 50;
|
|
10
8
|
const DEFAULT_DUPLICATE_LIMIT = 3;
|
|
11
9
|
const DEFAULT_STORAGE_KEY = 'fsl_ratelimit';
|
|
10
|
+
// Session-scoped by design: one browser session, one budget. Deliberately not
|
|
11
|
+
// per-Logger — see the module-scoped state rule in CLAUDE.md.
|
|
12
12
|
let config = {
|
|
13
13
|
sessionLimit: DEFAULT_SESSION_LIMIT,
|
|
14
14
|
duplicateLimit: DEFAULT_DUPLICATE_LIMIT,
|
|
@@ -17,7 +17,7 @@ let config = {
|
|
|
17
17
|
function configureRateLimiter(options) {
|
|
18
18
|
config = { ...config, ...options };
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function readState() {
|
|
21
21
|
try {
|
|
22
22
|
const stored = sessionStorage.getItem(config.storageKey);
|
|
23
23
|
return stored ? JSON.parse(stored) : { logCount: 0, errorSignatures: {} };
|
|
@@ -26,51 +26,50 @@ function getState() {
|
|
|
26
26
|
return { logCount: 0, errorSignatures: {} };
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
function
|
|
29
|
+
function writeState(state) {
|
|
30
30
|
try {
|
|
31
31
|
sessionStorage.setItem(config.storageKey, JSON.stringify(state));
|
|
32
32
|
}
|
|
33
33
|
catch {
|
|
34
|
-
//
|
|
34
|
+
// sessionStorage full or unavailable — rate limiting degrades, logging continues
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function getErrorSignature(error, screen, activity) {
|
|
37
|
+
/**
|
|
38
|
+
* Build the key used to recognise a repeat of the same problem. Two occurrences
|
|
39
|
+
* count as duplicates only if the message, the screen and the activity all match,
|
|
40
|
+
* so the same error from two different places is not collapsed into one.
|
|
41
|
+
*/
|
|
42
|
+
function signatureFor(error, screen, activity) {
|
|
44
43
|
const str = error instanceof Error ? `${error.name}:${error.message}` : String(error);
|
|
45
44
|
return `${str}|${screen ?? ''}|${activity ?? ''}`;
|
|
46
45
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Decide whether one log may be sent, and consume its budget if so.
|
|
48
|
+
*
|
|
49
|
+
* Check and consume are one operation on purpose. They used to be separate
|
|
50
|
+
* exports called from two different layers, which meant an error was checked
|
|
51
|
+
* against the session limit twice and counted against it twice — a configured
|
|
52
|
+
* limit of 50 was really 25 for errors. A single call cannot double-count, and
|
|
53
|
+
* cannot be checked without consuming.
|
|
54
|
+
*
|
|
55
|
+
* Pass a `signature` to opt this log into duplicate suppression. Any severity
|
|
56
|
+
* may do so; it is not reserved for errors.
|
|
57
|
+
*/
|
|
58
|
+
function allow(signature) {
|
|
59
|
+
const state = readState();
|
|
52
60
|
if (state.logCount >= config.sessionLimit) {
|
|
53
|
-
|
|
54
|
-
return false;
|
|
61
|
+
return { allowed: false, reason: 'session-limit' };
|
|
55
62
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
if (signature !== undefined) {
|
|
64
|
+
const seen = state.errorSignatures[signature] ?? 0;
|
|
65
|
+
if (seen >= config.duplicateLimit) {
|
|
66
|
+
return { allowed: false, reason: 'duplicate', signature };
|
|
67
|
+
}
|
|
68
|
+
state.errorSignatures[signature] = seen + 1;
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
mutateState((state) => {
|
|
65
|
-
state.logCount++;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function recordError(error, screen, activity) {
|
|
69
|
-
const sig = getErrorSignature(error, screen, activity);
|
|
70
|
-
mutateState((state) => {
|
|
71
|
-
state.errorSignatures[sig] = (state.errorSignatures[sig] ?? 0) + 1;
|
|
72
|
-
state.logCount++;
|
|
73
|
-
});
|
|
70
|
+
state.logCount++;
|
|
71
|
+
writeState(state);
|
|
72
|
+
return { allowed: true };
|
|
74
73
|
}
|
|
75
74
|
function resetRateLimiter() {
|
|
76
75
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logHandler.d.ts","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAA;AAU/D,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;
|
|
1
|
+
{"version":3,"file":"logHandler.d.ts","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAA;AAU/D,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AA8DD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,IAGrD,SAAS,eAAe,CAAC,UAAU,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAgCnE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,8FAM/F"}
|
|
@@ -19,7 +19,7 @@ function bundleFileFromUrl(url) {
|
|
|
19
19
|
* Attempt to symbolicate a minified error stack trace using source maps.
|
|
20
20
|
* Loads source maps per-bundle so multiple chunks are handled correctly.
|
|
21
21
|
*/
|
|
22
|
-
async function symbolicateError(releaseId, error) {
|
|
22
|
+
async function symbolicateError(releaseId, error, bucketName) {
|
|
23
23
|
if (!error?.stack)
|
|
24
24
|
return error;
|
|
25
25
|
try {
|
|
@@ -38,7 +38,7 @@ async function symbolicateError(releaseId, error) {
|
|
|
38
38
|
// Load source map for each unique bundle (getSourceMap handles caching)
|
|
39
39
|
const sourceMaps = new Map();
|
|
40
40
|
await Promise.all(Array.from(bundleFiles).map(async (bundle) => {
|
|
41
|
-
const map = await (0, sourceMapCache_1.getSourceMap)(releaseId, bundle);
|
|
41
|
+
const map = await (0, sourceMapCache_1.getSourceMap)(releaseId, bundle, bucketName);
|
|
42
42
|
if (map)
|
|
43
43
|
sourceMaps.set(bundle, map);
|
|
44
44
|
}));
|
|
@@ -79,7 +79,7 @@ function createClientLogHandler(config) {
|
|
|
79
79
|
let processedError = jsonPayload?.error;
|
|
80
80
|
if (processedError?.stack && !isEmulator) {
|
|
81
81
|
const releaseId = labels?.releaseId ?? 'unknown';
|
|
82
|
-
processedError = await symbolicateError(releaseId, processedError);
|
|
82
|
+
processedError = await symbolicateError(releaseId, processedError, config.bucketName);
|
|
83
83
|
}
|
|
84
84
|
(0, logger_1.writeLog)({
|
|
85
85
|
message,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logHandler.js","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"logHandler.js","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":";;AAoFA,wDAmCC;AASD,0DAOC;AAvID,uDAAsF;AAEtF,iDAA+C;AAC/C,qCAAgD;AAChD,qDAAyE;AACzE,+CAIsB;AAQtB,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,qBAAU,CAAC,CAAA;AAEpD;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAC7B,SAAiB,EACjB,KAA+B,EAC/B,UAAmB;IAEnB,IAAI,CAAC,KAAK,EAAE,KAAK;QAAE,OAAO,KAAK,CAAA;IAE/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,6BAAe,EAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE3C,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;QACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAChD,IAAI,MAAM;oBAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QAED,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAExC,wEAAwE;QACxE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoD,CAAA;QAC9E,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,GAAG,GAAG,MAAM,IAAA,6BAAY,EAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;YAC7D,IAAI,GAAG;gBAAE,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,CAAC,CAAC,CACH,CAAA;QAED,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAEvC,sDAAsD;QACtD,MAAM,YAAY,GAAG,IAAA,mCAAqB,EAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,IAAI,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAClE,OAAO,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC/C,CAAC,CAAC,CAAA;QAEF,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAA,8BAAgB,EAAC,YAAY,CAAC,EAAE,CAAA;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,MAA8B;IACnE,IAAI,MAAM,CAAC,UAAU;QAAE,IAAA,yCAAwB,EAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAElE,OAAO,KAAK,EAAE,OAAoC,EAAiB,EAAE;QACnE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAA;QAE/D,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAU,CAAC,kBAAkB,EAAE,6BAA6B,CAAC,CAAA;QACzE,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,kBAAU,CAAC,kBAAkB,EAAE,qBAAqB,QAAQ,EAAE,CAAC,CAAA;QAC3E,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAA;QAE5D,IAAI,CAAC;YACH,IAAI,cAAc,GAAG,WAAW,EAAE,KAAK,CAAA;YACvC,IAAI,cAAc,EAAE,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,SAAS,CAAA;gBAChD,cAAc,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;YACvF,CAAC;YAED,IAAA,iBAAQ,EAAC;gBACP,OAAO;gBACP,QAAQ;gBACR,MAAM,EAAE,IAAA,oBAAW,EAAC,MAAM,CAAyB;gBACnD,WAAW,EAAE,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE;gBACtD,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW;aACtC,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAA;YACxD,MAAM,IAAI,kBAAU,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,uBAAuB,CACrC,MAA8F;IAE9F,OAAO,IAAA,cAAM,EACX,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,EACrE,sBAAsB,CAAC,MAAM,CAAC,CAC/B,CAAA;AACH,CAAC"}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import type { Bucket } from '@google-cloud/storage';
|
|
1
2
|
import type { EncodedSourceMap } from '@jridgewell/trace-mapping';
|
|
2
3
|
export declare function configureSourceMapBucket(bucketName: string): void;
|
|
3
|
-
/**
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the configured Storage bucket, falling back to the project default.
|
|
6
|
+
*
|
|
7
|
+
* The return type is spelled out rather than inferred: without it the emitted
|
|
8
|
+
* `.d.ts` would need to name `Bucket` from a path inside `node_modules`, which
|
|
9
|
+
* TypeScript 7 rejects as non-portable (TS2883).
|
|
10
|
+
*/
|
|
11
|
+
export declare function getBucket(bucketName?: string | undefined): Bucket;
|
|
5
12
|
/**
|
|
6
13
|
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
7
14
|
*/
|
|
8
|
-
export declare function getSourceMap(releaseId: string, fileName: string): Promise<EncodedSourceMap | null>;
|
|
15
|
+
export declare function getSourceMap(releaseId: string, fileName: string, bucketName?: string): Promise<EncodedSourceMap | null>;
|
|
9
16
|
export declare function clearSourceMapCache(): void;
|
|
10
17
|
//# sourceMappingURL=sourceMapCache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sourceMapCache.d.ts","sourceRoot":"","sources":["../../src/functions/sourceMapCache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"sourceMapCache.d.ts","sourceRoot":"","sources":["../../src/functions/sourceMapCache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAcjE,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,UAAU,qBAAgB,GAAG,MAAM,CAE5D;AA4DD;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIlC;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
|
|
@@ -44,12 +44,22 @@ const storage_1 = require("firebase-admin/storage");
|
|
|
44
44
|
const cache = new Map();
|
|
45
45
|
// Separate cache for the embedded (current release) maps, keyed by bundle filename.
|
|
46
46
|
const embeddedCache = new Map();
|
|
47
|
-
|
|
47
|
+
// Process-wide fallback bucket. Used by writeLog() for attachments, which has
|
|
48
|
+
// no per-handler config to draw on. Source-map lookups do NOT rely on this —
|
|
49
|
+
// they take the bucket explicitly, so two handlers configured with different
|
|
50
|
+
// buckets cannot silently resolve to whichever was constructed last.
|
|
51
|
+
let defaultBucket;
|
|
48
52
|
function configureSourceMapBucket(bucketName) {
|
|
49
|
-
|
|
53
|
+
defaultBucket = bucketName;
|
|
50
54
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the configured Storage bucket, falling back to the project default.
|
|
57
|
+
*
|
|
58
|
+
* The return type is spelled out rather than inferred: without it the emitted
|
|
59
|
+
* `.d.ts` would need to name `Bucket` from a path inside `node_modules`, which
|
|
60
|
+
* TypeScript 7 rejects as non-portable (TS2883).
|
|
61
|
+
*/
|
|
62
|
+
function getBucket(bucketName = defaultBucket) {
|
|
53
63
|
return bucketName ? (0, storage_1.getStorage)().bucket(bucketName) : (0, storage_1.getStorage)().bucket();
|
|
54
64
|
}
|
|
55
65
|
/**
|
|
@@ -80,12 +90,14 @@ function readEmbeddedSourceMap(fileName) {
|
|
|
80
90
|
/**
|
|
81
91
|
* Load source map from Firebase Storage (for older releases).
|
|
82
92
|
*/
|
|
83
|
-
async function loadStorageSourceMap(releaseId, fileName) {
|
|
84
|
-
|
|
93
|
+
async function loadStorageSourceMap(releaseId, fileName, bucketName) {
|
|
94
|
+
// The bucket is part of the key: the same release/file in two buckets is two
|
|
95
|
+
// different maps, and caching them under one key would serve the wrong one.
|
|
96
|
+
const cacheKey = `${bucketName ?? defaultBucket ?? ''}/${releaseId}/${fileName}`;
|
|
85
97
|
if (cache.has(cacheKey))
|
|
86
98
|
return cache.get(cacheKey) ?? null;
|
|
87
99
|
try {
|
|
88
|
-
const file = getBucket().file(`sourcemaps/${releaseId}/${fileName}.map`);
|
|
100
|
+
const file = getBucket(bucketName).file(`sourcemaps/${releaseId}/${fileName}.map`);
|
|
89
101
|
const [exists] = await file.exists();
|
|
90
102
|
if (!exists) {
|
|
91
103
|
cache.set(cacheKey, null);
|
|
@@ -98,18 +110,18 @@ async function loadStorageSourceMap(releaseId, fileName) {
|
|
|
98
110
|
}
|
|
99
111
|
catch (err) {
|
|
100
112
|
console.warn(`[fsl] Failed to load Storage map for ${releaseId}/${fileName}:`, err);
|
|
101
|
-
cache.set(
|
|
113
|
+
cache.set(cacheKey, null);
|
|
102
114
|
return null;
|
|
103
115
|
}
|
|
104
116
|
}
|
|
105
117
|
/**
|
|
106
118
|
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
107
119
|
*/
|
|
108
|
-
async function getSourceMap(releaseId, fileName) {
|
|
120
|
+
async function getSourceMap(releaseId, fileName, bucketName) {
|
|
109
121
|
const embedded = loadEmbeddedSourceMap(fileName);
|
|
110
122
|
if (embedded)
|
|
111
123
|
return embedded;
|
|
112
|
-
return loadStorageSourceMap(releaseId, fileName);
|
|
124
|
+
return loadStorageSourceMap(releaseId, fileName, bucketName);
|
|
113
125
|
}
|
|
114
126
|
function clearSourceMapCache() {
|
|
115
127
|
cache.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sourceMapCache.js","sourceRoot":"","sources":["../../src/functions/sourceMapCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"sourceMapCache.js","sourceRoot":"","sources":["../../src/functions/sourceMapCache.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dasasian/firebase-structured-logger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Structured logging for Firebase apps — client, functions, and tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Dasasian",
|
|
@@ -65,13 +65,13 @@
|
|
|
65
65
|
"build:watch": "tsc --watch",
|
|
66
66
|
"clean": "rm -rf dist",
|
|
67
67
|
"typecheck": "tsc --noEmit",
|
|
68
|
-
"test": "tsx tests/logger.ts && tsx tests/breadcrumbs.ts && tsx tests/rateLimiter.ts && tsx tests/errorHandler.ts && FUNCTIONS_EMULATOR=true tsx tests/errorPayload.ts && FUNCTIONS_EMULATOR=true tsx tests/requestLogger.ts && FUNCTIONS_EMULATOR=true tsx tests/handler.ts && FUNCTIONS_EMULATOR=true tsx tests/symbolication.ts",
|
|
68
|
+
"test": "tsx tests/logger.ts && tsx tests/breadcrumbs.ts && tsx tests/rateLimiter.ts && tsx tests/errorHandler.ts && tsx tests/attachments.ts && FUNCTIONS_EMULATOR=true tsx tests/errorPayload.ts && FUNCTIONS_EMULATOR=true tsx tests/requestLogger.ts && FUNCTIONS_EMULATOR=true tsx tests/handler.ts && FUNCTIONS_EMULATOR=true tsx tests/symbolication.ts && FUNCTIONS_EMULATOR=true tsx tests/publicApi.ts && FUNCTIONS_EMULATOR=true tsx tests/configureTwice.ts && tsx tests/productionOutput.ts && tsx tests/handlerSymbolication.ts",
|
|
69
69
|
"prepublishOnly": "npm run build"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@google-cloud/storage": "^7.0.0",
|
|
73
73
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
74
|
-
"ulid": "^
|
|
74
|
+
"ulid": "^3.0.2"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"firebase": ">=10.0.0",
|
|
@@ -90,14 +90,16 @@
|
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@types/
|
|
93
|
+
"@types/jsdom": "^30.0.0",
|
|
94
|
+
"@types/node": "^26.2.0",
|
|
94
95
|
"firebase": "^12.0.0",
|
|
95
|
-
"firebase-admin": "^
|
|
96
|
+
"firebase-admin": "^14.2.0",
|
|
96
97
|
"firebase-functions": "^7.0.0",
|
|
98
|
+
"jsdom": "^27.0.1",
|
|
97
99
|
"tsx": "^4.19.0",
|
|
98
100
|
"typescript": "~5.9.3"
|
|
99
101
|
},
|
|
100
102
|
"engines": {
|
|
101
|
-
"node": ">=
|
|
103
|
+
"node": ">=22"
|
|
102
104
|
}
|
|
103
105
|
}
|