@sailfish-ai/sf-veritas 0.3.0 → 0.3.2
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 +88 -0
- package/dist/{contextManager-RxrMXs5c.js → contextManager-CZy0w11U.js} +118 -114
- package/dist/contextManager-qXvO_a5y.cjs +1 -0
- package/dist/plugins/funcspanEsbuildPlugin.cjs +1 -1
- package/dist/plugins/funcspanEsbuildPlugin.mjs +1 -1
- package/dist/plugins/funcspanRollupPlugin.cjs +1 -1
- package/dist/plugins/funcspanRollupPlugin.mjs +1 -1
- package/dist/plugins/funcspanTscPlugin.cjs +1 -1
- package/dist/plugins/funcspanTscPlugin.mjs +1 -1
- package/dist/plugins/funcspanVitePlugin.cjs +1 -1
- package/dist/plugins/funcspanVitePlugin.mjs +1 -1
- package/dist/plugins/funcspanWebpackPlugin.cjs +1 -1
- package/dist/plugins/funcspanWebpackPlugin.mjs +1 -1
- package/dist/{runtimeConfig-BZ61efqE.js → runtimeConfig-ButdW4zP.js} +329 -340
- package/dist/runtimeConfig-C4_zc4Zg.cjs +5 -0
- package/dist/sf-veritas.cjs +13 -13
- package/dist/sf-veritas.mjs +590 -424
- package/dist/types/constants.d.ts +7 -0
- package/dist/types/requestTransmitter.d.ts +75 -0
- package/dist/types/setupConfig.d.ts +39 -0
- package/dist/types/urlMatch.d.ts +19 -0
- package/dist/worker-pool-capture.cjs +1 -1
- package/dist/worker-pool-capture.mjs +1 -1
- package/dist/{workerPoolSpanCapture-Bg5av6gn.cjs → workerPoolSpanCapture-BUFN_RMW.cjs} +1 -1
- package/dist/{workerPoolSpanCapture-BjdZn3LE.js → workerPoolSpanCapture-BomWTMM2.js} +1 -1
- package/package.json +17 -1
- package/dist/contextManager-0D8uHQ1_.cjs +0 -1
- package/dist/runtimeConfig-CWpFWsmz.cjs +0 -6
package/README.md
CHANGED
|
@@ -277,3 +277,91 @@ addOrUpdateMetadata("user-123", { birthday: "2000-01-01" }, true);
|
|
|
277
277
|
- **Contextual Awareness**: Tracks context across threads, processes, and async tasks to associate logs with the correct sequence of events.
|
|
278
278
|
|
|
279
279
|
By following these steps, you can seamlessly integrate `sf-veritas` into your Node.js project and start capturing LEaPS (Logs, Exceptions, and Print Statements) effectively!
|
|
280
|
+
|
|
281
|
+
## Release Notes
|
|
282
|
+
|
|
283
|
+
### 0.3.2-alpha1
|
|
284
|
+
|
|
285
|
+
**Bug fix — outbound trace-header format matches Python**
|
|
286
|
+
|
|
287
|
+
Pre-0.3.2, the SDK emitted `X-Sf3-Rid = ${traceId}/${pageVisitUUID}/${networkUUID}`, producing a 5-segment string when `traceId` already had 3 segments (always, since `getOrSetSfTraceId()` returns either `session/page/request` for inbound-traced requests or `nonsession-applogs-v3/<apiKey>/<uuid>` for fresh ones). Server-side parsers that split on `/` and take `[0]`, `[1]`, `[last]` interpreted the string as garbage for nonsession-applogs traces — `sessionId` came out as the literal string `"nonsession-applogs-v3"` (identical for every nonsession customer) and `pageVisitId` as the customer's API key.
|
|
288
|
+
|
|
289
|
+
0.3.2 matches Python's `thread_local.py:1349` contract:
|
|
290
|
+
|
|
291
|
+
- **`X-Sf3-Rid`** is 3 segments: `<first-2-segments-of-trace>/<fresh-uuid>`.
|
|
292
|
+
- Session inbound: `session/page/<newUUID>` (newUUID unique per outbound).
|
|
293
|
+
- Nonsession: `nonsession-applogs-v3/<apiKey>/<newUUID>`.
|
|
294
|
+
- **`X-Sf4-Prid`** (new) carries the full parent trace id, mirroring Python's `PARENT_SESSION_ID_HEADER`. Server-side code can use this for parent-chain reconstruction.
|
|
295
|
+
|
|
296
|
+
**Feature — `domainsToPropagateHeadersTo` allowlist**
|
|
297
|
+
|
|
298
|
+
New `SetupOptions.domainsToPropagateHeadersTo` option (`string[]`, default `["*"]`). Enumerates domains whose outbound requests receive the tracing header. Supports the same wildcard syntax as the jsts-frontend matcher (`*`, `*.example.com`, `api.example.com/v1/*`, `example.com:8080`).
|
|
299
|
+
|
|
300
|
+
Interaction with existing `domainsToNotPropagateHeadersTo` and `DEFAULT_DOMAINS_TO_EXCLUDE`: **deny wins on conflict**. Exact decision logic:
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
propagate = matches(url, allowlist)
|
|
304
|
+
&& NOT matches(url, denylist)
|
|
305
|
+
&& NOT matches(url, DEFAULT_DOMAINS_TO_EXCLUDE)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Default `["*"]` preserves pre-0.3.2 behavior (all domains allowed, defaults/denylist still block). Set to `[]` to block every outbound propagation.
|
|
309
|
+
|
|
310
|
+
**Feature-parity audit published**
|
|
311
|
+
|
|
312
|
+
A detailed comparison of this package with the Python Sailfish SDK is now tracked in [`PYTHON_PARITY_GAPS.md`](./PYTHON_PARITY_GAPS.md). 12 gaps are enumerated with priority and effort for future PR planning — including queue instrumentation (BullMQ, Kafka), `reinitializeAfterFork()`, local-variable capture in exceptions, and manual-dispatch APIs.
|
|
313
|
+
|
|
314
|
+
**Test coverage**
|
|
315
|
+
|
|
316
|
+
+44 new tests (wildcard matcher matrix, trace-header format, allow-list decision logic). Full suite: 357 → ~400 passing.
|
|
317
|
+
|
|
318
|
+
### 0.3.1
|
|
319
|
+
|
|
320
|
+
**Critical fix — GraphQL error passthrough**
|
|
321
|
+
|
|
322
|
+
Resolves a regression where the global `Error` override created a fresh intermediate prototype instead of aliasing the native `Error.prototype` directly. This caused `instanceof Error` to return `false` for Error subclasses declared before SDK initialization — including `GraphQLError` — which in turn caused graphql-js's `locatedError` to wrap every resolver error with `"Unexpected error value: …"` and strip `path` / `locations`. The prototype is now aliased directly (`CustomError.prototype = OriginalError.prototype`), preserving the native prototype chain for every existing Error subclass.
|
|
323
|
+
|
|
324
|
+
**Timeline**
|
|
325
|
+
|
|
326
|
+
- **Dec 19, 2024** — `patchFetch` lands with a silent-swallow `catch (error) {}` block. Latent; dormant while telemetry paths were reliable.
|
|
327
|
+
- **Feb 20, 2025** — Global `Error` override ships with the `Object.create` prototype quirk. `instanceof Error` silently returns `false` for `GraphQLError` from this point on.
|
|
328
|
+
- **Apr 16, 2026** — `0.3.0` stable ships to npm. Both latent bugs widely exposed.
|
|
329
|
+
- **Apr 21, 2026 (morning)** — Design-partner customer reports `"Unexpected error value"` wrapping with `path`/`locations` stripped.
|
|
330
|
+
- **Apr 21, 2026 (afternoon)** — Offline reproduction rig built side-by-side against `0.3.0` (broken) and the local fix (fixed); all customer symptoms reproduced.
|
|
331
|
+
- **Apr 21, 2026 (evening)** — `0.3.1` ships. Primary fix + 5 adjacent `fetch`/`http` bugs closed + 327-test regression suite locked in.
|
|
332
|
+
|
|
333
|
+
**Adjacent fixes uncovered during the audit**
|
|
334
|
+
|
|
335
|
+
- `patchFetch` now rethrows native errors (previously swallowed — causing `fetch()` to resolve to `undefined`, which manifested downstream as `"Cannot return null for non-nullable field …"`).
|
|
336
|
+
- **400/403 retry policy is now configurable** via the new `retryOnClientError` option. Default (`'all'`) matches pre-0.3.1 behavior — on a 400/403 response carrying our tracing header, every method retries once with the header stripped, so customers whose backends reject unknown headers at the edge see no visible impact. Customers whose backends may commit side effects before returning 4xx (payment processors, booking systems, inventory APIs) should set `retryOnClientError: 'idempotent'` (only GET/HEAD/OPTIONS retry) or `'none'` (never retry). Also configurable via the `SF_RETRY_ON_CLIENT_ERROR` environment variable.
|
|
337
|
+
- `Request` inputs preserve `method`, `body`, `credentials`, `mode`, `redirect`, `signal`, `referrer`, `integrity`, `cache` through the instrumentation clone.
|
|
338
|
+
- Response-body capture moved off the critical path. Server-Sent Events and chunked responses no longer block `fetch()` resolution.
|
|
339
|
+
- Non-text response bodies (images, video, octet-stream, protobuf, etc.) are no longer decoded as UTF-8 garbage; they produce a size-only placeholder.
|
|
340
|
+
- Relative or malformed URLs (`fetch("/api/foo")` in isomorphic code) pass through to the native fetch instead of throwing inside the wrapper.
|
|
341
|
+
- Request body capture handles `URLSearchParams`, `Blob`, `FormData`, `ReadableStream`, `ArrayBuffer`, and typed arrays with meaningful placeholders instead of `"{}"`.
|
|
342
|
+
|
|
343
|
+
**Framework coverage — end-to-end integration tests**
|
|
344
|
+
|
|
345
|
+
Every mainstream server-side GraphQL framework is exercised through real HTTP (or real Web `Request`/`Response`) with the SDK loaded, so any regression in the request/response pipeline surfaces immediately in CI.
|
|
346
|
+
|
|
347
|
+
| Framework | Coverage |
|
|
348
|
+
| --- | --- |
|
|
349
|
+
| Apollo Server v4 | ✓ |
|
|
350
|
+
| Hapi + custom route | ✓ |
|
|
351
|
+
| Express + hand-rolled handler | ✓ |
|
|
352
|
+
| Fastify + Mercurius | ✓ |
|
|
353
|
+
| graphql-yoga | ✓ |
|
|
354
|
+
| Koa + graphql-js | ✓ |
|
|
355
|
+
| NestJS + `@nestjs/platform-express` | ✓ |
|
|
356
|
+
| Next.js App Router (Node runtime) | ✓ |
|
|
357
|
+
| Next.js App Router (Edge runtime) | ✓ |
|
|
358
|
+
| Raw graphql-js / fetch-in-resolver | ✓ |
|
|
359
|
+
|
|
360
|
+
**Hardening**
|
|
361
|
+
|
|
362
|
+
- **327** behavioral tests across **35** files (from 74 prior to the regression audit). `tsc --noEmit` clean.
|
|
363
|
+
- **Memory-leak verification** — 10,000-iteration scenarios for patched `fetch`, `console.log`, and `Error` throw+catch, with heap deltas measured after forced GC. Observed deltas: **+1.74 MB / +0.07 MB / +8 bytes** — well under the 50 MB budget and consistent with zero SDK-side retention.
|
|
364
|
+
- **AsyncLocalStorage context isolation** — concurrent requests across sessions receive distinct trace IDs with no cross-tenant bleed.
|
|
365
|
+
- **Process-handler preservation** — user-registered `uncaughtException` / `unhandledRejection` / `SIGINT` handlers still fire after SDK initialization; SDK does not add to either handler count.
|
|
366
|
+
- **Native error metadata preservation** — `err.code`, `err.errno`, `err.syscall` survive the `Error` override for `fs`, `dns`, and all other Node built-ins.
|
|
367
|
+
|
|
@@ -1,94 +1,96 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { AsyncLocalStorage as
|
|
5
|
-
import { execFile as
|
|
1
|
+
var G = Object.defineProperty;
|
|
2
|
+
var H = (n, e, t) => e in n ? G(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var r = (n, e, t) => H(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { AsyncLocalStorage as P } from "async_hooks";
|
|
5
|
+
import { execFile as V } from "child_process";
|
|
6
6
|
import { existsSync as m } from "fs";
|
|
7
|
-
import * as
|
|
7
|
+
import * as k from "fs/promises";
|
|
8
8
|
import * as N from "os";
|
|
9
9
|
const a = [];
|
|
10
10
|
for (let n = 0; n < 256; ++n) a.push((n + 256).toString(16).slice(1));
|
|
11
|
-
let
|
|
12
|
-
const
|
|
11
|
+
let T;
|
|
12
|
+
const F = new Uint8Array(16), A = { randomUUID: typeof crypto < "u" && crypto.randomUUID && crypto.randomUUID.bind(crypto) };
|
|
13
13
|
function C(n, e, t) {
|
|
14
14
|
if (A.randomUUID && !n) return A.randomUUID();
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
15
|
+
const s = (n = n || {}).random ?? n.rng?.() ?? (function() {
|
|
16
|
+
if (!T) {
|
|
17
17
|
if (typeof crypto > "u" || !crypto.getRandomValues) throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
18
|
-
|
|
18
|
+
T = crypto.getRandomValues.bind(crypto);
|
|
19
19
|
}
|
|
20
|
-
return
|
|
20
|
+
return T(F);
|
|
21
21
|
})();
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
22
|
+
if (s.length < 16) throw new Error("Random bytes length must be >= 16");
|
|
23
|
+
return s[6] = 15 & s[6] | 64, s[8] = 63 & s[8] | 128, (function(o, i = 0) {
|
|
24
24
|
return (a[o[i + 0]] + a[o[i + 1]] + a[o[i + 2]] + a[o[i + 3]] + "-" + a[o[i + 4]] + a[o[i + 5]] + "-" + a[o[i + 6]] + a[o[i + 7]] + "-" + a[o[i + 8]] + a[o[i + 9]] + "-" + a[o[i + 10]] + a[o[i + 11]] + a[o[i + 12]] + a[o[i + 13]] + a[o[i + 14]] + a[o[i + 15]]).toLowerCase();
|
|
25
|
-
})(
|
|
25
|
+
})(s);
|
|
26
26
|
}
|
|
27
|
-
class
|
|
27
|
+
class w {
|
|
28
28
|
constructor(e) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
29
|
+
r(this, "apiKey");
|
|
30
|
+
r(this, "apiGraphqlEndpoint");
|
|
31
|
+
r(this, "sfDebug");
|
|
32
|
+
r(this, "serviceIdentifier");
|
|
33
|
+
r(this, "serviceVersion");
|
|
34
|
+
r(this, "serviceUUID");
|
|
35
|
+
r(this, "serviceAdditionalMetadata");
|
|
36
|
+
r(this, "profilingModeEnabled");
|
|
37
|
+
r(this, "profilingMaxDepth");
|
|
38
|
+
r(this, "profilingMaxVariableSizeKb");
|
|
39
|
+
r(this, "domainsToNotPropagateHeadersTo");
|
|
40
|
+
r(this, "domainsToPropagateHeadersTo");
|
|
41
|
+
r(this, "nodeModulesToCollectLocalVariablesOn");
|
|
42
|
+
r(this, "printConfigurationStatuses");
|
|
43
|
+
r(this, "logLevel");
|
|
44
|
+
r(this, "stackDepthLocals");
|
|
45
|
+
r(this, "stackDepthCodeTraceDepth");
|
|
46
|
+
r(this, "packageLibraryType");
|
|
47
|
+
r(this, "version");
|
|
48
|
+
r(this, "gitSha");
|
|
49
|
+
r(this, "gitOrg");
|
|
50
|
+
r(this, "gitRepo");
|
|
51
|
+
r(this, "gitProvider");
|
|
52
|
+
r(this, "serviceDisplayName");
|
|
53
|
+
r(this, "infrastructureType");
|
|
54
|
+
r(this, "infrastructureDetails");
|
|
55
|
+
r(this, "framework");
|
|
56
|
+
r(this, "additionalFrameworks");
|
|
57
|
+
r(this, "serviceRole");
|
|
58
|
+
r(this, "setupInterceptorsFile");
|
|
59
|
+
r(this, "setupInterceptorsLine");
|
|
60
|
+
r(this, "logIgnoreRegex");
|
|
61
|
+
r(this, "captureRequestHeaders");
|
|
62
|
+
r(this, "captureResponseHeaders");
|
|
63
|
+
r(this, "captureRequestBody");
|
|
64
|
+
r(this, "captureResponseBody");
|
|
65
|
+
r(this, "requestBodyLimitBytes");
|
|
66
|
+
r(this, "responseBodyLimitBytes");
|
|
67
|
+
r(this, "retryOnClientError");
|
|
68
|
+
r(this, "_serviceIdentificationReceived", !1);
|
|
67
69
|
this.apiKey = e.apiKey, this.apiGraphqlEndpoint = e?.apiGraphqlEndpoint || process.env.SAILFISH_GRAPHQL_ENDPOINT || "https://api-service.sailfishqa.com/graphql/", this.sfDebug = e?.debug === !0 || process.env.SF_DEBUG === "true", this.serviceIdentifier = e?.serviceIdentifier || process.env.SERVICE_IDENTIFIER, this.serviceUUID = C(), this.serviceVersion = e?.serviceVersion || process.env.SERVICE_VERSION, this.gitSha = e?.gitSha || process.env.GIT_SHA || process.env.GITHUB_SHA || process.env.CI_COMMIT_SHA || process.env.BITBUCKET_COMMIT || process.env.VERCEL_GIT_COMMIT_SHA || process.env.CIRCLE_SHA1 || process.env.HEROKU_SLUG_COMMIT || process.env.RENDER_GIT_COMMIT || process.env.RAILWAY_GIT_COMMIT_SHA || process.env.CODEBUILD_RESOLVED_SOURCE_VERSION;
|
|
68
70
|
const t = process.env.GITHUB_REPOSITORY?.split("/");
|
|
69
|
-
this.gitOrg = e?.gitOrg || process.env.GIT_ORG || (t && t.length >= 2 ? t[0] : void 0) || process.env.CI_PROJECT_NAMESPACE || process.env.BITBUCKET_REPO_OWNER || process.env.VERCEL_GIT_REPO_OWNER || process.env.CIRCLE_PROJECT_USERNAME, this.gitRepo = e?.gitRepo || process.env.GIT_REPO || (t && t.length >= 2 ? t.slice(1).join("/") : void 0) || process.env.CI_PROJECT_NAME || process.env.BITBUCKET_REPO_SLUG || process.env.VERCEL_GIT_REPO_SLUG || process.env.CIRCLE_PROJECT_REPONAME, this.gitProvider = e?.gitProvider || process.env.GIT_PROVIDER || (process.env.GITHUB_ACTIONS ? "github" : void 0) || (process.env.GITLAB_CI ? "gitlab" : void 0) || (process.env.BITBUCKET_PIPELINE_UUID ? "bitbucket" : void 0) || (process.env.CIRCLECI ? "circleci" : void 0), this.serviceDisplayName = e?.serviceDisplayName || process.env.SERVICE_DISPLAY_NAME, this.serviceAdditionalMetadata = e?.serviceAdditionalMetadata || {}, this.profilingModeEnabled = e?.profilingModeEnabled ?? !1, this.profilingMaxDepth = e?.profilingMaxDepth ?? 5, this.profilingMaxVariableSizeKb = e?.profilingMaxVariableSizeKb ?? 25, this.domainsToNotPropagateHeadersTo = e?.domainsToNotPropagateHeadersTo || [], this.nodeModulesToCollectLocalVariablesOn = e?.nodeModulesToCollectLocalVariablesOn || ["_all_"], this.printConfigurationStatuses = process.env.PRINT_CONFIGURATION_STATUSES || "true", this.logLevel = process.env.LOG_LEVEL || "INFO", this.stackDepthLocals = process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS !== void 0 ? parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS, 10) : 5, isNaN(this.stackDepthLocals) && (this.stackDepthLocals = -1), this.stackDepthCodeTraceDepth = process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH !== void 0 ? parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH, 10) : -1, isNaN(this.stackDepthCodeTraceDepth) && (this.stackDepthCodeTraceDepth = -1), this.packageLibraryType = "JS/TS BACKEND", this.version = this.getPackageVersion();
|
|
70
|
-
const
|
|
71
|
+
this.gitOrg = e?.gitOrg || process.env.GIT_ORG || (t && t.length >= 2 ? t[0] : void 0) || process.env.CI_PROJECT_NAMESPACE || process.env.BITBUCKET_REPO_OWNER || process.env.VERCEL_GIT_REPO_OWNER || process.env.CIRCLE_PROJECT_USERNAME, this.gitRepo = e?.gitRepo || process.env.GIT_REPO || (t && t.length >= 2 ? t.slice(1).join("/") : void 0) || process.env.CI_PROJECT_NAME || process.env.BITBUCKET_REPO_SLUG || process.env.VERCEL_GIT_REPO_SLUG || process.env.CIRCLE_PROJECT_REPONAME, this.gitProvider = e?.gitProvider || process.env.GIT_PROVIDER || (process.env.GITHUB_ACTIONS ? "github" : void 0) || (process.env.GITLAB_CI ? "gitlab" : void 0) || (process.env.BITBUCKET_PIPELINE_UUID ? "bitbucket" : void 0) || (process.env.CIRCLECI ? "circleci" : void 0), this.serviceDisplayName = e?.serviceDisplayName || process.env.SERVICE_DISPLAY_NAME, this.serviceAdditionalMetadata = e?.serviceAdditionalMetadata || {}, this.profilingModeEnabled = e?.profilingModeEnabled ?? !1, this.profilingMaxDepth = e?.profilingMaxDepth ?? 5, this.profilingMaxVariableSizeKb = e?.profilingMaxVariableSizeKb ?? 25, this.domainsToNotPropagateHeadersTo = e?.domainsToNotPropagateHeadersTo || [], this.domainsToPropagateHeadersTo = e?.domainsToPropagateHeadersTo !== void 0 ? e.domainsToPropagateHeadersTo : ["*"], this.nodeModulesToCollectLocalVariablesOn = e?.nodeModulesToCollectLocalVariablesOn || ["_all_"], this.printConfigurationStatuses = process.env.PRINT_CONFIGURATION_STATUSES || "true", this.logLevel = process.env.LOG_LEVEL || "INFO", this.stackDepthLocals = process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS !== void 0 ? parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS, 10) : 5, isNaN(this.stackDepthLocals) && (this.stackDepthLocals = -1), this.stackDepthCodeTraceDepth = process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH !== void 0 ? parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH, 10) : -1, isNaN(this.stackDepthCodeTraceDepth) && (this.stackDepthCodeTraceDepth = -1), this.packageLibraryType = "JS/TS BACKEND", this.version = this.getPackageVersion();
|
|
72
|
+
const s = (function() {
|
|
71
73
|
return process.env.KUBERNETES_SERVICE_HOST || m("/var/run/secrets/kubernetes.io/serviceaccount/token") ? { type: "Kubernetes", details: { namespace: process.env.POD_NAMESPACE || "", podName: process.env.HOSTNAME || "", nodeName: process.env.NODE_NAME || "" } } : process.env.AWS_LAMBDA_FUNCTION_NAME ? { type: "AWS Lambda", details: { functionName: process.env.AWS_LAMBDA_FUNCTION_NAME || "", region: process.env.AWS_REGION || "", runtime: process.env.AWS_EXECUTION_ENV || "" } } : process.env.AWS_EXECUTION_ENV ? { type: "AWS", details: { executionEnv: process.env.AWS_EXECUTION_ENV || "", region: process.env.AWS_REGION || "" } } : process.env.GOOGLE_CLOUD_PROJECT ? { type: "Google Cloud", details: { project: process.env.GOOGLE_CLOUD_PROJECT || "" } } : process.env.AZURE_FUNCTIONS_ENVIRONMENT ? { type: "Azure Functions", details: { environment: process.env.AZURE_FUNCTIONS_ENVIRONMENT || "" } } : process.env.VERCEL ? { type: "Vercel", details: { env: process.env.VERCEL_ENV || "", region: process.env.VERCEL_REGION || "" } } : process.env.NETLIFY ? { type: "Netlify", details: {} } : process.env.FLY_APP_NAME ? { type: "Fly.io", details: { appName: process.env.FLY_APP_NAME || "", region: process.env.FLY_REGION || "" } } : process.env.RENDER_SERVICE_ID ? { type: "Render", details: { serviceId: process.env.RENDER_SERVICE_ID || "" } } : process.env.RAILWAY_ENVIRONMENT ? { type: "Railway", details: { environment: process.env.RAILWAY_ENVIRONMENT || "" } } : m("/.dockerenv") ? { type: "Docker", details: {} } : { type: "Unknown", details: { os: N.platform(), arch: N.arch(), nodeVersion: process.version } };
|
|
72
74
|
})();
|
|
73
|
-
this.infrastructureType =
|
|
75
|
+
this.infrastructureType = s.type, this.infrastructureDetails = s.details;
|
|
74
76
|
const o = (function() {
|
|
75
|
-
const
|
|
76
|
-
for (const { pkg:
|
|
77
|
-
require.resolve(
|
|
77
|
+
const b = [{ pkg: "@nestjs/core", name: "nestjs" }, { pkg: "@apollo/server", name: "apollo-server" }, { pkg: "apollo-server", name: "apollo-server" }, { pkg: "mercurius", name: "mercurius" }, { pkg: "next", name: "nextjs" }, { pkg: "nuxt", name: "nuxtjs" }, { pkg: "express", name: "express" }, { pkg: "fastify", name: "fastify" }, { pkg: "koa", name: "koa" }, { pkg: "@hapi/hapi", name: "hapi" }, { pkg: "hono", name: "hono" }], E = [], g = /* @__PURE__ */ new Set();
|
|
78
|
+
for (const { pkg: I, name: S } of b) if (!g.has(S)) try {
|
|
79
|
+
require.resolve(I), E.push(S), g.add(S);
|
|
78
80
|
} catch {
|
|
79
81
|
}
|
|
80
82
|
if (typeof process < "u") {
|
|
81
|
-
if (!
|
|
82
|
-
let
|
|
83
|
+
if (!g.has("nuxtjs") && globalThis._importMeta_ !== void 0) {
|
|
84
|
+
let I = !1;
|
|
83
85
|
try {
|
|
84
|
-
(globalThis._importMeta_?.url || "").includes(".output/server") && (
|
|
86
|
+
(globalThis._importMeta_?.url || "").includes(".output/server") && (I = !0);
|
|
85
87
|
} catch {
|
|
86
88
|
}
|
|
87
|
-
|
|
89
|
+
I && (E.unshift("nuxtjs"), g.add("nuxtjs"));
|
|
88
90
|
}
|
|
89
|
-
!
|
|
91
|
+
!g.has("meteorjs") && process.env.METEOR_SHELL_DIR && (E.unshift("meteorjs"), g.add("meteorjs"));
|
|
90
92
|
}
|
|
91
|
-
return { framework:
|
|
93
|
+
return { framework: E.length > 0 ? E[0] : null, additionalFrameworks: E.slice(1), serviceRole: E.includes("nextjs") || E.includes("nuxtjs") ? "fullstack" : "backend" };
|
|
92
94
|
})();
|
|
93
95
|
this.framework = o.framework ?? void 0, this.additionalFrameworks = o.additionalFrameworks, this.serviceRole = o.serviceRole;
|
|
94
96
|
const i = process.env.SF_LOG_IGNORE_REGEX;
|
|
@@ -101,6 +103,8 @@ class F {
|
|
|
101
103
|
this.requestBodyLimitBytes = 1024 * (isNaN(c) ? 1 : c) * 1024;
|
|
102
104
|
const p = parseInt(process.env.SF_NETWORKHOP_RESPONSE_LIMIT_MB || "1", 10);
|
|
103
105
|
this.responseBodyLimitBytes = 1024 * (isNaN(p) ? 1 : p) * 1024;
|
|
106
|
+
const u = (process.env.SF_RETRY_ON_CLIENT_ERROR || "").toLowerCase(), M = u === "all" || u === "idempotent" || u === "none" ? u : void 0;
|
|
107
|
+
this.retryOnClientError = M ?? e.retryOnClientError ?? "all";
|
|
104
108
|
}
|
|
105
109
|
getPackageVersion() {
|
|
106
110
|
return "0.2.14";
|
|
@@ -112,33 +116,33 @@ class F {
|
|
|
112
116
|
this._serviceIdentificationReceived = e;
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
|
-
async function
|
|
119
|
+
async function q(n) {
|
|
116
120
|
if (!(n.gitOrg && n.gitRepo && n.gitProvider)) try {
|
|
117
121
|
const e = await (async function() {
|
|
118
122
|
let t = "";
|
|
119
123
|
try {
|
|
120
|
-
t = await new Promise((
|
|
121
|
-
|
|
122
|
-
i ? o(i) :
|
|
124
|
+
t = await new Promise((s, o) => {
|
|
125
|
+
V("git", ["remote", "get-url", "origin"], { timeout: 3e3 }, (i, c) => {
|
|
126
|
+
i ? o(i) : s((c || "").trim());
|
|
123
127
|
});
|
|
124
128
|
});
|
|
125
129
|
} catch {
|
|
126
130
|
try {
|
|
127
|
-
const
|
|
128
|
-
|
|
131
|
+
const s = (await k.readFile(".git/config", "utf-8")).match(/\[remote "origin"\][^[]*url\s*=\s*(.+)/m);
|
|
132
|
+
s && (t = s[1].trim());
|
|
129
133
|
} catch {
|
|
130
134
|
}
|
|
131
135
|
}
|
|
132
|
-
return t ? (function(
|
|
136
|
+
return t ? (function(s) {
|
|
133
137
|
let o, i, c;
|
|
134
|
-
if (
|
|
135
|
-
const p =
|
|
138
|
+
if (s.includes("github.com") ? o = "github" : s.includes("gitlab.com") ? o = "gitlab" : s.includes("bitbucket.org") && (o = "bitbucket"), s.startsWith("https://") || s.startsWith("http://")) {
|
|
139
|
+
const p = s.split("/");
|
|
136
140
|
p.length >= 5 && (i = p[3], c = p[4].replace(/\.git$/, ""));
|
|
137
141
|
} else {
|
|
138
|
-
const p =
|
|
142
|
+
const p = s.indexOf(":");
|
|
139
143
|
if (p > 0) {
|
|
140
|
-
const
|
|
141
|
-
|
|
144
|
+
const u = s.substring(p + 1).replace(/\.git$/, "").split("/");
|
|
145
|
+
u.length >= 2 && (i = u[0], c = u[1]);
|
|
142
146
|
}
|
|
143
147
|
}
|
|
144
148
|
return { org: i, repo: c, provider: o };
|
|
@@ -148,24 +152,24 @@ async function j(n) {
|
|
|
148
152
|
} catch {
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
|
-
const
|
|
155
|
+
const U = Symbol.for("sailfish.sf_config");
|
|
152
156
|
function x() {
|
|
153
|
-
return globalThis[
|
|
157
|
+
return globalThis[U];
|
|
154
158
|
}
|
|
155
|
-
function
|
|
159
|
+
function X(n) {
|
|
156
160
|
const e = x();
|
|
157
161
|
if (e) return { config: e };
|
|
158
|
-
const t = new
|
|
159
|
-
return (function(
|
|
160
|
-
globalThis[
|
|
162
|
+
const t = new w(n);
|
|
163
|
+
return (function(s) {
|
|
164
|
+
globalThis[U] = s;
|
|
161
165
|
})(t), t.sfDebug && console.log("[[getOrCreateConfig]] Created global config:", t), { config: t };
|
|
162
166
|
}
|
|
163
|
-
function
|
|
167
|
+
function f() {
|
|
164
168
|
const n = x();
|
|
165
169
|
if (!n) throw new Error("Configuration has not been initialized. Call getOrCreateConfig(options) first.");
|
|
166
170
|
return n;
|
|
167
171
|
}
|
|
168
|
-
const D = Symbol.for("sf.ctx.storeAls"),
|
|
172
|
+
const D = Symbol.for("sf.ctx.storeAls"), d = globalThis, O = d[D] ?? (d[D] = new P()), B = ["identitytoolkit.googleapis.com", "t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com"], L = Symbol.for("sf.ctx.als"), v = d[L] ?? (d[L] = new P()), y = Symbol.for("sf.ctx.sessionRegistry"), _ = d[y] ?? (d[y] = /* @__PURE__ */ new Map()), h = { handledExceptions: /* @__PURE__ */ new Set(), reentrancyGuardLoggingActive: !1, reentrancyGuardLoggingPreActive: !1, reentrancyGuardPrintActive: !1, reentrancyGuardPrintPreActive: !1, reentrancyGuardExceptionActive: !1, reentrancyGuardExceptionPreActive: !1, excludedDomains: new Set(B), supportedDomains: /* @__PURE__ */ new Set() }, l = class l {
|
|
169
173
|
constructor() {
|
|
170
174
|
}
|
|
171
175
|
current() {
|
|
@@ -178,34 +182,34 @@ const D = Symbol.for("sf.ctx.storeAls"), u = globalThis, O = u[D] ?? (u[D] = new
|
|
|
178
182
|
return O.enterWith(t), t;
|
|
179
183
|
}
|
|
180
184
|
runWith(e, t) {
|
|
181
|
-
const
|
|
185
|
+
const s = this.current() ?? /* @__PURE__ */ new Map(), o = new Map(s);
|
|
182
186
|
for (const [i, c] of Object.entries(e)) o.set(i, c);
|
|
183
187
|
return O.run(o, t);
|
|
184
188
|
}
|
|
185
189
|
static getInstance() {
|
|
186
|
-
return
|
|
190
|
+
return d[l.GLOBAL_MANAGER_SYMBOL] || (d[l.GLOBAL_MANAGER_SYMBOL] = new l()), d[l.GLOBAL_MANAGER_SYMBOL];
|
|
187
191
|
}
|
|
188
192
|
getCurrentContext() {
|
|
189
|
-
return
|
|
193
|
+
return v.getStore() || h;
|
|
190
194
|
}
|
|
191
195
|
setCurrentContext(e) {
|
|
192
|
-
const t =
|
|
193
|
-
|
|
196
|
+
const t = v.getStore() || h;
|
|
197
|
+
v.enterWith({ ...t, ...e });
|
|
194
198
|
}
|
|
195
199
|
ensureSession(e) {
|
|
196
200
|
let t = _.get(e);
|
|
197
|
-
return t || (t = { ...
|
|
201
|
+
return t || (t = { ...h }, _.set(e, t)), t;
|
|
198
202
|
}
|
|
199
203
|
getContextFor(e) {
|
|
200
|
-
return _.get(e) ??
|
|
204
|
+
return _.get(e) ?? h;
|
|
201
205
|
}
|
|
202
206
|
updateContextFor(e, t) {
|
|
203
|
-
const
|
|
204
|
-
_.set(e, { ...
|
|
207
|
+
const s = this.ensureSession(e);
|
|
208
|
+
_.set(e, { ...s, ...t });
|
|
205
209
|
}
|
|
206
210
|
runWithSession(e, t) {
|
|
207
|
-
const
|
|
208
|
-
return
|
|
211
|
+
const s = { ...this.ensureSession(e) };
|
|
212
|
+
return v.run(s, t);
|
|
209
213
|
}
|
|
210
214
|
deleteSession(e) {
|
|
211
215
|
_.delete(e);
|
|
@@ -232,12 +236,12 @@ const D = Symbol.for("sf.ctx.storeAls"), u = globalThis, O = u[D] ?? (u[D] = new
|
|
|
232
236
|
this.setCurrentContext({ currentFunctionSpanId: void 0 });
|
|
233
237
|
}
|
|
234
238
|
getOrSetSfTraceId(e, t = !1) {
|
|
235
|
-
let
|
|
236
|
-
return
|
|
239
|
+
let s = this.getTraceId();
|
|
240
|
+
return s || (s = e || (t ? C() : `nonsession-applogs-v3/${f().apiKey}/${C()}`), this.setTraceId(s), f().sfDebug && console.log(" Created new trace ID:", s), s);
|
|
237
241
|
}
|
|
238
242
|
getOrSetPageVisitUUID() {
|
|
239
243
|
let e = this.getPageVisitUUID();
|
|
240
|
-
return e || (e = C(), this.setPageVisitUUID(e),
|
|
244
|
+
return e || (e = C(), this.setPageVisitUUID(e), f().sfDebug && console.log(" Created new page visit UUID:", e), e);
|
|
241
245
|
}
|
|
242
246
|
getHandledExceptions() {
|
|
243
247
|
return this.getCurrentContext().handledExceptions;
|
|
@@ -268,25 +272,25 @@ const D = Symbol.for("sf.ctx.storeAls"), u = globalThis, O = u[D] ?? (u[D] = new
|
|
|
268
272
|
this.updateContextFor(e, { pageVisitUUID: t });
|
|
269
273
|
}
|
|
270
274
|
};
|
|
271
|
-
|
|
272
|
-
let
|
|
273
|
-
function
|
|
274
|
-
const e = { ...
|
|
275
|
-
|
|
275
|
+
r(l, "GLOBAL_MANAGER_SYMBOL", Symbol.for("sf.ctx.manager"));
|
|
276
|
+
let R = l;
|
|
277
|
+
function z(n) {
|
|
278
|
+
const e = { ...R.getInstance().getCurrentContext() };
|
|
279
|
+
v.run(e, () => {
|
|
276
280
|
n();
|
|
277
281
|
});
|
|
278
282
|
}
|
|
279
|
-
function
|
|
280
|
-
return
|
|
283
|
+
function J() {
|
|
284
|
+
return R.getInstance().getCurrentFunctionSpanId();
|
|
281
285
|
}
|
|
282
286
|
export {
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
R as C,
|
|
288
|
+
B as D,
|
|
285
289
|
x as a,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
J as b,
|
|
291
|
+
X as c,
|
|
292
|
+
q as d,
|
|
293
|
+
f as g,
|
|
294
|
+
z as r,
|
|
291
295
|
C as v
|
|
292
296
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const L=require("async_hooks"),G=require("child_process"),O=require("fs"),H=require("fs/promises"),V=require("os");function P(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const F=P(H),m=P(V),i=[];for(let s=0;s<256;++s)i.push((s+256).toString(16).slice(1));let R;const k=new Uint8Array(16),N={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function I(s,e,t){if(N.randomUUID&&!s)return N.randomUUID();const r=(s=s||{}).random??s.rng?.()??(function(){if(!R){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");R=crypto.getRandomValues.bind(crypto)}return R(k)})();if(r.length<16)throw new Error("Random bytes length must be >= 16");return r[6]=15&r[6]|64,r[8]=63&r[8]|128,(function(n,o=0){return(i[n[o+0]]+i[n[o+1]]+i[n[o+2]]+i[n[o+3]]+"-"+i[n[o+4]]+i[n[o+5]]+"-"+i[n[o+6]]+i[n[o+7]]+"-"+i[n[o+8]]+i[n[o+9]]+"-"+i[n[o+10]]+i[n[o+11]]+i[n[o+12]]+i[n[o+13]]+i[n[o+14]]+i[n[o+15]]).toLowerCase()})(r)}class w{apiKey;apiGraphqlEndpoint;sfDebug;serviceIdentifier;serviceVersion;serviceUUID;serviceAdditionalMetadata;profilingModeEnabled;profilingMaxDepth;profilingMaxVariableSizeKb;domainsToNotPropagateHeadersTo;domainsToPropagateHeadersTo;nodeModulesToCollectLocalVariablesOn;printConfigurationStatuses;logLevel;stackDepthLocals;stackDepthCodeTraceDepth;packageLibraryType;version;gitSha;gitOrg;gitRepo;gitProvider;serviceDisplayName;infrastructureType;infrastructureDetails;framework;additionalFrameworks;serviceRole;setupInterceptorsFile;setupInterceptorsLine;logIgnoreRegex;captureRequestHeaders;captureResponseHeaders;captureRequestBody;captureResponseBody;requestBodyLimitBytes;responseBodyLimitBytes;retryOnClientError;_serviceIdentificationReceived=!1;constructor(e){this.apiKey=e.apiKey,this.apiGraphqlEndpoint=e?.apiGraphqlEndpoint||process.env.SAILFISH_GRAPHQL_ENDPOINT||"https://api-service.sailfishqa.com/graphql/",this.sfDebug=e?.debug===!0||process.env.SF_DEBUG==="true",this.serviceIdentifier=e?.serviceIdentifier||process.env.SERVICE_IDENTIFIER,this.serviceUUID=I(),this.serviceVersion=e?.serviceVersion||process.env.SERVICE_VERSION,this.gitSha=e?.gitSha||process.env.GIT_SHA||process.env.GITHUB_SHA||process.env.CI_COMMIT_SHA||process.env.BITBUCKET_COMMIT||process.env.VERCEL_GIT_COMMIT_SHA||process.env.CIRCLE_SHA1||process.env.HEROKU_SLUG_COMMIT||process.env.RENDER_GIT_COMMIT||process.env.RAILWAY_GIT_COMMIT_SHA||process.env.CODEBUILD_RESOLVED_SOURCE_VERSION;const t=process.env.GITHUB_REPOSITORY?.split("/");this.gitOrg=e?.gitOrg||process.env.GIT_ORG||(t&&t.length>=2?t[0]:void 0)||process.env.CI_PROJECT_NAMESPACE||process.env.BITBUCKET_REPO_OWNER||process.env.VERCEL_GIT_REPO_OWNER||process.env.CIRCLE_PROJECT_USERNAME,this.gitRepo=e?.gitRepo||process.env.GIT_REPO||(t&&t.length>=2?t.slice(1).join("/"):void 0)||process.env.CI_PROJECT_NAME||process.env.BITBUCKET_REPO_SLUG||process.env.VERCEL_GIT_REPO_SLUG||process.env.CIRCLE_PROJECT_REPONAME,this.gitProvider=e?.gitProvider||process.env.GIT_PROVIDER||(process.env.GITHUB_ACTIONS?"github":void 0)||(process.env.GITLAB_CI?"gitlab":void 0)||(process.env.BITBUCKET_PIPELINE_UUID?"bitbucket":void 0)||(process.env.CIRCLECI?"circleci":void 0),this.serviceDisplayName=e?.serviceDisplayName||process.env.SERVICE_DISPLAY_NAME,this.serviceAdditionalMetadata=e?.serviceAdditionalMetadata||{},this.profilingModeEnabled=e?.profilingModeEnabled??!1,this.profilingMaxDepth=e?.profilingMaxDepth??5,this.profilingMaxVariableSizeKb=e?.profilingMaxVariableSizeKb??25,this.domainsToNotPropagateHeadersTo=e?.domainsToNotPropagateHeadersTo||[],this.domainsToPropagateHeadersTo=e?.domainsToPropagateHeadersTo!==void 0?e.domainsToPropagateHeadersTo:["*"],this.nodeModulesToCollectLocalVariablesOn=e?.nodeModulesToCollectLocalVariablesOn||["_all_"],this.printConfigurationStatuses=process.env.PRINT_CONFIGURATION_STATUSES||"true",this.logLevel=process.env.LOG_LEVEL||"INFO",this.stackDepthLocals=process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS!==void 0?parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS,10):5,isNaN(this.stackDepthLocals)&&(this.stackDepthLocals=-1),this.stackDepthCodeTraceDepth=process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH!==void 0?parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH,10):-1,isNaN(this.stackDepthCodeTraceDepth)&&(this.stackDepthCodeTraceDepth=-1),this.packageLibraryType="JS/TS BACKEND",this.version=this.getPackageVersion();const r=(function(){return process.env.KUBERNETES_SERVICE_HOST||O.existsSync("/var/run/secrets/kubernetes.io/serviceaccount/token")?{type:"Kubernetes",details:{namespace:process.env.POD_NAMESPACE||"",podName:process.env.HOSTNAME||"",nodeName:process.env.NODE_NAME||""}}:process.env.AWS_LAMBDA_FUNCTION_NAME?{type:"AWS Lambda",details:{functionName:process.env.AWS_LAMBDA_FUNCTION_NAME||"",region:process.env.AWS_REGION||"",runtime:process.env.AWS_EXECUTION_ENV||""}}:process.env.AWS_EXECUTION_ENV?{type:"AWS",details:{executionEnv:process.env.AWS_EXECUTION_ENV||"",region:process.env.AWS_REGION||""}}:process.env.GOOGLE_CLOUD_PROJECT?{type:"Google Cloud",details:{project:process.env.GOOGLE_CLOUD_PROJECT||""}}:process.env.AZURE_FUNCTIONS_ENVIRONMENT?{type:"Azure Functions",details:{environment:process.env.AZURE_FUNCTIONS_ENVIRONMENT||""}}:process.env.VERCEL?{type:"Vercel",details:{env:process.env.VERCEL_ENV||"",region:process.env.VERCEL_REGION||""}}:process.env.NETLIFY?{type:"Netlify",details:{}}:process.env.FLY_APP_NAME?{type:"Fly.io",details:{appName:process.env.FLY_APP_NAME||"",region:process.env.FLY_REGION||""}}:process.env.RENDER_SERVICE_ID?{type:"Render",details:{serviceId:process.env.RENDER_SERVICE_ID||""}}:process.env.RAILWAY_ENVIRONMENT?{type:"Railway",details:{environment:process.env.RAILWAY_ENVIRONMENT||""}}:O.existsSync("/.dockerenv")?{type:"Docker",details:{}}:{type:"Unknown",details:{os:m.platform(),arch:m.arch(),nodeVersion:process.version}}})();this.infrastructureType=r.type,this.infrastructureDetails=r.details;const n=(function(){const b=[{pkg:"@nestjs/core",name:"nestjs"},{pkg:"@apollo/server",name:"apollo-server"},{pkg:"apollo-server",name:"apollo-server"},{pkg:"mercurius",name:"mercurius"},{pkg:"next",name:"nextjs"},{pkg:"nuxt",name:"nuxtjs"},{pkg:"express",name:"express"},{pkg:"fastify",name:"fastify"},{pkg:"koa",name:"koa"},{pkg:"@hapi/hapi",name:"hapi"},{pkg:"hono",name:"hono"}],d=[],g=new Set;for(const{pkg:v,name:S}of b)if(!g.has(S))try{require.resolve(v),d.push(S),g.add(S)}catch{}if(typeof process<"u"){if(!g.has("nuxtjs")&&globalThis._importMeta_!==void 0){let v=!1;try{(globalThis._importMeta_?.url||"").includes(".output/server")&&(v=!0)}catch{}v&&(d.unshift("nuxtjs"),g.add("nuxtjs"))}!g.has("meteorjs")&&process.env.METEOR_SHELL_DIR&&(d.unshift("meteorjs"),g.add("meteorjs"))}return{framework:d.length>0?d[0]:null,additionalFrameworks:d.slice(1),serviceRole:d.includes("nextjs")||d.includes("nuxtjs")?"fullstack":"backend"}})();this.framework=n.framework??void 0,this.additionalFrameworks=n.additionalFrameworks,this.serviceRole=n.serviceRole;const o=process.env.SF_LOG_IGNORE_REGEX;if(o)try{this.logIgnoreRegex=new RegExp(o)}catch{}this.captureRequestHeaders=process.env.SF_NETWORKHOP_CAPTURE_REQUEST_HEADERS==="true",this.captureResponseHeaders=process.env.SF_NETWORKHOP_CAPTURE_RESPONSE_HEADERS==="true",this.captureRequestBody=process.env.SF_NETWORKHOP_CAPTURE_REQUEST_BODY==="true",this.captureResponseBody=process.env.SF_NETWORKHOP_CAPTURE_RESPONSE_BODY==="true";const a=parseInt(process.env.SF_NETWORKHOP_REQUEST_LIMIT_MB||"1",10);this.requestBodyLimitBytes=1024*(isNaN(a)?1:a)*1024;const c=parseInt(process.env.SF_NETWORKHOP_RESPONSE_LIMIT_MB||"1",10);this.responseBodyLimitBytes=1024*(isNaN(c)?1:c)*1024;const u=(process.env.SF_RETRY_ON_CLIENT_ERROR||"").toLowerCase(),x=u==="all"||u==="idempotent"||u==="none"?u:void 0;this.retryOnClientError=x??e.retryOnClientError??"all"}getPackageVersion(){return"0.2.14"}get serviceIdentificationReceived(){return this._serviceIdentificationReceived}setServiceIdentificationReceived(e){this._serviceIdentificationReceived=e}}const U=Symbol.for("sailfish.sf_config");function T(){return globalThis[U]}function C(){const s=T();if(!s)throw new Error("Configuration has not been initialized. Call getOrCreateConfig(options) first.");return s}const A=Symbol.for("sf.ctx.storeAls"),p=globalThis,f=p[A]??(p[A]=new L.AsyncLocalStorage),M=["identitytoolkit.googleapis.com","t.co","*.twitter.com","*.gravatar.com","*.googleapis.com","*.amazonaws.com","*.smooch.io","*.zendesk.com"],D=Symbol.for("sf.ctx.als"),_=p[D]??(p[D]=new L.AsyncLocalStorage),y=Symbol.for("sf.ctx.sessionRegistry"),E=p[y]??(p[y]=new Map),h={handledExceptions:new Set,reentrancyGuardLoggingActive:!1,reentrancyGuardLoggingPreActive:!1,reentrancyGuardPrintActive:!1,reentrancyGuardPrintPreActive:!1,reentrancyGuardExceptionActive:!1,reentrancyGuardExceptionPreActive:!1,excludedDomains:new Set(M),supportedDomains:new Set};class l{static GLOBAL_MANAGER_SYMBOL=Symbol.for("sf.ctx.manager");constructor(){}current(){return f.getStore()}ensureStore(){const e=this.current();if(e)return e;const t=new Map;return f.enterWith(t),t}runWith(e,t){const r=this.current()??new Map,n=new Map(r);for(const[o,a]of Object.entries(e))n.set(o,a);return f.run(n,t)}static getInstance(){return p[l.GLOBAL_MANAGER_SYMBOL]||(p[l.GLOBAL_MANAGER_SYMBOL]=new l),p[l.GLOBAL_MANAGER_SYMBOL]}getCurrentContext(){return _.getStore()||h}setCurrentContext(e){const t=_.getStore()||h;_.enterWith({...t,...e})}ensureSession(e){let t=E.get(e);return t||(t={...h},E.set(e,t)),t}getContextFor(e){return E.get(e)??h}updateContextFor(e,t){const r=this.ensureSession(e);E.set(e,{...r,...t})}runWithSession(e,t){const r={...this.ensureSession(e)};return _.run(r,t)}deleteSession(e){E.delete(e)}getTraceId(){return this.getCurrentContext().traceId}getPageVisitUUID(){return this.getCurrentContext().pageVisitUUID}setTraceId(e){this.setCurrentContext({traceId:e})}setPageVisitUUID(e){this.setCurrentContext({pageVisitUUID:e})}getCurrentFunctionSpanId(){return this.getCurrentContext().currentFunctionSpanId}setCurrentFunctionSpanId(e){this.setCurrentContext({currentFunctionSpanId:e})}clearCurrentFunctionSpanId(){this.setCurrentContext({currentFunctionSpanId:void 0})}getOrSetSfTraceId(e,t=!1){let r=this.getTraceId();return r||(r=e||(t?I():`nonsession-applogs-v3/${C().apiKey}/${I()}`),this.setTraceId(r),C().sfDebug&&console.log(" Created new trace ID:",r),r)}getOrSetPageVisitUUID(){let e=this.getPageVisitUUID();return e||(e=I(),this.setPageVisitUUID(e),C().sfDebug&&console.log(" Created new page visit UUID:",e),e)}getHandledExceptions(){return this.getCurrentContext().handledExceptions}markExceptionHandled(e){const t=this.getHandledExceptions();t.add(e),this.setCurrentContext({handledExceptions:t})}hasHandledException(e){return this.getHandledExceptions().has(e)}resetHandledExceptions(){this.setCurrentContext({handledExceptions:new Set})}getExcludedDomains(){return this.getCurrentContext().excludedDomains}getSupportedDomains(){return this.getCurrentContext().supportedDomains}addSupportedDomains(e){this.getCurrentContext().supportedDomains.add(e.toLowerCase().trim())}setTraceIdFor(e,t){this.updateContextFor(e,{traceId:t})}setPageVisitUUIDFor(e,t){this.updateContextFor(e,{pageVisitUUID:t})}}exports.ContextManager=l,exports.DEFAULT_DOMAINS_TO_EXCLUDE=M,exports.backfillGitInfoAsync=async function(s){if(!(s.gitOrg&&s.gitRepo&&s.gitProvider))try{const e=await(async function(){let t="";try{t=await new Promise((r,n)=>{G.execFile("git",["remote","get-url","origin"],{timeout:3e3},(o,a)=>{o?n(o):r((a||"").trim())})})}catch{try{const r=(await F.readFile(".git/config","utf-8")).match(/\[remote "origin"\][^[]*url\s*=\s*(.+)/m);r&&(t=r[1].trim())}catch{}}return t?(function(r){let n,o,a;if(r.includes("github.com")?n="github":r.includes("gitlab.com")?n="gitlab":r.includes("bitbucket.org")&&(n="bitbucket"),r.startsWith("https://")||r.startsWith("http://")){const c=r.split("/");c.length>=5&&(o=c[3],a=c[4].replace(/\.git$/,""))}else{const c=r.indexOf(":");if(c>0){const u=r.substring(c+1).replace(/\.git$/,"").split("/");u.length>=2&&(o=u[0],a=u[1])}}return{org:o,repo:a,provider:n}})(t):{}})();s.gitOrg||(s.gitOrg=e.org),s.gitRepo||(s.gitRepo=e.repo),s.gitProvider||(s.gitProvider=e.provider)}catch{}},exports.getConfig=C,exports.getCurrentFunctionSpanId=function(){return l.getInstance().getCurrentFunctionSpanId()},exports.getGlobalConfigUnsafe=T,exports.getOrCreateConfig=function(s){const e=T();if(e)return{config:e};const t=new w(s);return(function(r){globalThis[U]=r})(t),t.sfDebug&&console.log("[[getOrCreateConfig]] Created global config:",t),{config:t}},exports.runWithContext=function(s){const e={...l.getInstance().getCurrentContext()};_.run(e,()=>{s()})},exports.v4=I;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("fs"),p=require("../funcSpanTransformer-D0W2t41q.cjs"),f=require("../consoleLocationTransformer-BSSB5msZ.cjs"),h=require("../runtimeConfig-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("fs"),p=require("../funcSpanTransformer-D0W2t41q.cjs"),f=require("../consoleLocationTransformer-BSSB5msZ.cjs"),h=require("../runtimeConfig-C4_zc4Zg.cjs");function d(a={}){try{if(h.shouldEnableRuntimeHooks())return console.warn("[FuncSpan Esbuild Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"),{name:"sailfish-funcspan-esbuild-disabled",setup(){}}}catch{}const{enabled:r=!0,includeNodeModules:i=[],debug:s=!1}=a;return{name:"sailfish-funcspan-esbuild",setup(u){r&&(u.onLoad({filter:/\.(js|ts|jsx|tsx)$/},async e=>{if(e.path.includes("node_modules")&&!i.some(n=>e.path.includes(`node_modules/${n}`))||e.path.includes("@sailfish-ai/sf-veritas")||e.path.includes("jsts-backend/dist"))return null;try{let n=c.readFileSync(e.path,"utf-8"),o=!1;const t=await p.transformFunctionSpans(n,e.path,{projectRoot:process.cwd(),includeNodeModules:i,debug:s});t.modified&&(n=t.code,o=!0);const l=await f.transformConsoleLocations(n,e.path,{projectRoot:process.cwd(),includeNodeModules:i,debug:s});if(l.modified&&(n=l.code,o=!0),o)return{contents:n,loader:e.path.endsWith(".ts")||e.path.endsWith(".tsx")?"ts":"js"}}catch(n){s&&console.error(`[FuncSpan Esbuild] Error transforming ${e.path}:`,n)}return null}),s&&console.log("[FuncSpan Esbuild] Plugin initialized"))}}}exports.default=d,exports.funcspanEsbuildPlugin=d;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync as r } from "fs";
|
|
2
2
|
import { t as c } from "../funcSpanTransformer-S_WeAt_m.js";
|
|
3
3
|
import { t as p } from "../consoleLocationTransformer-DZu_9MDA.js";
|
|
4
|
-
import { s as f } from "../runtimeConfig-
|
|
4
|
+
import { s as f } from "../runtimeConfig-ButdW4zP.js";
|
|
5
5
|
function j(a = {}) {
|
|
6
6
|
try {
|
|
7
7
|
if (f()) return console.warn("[FuncSpan Esbuild Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"), { name: "sailfish-funcspan-esbuild-disabled", setup() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const f=require("../funcSpanTransformer-D0W2t41q.cjs"),p=require("../consoleLocationTransformer-BSSB5msZ.cjs"),m=require("../runtimeConfig-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const f=require("../funcSpanTransformer-D0W2t41q.cjs"),p=require("../consoleLocationTransformer-BSSB5msZ.cjs"),m=require("../runtimeConfig-C4_zc4Zg.cjs");function d(a={}){try{if(m.shouldEnableRuntimeHooks())return console.warn("[FuncSpan Rollup Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"),{name:"sailfish-funcspan-rollup-disabled"}}catch{}const{enabled:c=!0,includeNodeModules:o=[],debug:u=!1}=a;return{name:"sailfish-funcspan-rollup",async transform(s,n){if(!c||!n.match(/\.(js|ts|jsx|tsx)$/)||n.includes("node_modules")&&!o.some(e=>n.includes(`node_modules/${e}`))||n.includes("@sailfish-ai/sf-veritas")||n.includes("jsts-backend/dist"))return null;try{let e=s,l=null,r=!1;const t=await f.transformFunctionSpans(e,n,{projectRoot:process.cwd(),includeNodeModules:o,debug:u});t.modified&&(e=t.code,l=t.map,r=!0);const i=await p.transformConsoleLocations(e,n,{projectRoot:process.cwd(),includeNodeModules:o,debug:u});if(i.modified&&(e=i.code,l=i.map,r=!0),r)return{code:e,map:l||null}}catch(e){u&&console.error(`[FuncSpan Rollup] Error transforming ${n}:`,e)}return null}}}exports.default=d,exports.funcspanRollupPlugin=d;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as c } from "../funcSpanTransformer-S_WeAt_m.js";
|
|
2
2
|
import { t as p } from "../consoleLocationTransformer-DZu_9MDA.js";
|
|
3
|
-
import { s as f } from "../runtimeConfig-
|
|
3
|
+
import { s as f } from "../runtimeConfig-ButdW4zP.js";
|
|
4
4
|
function h(r = {}) {
|
|
5
5
|
try {
|
|
6
6
|
if (f()) return console.warn("[FuncSpan Rollup Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"), { name: "sailfish-funcspan-rollup-disabled" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("fs"),T=require("glob"),y=require("path"),D=require("../funcSpanTransformer-D0W2t41q.cjs"),b=require("../consoleLocationTransformer-BSSB5msZ.cjs"),v=require("../runtimeConfig-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("fs"),T=require("glob"),y=require("path"),D=require("../funcSpanTransformer-D0W2t41q.cjs"),b=require("../consoleLocationTransformer-BSSB5msZ.cjs"),v=require("../runtimeConfig-C4_zc4Zg.cjs");async function C(n={}){try{if(v.shouldEnableRuntimeHooks())return void console.warn("[FuncSpan TSC Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation")}catch{}const{outDir:N="dist",include:_=["**/*.js"],exclude:m=["**/*.test.js","**/*.spec.js","**/__tests__/**"],projectRoot:c=process.cwd(),includeNodeModules:d=[],debug:s=!1}=n,p=y.resolve(c,N);console.log("[FuncSpan TSC] Starting post-build function instrumentation..."),console.log(`[FuncSpan TSC] Output directory: ${p}`),console.log(`[FuncSpan TSC] Project root: ${c}`);const i=[];for(const o of _){const e=T.sync(o,{cwd:p,absolute:!0,ignore:m});i.push(...e)}console.log(`[FuncSpan TSC] Found ${i.length} JavaScript files to process`);let S=0,f=0;for(const o of i)try{let e=a.readFileSync(o,"utf-8"),r=null,u=!1;const t=await D.transformFunctionSpans(e,o,{projectRoot:c,includeNodeModules:d,debug:s});t.modified&&(e=t.code,r=t.map,u=!0);const l=await b.transformConsoleLocations(e,o,{projectRoot:c,includeNodeModules:d,debug:s});if(l.modified&&(e=l.code,r=l.map,u=!0),u){if(a.writeFileSync(o,e,"utf-8"),r){const F=`${o}.map`;a.writeFileSync(F,JSON.stringify(r),"utf-8"),s&&console.log(`[FuncSpan TSC] Generated source map: ${F}`)}S++,f+=t.functionsWrapped,s&&console.log(`[FuncSpan TSC] Modified: ${o} (${t.functionsWrapped} functions)`)}}catch(e){console.error(`[FuncSpan TSC] Error processing ${o}:`,e)}console.log(`[FuncSpan TSC] ✅ Completed: Modified ${S} files, wrapped ${f} functions`)}async function g(){const n={outDir:process.env.SF_FUNCSPAN_OUT_DIR||"dist",debug:process.env.SF_FUNCSPAN_DEBUG==="true",includeNodeModules:process.env.SF_FUNCSPAN_INCLUDE_NODE_MODULES?process.env.SF_FUNCSPAN_INCLUDE_NODE_MODULES.split(","):[]};await C(n)}require.main===module&&g().catch(n=>{console.error("[FuncSpan TSC] Fatal error:",n),process.exit(1)}),exports.cli=g,exports.processTscFiles=C;
|
|
@@ -3,7 +3,7 @@ import { sync as _ } from "glob";
|
|
|
3
3
|
import { resolve as D } from "path";
|
|
4
4
|
import { t as T } from "../funcSpanTransformer-S_WeAt_m.js";
|
|
5
5
|
import { t as U } from "../consoleLocationTransformer-DZu_9MDA.js";
|
|
6
|
-
import { s as $ } from "../runtimeConfig-
|
|
6
|
+
import { s as $ } from "../runtimeConfig-ButdW4zP.js";
|
|
7
7
|
async function v(n = {}) {
|
|
8
8
|
try {
|
|
9
9
|
if ($()) return void console.warn("[FuncSpan TSC Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("../funcSpanTransformer-D0W2t41q.cjs"),a=require("../consoleLocationTransformer-BSSB5msZ.cjs"),f=require("../runtimeConfig-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("../funcSpanTransformer-D0W2t41q.cjs"),a=require("../consoleLocationTransformer-BSSB5msZ.cjs"),f=require("../runtimeConfig-C4_zc4Zg.cjs");exports.funcspanVitePlugin=function(l={}){try{if(f.shouldEnableRuntimeHooks())return console.warn("[FuncSpan Vite Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"),{name:"sailfish-funcspan-vite-disabled"}}catch{}const{enabled:c=!0,includeNodeModules:t=[],debug:o=!1}=l;return{name:"sailfish-funcspan-vite",enforce:"pre",async transform(s,e){if(!c||!e.match(/\.(js|ts|jsx|tsx)$/)||e.startsWith("\0")||e.includes("node_modules")&&!t.some(n=>e.includes(`node_modules/${n}`))||e.includes("@sailfish-ai/sf-veritas")||e.includes("jsts-backend/dist"))return null;try{let n=s,i=!1;const u=await d.transformFunctionSpans(n,e,{projectRoot:process.cwd(),includeNodeModules:t,debug:o});u.modified&&(n=u.code,i=!0);const r=await a.transformConsoleLocations(n,e,{projectRoot:process.cwd(),includeNodeModules:t,debug:o});if(r.modified&&(n=r.code,i=!0),i)return{code:n,map:null}}catch(n){o&&console.error(`[FuncSpan Vite] Error transforming ${e}:`,n)}return null}}};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as d } from "../funcSpanTransformer-S_WeAt_m.js";
|
|
2
2
|
import { t as a } from "../consoleLocationTransformer-DZu_9MDA.js";
|
|
3
|
-
import { s as f } from "../runtimeConfig-
|
|
3
|
+
import { s as f } from "../runtimeConfig-ButdW4zP.js";
|
|
4
4
|
function g(l = {}) {
|
|
5
5
|
try {
|
|
6
6
|
if (f()) return console.warn("[FuncSpan Vite Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation"), { name: "sailfish-funcspan-vite-disabled" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("../runtimeConfig-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("../runtimeConfig-C4_zc4Zg.cjs"),a=require("path"),P=require("url");function m(r){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const n in r)if(n!=="default"){const t=Object.getOwnPropertyDescriptor(r,n);Object.defineProperty(o,n,t.get?t:{enumerable:!0,get:()=>r[n]})}}return o.default=r,Object.freeze(o)}const f=m(a);class u{options;constructor(o={}){this.options={enabled:!0,includeNodeModules:[],debug:!1,enableWorkerPoolTracking:!1,workerPoolTrackDns:!1,workerPoolTrackFs:!1,workerPoolTrackCrypto:!1,workerPoolTrackZlib:!1,...o}}apply(o){try{if(b.shouldEnableRuntimeHooks())return void console.warn("[FuncSpan Webpack Plugin] Runtime mode active - build plugin DISABLED to prevent double-instrumentation")}catch{}const{enabled:n,includeNodeModules:t,debug:c}=this.options;if(!n)return;const l="FuncspanWebpackPlugin";o.hooks.compilation.tap(l,s=>{s.hooks.buildModule.tap(l,i=>{i.resource&&i.resource.match(/\.(js|ts|jsx|tsx)$/)&&(!i.resource.includes("node_modules")||t?.some(e=>i.resource.includes(`node_modules/${e}`)))}),o.webpack.NormalModule.getCompilationHooks(s).loader.tap(l,(i,e)=>{if(!e.resource||!e.resource.match(/\.(js|ts|jsx|tsx)$/)||e.resource.includes("node_modules")&&!t?.some(p=>e.resource.includes(`node_modules/${p}`)))return;const d=typeof __dirname<"u"?__dirname:a.dirname(P.fileURLToPath(require("node:url").pathToFileURL(__filename).href)),k=f.join(d,"funcspanWebpackLoader.cjs");e.loaders.push({loader:k,options:{projectRoot:o.context,includeNodeModules:t,debug:c,enableWorkerPoolTracking:this.options.enableWorkerPoolTracking,workerPoolTrackDns:this.options.workerPoolTrackDns,workerPoolTrackFs:this.options.workerPoolTrackFs,workerPoolTrackCrypto:this.options.workerPoolTrackCrypto,workerPoolTrackZlib:this.options.workerPoolTrackZlib}})})}),c&&console.log("[FuncSpan Webpack] Plugin initialized")}}exports.FuncspanWebpackPlugin=u,exports.default=u;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var k = Object.defineProperty;
|
|
2
2
|
var m = (r, o, s) => o in r ? k(r, o, { enumerable: !0, configurable: !0, writable: !0, value: s }) : r[o] = s;
|
|
3
3
|
var c = (r, o, s) => m(r, typeof o != "symbol" ? o + "" : o, s);
|
|
4
|
-
import { s as b } from "../runtimeConfig-
|
|
4
|
+
import { s as b } from "../runtimeConfig-ButdW4zP.js";
|
|
5
5
|
import * as P from "path";
|
|
6
6
|
import { dirname as T } from "path";
|
|
7
7
|
import { fileURLToPath as f } from "url";
|