@dasasian/firebase-structured-logger 0.4.0 → 0.5.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 +23 -5
- package/dist/client/logger.d.ts.map +1 -1
- package/dist/client/logger.js +22 -2
- package/dist/client/logger.js.map +1 -1
- package/dist/functions/index.d.ts +1 -1
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +2 -1
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/requestLogger.d.ts +46 -18
- package/dist/functions/requestLogger.d.ts.map +1 -1
- package/dist/functions/requestLogger.js +69 -19
- package/dist/functions/requestLogger.js.map +1 -1
- package/dist/functions/sourceMapCache.d.ts +38 -0
- package/dist/functions/sourceMapCache.d.ts.map +1 -1
- package/dist/functions/sourceMapCache.js +136 -9
- package/dist/functions/sourceMapCache.js.map +1 -1
- package/dist/tools/index.js +5 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/uploadSourceMaps.d.ts +21 -1
- package/dist/tools/uploadSourceMaps.d.ts.map +1 -1
- package/dist/tools/uploadSourceMaps.js +40 -13
- package/dist/tools/uploadSourceMaps.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -163,16 +163,34 @@ logger.addBreadcrumb(type, name, data?)
|
|
|
163
163
|
## Functions API
|
|
164
164
|
|
|
165
165
|
```ts
|
|
166
|
-
import { initLogger,
|
|
166
|
+
import { initLogger, withLogging, logError, logInfo } from '@dasasian/firebase-structured-logger/functions'
|
|
167
167
|
|
|
168
168
|
initLogger({ appId: 'my-app' }) // at module load
|
|
169
169
|
|
|
170
|
-
export const myFunction = onCall(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
})
|
|
170
|
+
export const myFunction = onCall(
|
|
171
|
+
withLogging({ functionName: 'myFunction' }, async (request) => {
|
|
172
|
+
logInfo('started') // carries userId + functionName automatically
|
|
173
|
+
}),
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`withLogging` binds the request's labels for the duration of the handler and unwinds
|
|
178
|
+
afterwards, so one request's `userId` can never appear on another's logs. Labels that
|
|
179
|
+
depend on the request are computed per call:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
withLogging(
|
|
183
|
+
(request) => ({ functionName: 'myFunction', labels: { orgId: request.data.orgId } }),
|
|
184
|
+
async (request) => { /* … */ },
|
|
185
|
+
)
|
|
174
186
|
```
|
|
175
187
|
|
|
188
|
+
> **`initRequestLogger` is deprecated and removed in 0.6.0.** It binds the scope with
|
|
189
|
+
> `enterWith()`, which is never unwound — the labels outlive the request, so a later
|
|
190
|
+
> handler that does *not* call it (a scheduled function, a Firestore trigger, or anything
|
|
191
|
+
> relying on `getLogger()`'s anonymous fallback) inherits whichever user last touched the
|
|
192
|
+
> warm instance. Handlers that all call it are unaffected; the hazard is the ones that don't.
|
|
193
|
+
|
|
176
194
|
Backend log methods also accept an optional `attachments` (`Record<string, string | Buffer>`).
|
|
177
195
|
|
|
178
196
|
## CLI (`fsl`)
|
|
@@ -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,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAWxF,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,eAAe,CAAA;AAEtB,YAAY,EAAE,eAAe,EAAE,CAAA;AAE/B,KAAK,WAAW,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAEzD,MAAM,WAAW,gBAAgB,CAC/B,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzF,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,gBAAgB,CAAC,EAAE,eAAe,CAAA;CACnC;AAmDD,qBAAa,MAAM,CACjB,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAyB;gBAE/B,MAAM,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAQ/C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAK5D,SAAS,IAAI,IAAI;IAMjB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,aAAa,CACX,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,EAC1C,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI;IAIP,KAAK,CACH,GAAG,EAAE,OAAO,EACZ,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,EACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,GACjD,IAAI;IAmBP,IAAI,CACF,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,EACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,GACjD,IAAI;IAIP,OAAO,CACL,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,EACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,GACjD,IAAI;IAIP,KAAK,CACH,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,EACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,GACjD,IAAI;YAIO,IAAI;
|
|
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
|
@@ -124,12 +124,32 @@ class Logger {
|
|
|
124
124
|
...this.userLabels,
|
|
125
125
|
...labels,
|
|
126
126
|
};
|
|
127
|
+
// Each attachment is converted in its own try. A Blob or File can fail to
|
|
128
|
+
// read — a user picks a file from <input type="file">, moves or deletes it,
|
|
129
|
+
// then submits, and the browser raises NotReadableError. Previously one
|
|
130
|
+
// such failure escaped to the outer catch and the ENTIRE entry was lost:
|
|
131
|
+
// message, labels, breadcrumbs and all. The message and breadcrumbs are
|
|
132
|
+
// the valuable part; an attachment is a bonus.
|
|
127
133
|
let base64Attachments;
|
|
134
|
+
const failedAttachments = [];
|
|
128
135
|
if (attachments && Object.keys(attachments).length > 0) {
|
|
129
|
-
|
|
136
|
+
const converted = {};
|
|
130
137
|
for (const [name, attachment] of Object.entries(attachments)) {
|
|
131
|
-
|
|
138
|
+
try {
|
|
139
|
+
converted[name] = await assetToBase64(attachment);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
failedAttachments.push(name);
|
|
143
|
+
console.warn(`[fsl] Could not read attachment "${name}" — sending the log without it:`, err instanceof Error ? err.message : err);
|
|
144
|
+
}
|
|
132
145
|
}
|
|
146
|
+
if (Object.keys(converted).length > 0)
|
|
147
|
+
base64Attachments = converted;
|
|
148
|
+
}
|
|
149
|
+
// Without this the absence of hasAttachments is a mystery. Labels are
|
|
150
|
+
// promoted to Cloud Logging entry labels, so this is filterable.
|
|
151
|
+
if (failedAttachments.length > 0) {
|
|
152
|
+
allLabels.attachmentsFailed = failedAttachments.join(',');
|
|
133
153
|
}
|
|
134
154
|
const payload = {
|
|
135
155
|
message,
|
|
@@ -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":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LogWriter } from './logger';
|
|
2
2
|
export { initLogger } from './logger';
|
|
3
3
|
export type { LogWriter } from './logger';
|
|
4
|
-
export { initRequestLogger, getLogger } from './requestLogger';
|
|
4
|
+
export { withLogging, initRequestLogger, getLogger } from './requestLogger';
|
|
5
5
|
export { createClientLogHandler, createClientLogFunction } from './logHandler';
|
|
6
6
|
export type { ClientLogHandlerConfig } from './logHandler';
|
|
7
7
|
export type { LogSeverity, LogPayload, BaseLabels } from '../shared/types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3E,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAC9E,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC1D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE1E,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA;AACrG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAG,IAAoC,CAAA;AACxG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAG,IAAiC,CAAA;AAClG,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA"}
|
package/dist/functions/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logDebug = exports.logInfo = exports.logWarn = exports.logError = exports.createClientLogFunction = exports.createClientLogHandler = exports.getLogger = exports.initRequestLogger = exports.initLogger = void 0;
|
|
3
|
+
exports.logDebug = exports.logInfo = exports.logWarn = exports.logError = exports.createClientLogFunction = exports.createClientLogHandler = exports.getLogger = exports.initRequestLogger = exports.withLogging = exports.initLogger = void 0;
|
|
4
4
|
const requestLogger_1 = require("./requestLogger");
|
|
5
5
|
var logger_1 = require("./logger");
|
|
6
6
|
Object.defineProperty(exports, "initLogger", { enumerable: true, get: function () { return logger_1.initLogger; } });
|
|
7
7
|
var requestLogger_2 = require("./requestLogger");
|
|
8
|
+
Object.defineProperty(exports, "withLogging", { enumerable: true, get: function () { return requestLogger_2.withLogging; } });
|
|
8
9
|
Object.defineProperty(exports, "initRequestLogger", { enumerable: true, get: function () { return requestLogger_2.initRequestLogger; } });
|
|
9
10
|
Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return requestLogger_2.getLogger; } });
|
|
10
11
|
var logHandler_1 = require("./logHandler");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":";;;AAAA,mDAA2C;AAG3C,mCAAqC;AAA5B,oGAAA,UAAU,OAAA;AAEnB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":";;;AAAA,mDAA2C;AAG3C,mCAAqC;AAA5B,oGAAA,UAAU,OAAA;AAEnB,iDAA2E;AAAlE,4GAAA,WAAW,OAAA;AAAE,kHAAA,iBAAiB,OAAA;AAAE,0GAAA,SAAS,OAAA;AAClD,2CAA8E;AAArE,oHAAA,sBAAsB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAIjD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAoC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AAAxF,QAAA,QAAQ,YAAgF;AAC9F,MAAM,OAAO,GAAG,CAAC,GAAG,IAAsC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;AAA3F,QAAA,OAAO,WAAoF;AACjG,MAAM,OAAO,GAAG,CAAC,GAAG,IAAmC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;AAArF,QAAA,OAAO,WAA8E;AAC3F,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAoC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AAAxF,QAAA,QAAQ,YAAgF"}
|
|
@@ -1,30 +1,58 @@
|
|
|
1
1
|
import type { CallableRequest } from 'firebase-functions/v2/https';
|
|
2
2
|
import { type LogWriter } from './logger';
|
|
3
|
+
interface RequestLoggerOptions<AppLabels extends Record<string, string | undefined>> {
|
|
4
|
+
functionName?: string;
|
|
5
|
+
appId?: string;
|
|
6
|
+
labels?: Partial<AppLabels>;
|
|
7
|
+
}
|
|
3
8
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Call at the start of every onCall handler.
|
|
9
|
+
* Wrap an onCall handler so every log inside it carries the request's labels.
|
|
6
10
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
11
|
+
* This is the correct way to scope a request logger. The store is bound with
|
|
12
|
+
* `AsyncLocalStorage.run()`, which restores the previous context when the
|
|
13
|
+
* handler settles — so a request's labels cannot outlive the request.
|
|
9
14
|
*
|
|
10
15
|
* @example
|
|
11
|
-
* export const myFunc = onCall(
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* export const myFunc = onCall(
|
|
17
|
+
* withLogging<AppLabels>({ functionName: 'myFunc' }, async (request) => {
|
|
18
|
+
* logInfo('started')
|
|
19
|
+
* }),
|
|
20
|
+
* )
|
|
21
|
+
*
|
|
22
|
+
* Labels that depend on the request are computed per call:
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* withLogging<AppLabels>(
|
|
26
|
+
* (request) => ({ functionName: 'myFunc', labels: { orgId: request.data.orgId } }),
|
|
27
|
+
* async (request) => { ... },
|
|
28
|
+
* )
|
|
18
29
|
*/
|
|
19
|
-
export declare function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
30
|
+
export declare function withLogging<AppLabels extends Record<string, string | undefined> = Record<string, string | undefined>, Req extends CallableRequest = CallableRequest, Res = unknown>(options: RequestLoggerOptions<AppLabels> | ((request: Req) => RequestLoggerOptions<AppLabels>), handler: (request: Req) => Res | Promise<Res>): (request: Req) => Promise<Res>;
|
|
31
|
+
/**
|
|
32
|
+
* Initialize a request-scoped logger and store it in AsyncLocalStorage.
|
|
33
|
+
*
|
|
34
|
+
* @deprecated Use {@link withLogging}. This leaks the request scope: it binds
|
|
35
|
+
* with `AsyncLocalStorage.enterWith()`, which persists for the remainder of the
|
|
36
|
+
* execution context and is never unwound. The labels therefore outlive the
|
|
37
|
+
* request, and any later handler that does NOT call this — a scheduled
|
|
38
|
+
* function, a Firestore or Storage trigger, or anything relying on
|
|
39
|
+
* `getLogger()`'s anonymous fallback — inherits whichever user last touched the
|
|
40
|
+
* warm instance.
|
|
41
|
+
*
|
|
42
|
+
* Handlers that all call this are unaffected: each overwrites the store with
|
|
43
|
+
* its own labels. The hazard is the handlers that do not.
|
|
44
|
+
*
|
|
45
|
+
* Removed in 0.6.0.
|
|
46
|
+
*/
|
|
47
|
+
export declare function initRequestLogger<AppLabels extends Record<string, string | undefined> = Record<string, string | undefined>>(request: CallableRequest, extra?: RequestLoggerOptions<AppLabels>): LogWriter;
|
|
24
48
|
/**
|
|
25
49
|
* Retrieve the request-scoped logger.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
50
|
+
*
|
|
51
|
+
* Returns an anonymous writer (no request labels) when called outside a
|
|
52
|
+
* request. That is only reliable when requests are scoped with
|
|
53
|
+
* {@link withLogging} — under the deprecated `initRequestLogger`, a previous
|
|
54
|
+
* request's writer can still be in scope here.
|
|
28
55
|
*/
|
|
29
56
|
export declare function getLogger(): LogWriter;
|
|
57
|
+
export {};
|
|
30
58
|
//# sourceMappingURL=requestLogger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestLogger.d.ts","sourceRoot":"","sources":["../../src/functions/requestLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AAIvE
|
|
1
|
+
{"version":3,"file":"requestLogger.d.ts","sourceRoot":"","sources":["../../src/functions/requestLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AAIvE,UAAU,oBAAoB,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACjF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;CAC5B;AAgBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CACzB,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACzF,GAAG,SAAS,eAAe,GAAG,eAAe,EAC7C,GAAG,GAAG,OAAO,EAEb,OAAO,EACH,oBAAoB,CAAC,SAAS,CAAC,GAC/B,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,oBAAoB,CAAC,SAAS,CAAC,CAAC,EACvD,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAC5C,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAMhC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAEzF,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,GACtC,SAAS,CAKX;AAiBD;;;;;;;GAOG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
|
|
@@ -1,40 +1,90 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withLogging = withLogging;
|
|
3
4
|
exports.initRequestLogger = initRequestLogger;
|
|
4
5
|
exports.getLogger = getLogger;
|
|
5
6
|
const async_hooks_1 = require("async_hooks");
|
|
6
7
|
const logger_1 = require("./logger");
|
|
7
8
|
const storage = new async_hooks_1.AsyncLocalStorage();
|
|
9
|
+
function writerFor(request, extra) {
|
|
10
|
+
return (0, logger_1.createLogWriter)((0, logger_1.cleanLabels)({
|
|
11
|
+
functionName: extra?.functionName,
|
|
12
|
+
userId: request.auth?.uid,
|
|
13
|
+
appId: extra?.appId,
|
|
14
|
+
...extra?.labels,
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
8
17
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
18
|
+
* Wrap an onCall handler so every log inside it carries the request's labels.
|
|
19
|
+
*
|
|
20
|
+
* This is the correct way to scope a request logger. The store is bound with
|
|
21
|
+
* `AsyncLocalStorage.run()`, which restores the previous context when the
|
|
22
|
+
* handler settles — so a request's labels cannot outlive the request.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* export const myFunc = onCall(
|
|
26
|
+
* withLogging<AppLabels>({ functionName: 'myFunc' }, async (request) => {
|
|
27
|
+
* logInfo('started')
|
|
28
|
+
* }),
|
|
29
|
+
* )
|
|
11
30
|
*
|
|
12
|
-
*
|
|
13
|
-
* Any labels passed here are seeded on every log call in the request.
|
|
31
|
+
* Labels that depend on the request are computed per call:
|
|
14
32
|
*
|
|
15
33
|
* @example
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
* withLogging<AppLabels>(
|
|
35
|
+
* (request) => ({ functionName: 'myFunc', labels: { orgId: request.data.orgId } }),
|
|
36
|
+
* async (request) => { ... },
|
|
37
|
+
* )
|
|
38
|
+
*/
|
|
39
|
+
function withLogging(options, handler) {
|
|
40
|
+
return (request) => {
|
|
41
|
+
const resolved = typeof options === 'function' ? options(request) : options;
|
|
42
|
+
const writer = writerFor(request, resolved);
|
|
43
|
+
return storage.run(writer, async () => handler(request));
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Initialize a request-scoped logger and store it in AsyncLocalStorage.
|
|
48
|
+
*
|
|
49
|
+
* @deprecated Use {@link withLogging}. This leaks the request scope: it binds
|
|
50
|
+
* with `AsyncLocalStorage.enterWith()`, which persists for the remainder of the
|
|
51
|
+
* execution context and is never unwound. The labels therefore outlive the
|
|
52
|
+
* request, and any later handler that does NOT call this — a scheduled
|
|
53
|
+
* function, a Firestore or Storage trigger, or anything relying on
|
|
54
|
+
* `getLogger()`'s anonymous fallback — inherits whichever user last touched the
|
|
55
|
+
* warm instance.
|
|
56
|
+
*
|
|
57
|
+
* Handlers that all call this are unaffected: each overwrites the store with
|
|
58
|
+
* its own labels. The hazard is the handlers that do not.
|
|
59
|
+
*
|
|
60
|
+
* Removed in 0.6.0.
|
|
23
61
|
*/
|
|
24
62
|
function initRequestLogger(request, extra) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
userId: request.auth?.uid,
|
|
28
|
-
appId: extra?.appId,
|
|
29
|
-
...extra?.labels,
|
|
30
|
-
}));
|
|
63
|
+
warnDeprecated(extra?.functionName);
|
|
64
|
+
const writer = writerFor(request, extra);
|
|
31
65
|
storage.enterWith(writer);
|
|
32
66
|
return writer;
|
|
33
67
|
}
|
|
68
|
+
// Warn once per function name rather than per invocation — a per-request warning
|
|
69
|
+
// on a hot path is noise that gets filtered out and then ignored.
|
|
70
|
+
const warned = new Set();
|
|
71
|
+
function warnDeprecated(functionName) {
|
|
72
|
+
const key = functionName ?? '(unnamed)';
|
|
73
|
+
if (warned.has(key))
|
|
74
|
+
return;
|
|
75
|
+
warned.add(key);
|
|
76
|
+
console.warn(`[fsl] initRequestLogger() is deprecated (${key}). It binds the request scope with ` +
|
|
77
|
+
'enterWith(), which is never unwound — the labels outlive the request, so a later ' +
|
|
78
|
+
'handler that does not call it inherits this request\'s userId. Wrap the handler ' +
|
|
79
|
+
'with withLogging() instead. Removed in 0.6.0.');
|
|
80
|
+
}
|
|
34
81
|
/**
|
|
35
82
|
* Retrieve the request-scoped logger.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
83
|
+
*
|
|
84
|
+
* Returns an anonymous writer (no request labels) when called outside a
|
|
85
|
+
* request. That is only reliable when requests are scoped with
|
|
86
|
+
* {@link withLogging} — under the deprecated `initRequestLogger`, a previous
|
|
87
|
+
* request's writer can still be in scope here.
|
|
38
88
|
*/
|
|
39
89
|
function getLogger() {
|
|
40
90
|
return storage.getStore() ?? (0, logger_1.createLogWriter)({});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestLogger.js","sourceRoot":"","sources":["../../src/functions/requestLogger.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"requestLogger.js","sourceRoot":"","sources":["../../src/functions/requestLogger.ts"],"names":[],"mappings":";;AAgDA,kCAeC;AAkBD,8CAUC;AAyBD,8BAEC;AAtHD,6CAA+C;AAE/C,qCAAuE;AAEvE,MAAM,OAAO,GAAG,IAAI,+BAAiB,EAAa,CAAA;AAQlD,SAAS,SAAS,CAChB,OAAwB,EACxB,KAAuC;IAEvC,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC;QACV,YAAY,EAAE,KAAK,EAAE,YAAY;QACjC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG;QACzB,KAAK,EAAE,KAAK,EAAE,KAAK;QACnB,GAAG,KAAK,EAAE,MAAM;KACjB,CAAC,CACH,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,WAAW,CAKzB,OAEuD,EACvD,OAA6C;IAE7C,OAAO,CAAC,OAAY,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QAC3E,MAAM,MAAM,GAAG,SAAS,CAAY,OAAO,EAAE,QAAQ,CAAC,CAAA;QACtD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1D,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,iBAAiB,CAG/B,OAAwB,EACxB,KAAuC;IAEvC,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,SAAS,CAAY,OAAO,EAAE,KAAK,CAAC,CAAA;IACnD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACzB,OAAO,MAAM,CAAA;AACf,CAAC;AAED,iFAAiF;AACjF,kEAAkE;AAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;AAChC,SAAS,cAAc,CAAC,YAAgC;IACtD,MAAM,GAAG,GAAG,YAAY,IAAI,WAAW,CAAA;IACvC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAM;IAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACf,OAAO,CAAC,IAAI,CACV,4CAA4C,GAAG,qCAAqC;QAClF,mFAAmF;QACnF,kFAAkF;QAClF,+CAA+C,CAClD,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAA,wBAAe,EAAC,EAAE,CAAC,CAAA;AAClD,CAAC"}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { Bucket } from '@google-cloud/storage';
|
|
2
2
|
import type { EncodedSourceMap } from '@jridgewell/trace-mapping';
|
|
3
|
+
interface CacheEntry {
|
|
4
|
+
map: EncodedSourceMap | null;
|
|
5
|
+
bytes: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Test-only handle on the cache internals. Not exported from the package entry
|
|
9
|
+
* point, so it is not public API — the eviction policy is worth asserting
|
|
10
|
+
* directly rather than inferring from behaviour through a live bucket.
|
|
11
|
+
*/
|
|
12
|
+
export declare const __cacheForTests: {
|
|
13
|
+
get: (key: string) => CacheEntry | undefined;
|
|
14
|
+
set: (key: string, map: EncodedSourceMap | null, bytes: number) => void;
|
|
15
|
+
clear: () => void;
|
|
16
|
+
stats: () => {
|
|
17
|
+
entries: number;
|
|
18
|
+
bytes: number;
|
|
19
|
+
limit: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
3
22
|
export declare function configureSourceMapBucket(bucketName: string): void;
|
|
4
23
|
/**
|
|
5
24
|
* Resolve the configured Storage bucket, falling back to the project default.
|
|
@@ -12,6 +31,25 @@ export declare function getBucket(bucketName?: string | undefined): Bucket;
|
|
|
12
31
|
/**
|
|
13
32
|
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
14
33
|
*/
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the source map for a bundle in a given release.
|
|
36
|
+
*
|
|
37
|
+
* The embedded directory is keyed by filename alone and holds exactly one
|
|
38
|
+
* release's maps, so preferring it unconditionally meant an old stack could be
|
|
39
|
+
* resolved with the CURRENT release's map — plausible-looking wrong line
|
|
40
|
+
* numbers, which is worse than none. But requiring an exact match would break
|
|
41
|
+
* apps that simply deploy and never version anything: they have one release's
|
|
42
|
+
* maps, never need Storage, and their releaseId will not match a marker.
|
|
43
|
+
*
|
|
44
|
+
* So Storage is preferred only when it actually has something better:
|
|
45
|
+
*
|
|
46
|
+
* matches the embedded release -> embedded, no network
|
|
47
|
+
* differs -> Storage, falling back to embedded on a miss
|
|
48
|
+
*
|
|
49
|
+
* That is strictly better than preferring embedded in every case, and it leaves
|
|
50
|
+
* the unversioned setup working exactly as before.
|
|
51
|
+
*/
|
|
15
52
|
export declare function getSourceMap(releaseId: string, fileName: string, bucketName?: string): Promise<EncodedSourceMap | null>;
|
|
16
53
|
export declare function clearSourceMapCache(): void;
|
|
54
|
+
export {};
|
|
17
55
|
//# 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,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,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;AAkBjE,UAAU,UAAU;IAClB,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;CACd;AAgCD;;;;GAIG;AACH,eAAO,MAAM,eAAe;eACf,MAAM;eACN,MAAM,OAAO,gBAAgB,GAAG,IAAI,SAAS,MAAM;;;;;;;CAG/D,CAAA;AAuBD,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,UAAU,qBAAgB,GAAG,MAAM,CAE5D;AA6ED;;GAEG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgBlC;AAiBD,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C"}
|
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.__cacheForTests = void 0;
|
|
36
37
|
exports.configureSourceMapBucket = configureSourceMapBucket;
|
|
37
38
|
exports.getBucket = getBucket;
|
|
38
39
|
exports.getSourceMap = getSourceMap;
|
|
@@ -40,10 +41,74 @@ exports.clearSourceMapCache = clearSourceMapCache;
|
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
41
42
|
const path = __importStar(require("path"));
|
|
42
43
|
const storage_1 = require("firebase-admin/storage");
|
|
43
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Storage-map cache, bounded by approximate bytes with LRU eviction.
|
|
46
|
+
*
|
|
47
|
+
* This grows with releases x bundles and lives for the instance's lifetime, so
|
|
48
|
+
* unbounded it is a plausible out-of-memory on a 256MB Cloud Function —
|
|
49
|
+
* presenting as random instance crashes rather than a logging fault, which is
|
|
50
|
+
* miserable to attribute. A real Vite map is ~580KB after `sourcesContent` is
|
|
51
|
+
* stripped, and maps uploaded before 0.4.0 still carry theirs at ~2.2MB.
|
|
52
|
+
*
|
|
53
|
+
* Negative entries (null = confirmed not found) are exempt from the budget.
|
|
54
|
+
* They cost nothing and each one prevents a repeated Storage round-trip on the
|
|
55
|
+
* per-error path — more valuable since a release mismatch now consults Storage
|
|
56
|
+
* first and usually misses.
|
|
57
|
+
*/
|
|
58
|
+
const MAX_CACHE_BYTES = 64 * 1024 * 1024;
|
|
44
59
|
const cache = new Map();
|
|
45
|
-
|
|
60
|
+
let cacheBytes = 0;
|
|
61
|
+
/** Read, moving the entry to the most-recent position. */
|
|
62
|
+
function cacheGet(key) {
|
|
63
|
+
const entry = cache.get(key);
|
|
64
|
+
if (!entry)
|
|
65
|
+
return undefined;
|
|
66
|
+
// Map iterates in insertion order, so delete + re-insert makes it LRU.
|
|
67
|
+
cache.delete(key);
|
|
68
|
+
cache.set(key, entry);
|
|
69
|
+
return entry;
|
|
70
|
+
}
|
|
71
|
+
function cacheSet(key, map, bytes) {
|
|
72
|
+
const existing = cache.get(key);
|
|
73
|
+
if (existing)
|
|
74
|
+
cacheBytes -= existing.bytes;
|
|
75
|
+
const size = map === null ? 0 : bytes;
|
|
76
|
+
cache.set(key, { map, bytes: size });
|
|
77
|
+
cacheBytes += size;
|
|
78
|
+
// Evict oldest first, skipping negative entries — they are free and useful.
|
|
79
|
+
for (const [k, entry] of cache) {
|
|
80
|
+
if (cacheBytes <= MAX_CACHE_BYTES)
|
|
81
|
+
break;
|
|
82
|
+
if (k === key || entry.map === null)
|
|
83
|
+
continue;
|
|
84
|
+
cache.delete(k);
|
|
85
|
+
cacheBytes -= entry.bytes;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Test-only handle on the cache internals. Not exported from the package entry
|
|
90
|
+
* point, so it is not public API — the eviction policy is worth asserting
|
|
91
|
+
* directly rather than inferring from behaviour through a live bucket.
|
|
92
|
+
*/
|
|
93
|
+
exports.__cacheForTests = {
|
|
94
|
+
get: (key) => cacheGet(key),
|
|
95
|
+
set: (key, map, bytes) => cacheSet(key, map, bytes),
|
|
96
|
+
clear: () => clearSourceMapCache(),
|
|
97
|
+
stats: () => ({ entries: cache.size, bytes: cacheBytes, limit: MAX_CACHE_BYTES }),
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Embedded (deployed release) maps, keyed by bundle filename.
|
|
101
|
+
*
|
|
102
|
+
* Deliberately unbounded: this only ever holds the maps for the one release the
|
|
103
|
+
* function was deployed with, so it is bounded by that build's chunk count and
|
|
104
|
+
* every entry is hot. The Storage cache is the one that grows without limit —
|
|
105
|
+
* it accumulates across releases.
|
|
106
|
+
*/
|
|
46
107
|
const embeddedCache = new Map();
|
|
108
|
+
// Which release the embedded maps belong to, written by
|
|
109
|
+
// `fsl upload-sourcemaps --embed-sourcemaps`. undefined = not yet read,
|
|
110
|
+
// null = no marker (older deploys, or embedding was never used).
|
|
111
|
+
let embeddedRelease;
|
|
47
112
|
// Process-wide fallback bucket. Used by writeLog() for attachments, which has
|
|
48
113
|
// no per-handler config to draw on. Source-map lookups do NOT rely on this —
|
|
49
114
|
// they take the bucket explicitly, so two handlers configured with different
|
|
@@ -75,6 +140,21 @@ function loadEmbeddedSourceMap(fileName) {
|
|
|
75
140
|
embeddedCache.set(fileName, sourceMap);
|
|
76
141
|
return sourceMap;
|
|
77
142
|
}
|
|
143
|
+
/** The release the embedded maps were built from, or null if unmarked. */
|
|
144
|
+
function readEmbeddedRelease() {
|
|
145
|
+
if (embeddedRelease !== undefined)
|
|
146
|
+
return embeddedRelease;
|
|
147
|
+
try {
|
|
148
|
+
const markerPath = path.join(process.cwd(), 'sourcemaps', 'current', '.release');
|
|
149
|
+
embeddedRelease = fs.existsSync(markerPath)
|
|
150
|
+
? fs.readFileSync(markerPath, 'utf-8').trim() || null
|
|
151
|
+
: null;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
embeddedRelease = null;
|
|
155
|
+
}
|
|
156
|
+
return embeddedRelease;
|
|
157
|
+
}
|
|
78
158
|
function readEmbeddedSourceMap(fileName) {
|
|
79
159
|
try {
|
|
80
160
|
// Looks for sourcemaps/current/{fileName}.map relative to the Cloud Function working directory
|
|
@@ -94,37 +174,84 @@ async function loadStorageSourceMap(releaseId, fileName, bucketName) {
|
|
|
94
174
|
// The bucket is part of the key: the same release/file in two buckets is two
|
|
95
175
|
// different maps, and caching them under one key would serve the wrong one.
|
|
96
176
|
const cacheKey = `${bucketName ?? defaultBucket ?? ''}/${releaseId}/${fileName}`;
|
|
97
|
-
|
|
98
|
-
|
|
177
|
+
const hit = cacheGet(cacheKey);
|
|
178
|
+
if (hit)
|
|
179
|
+
return hit.map;
|
|
99
180
|
try {
|
|
100
181
|
const file = getBucket(bucketName).file(`sourcemaps/${releaseId}/${fileName}.map`);
|
|
101
182
|
const [exists] = await file.exists();
|
|
102
183
|
if (!exists) {
|
|
103
|
-
|
|
184
|
+
cacheSet(cacheKey, null, 0);
|
|
104
185
|
return null;
|
|
105
186
|
}
|
|
106
187
|
const [content] = await file.download();
|
|
107
188
|
const sourceMap = JSON.parse(content.toString());
|
|
108
|
-
|
|
189
|
+
// content.length is the byte size we already hold — no re-serialising a
|
|
190
|
+
// half-megabyte object just to measure it.
|
|
191
|
+
cacheSet(cacheKey, sourceMap, content.length);
|
|
109
192
|
return sourceMap;
|
|
110
193
|
}
|
|
111
194
|
catch (err) {
|
|
112
195
|
console.warn(`[fsl] Failed to load Storage map for ${releaseId}/${fileName}:`, err);
|
|
113
|
-
|
|
196
|
+
cacheSet(cacheKey, null, 0);
|
|
114
197
|
return null;
|
|
115
198
|
}
|
|
116
199
|
}
|
|
117
200
|
/**
|
|
118
201
|
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
119
202
|
*/
|
|
203
|
+
/**
|
|
204
|
+
* Resolve the source map for a bundle in a given release.
|
|
205
|
+
*
|
|
206
|
+
* The embedded directory is keyed by filename alone and holds exactly one
|
|
207
|
+
* release's maps, so preferring it unconditionally meant an old stack could be
|
|
208
|
+
* resolved with the CURRENT release's map — plausible-looking wrong line
|
|
209
|
+
* numbers, which is worse than none. But requiring an exact match would break
|
|
210
|
+
* apps that simply deploy and never version anything: they have one release's
|
|
211
|
+
* maps, never need Storage, and their releaseId will not match a marker.
|
|
212
|
+
*
|
|
213
|
+
* So Storage is preferred only when it actually has something better:
|
|
214
|
+
*
|
|
215
|
+
* matches the embedded release -> embedded, no network
|
|
216
|
+
* differs -> Storage, falling back to embedded on a miss
|
|
217
|
+
*
|
|
218
|
+
* That is strictly better than preferring embedded in every case, and it leaves
|
|
219
|
+
* the unversioned setup working exactly as before.
|
|
220
|
+
*/
|
|
120
221
|
async function getSourceMap(releaseId, fileName, bucketName) {
|
|
121
222
|
const embedded = loadEmbeddedSourceMap(fileName);
|
|
122
|
-
|
|
223
|
+
const marker = readEmbeddedRelease();
|
|
224
|
+
// No marker means we cannot tell whether this stack belongs to the embedded
|
|
225
|
+
// release. Older deploys have none, so keep the previous behaviour.
|
|
226
|
+
if (embedded && (marker === null || marker === releaseId))
|
|
123
227
|
return embedded;
|
|
124
|
-
|
|
228
|
+
const stored = await loadStorageSourceMap(releaseId, fileName, bucketName);
|
|
229
|
+
if (stored)
|
|
230
|
+
return stored;
|
|
231
|
+
if (embedded) {
|
|
232
|
+
warnReleaseFallback(releaseId, marker);
|
|
233
|
+
return embedded;
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
// Warn once per (release, marker) pair — this sits on the per-error path.
|
|
238
|
+
const warnedFallbacks = new Set();
|
|
239
|
+
function warnReleaseFallback(releaseId, marker) {
|
|
240
|
+
const key = `${releaseId}|${marker}`;
|
|
241
|
+
if (warnedFallbacks.has(key))
|
|
242
|
+
return;
|
|
243
|
+
warnedFallbacks.add(key);
|
|
244
|
+
console.warn(`[fsl] Stack is from release '${releaseId}' but the deployed maps are for ` +
|
|
245
|
+
`'${marker}', and Storage has no map for '${releaseId}'. Symbolicating with ` +
|
|
246
|
+
'the deployed maps — line numbers may be wrong if the bundle changed between ' +
|
|
247
|
+
'releases. If you did not mean to version releases, ignore this; if you did, ' +
|
|
248
|
+
'check that the client\'s releaseId matches the one used at upload time.');
|
|
125
249
|
}
|
|
126
250
|
function clearSourceMapCache() {
|
|
127
251
|
cache.clear();
|
|
252
|
+
cacheBytes = 0;
|
|
128
253
|
embeddedCache.clear();
|
|
254
|
+
embeddedRelease = undefined;
|
|
255
|
+
warnedFallbacks.clear();
|
|
129
256
|
}
|
|
130
257
|
//# sourceMappingURL=sourceMapCache.js.map
|
|
@@ -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/dist/tools/index.js
CHANGED
|
@@ -84,13 +84,17 @@ async function main() {
|
|
|
84
84
|
console.error('Bucket can also be set via VITE_FIREBASE_STORAGE_BUCKET or FIREBASE_STORAGE_BUCKET env var (loaded from .env.local automatically).');
|
|
85
85
|
process.exit(1);
|
|
86
86
|
}
|
|
87
|
-
await (0, uploadSourceMaps_1.uploadSourceMaps)({
|
|
87
|
+
const result = await (0, uploadSourceMaps_1.uploadSourceMaps)({
|
|
88
88
|
bucket,
|
|
89
89
|
release: args.release,
|
|
90
90
|
distDir: args.dist,
|
|
91
91
|
functionsDir: args.functions,
|
|
92
92
|
embedSourcemaps: args['embed-sourcemaps'] === 'true',
|
|
93
93
|
});
|
|
94
|
+
// Distinct code so a deploy chain can choose to continue:
|
|
95
|
+
// npx fsl upload-sourcemaps … || [ $? -eq 3 ]
|
|
96
|
+
if (!result.uploaded)
|
|
97
|
+
process.exit(uploadSourceMaps_1.EXIT_UPLOAD_FAILED_BUT_EMBEDDED);
|
|
94
98
|
break;
|
|
95
99
|
}
|
|
96
100
|
case 'install-skills': {
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uCAAwB;AACxB,2CAA4B;AAC5B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit code used when maps were embedded but the Storage upload failed.
|
|
3
|
+
*
|
|
4
|
+
* Distinct from 1 so a deploy script can decide: `|| [ $? -eq 3 ]` to continue
|
|
5
|
+
* anyway, or let it stop the chain. Exiting 0 was too quiet — the deploy script
|
|
6
|
+
* is a `&&` chain, so the deploy proceeded and the only signal was a warning
|
|
7
|
+
* scrolling past in CI output.
|
|
8
|
+
*/
|
|
9
|
+
export declare const EXIT_UPLOAD_FAILED_BUT_EMBEDDED = 3;
|
|
10
|
+
/**
|
|
11
|
+
* Records which release the embedded maps belong to.
|
|
12
|
+
*
|
|
13
|
+
* Without it the runtime cannot tell "this stack is from the deployed release"
|
|
14
|
+
* from "this stack is from an older one" — the embedded directory is keyed only
|
|
15
|
+
* by filename, so an old stack naming a bundle that still exists would be
|
|
16
|
+
* resolved with the current map, giving confidently wrong line numbers.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EMBEDDED_RELEASE_MARKER = ".release";
|
|
1
19
|
export interface UploadOptions {
|
|
2
20
|
bucket: string;
|
|
3
21
|
release?: string;
|
|
@@ -26,5 +44,7 @@ export declare function stripSourcesContent(raw: string): {
|
|
|
26
44
|
json: string;
|
|
27
45
|
stripped: boolean;
|
|
28
46
|
};
|
|
29
|
-
export declare function uploadSourceMaps(options: UploadOptions): Promise<
|
|
47
|
+
export declare function uploadSourceMaps(options: UploadOptions): Promise<{
|
|
48
|
+
uploaded: boolean;
|
|
49
|
+
}>;
|
|
30
50
|
//# sourceMappingURL=uploadSourceMaps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadSourceMaps.d.ts","sourceRoot":"","sources":["../../src/tools/uploadSourceMaps.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CASpF;AA8BD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"uploadSourceMaps.d.ts","sourceRoot":"","sources":["../../src/tools/uploadSourceMaps.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,IAAI,CAAA;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,aAAa,CAAA;AAEjD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CASpF;AA8BD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAmF7F"}
|
|
@@ -33,11 +33,30 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.EMBEDDED_RELEASE_MARKER = exports.EXIT_UPLOAD_FAILED_BUT_EMBEDDED = void 0;
|
|
36
37
|
exports.stripSourcesContent = stripSourcesContent;
|
|
37
38
|
exports.uploadSourceMaps = uploadSourceMaps;
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const path = __importStar(require("path"));
|
|
40
41
|
const storage_1 = require("@google-cloud/storage");
|
|
42
|
+
/**
|
|
43
|
+
* Exit code used when maps were embedded but the Storage upload failed.
|
|
44
|
+
*
|
|
45
|
+
* Distinct from 1 so a deploy script can decide: `|| [ $? -eq 3 ]` to continue
|
|
46
|
+
* anyway, or let it stop the chain. Exiting 0 was too quiet — the deploy script
|
|
47
|
+
* is a `&&` chain, so the deploy proceeded and the only signal was a warning
|
|
48
|
+
* scrolling past in CI output.
|
|
49
|
+
*/
|
|
50
|
+
exports.EXIT_UPLOAD_FAILED_BUT_EMBEDDED = 3;
|
|
51
|
+
/**
|
|
52
|
+
* Records which release the embedded maps belong to.
|
|
53
|
+
*
|
|
54
|
+
* Without it the runtime cannot tell "this stack is from the deployed release"
|
|
55
|
+
* from "this stack is from an older one" — the embedded directory is keyed only
|
|
56
|
+
* by filename, so an old stack naming a bundle that still exists would be
|
|
57
|
+
* resolved with the current map, giving confidently wrong line numbers.
|
|
58
|
+
*/
|
|
59
|
+
exports.EMBEDDED_RELEASE_MARKER = '.release';
|
|
41
60
|
/**
|
|
42
61
|
* Drop `sourcesContent` from a source map, returning the JSON to store.
|
|
43
62
|
*
|
|
@@ -101,7 +120,7 @@ async function uploadSourceMaps(options) {
|
|
|
101
120
|
const mapFiles = findMapFiles(distDir);
|
|
102
121
|
if (mapFiles.length === 0) {
|
|
103
122
|
console.log('[fsl] No .map files found in', distDir);
|
|
104
|
-
return;
|
|
123
|
+
return { uploaded: true };
|
|
105
124
|
}
|
|
106
125
|
console.log(`[fsl] Uploading ${mapFiles.length} source map(s) for release ${releaseId}...`);
|
|
107
126
|
// Embed maps into functions directory before uploading (for fast lookup of current release)
|
|
@@ -141,22 +160,30 @@ async function uploadSourceMaps(options) {
|
|
|
141
160
|
console.log(` ✗ deleted ${path.relative(process.cwd(), localPath)}`);
|
|
142
161
|
}
|
|
143
162
|
console.log('[fsl] Source map upload complete.');
|
|
163
|
+
return { uploaded: true };
|
|
144
164
|
}
|
|
145
165
|
catch (err) {
|
|
146
|
-
if (options.embedSourcemaps)
|
|
147
|
-
console.warn('[fsl] Warning: GCS upload failed — symbolication will work for this release only (via embedded maps). Previous releases will not be symbolicated.');
|
|
148
|
-
console.warn('[fsl] GCS error:', err?.message ?? err);
|
|
149
|
-
// Delete local .map files even though GCS upload failed — they are embedded and should not be deployed to hosting
|
|
150
|
-
for (const localPath of mapFiles) {
|
|
151
|
-
if (fs.existsSync(localPath)) {
|
|
152
|
-
fs.unlinkSync(localPath);
|
|
153
|
-
console.log(` ✗ deleted ${path.relative(process.cwd(), localPath)}`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
166
|
+
if (!options.embedSourcemaps)
|
|
158
167
|
throw err;
|
|
168
|
+
// Be precise about the consequence. Previous releases are unaffected —
|
|
169
|
+
// their maps reached Storage on earlier runs. What is at risk is THIS
|
|
170
|
+
// release: its maps never got there, and the embedded copy lives in
|
|
171
|
+
// {functionsDir}/sourcemaps/current/, which the next deploy wipes.
|
|
172
|
+
console.warn(`[fsl] GCS upload FAILED for release ${releaseId}.`);
|
|
173
|
+
console.warn('[fsl] GCS error:', err?.message ?? err);
|
|
174
|
+
console.warn(`[fsl] Errors from ${releaseId} will still symbolicate while it is the deployed`);
|
|
175
|
+
console.warn('[fsl] release, because the embedded copy is checked first. Once a newer release');
|
|
176
|
+
console.warn(`[fsl] is deployed, sourcemaps/current/ is replaced and ${releaseId} can no`);
|
|
177
|
+
console.warn('[fsl] longer be symbolicated. Re-run upload-sourcemaps before deploying again.');
|
|
178
|
+
// Deleted regardless: the maps are embedded, and leaving them in dist/ would
|
|
179
|
+
// ship source maps to browsers, which is the worse outcome.
|
|
180
|
+
for (const localPath of mapFiles) {
|
|
181
|
+
if (fs.existsSync(localPath)) {
|
|
182
|
+
fs.unlinkSync(localPath);
|
|
183
|
+
console.log(` ✗ deleted ${path.relative(process.cwd(), localPath)}`);
|
|
184
|
+
}
|
|
159
185
|
}
|
|
186
|
+
return { uploaded: false };
|
|
160
187
|
}
|
|
161
188
|
}
|
|
162
189
|
//# sourceMappingURL=uploadSourceMaps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadSourceMaps.js","sourceRoot":"","sources":["../../src/tools/uploadSourceMaps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"uploadSourceMaps.js","sourceRoot":"","sources":["../../src/tools/uploadSourceMaps.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.5.0",
|
|
4
4
|
"description": "Structured logging for Firebase apps \u2014 client, functions, and tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Dasasian",
|
|
@@ -65,7 +65,7 @@
|
|
|
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 && tsx tests/attachments.ts && tsx tests/sourceMapStripping.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",
|
|
68
|
+
"test": "tsx tests/logger.ts && tsx tests/breadcrumbs.ts && tsx tests/rateLimiter.ts && tsx tests/errorHandler.ts && tsx tests/attachments.ts && tsx tests/sourceMapStripping.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 && tsx tests/releaseResolution.ts && tsx tests/sourceMapCacheBounds.ts",
|
|
69
69
|
"prepublishOnly": "npm run clean && npm run build",
|
|
70
70
|
"smoke:deploy": "cd smoke/functions && npm install && npm run build && cd .. && firebase deploy --only functions --project $(grep '^FSL_SMOKE_PROJECT=' .env.local | cut -d= -f2)",
|
|
71
71
|
"smoke": "tsx smoke/run.ts"
|