@dasasian/firebase-structured-logger 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/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/client/breadcrumbs.d.ts +15 -0
- package/dist/client/breadcrumbs.d.ts.map +1 -0
- package/dist/client/breadcrumbs.js +52 -0
- package/dist/client/breadcrumbs.js.map +1 -0
- package/dist/client/errorHandler.d.ts +5 -0
- package/dist/client/errorHandler.d.ts.map +1 -0
- package/dist/client/errorHandler.js +19 -0
- package/dist/client/errorHandler.js.map +1 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +16 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/logger.d.ts +40 -0
- package/dist/client/logger.d.ts.map +1 -0
- package/dist/client/logger.js +199 -0
- package/dist/client/logger.js.map +1 -0
- package/dist/client/rateLimiter.d.ts +12 -0
- package/dist/client/rateLimiter.d.ts.map +1 -0
- package/dist/client/rateLimiter.js +80 -0
- package/dist/client/rateLimiter.js.map +1 -0
- package/dist/functions/index.d.ts +12 -0
- package/dist/functions/index.d.ts.map +1 -0
- package/dist/functions/index.js +21 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/functions/logHandler.d.ts +27 -0
- package/dist/functions/logHandler.d.ts.map +1 -0
- package/dist/functions/logHandler.js +137 -0
- package/dist/functions/logHandler.js.map +1 -0
- package/dist/functions/logger.d.ts +32 -0
- package/dist/functions/logger.d.ts.map +1 -0
- package/dist/functions/logger.js +253 -0
- package/dist/functions/logger.js.map +1 -0
- package/dist/functions/requestLogger.d.ts +30 -0
- package/dist/functions/requestLogger.d.ts.map +1 -0
- package/dist/functions/requestLogger.js +45 -0
- package/dist/functions/requestLogger.js.map +1 -0
- package/dist/functions/sourceMapCache.d.ts +9 -0
- package/dist/functions/sourceMapCache.d.ts.map +1 -0
- package/dist/functions/sourceMapCache.js +107 -0
- package/dist/functions/sourceMapCache.js.map +1 -0
- package/dist/functions/symbolicate.d.ts +31 -0
- package/dist/functions/symbolicate.d.ts.map +1 -0
- package/dist/functions/symbolicate.js +112 -0
- package/dist/functions/symbolicate.js.map +1 -0
- package/dist/shared/types.d.ts +36 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +152 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/installSkills.d.ts +6 -0
- package/dist/tools/installSkills.d.ts.map +1 -0
- package/dist/tools/installSkills.js +89 -0
- package/dist/tools/installSkills.js.map +1 -0
- package/dist/tools/packDeploy.d.ts +15 -0
- package/dist/tools/packDeploy.d.ts.map +1 -0
- package/dist/tools/packDeploy.js +148 -0
- package/dist/tools/packDeploy.js.map +1 -0
- package/dist/tools/uploadSourceMaps.d.ts +9 -0
- package/dist/tools/uploadSourceMaps.d.ts.map +1 -0
- package/dist/tools/uploadSourceMaps.js +120 -0
- package/dist/tools/uploadSourceMaps.js.map +1 -0
- package/package.json +103 -0
- package/skills/logs/SKILL.md +185 -0
- package/skills/query-logs/SKILL.md +93 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CallableRequest } from 'firebase-functions/v2/https';
|
|
2
|
+
import { type LogWriter } from './logger';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize a request-scoped logger and store it in AsyncLocalStorage.
|
|
5
|
+
* Call at the start of every onCall handler.
|
|
6
|
+
*
|
|
7
|
+
* Pass AppLabels as a type parameter to get typed label checking on the `labels` field.
|
|
8
|
+
* Any labels passed here are seeded on every log call in the request.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* export const myFunc = onCall(async (request) => {
|
|
12
|
+
* initRequestLogger<AppLabels>(request, {
|
|
13
|
+
* functionName: 'myFunc',
|
|
14
|
+
* labels: { organizationId: request.data.organizationId },
|
|
15
|
+
* })
|
|
16
|
+
* logInfo('started')
|
|
17
|
+
* })
|
|
18
|
+
*/
|
|
19
|
+
export declare function initRequestLogger<AppLabels extends Record<string, string | undefined> = Record<string, string | undefined>>(request: CallableRequest, extra?: {
|
|
20
|
+
functionName?: string;
|
|
21
|
+
appId?: string;
|
|
22
|
+
labels?: Partial<AppLabels>;
|
|
23
|
+
}): LogWriter;
|
|
24
|
+
/**
|
|
25
|
+
* Retrieve the request-scoped logger.
|
|
26
|
+
* Falls back to an anonymous logger (no request labels) when called outside a request context.
|
|
27
|
+
* Logs written outside a request will be missing userId, functionName, etc. — visible in Cloud Logging.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getLogger(): LogWriter;
|
|
30
|
+
//# sourceMappingURL=requestLogger.d.ts.map
|
|
@@ -0,0 +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,EAAmB,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AAI1D;;;;;;;;;;;;;;;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;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,GAC7E,SAAS,CAgBX;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initRequestLogger = initRequestLogger;
|
|
4
|
+
exports.getLogger = getLogger;
|
|
5
|
+
const async_hooks_1 = require("async_hooks");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
const storage = new async_hooks_1.AsyncLocalStorage();
|
|
8
|
+
/**
|
|
9
|
+
* Initialize a request-scoped logger and store it in AsyncLocalStorage.
|
|
10
|
+
* Call at the start of every onCall handler.
|
|
11
|
+
*
|
|
12
|
+
* Pass AppLabels as a type parameter to get typed label checking on the `labels` field.
|
|
13
|
+
* Any labels passed here are seeded on every log call in the request.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* export const myFunc = onCall(async (request) => {
|
|
17
|
+
* initRequestLogger<AppLabels>(request, {
|
|
18
|
+
* functionName: 'myFunc',
|
|
19
|
+
* labels: { organizationId: request.data.organizationId },
|
|
20
|
+
* })
|
|
21
|
+
* logInfo('started')
|
|
22
|
+
* })
|
|
23
|
+
*/
|
|
24
|
+
function initRequestLogger(request, extra) {
|
|
25
|
+
const labels = {
|
|
26
|
+
functionName: extra?.functionName,
|
|
27
|
+
userId: request.auth?.uid,
|
|
28
|
+
appId: extra?.appId,
|
|
29
|
+
...extra?.labels,
|
|
30
|
+
};
|
|
31
|
+
// Remove undefined values
|
|
32
|
+
const cleanLabels = Object.fromEntries(Object.entries(labels).filter(([, v]) => v !== undefined));
|
|
33
|
+
const writer = (0, logger_1.createLogWriter)(cleanLabels);
|
|
34
|
+
storage.enterWith(writer);
|
|
35
|
+
return writer;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve the request-scoped logger.
|
|
39
|
+
* Falls back to an anonymous logger (no request labels) when called outside a request context.
|
|
40
|
+
* Logs written outside a request will be missing userId, functionName, etc. — visible in Cloud Logging.
|
|
41
|
+
*/
|
|
42
|
+
function getLogger() {
|
|
43
|
+
return storage.getStore() ?? (0, logger_1.createLogWriter)({});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=requestLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestLogger.js","sourceRoot":"","sources":["../../src/functions/requestLogger.ts"],"names":[],"mappings":";;AAsBA,8CAqBC;AAOD,8BAEC;AApDD,6CAA+C;AAE/C,qCAA0D;AAE1D,MAAM,OAAO,GAAG,IAAI,+BAAiB,EAAa,CAAA;AAElD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,iBAAiB,CAG/B,OAAwB,EACxB,KAA8E;IAE9E,MAAM,MAAM,GAAuC;QACjD,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,CAAA;IAED,0BAA0B;IAC1B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAChC,CAAA;IAE3B,MAAM,MAAM,GAAG,IAAA,wBAAe,EAAC,WAAW,CAAC,CAAA;IAC3C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACzB,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAA,wBAAe,EAAC,EAAE,CAAC,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EncodedSourceMap } from '@jridgewell/trace-mapping';
|
|
2
|
+
export declare function configureSourceMapBucket(bucketName: string): void;
|
|
3
|
+
export declare function getConfiguredBucket(): string | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
6
|
+
*/
|
|
7
|
+
export declare function getSourceMap(releaseId: string, fileName: string): Promise<EncodedSourceMap | null>;
|
|
8
|
+
export declare function clearSourceMapCache(): void;
|
|
9
|
+
//# sourceMappingURL=sourceMapCache.d.ts.map
|
|
@@ -0,0 +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;AAOjE,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExD;AAiDD;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIlC;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.configureSourceMapBucket = configureSourceMapBucket;
|
|
37
|
+
exports.getConfiguredBucket = getConfiguredBucket;
|
|
38
|
+
exports.getSourceMap = getSourceMap;
|
|
39
|
+
exports.clearSourceMapCache = clearSourceMapCache;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const storage_1 = require("firebase-admin/storage");
|
|
43
|
+
// In-memory cache: cacheKey → EncodedSourceMap | null (null = confirmed not found)
|
|
44
|
+
const cache = new Map();
|
|
45
|
+
let configuredBucket;
|
|
46
|
+
function configureSourceMapBucket(bucketName) {
|
|
47
|
+
configuredBucket = bucketName;
|
|
48
|
+
}
|
|
49
|
+
function getConfiguredBucket() {
|
|
50
|
+
return configuredBucket;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Load source map from embedded current release directory (instant for current release).
|
|
54
|
+
*/
|
|
55
|
+
function loadEmbeddedSourceMap(fileName) {
|
|
56
|
+
try {
|
|
57
|
+
// Looks for sourcemaps/current/{fileName}.map relative to the Cloud Function working directory
|
|
58
|
+
const mapPath = path.join(process.cwd(), 'sourcemaps', 'current', `${fileName}.map`);
|
|
59
|
+
if (!fs.existsSync(mapPath))
|
|
60
|
+
return null;
|
|
61
|
+
return JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Load source map from Firebase Storage (for older releases).
|
|
69
|
+
*/
|
|
70
|
+
async function loadStorageSourceMap(releaseId, fileName) {
|
|
71
|
+
const cacheKey = `${releaseId}/${fileName}`;
|
|
72
|
+
if (cache.has(cacheKey))
|
|
73
|
+
return cache.get(cacheKey) ?? null;
|
|
74
|
+
try {
|
|
75
|
+
const bucket = configuredBucket
|
|
76
|
+
? (0, storage_1.getStorage)().bucket(configuredBucket)
|
|
77
|
+
: (0, storage_1.getStorage)().bucket();
|
|
78
|
+
const file = bucket.file(`sourcemaps/${releaseId}/${fileName}.map`);
|
|
79
|
+
const [exists] = await file.exists();
|
|
80
|
+
if (!exists) {
|
|
81
|
+
cache.set(cacheKey, null);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const [content] = await file.download();
|
|
85
|
+
const sourceMap = JSON.parse(content.toString());
|
|
86
|
+
cache.set(cacheKey, sourceMap);
|
|
87
|
+
return sourceMap;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.warn(`[fsl] Failed to load Storage map for ${releaseId}/${fileName}:`, err);
|
|
91
|
+
cache.set(`${releaseId}/${fileName}`, null);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get source map — checks embedded first (instant), then Storage (for old releases).
|
|
97
|
+
*/
|
|
98
|
+
async function getSourceMap(releaseId, fileName) {
|
|
99
|
+
const embedded = loadEmbeddedSourceMap(fileName);
|
|
100
|
+
if (embedded)
|
|
101
|
+
return embedded;
|
|
102
|
+
return loadStorageSourceMap(releaseId, fileName);
|
|
103
|
+
}
|
|
104
|
+
function clearSourceMapCache() {
|
|
105
|
+
cache.clear();
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=sourceMapCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceMapCache.js","sourceRoot":"","sources":["../../src/functions/sourceMapCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,4DAEC;AAED,kDAEC;AAoDD,oCAOC;AAED,kDAEC;AA/ED,uCAAwB;AACxB,2CAA4B;AAC5B,oDAAmD;AAGnD,mFAAmF;AACnF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAA;AAExD,IAAI,gBAAoC,CAAA;AAExC,SAAgB,wBAAwB,CAAC,UAAkB;IACzD,gBAAgB,GAAG,UAAU,CAAA;AAC/B,CAAC;AAED,SAAgB,mBAAmB;IACjC,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,+FAA+F;QAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAA;QACpF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAA;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAqB,CAAA;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,oBAAoB,CACjC,SAAiB,EACjB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAA;IAC3C,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAA;IAE3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,gBAAgB;YAC7B,CAAC,CAAC,IAAA,oBAAU,GAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC;YACvC,CAAC,CAAC,IAAA,oBAAU,GAAE,CAAC,MAAM,EAAE,CAAA;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,SAAS,IAAI,QAAQ,MAAM,CAAC,CAAA;QACnE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;QAEpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YACzB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAA;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAqB,CAAA;QACpE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;QAC9B,OAAO,SAAS,CAAA;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,wCAAwC,SAAS,IAAI,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAA;QACnF,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAA;QAC3C,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;IAChD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC7B,OAAO,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AAClD,CAAC;AAED,SAAgB,mBAAmB;IACjC,KAAK,CAAC,KAAK,EAAE,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type EncodedSourceMap } from '@jridgewell/trace-mapping';
|
|
2
|
+
export interface StackFrame {
|
|
3
|
+
raw: string;
|
|
4
|
+
fileName?: string;
|
|
5
|
+
functionName?: string;
|
|
6
|
+
lineNumber?: number;
|
|
7
|
+
columnNumber?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse browser stack trace into structured frames.
|
|
11
|
+
* Handles Chrome, Firefox, and Safari formats (including anonymous frames).
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseStackTrace(stack: string): StackFrame[];
|
|
14
|
+
/**
|
|
15
|
+
* Look up original source location for a generated line/column.
|
|
16
|
+
*/
|
|
17
|
+
export declare function symbolicate(sourceMap: EncodedSourceMap, generatedLine: number, generatedColumn: number): {
|
|
18
|
+
source: string;
|
|
19
|
+
line: number;
|
|
20
|
+
column: number;
|
|
21
|
+
name?: string;
|
|
22
|
+
} | null;
|
|
23
|
+
/**
|
|
24
|
+
* Apply source map to all frames in a stack trace.
|
|
25
|
+
*/
|
|
26
|
+
export declare function symbolicateStackTrace(frames: StackFrame[], sourceMap: EncodedSourceMap): StackFrame[];
|
|
27
|
+
/**
|
|
28
|
+
* Format symbolicated frames back to a stack trace string.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatStackTrace(frames: StackFrame[]): string;
|
|
31
|
+
//# sourceMappingURL=symbolicate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbolicate.d.ts","sourceRoot":"","sources":["../../src/functions/symbolicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEhG,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAGD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAkD3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,gBAAgB,EAC3B,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,GACtB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAAE,EACpB,SAAS,EAAE,gBAAgB,GAC1B,UAAU,EAAE,CAgBd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAQ7D"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStackTrace = parseStackTrace;
|
|
4
|
+
exports.symbolicate = symbolicate;
|
|
5
|
+
exports.symbolicateStackTrace = symbolicateStackTrace;
|
|
6
|
+
exports.formatStackTrace = formatStackTrace;
|
|
7
|
+
const trace_mapping_1 = require("@jridgewell/trace-mapping");
|
|
8
|
+
/**
|
|
9
|
+
* Parse browser stack trace into structured frames.
|
|
10
|
+
* Handles Chrome, Firefox, and Safari formats (including anonymous frames).
|
|
11
|
+
*/
|
|
12
|
+
function parseStackTrace(stack) {
|
|
13
|
+
const frames = [];
|
|
14
|
+
for (const line of stack.split('\n')) {
|
|
15
|
+
const trimmed = line.trim();
|
|
16
|
+
if (!trimmed)
|
|
17
|
+
continue;
|
|
18
|
+
// Chrome: "at functionName (file:line:col)"
|
|
19
|
+
const chromeMatch = trimmed.match(/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/);
|
|
20
|
+
if (chromeMatch) {
|
|
21
|
+
frames.push({
|
|
22
|
+
raw: trimmed,
|
|
23
|
+
functionName: chromeMatch[1],
|
|
24
|
+
fileName: chromeMatch[2],
|
|
25
|
+
lineNumber: parseInt(chromeMatch[3], 10),
|
|
26
|
+
columnNumber: parseInt(chromeMatch[4], 10),
|
|
27
|
+
});
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
// Chrome without function: "at file:line:col"
|
|
31
|
+
const chromeSimple = trimmed.match(/^at\s+(.+?):(\d+):(\d+)$/);
|
|
32
|
+
if (chromeSimple) {
|
|
33
|
+
frames.push({
|
|
34
|
+
raw: trimmed,
|
|
35
|
+
functionName: 'anonymous',
|
|
36
|
+
fileName: chromeSimple[1],
|
|
37
|
+
lineNumber: parseInt(chromeSimple[2], 10),
|
|
38
|
+
columnNumber: parseInt(chromeSimple[3], 10),
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
// Firefox/Safari: "functionName@file:line:col" or "@file:line:col" (anonymous)
|
|
43
|
+
const firefoxMatch = trimmed.match(/^(.*?)@(.+?):(\d+):(\d+)$/);
|
|
44
|
+
if (firefoxMatch) {
|
|
45
|
+
frames.push({
|
|
46
|
+
raw: trimmed,
|
|
47
|
+
functionName: firefoxMatch[1] || 'anonymous',
|
|
48
|
+
fileName: firefoxMatch[2],
|
|
49
|
+
lineNumber: parseInt(firefoxMatch[3], 10),
|
|
50
|
+
columnNumber: parseInt(firefoxMatch[4], 10),
|
|
51
|
+
});
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
frames.push({ raw: trimmed });
|
|
55
|
+
}
|
|
56
|
+
return frames;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Look up original source location for a generated line/column.
|
|
60
|
+
*/
|
|
61
|
+
function symbolicate(sourceMap, generatedLine, generatedColumn) {
|
|
62
|
+
try {
|
|
63
|
+
const tracer = new trace_mapping_1.TraceMap(sourceMap);
|
|
64
|
+
const result = (0, trace_mapping_1.originalPositionFor)(tracer, { line: generatedLine, column: generatedColumn });
|
|
65
|
+
if (!result.source)
|
|
66
|
+
return null;
|
|
67
|
+
return {
|
|
68
|
+
source: result.source,
|
|
69
|
+
line: result.line ?? generatedLine,
|
|
70
|
+
column: result.column ?? generatedColumn,
|
|
71
|
+
name: result.name ?? undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Apply source map to all frames in a stack trace.
|
|
80
|
+
*/
|
|
81
|
+
function symbolicateStackTrace(frames, sourceMap) {
|
|
82
|
+
return frames.map((frame) => {
|
|
83
|
+
if (!frame.lineNumber || !frame.columnNumber || !frame.fileName)
|
|
84
|
+
return frame;
|
|
85
|
+
if (!frame.fileName.includes('.js'))
|
|
86
|
+
return frame;
|
|
87
|
+
const result = symbolicate(sourceMap, frame.lineNumber, frame.columnNumber);
|
|
88
|
+
if (!result)
|
|
89
|
+
return frame;
|
|
90
|
+
return {
|
|
91
|
+
...frame,
|
|
92
|
+
fileName: result.source,
|
|
93
|
+
lineNumber: result.line,
|
|
94
|
+
columnNumber: result.column,
|
|
95
|
+
functionName: result.name ?? frame.functionName,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Format symbolicated frames back to a stack trace string.
|
|
101
|
+
*/
|
|
102
|
+
function formatStackTrace(frames) {
|
|
103
|
+
return frames
|
|
104
|
+
.map((frame) => {
|
|
105
|
+
if (!frame.fileName)
|
|
106
|
+
return frame.raw;
|
|
107
|
+
const func = frame.functionName ?? 'anonymous';
|
|
108
|
+
return ` at ${func} (${frame.fileName}:${frame.lineNumber ?? '?'}:${frame.columnNumber ?? '?'})`;
|
|
109
|
+
})
|
|
110
|
+
.join('\n');
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=symbolicate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbolicate.js","sourceRoot":"","sources":["../../src/functions/symbolicate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type LogSeverity = 'ERROR' | 'WARNING' | 'INFO' | 'DEBUG';
|
|
2
|
+
export interface BaseLabels {
|
|
3
|
+
appId: string;
|
|
4
|
+
userId?: string;
|
|
5
|
+
screen?: string;
|
|
6
|
+
platform?: string;
|
|
7
|
+
browser?: string;
|
|
8
|
+
releaseId?: string;
|
|
9
|
+
errorType?: string;
|
|
10
|
+
errorCategory?: string;
|
|
11
|
+
activity?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface LogPayload {
|
|
14
|
+
message: string;
|
|
15
|
+
severity: LogSeverity;
|
|
16
|
+
labels: BaseLabels & Record<string, string | undefined>;
|
|
17
|
+
jsonPayload?: {
|
|
18
|
+
breadcrumbs?: BreadcrumbEntry[];
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
error?: {
|
|
21
|
+
message: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
cause?: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/** Base64-encoded attachments keyed by name. Uploaded to GCS, stripped before writing to Cloud Logging. */
|
|
28
|
+
attachments?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export interface BreadcrumbEntry {
|
|
31
|
+
timestamp: number;
|
|
32
|
+
type: 'action' | 'state' | 'nav' | 'error';
|
|
33
|
+
name: string;
|
|
34
|
+
data?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAA;AAEhE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,WAAW,CAAA;IACrB,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACvD,WAAW,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;QAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,KAAK,CAAC,EAAE;YACN,OAAO,EAAE,MAAM,CAAA;YACf,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,KAAK,CAAC,EAAE,MAAM,CAAA;SACf,CAAA;KACF,CAAA;IACD,2GAA2G;IAC3G,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAA;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const uploadSourceMaps_1 = require("./uploadSourceMaps");
|
|
40
|
+
const installSkills_1 = require("./installSkills");
|
|
41
|
+
const packDeploy_1 = require("./packDeploy");
|
|
42
|
+
const [, , command, ...rawArgs] = process.argv;
|
|
43
|
+
function parseArgs(args) {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const arg of args) {
|
|
46
|
+
const match = arg.match(/^--([^=]+)=(.*)$/);
|
|
47
|
+
if (match) {
|
|
48
|
+
result[match[1]] = match[2];
|
|
49
|
+
}
|
|
50
|
+
else if (arg.startsWith('--')) {
|
|
51
|
+
result[arg.slice(2)] = 'true';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
function loadEnvFile(filePath) {
|
|
57
|
+
const resolved = path.resolve(process.cwd(), filePath);
|
|
58
|
+
if (!fs.existsSync(resolved))
|
|
59
|
+
return;
|
|
60
|
+
for (const line of fs.readFileSync(resolved, 'utf-8').split('\n')) {
|
|
61
|
+
const trimmed = line.trim();
|
|
62
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
63
|
+
continue;
|
|
64
|
+
const eq = trimmed.indexOf('=');
|
|
65
|
+
if (eq === -1)
|
|
66
|
+
continue;
|
|
67
|
+
const key = trimmed.slice(0, eq).trim();
|
|
68
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
69
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
70
|
+
value = value.slice(1, -1);
|
|
71
|
+
}
|
|
72
|
+
if (!process.env[key])
|
|
73
|
+
process.env[key] = value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function main() {
|
|
77
|
+
const args = parseArgs(rawArgs);
|
|
78
|
+
// Auto-load .env.local from cwd if present
|
|
79
|
+
loadEnvFile('.env.local');
|
|
80
|
+
switch (command) {
|
|
81
|
+
case 'upload-sourcemaps': {
|
|
82
|
+
const bucket = args.bucket ?? process.env.VITE_FIREBASE_STORAGE_BUCKET ?? process.env.FIREBASE_STORAGE_BUCKET;
|
|
83
|
+
if (!bucket) {
|
|
84
|
+
console.error('Usage: fsl upload-sourcemaps [--bucket=<name>] [--functions=<path>] [--embed-sourcemaps] [--release=<id>] [--dist=<path>]');
|
|
85
|
+
console.error('Bucket can also be set via VITE_FIREBASE_STORAGE_BUCKET or FIREBASE_STORAGE_BUCKET env var (loaded from .env.local automatically).');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
await (0, uploadSourceMaps_1.uploadSourceMaps)({
|
|
89
|
+
bucket,
|
|
90
|
+
release: args.release,
|
|
91
|
+
distDir: args.dist,
|
|
92
|
+
functionsDir: args.functions,
|
|
93
|
+
embedSourcemaps: args['embed-sourcemaps'] === 'true',
|
|
94
|
+
});
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case 'install-skills': {
|
|
98
|
+
await (0, installSkills_1.installSkills)({ global: args.global === 'true', force: args.force === 'true' });
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case 'pack': {
|
|
102
|
+
if (!args.functions) {
|
|
103
|
+
console.error('Usage: fsl pack --functions=<path>');
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
await (0, packDeploy_1.pack)({ functionsDir: args.functions });
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case 'pack-restore': {
|
|
110
|
+
if (!args.functions) {
|
|
111
|
+
console.error('Usage: fsl pack-restore --functions=<path>');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
await (0, packDeploy_1.packRestore)({ functionsDir: args.functions });
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
default: {
|
|
118
|
+
console.log(`
|
|
119
|
+
firebase-structured-logger (fsl)
|
|
120
|
+
|
|
121
|
+
Commands:
|
|
122
|
+
fsl upload-sourcemaps [--bucket=<name>] [--functions=<path>] [--embed-sourcemaps] [--release=<id>] [--dist=<path>]
|
|
123
|
+
Upload .map files from dist/ to Cloud Storage and delete them locally.
|
|
124
|
+
--bucket defaults to VITE_FIREBASE_STORAGE_BUCKET or FIREBASE_STORAGE_BUCKET (loaded from .env.local automatically).
|
|
125
|
+
--functions path to Cloud Functions directory (e.g. ./functions or ./backend).
|
|
126
|
+
--embed-sourcemaps copies maps to {functions}/sourcemaps/current/ for fast lookup of current release.
|
|
127
|
+
Authenticates via FIREBASE_SERVICE_ACCOUNT_PATH if set, otherwise uses ADC.
|
|
128
|
+
Release ID defaults to git rev-parse --short HEAD.
|
|
129
|
+
|
|
130
|
+
fsl install-skills [--global] [--force]
|
|
131
|
+
Copy skills/ to .claude/skills/ (project) or ~/.claude/skills/ (--global).
|
|
132
|
+
Prompts before overwriting existing skills. Use --force to skip prompts.
|
|
133
|
+
|
|
134
|
+
fsl pack --functions=<path>
|
|
135
|
+
Build + pack firebase-structured-logger, copy tgz to functions/vendor/,
|
|
136
|
+
and patch functions/package.json. Run before firebase deploy.
|
|
137
|
+
|
|
138
|
+
fsl pack-restore --functions=<path>
|
|
139
|
+
Restore functions/package.json to its file: reference after deploy.
|
|
140
|
+
`);
|
|
141
|
+
if (command) {
|
|
142
|
+
console.error(`Unknown command: ${command}`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
main().catch((err) => {
|
|
149
|
+
console.error(err);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installSkills.d.ts","sourceRoot":"","sources":["../../src/tools/installSkills.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAYD,wBAAsB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CrF"}
|