@glasstrace/sdk 1.15.0 → 1.16.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 +117 -8
- package/dist/async-context/index.cjs +21 -2
- package/dist/async-context/index.cjs.map +1 -1
- package/dist/async-context/index.js +2 -2
- package/dist/{capture-error-03qDnC5v.d.cts → capture-error-B0txjNut.d.cts} +2 -2
- package/dist/{capture-error-CAfFUyIU.d.ts → capture-error-Dc01rYNR.d.ts} +2 -2
- package/dist/{chunk-F7A3QXCT.js → chunk-774XIOZG.js} +2 -2
- package/dist/{chunk-VMK2G6QR.js → chunk-AFTCLH77.js} +2 -2
- package/dist/{chunk-XMD5OYD6.js → chunk-BGJKEFBN.js} +2 -2
- package/dist/{chunk-LQZRGBN5.js → chunk-DW3CZDS6.js} +2 -2
- package/dist/{chunk-PSMSSLQY.js → chunk-EWW3TZ52.js} +123 -12
- package/dist/{chunk-PSMSSLQY.js.map → chunk-EWW3TZ52.js.map} +1 -1
- package/dist/{chunk-7LE2O4ZJ.js → chunk-GBVMPMVV.js} +54 -5
- package/dist/{chunk-7LE2O4ZJ.js.map → chunk-GBVMPMVV.js.map} +1 -1
- package/dist/{chunk-HMEHYSTS.js → chunk-KM4UNN3Q.js} +2 -2
- package/dist/{chunk-MP3QNDXQ.js → chunk-OHSX224U.js} +2 -2
- package/dist/{chunk-6ST4QV7T.js → chunk-T7B752NF.js} +3 -3
- package/dist/{chunk-ZIYT2Y4B.js → chunk-WOYJAG7H.js} +3 -3
- package/dist/cli/init.cjs +18 -5
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +7 -7
- package/dist/cli/mcp-add.cjs +15 -2
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +3 -3
- package/dist/cli/uninit.js +3 -3
- package/dist/cli/upgrade-instructions.cjs +1 -1
- package/dist/cli/upgrade-instructions.js +3 -3
- package/dist/cli/validate.cjs +14 -1
- package/dist/cli/validate.cjs.map +1 -1
- package/dist/cli/validate.js +2 -2
- package/dist/{correlation-id-YcfcqOru.d.ts → correlation-id-B9YYmoZw.d.ts} +1 -1
- package/dist/{correlation-id-CZ2bstzA.d.cts → correlation-id-CelUvw7j.d.cts} +1 -1
- package/dist/edge-entry.cjs +21 -2
- package/dist/edge-entry.cjs.map +1 -1
- package/dist/edge-entry.d.cts +2 -2
- package/dist/edge-entry.d.ts +2 -2
- package/dist/edge-entry.js +4 -4
- package/dist/import-graph-DBLGNjcI.d.cts +238 -0
- package/dist/import-graph-Dka_Fm7j.d.ts +238 -0
- package/dist/index.cjs +165 -12
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-BQIJ5Dvc.d.cts → index.d-3-cJoY8y.d.cts} +10 -2
- package/dist/{index.d-BQIJ5Dvc.d.ts → index.d-3-cJoY8y.d.ts} +10 -2
- package/dist/index.d.cts +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +5 -5
- package/dist/middleware/index.cjs +21 -2
- package/dist/middleware/index.cjs.map +1 -1
- package/dist/middleware/index.js +2 -2
- package/dist/node-entry.cjs +56 -9
- package/dist/node-entry.cjs.map +1 -1
- package/dist/node-entry.d.cts +4 -4
- package/dist/node-entry.d.ts +4 -4
- package/dist/node-entry.js +7 -7
- package/dist/node-subpath.cjs +27 -1
- package/dist/node-subpath.cjs.map +1 -1
- package/dist/node-subpath.d.cts +51 -235
- package/dist/node-subpath.d.ts +51 -235
- package/dist/node-subpath.js +16 -3
- package/dist/node-subpath.js.map +1 -1
- package/dist/{source-map-uploader-NUONOEJG.js → source-map-uploader-UJPZCUFN.js} +3 -3
- package/dist/trpc/index.cjs +21 -2
- package/dist/trpc/index.cjs.map +1 -1
- package/dist/trpc/index.js +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-F7A3QXCT.js.map → chunk-774XIOZG.js.map} +0 -0
- /package/dist/{chunk-VMK2G6QR.js.map → chunk-AFTCLH77.js.map} +0 -0
- /package/dist/{chunk-XMD5OYD6.js.map → chunk-BGJKEFBN.js.map} +0 -0
- /package/dist/{chunk-LQZRGBN5.js.map → chunk-DW3CZDS6.js.map} +0 -0
- /package/dist/{chunk-HMEHYSTS.js.map → chunk-KM4UNN3Q.js.map} +0 -0
- /package/dist/{chunk-MP3QNDXQ.js.map → chunk-OHSX224U.js.map} +0 -0
- /package/dist/{chunk-6ST4QV7T.js.map → chunk-T7B752NF.js.map} +0 -0
- /package/dist/{chunk-ZIYT2Y4B.js.map → chunk-WOYJAG7H.js.map} +0 -0
- /package/dist/{source-map-uploader-NUONOEJG.js.map → source-map-uploader-UJPZCUFN.js.map} +0 -0
package/README.md
CHANGED
|
@@ -363,6 +363,49 @@ A future SDK release may extend the auto-attach detection to recognize
|
|
|
363
363
|
additional Next 16 provider shapes; until that ships, the manual path
|
|
364
364
|
above is the production-supported integration.
|
|
365
365
|
|
|
366
|
+
## Database query spans (Prisma)
|
|
367
|
+
|
|
368
|
+
When Glasstrace manages the OpenTelemetry provider — the default when
|
|
369
|
+
your app does not already run its own OpenTelemetry or Sentry setup — it
|
|
370
|
+
automatically instruments [Prisma](https://www.prisma.io/) queries.
|
|
371
|
+
Install
|
|
372
|
+
[`@prisma/instrumentation`](https://www.npmjs.com/package/@prisma/instrumentation)
|
|
373
|
+
(an optional peer dependency, Prisma 4–7) and query spans appear once the
|
|
374
|
+
package is reachable; no extra wiring is required.
|
|
375
|
+
|
|
376
|
+
If Glasstrace instead detects a provider you already registered (Sentry,
|
|
377
|
+
a custom OpenTelemetry SDK, and similar), it attaches its exporter to
|
|
378
|
+
that provider rather than taking over instrumentation — so it does not
|
|
379
|
+
add Prisma instrumentation itself, and the diagnostic below does not
|
|
380
|
+
apply. Register `@prisma/instrumentation` on your own provider;
|
|
381
|
+
Glasstrace exports the spans it produces.
|
|
382
|
+
|
|
383
|
+
Prisma ORM versions **4.2.0 through 6.1.0** additionally require enabling
|
|
384
|
+
the `tracing`
|
|
385
|
+
[preview feature](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing)
|
|
386
|
+
in your schema's `generator` block — `previewFeatures = ["tracing"]` —
|
|
387
|
+
before any tracing spans are emitted. Later Prisma versions need no flag.
|
|
388
|
+
|
|
389
|
+
**Missing Prisma query spans?** On Prisma 4.2.0–6.1.0, first confirm the
|
|
390
|
+
`tracing` preview feature above is enabled. Otherwise, the usual cause is
|
|
391
|
+
a package manager that does not expose transitive copies of optional
|
|
392
|
+
peers. Under pnpm's
|
|
393
|
+
strict, isolated `node_modules`, `@prisma/instrumentation` can sit in
|
|
394
|
+
the virtual store (pulled in by another dependency) without being
|
|
395
|
+
linked into your app's `node_modules/@prisma/` — so the SDK's optional
|
|
396
|
+
import resolves to nothing and Prisma spans are silently skipped. Add it
|
|
397
|
+
as a **direct dependency** of your app:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
npm install @prisma/instrumentation
|
|
401
|
+
# pnpm add @prisma/instrumentation
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
To confirm whether it was loaded, enable verbose mode
|
|
405
|
+
(`registerGlasstrace({ verbose: true })`): when
|
|
406
|
+
`@prisma/instrumentation` cannot be loaded, the SDK logs a diagnostic
|
|
407
|
+
noting that Prisma query spans will not be captured.
|
|
408
|
+
|
|
366
409
|
## Capturing error response bodies
|
|
367
410
|
|
|
368
411
|
When debugging a 4xx or 5xx, the response body is often the most useful
|
|
@@ -627,6 +670,63 @@ ingestion service before persistence. This is intentional
|
|
|
627
670
|
defense-in-depth: the SDK is the first gate; the product receiver
|
|
628
671
|
is the second.
|
|
629
672
|
|
|
673
|
+
### Value-fidelity scalars
|
|
674
|
+
|
|
675
|
+
Beyond the categorical `fields` channel, `recordSideEffect()` accepts an
|
|
676
|
+
optional `scalars` map for type-aware magnitudes emitted on a separate
|
|
677
|
+
`glasstrace.side_effect.scalar.*` channel. The key suffix declares the
|
|
678
|
+
value type:
|
|
679
|
+
|
|
680
|
+
- `*Ms` / `*Amount` / `*Bytes` / `*Ratio` / `*Value` → a finite `number`
|
|
681
|
+
- `*Flag` → a `boolean`
|
|
682
|
+
- `*Id` → a pseudonymized `gthid_` string (see `hashId` below)
|
|
683
|
+
|
|
684
|
+
(`Count` stays on the categorical `fields` channel; free-form string
|
|
685
|
+
enums belong there too, not on the scalar channel.)
|
|
686
|
+
|
|
687
|
+
```ts
|
|
688
|
+
import { recordSideEffect } from "@glasstrace/sdk";
|
|
689
|
+
import { hashId } from "@glasstrace/sdk/node";
|
|
690
|
+
|
|
691
|
+
recordSideEffect({
|
|
692
|
+
kind: "external_api",
|
|
693
|
+
operation: "charge.create",
|
|
694
|
+
status: "succeeded",
|
|
695
|
+
scalars: {
|
|
696
|
+
latencyMs: 142, // bounded delta — not a wall-clock epoch
|
|
697
|
+
amountValue: 1999, // a magnitude
|
|
698
|
+
retriedFlag: false, // a boolean condition
|
|
699
|
+
// Identifiers must be pseudonymized; raw ids are rejected.
|
|
700
|
+
customerId: hashId(rawCustomerId, process.env.GLASSTRACE_ATTR_HMAC_KEY!),
|
|
701
|
+
},
|
|
702
|
+
});
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
Scalars are validated at emit time under a **fail-closed `strict`**
|
|
706
|
+
posture. (An account-level `captureFidelity` setting that can relax the
|
|
707
|
+
timestamp/identifier rejections is part of the wire contract but is **not
|
|
708
|
+
active in this release** — scalars are always validated as `strict`
|
|
709
|
+
here.) Under `strict` the SDK rejects values that would leak raw,
|
|
710
|
+
high-cardinality data before they reach the wire, recording only an
|
|
711
|
+
integer omission count:
|
|
712
|
+
|
|
713
|
+
| Rejected value | Omission reason |
|
|
714
|
+
|---|---|
|
|
715
|
+
| A `Date`, or a raw epoch on a `*Ms` key | `raw_timestamp` |
|
|
716
|
+
| A non-`gthid_` value on an `*Id` key | `unhashed_id` |
|
|
717
|
+
| `NaN` / `±Infinity` | `non_finite` |
|
|
718
|
+
| A value whose type doesn't match its key suffix (e.g. a string or boolean on `*Ms`) | `raw_payload` |
|
|
719
|
+
| A key not matching the scalar pattern | `unsupported_key` |
|
|
720
|
+
| More than 16 scalars in one call (the excess are dropped) | `value_too_long` |
|
|
721
|
+
|
|
722
|
+
Send **bounded deltas as numbers** (e.g. `latencyMs: 142`), not absolute
|
|
723
|
+
timestamps. Note that raw-epoch screening applies only to `*Ms` keys (the
|
|
724
|
+
time-typed suffix) — keep wall-clock values off other numeric suffixes.
|
|
725
|
+
Pseudonymize identifiers with **`hashId`** (HMAC-SHA256, fixed-shape
|
|
726
|
+
`gthid_<hex>`, fail-closed — returns `null` without a key), which ships on
|
|
727
|
+
the Node-only `@glasstrace/sdk/node` subpath because it uses
|
|
728
|
+
`node:crypto`. At most 16 scalars are recorded per operation.
|
|
729
|
+
|
|
630
730
|
## Source maps
|
|
631
731
|
|
|
632
732
|
Glasstrace uploads server-side source maps at build time and resolves
|
|
@@ -798,7 +898,7 @@ without a deprecation cycle. Rely on the static file.
|
|
|
798
898
|
|
|
799
899
|
## Subpath exports
|
|
800
900
|
|
|
801
|
-
`@glasstrace/sdk` ships
|
|
901
|
+
`@glasstrace/sdk` ships six public entries:
|
|
802
902
|
|
|
803
903
|
- **`@glasstrace/sdk`** — primary import site. Use from
|
|
804
904
|
`instrumentation.ts` (runtime instrumentation) and `next.config.ts`
|
|
@@ -810,14 +910,19 @@ without a deprecation cycle. Rely on the static file.
|
|
|
810
910
|
runtimes; workloads running strictly on workerd or Vercel Edge
|
|
811
911
|
should import from the internal edge-entry bundle — not currently
|
|
812
912
|
exposed as a public entry — or ask for a public `/edge` subpath.
|
|
813
|
-
- **`@glasstrace/sdk/node`** — Node-only build-time tooling
|
|
814
|
-
(source-map uploading, import-graph construction)
|
|
815
|
-
`
|
|
816
|
-
condition; non-Node runtimes (workerd,
|
|
817
|
-
module resolution rather than at
|
|
913
|
+
- **`@glasstrace/sdk/node`** — Node-only helpers: build-time tooling
|
|
914
|
+
(source-map uploading, import-graph construction) plus the request-time
|
|
915
|
+
`hashId` identifier-pseudonymization helper for value-fidelity scalars.
|
|
916
|
+
Resolves only under the Node condition; non-Node runtimes (workerd,
|
|
917
|
+
edge-light) fail cleanly at module resolution rather than at
|
|
918
|
+
evaluation.
|
|
818
919
|
- **`@glasstrace/sdk/drizzle`** — Drizzle ORM adapter.
|
|
819
920
|
- **`@glasstrace/sdk/trpc`** — tRPC middleware-chain instrumentation.
|
|
820
921
|
See "tRPC middleware instrumentation" below.
|
|
922
|
+
- **`@glasstrace/sdk/middleware`** — request-middleware tracing wrapper
|
|
923
|
+
(`tracedRequestMiddleware`).
|
|
924
|
+
- **`@glasstrace/sdk/async-context`** — async causality propagation
|
|
925
|
+
(`withAsyncCausality`).
|
|
821
926
|
|
|
822
927
|
The source-map and import-graph helpers previously reachable from the
|
|
823
928
|
`@glasstrace/sdk` root specifier have moved to `@glasstrace/sdk/node`
|
|
@@ -863,11 +968,15 @@ and the recommended call site.
|
|
|
863
968
|
| `discoverTestFiles` | function | `node:fs`, `node:path` | — (call from a build script / CI job) |
|
|
864
969
|
| `extractImports` | function | — (pure string processing) | — (kept under `/node` for API cohesion with `buildImportGraph`) |
|
|
865
970
|
| `buildImportGraph` | function | `node:fs`, `node:path`, `node:crypto` | — (call from a build script / CI job) |
|
|
971
|
+
| `hashId` | function | `node:crypto` | — (call from the request handler that records the side effect) |
|
|
866
972
|
|
|
867
973
|
Type exports erase at runtime and are technically safe to import from
|
|
868
974
|
edge code, but every runtime function that produces or consumes them is
|
|
869
|
-
Node-only, so the practical signal is the same: reach for
|
|
870
|
-
your build pipeline, not from a request
|
|
975
|
+
Node-only, so the practical signal is the same: reach for the source-map
|
|
976
|
+
and import-graph helpers from your build pipeline, not from a request
|
|
977
|
+
handler. `hashId` is the exception — it is a request-time helper for
|
|
978
|
+
pseudonymizing identifiers before `recordSideEffect()`, Node-only only
|
|
979
|
+
because it uses `node:crypto`.
|
|
871
980
|
|
|
872
981
|
#### Why is X Node-only?
|
|
873
982
|
|
|
@@ -15297,7 +15297,20 @@ var CaptureConfigSchema = external_exports.object({
|
|
|
15297
15297
|
* client-side allowlist enforcement layered with the product's
|
|
15298
15298
|
* storage-time filter as defense-in-depth.
|
|
15299
15299
|
*/
|
|
15300
|
-
sideEffectEvidence: external_exports.boolean().optional().default(false)
|
|
15300
|
+
sideEffectEvidence: external_exports.boolean().optional().default(false),
|
|
15301
|
+
/**
|
|
15302
|
+
* Per-account value-fidelity capture posture (server-pushed).
|
|
15303
|
+
*
|
|
15304
|
+
* `strict` (default) is fail-closed: the SDK rejects raw wall-clock
|
|
15305
|
+
* timestamps and unhashed identifiers from the `scalar.*` channel at
|
|
15306
|
+
* emit time. `full` relaxes those rejections so raw magnitudes can be
|
|
15307
|
+
* surfaced — but only in conjunction with an explicit producer opt-in
|
|
15308
|
+
* (so a `full`-configured account still emits strict-shaped scalars
|
|
15309
|
+
* unless the producer also opts in). The operator owns this flag; it
|
|
15310
|
+
* is never derived from producer or request input. Absent on the wire
|
|
15311
|
+
* ⇒ `strict`.
|
|
15312
|
+
*/
|
|
15313
|
+
captureFidelity: external_exports.enum(["strict", "full"]).optional().default("strict")
|
|
15301
15314
|
});
|
|
15302
15315
|
var SdkCachedConfigSchema = external_exports.object({
|
|
15303
15316
|
response: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
@@ -15488,7 +15501,13 @@ var GLASSTRACE_ATTRIBUTE_NAMES = {
|
|
|
15488
15501
|
SIDE_EFFECT_OMITTED_UNSUPPORTED_KEY: "glasstrace.side_effect.omitted.unsupported_key",
|
|
15489
15502
|
SIDE_EFFECT_OMITTED_VALUE_TOO_LONG: "glasstrace.side_effect.omitted.value_too_long",
|
|
15490
15503
|
SIDE_EFFECT_OMITTED_NOT_EMITTED: "glasstrace.side_effect.omitted.not_emitted",
|
|
15491
|
-
SIDE_EFFECT_OMITTED_CAPTURE_DISABLED: "glasstrace.side_effect.omitted.capture_disabled"
|
|
15504
|
+
SIDE_EFFECT_OMITTED_CAPTURE_DISABLED: "glasstrace.side_effect.omitted.capture_disabled",
|
|
15505
|
+
// Value-fidelity scalar-channel omission reasons. Counts only; the
|
|
15506
|
+
// rejected raw value (timestamp, unhashed id, non-finite number) is
|
|
15507
|
+
// never echoed. Mirror the product omission enum verbatim.
|
|
15508
|
+
SIDE_EFFECT_OMITTED_RAW_TIMESTAMP: "glasstrace.side_effect.omitted.raw_timestamp",
|
|
15509
|
+
SIDE_EFFECT_OMITTED_UNHASHED_ID: "glasstrace.side_effect.omitted.unhashed_id",
|
|
15510
|
+
SIDE_EFFECT_OMITTED_NON_FINITE: "glasstrace.side_effect.omitted.non_finite"
|
|
15492
15511
|
};
|
|
15493
15512
|
var MAX_SOURCE_MAP_FILE_PATH_LENGTH = 512;
|
|
15494
15513
|
var MAX_SOURCE_MAP_FILE_SIZE = 50 * 1024 * 1024;
|