@logbrew/sdk 0.1.38 → 0.1.39
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/automatic-delivery.cjs +271 -0
- package/batch-sender.cjs +164 -0
- package/bounded-number.cjs +34 -0
- package/browser-breadcrumbs.cjs +346 -136
- package/capture-support.cjs +100 -0
- package/client-options.cjs +292 -0
- package/client-report.cjs +232 -0
- package/client.cjs +447 -0
- package/console-arguments.cjs +151 -0
- package/console-capture.cjs +194 -0
- package/core.cjs +30 -2810
- package/delivery-health.cjs +133 -0
- package/error-causes.cjs +130 -0
- package/error-details.cjs +124 -0
- package/error-issue.cjs +187 -0
- package/event-clone.cjs +55 -0
- package/event-metadata.cjs +40 -0
- package/event-pipeline.cjs +325 -0
- package/event-queue.cjs +306 -0
- package/event-store.cjs +237 -0
- package/event-validation.cjs +159 -0
- package/examples/agent-timeline.cjs +57 -46
- package/examples/agent-timeline.mjs +41 -35
- package/examples/index.mjs +122 -94
- package/examples/readme-example.cjs +36 -27
- package/examples/readme-example.mjs +21 -17
- package/examples/real-user-smoke.cjs +41 -32
- package/examples/real-user-smoke.mjs +26 -22
- package/exception-chain.cjs +205 -0
- package/index.d.ts +144 -1076
- package/index.js +1 -1
- package/issue-exception.cjs +13 -8
- package/metric-validation.cjs +95 -0
- package/network-milestone.cjs +155 -0
- package/null-value.cjs +4 -0
- package/opentelemetry-bridge.cjs +330 -0
- package/opentelemetry-context.cjs +245 -0
- package/opentelemetry-exceptions.cjs +69 -0
- package/opentelemetry-keys.cjs +183 -0
- package/opentelemetry-span.cjs +286 -0
- package/opentelemetry-summary.cjs +213 -0
- package/opentelemetry-time.cjs +131 -0
- package/opentelemetry.cjs +99 -1068
- package/package.json +55 -1
- package/pino-destination.cjs +108 -0
- package/pino-record.cjs +237 -0
- package/product-action.cjs +163 -0
- package/provided-breadcrumbs.cjs +117 -0
- package/random-hex.cjs +29 -0
- package/react-native.js +1 -1
- package/recording-transport.cjs +68 -0
- package/release-artifacts-build.cjs +263 -84
- package/release-artifacts-common.js +347 -66
- package/release-artifacts-debug-id.js +178 -0
- package/release-artifacts-inspect.js +213 -0
- package/release-artifacts-issue-event.js +99 -0
- package/release-artifacts-manifest-artifact.js +107 -0
- package/release-artifacts-manifest.js +77 -0
- package/release-artifacts-mappings.js +265 -0
- package/release-artifacts-prepare.js +297 -0
- package/release-artifacts-source-context.js +210 -0
- package/release-artifacts-symbolication.js +272 -421
- package/release-artifacts-upload-files.js +122 -0
- package/release-artifacts-upload-request.js +246 -0
- package/release-artifacts-upload.js +155 -300
- package/release-artifacts-urls.js +49 -0
- package/release-artifacts.js +189 -662
- package/retry-delay.cjs +32 -0
- package/span-validation.cjs +191 -0
- package/stored-events.cjs +243 -0
- package/types/client.d.ts +67 -0
- package/types/delivery.d.ts +125 -0
- package/types/issues.d.ts +249 -0
- package/types/logging.d.ts +175 -0
- package/types/opentelemetry.d.ts +205 -0
- package/types/product.d.ts +128 -0
- package/types/recording-transport.d.ts +15 -0
- package/types/sdk-error.d.ts +9 -0
- package/types/telemetry.d.ts +171 -0
- package/types/trace-context.d.ts +110 -0
- package/types/transport-error.d.ts +10 -0
- package/utf8.cjs +37 -0
- package/validation.cjs +49 -1
- package/vite-release-artifacts-config.cjs +120 -0
- package/vite-release-artifacts.cjs +199 -99
- package/vite-release-artifacts.d.cts +65 -40
- package/vite-release-artifacts.d.ts +65 -40
- package/vite-release-artifacts.js +2 -2
- package/winston-info.cjs +205 -0
- package/winston.cjs +189 -289
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
byteSize,
|
|
3
|
+
fileReference,
|
|
4
|
+
isDirectory,
|
|
5
|
+
isFile,
|
|
6
|
+
pathExists,
|
|
7
|
+
readText,
|
|
8
|
+
realPath,
|
|
9
|
+
relativeTo,
|
|
10
|
+
safeResolve
|
|
11
|
+
} from "./release-artifacts-common.js";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @import { OriginalPosition } from "./release-artifacts-mappings.js"
|
|
16
|
+
* @typedef {{ readonly contextLines: number, readonly sourceRoot: string }} SourceContextOptions
|
|
17
|
+
* @typedef {{ readonly highlighted: boolean, readonly line: number, readonly text: string }} SourceContextLine
|
|
18
|
+
* @typedef {{ readonly lines: readonly SourceContextLine[], readonly source: string, readonly startLine: number }} SourceContext
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const DEFAULT_CONTEXT_LINES = 2;
|
|
22
|
+
const MAX_CONTEXT_LINES = 10;
|
|
23
|
+
const MIN_CONTEXT_LINES = 0;
|
|
24
|
+
const MAX_SOURCE_CONTEXT_FILE_BYTES = 1_048_576;
|
|
25
|
+
const FIRST_LINE = 1;
|
|
26
|
+
const FIRST_PART = 0;
|
|
27
|
+
const NOT_FOUND = -1;
|
|
28
|
+
const BUNDLER_PROJECT_SEGMENT_RE = /^\[[^\]/]+\]$/u;
|
|
29
|
+
const LEADING_SLASHES_RE = /^\/+/u;
|
|
30
|
+
const LINE_BREAK_RE = /\r?\n/u;
|
|
31
|
+
const URL_WITH_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:\/\//u;
|
|
32
|
+
const WINDOWS_DRIVE_RE = /^[A-Za-z]:[\\/]/u;
|
|
33
|
+
const BUNDLER_MARKERS = ["/./", "!./"];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {number | undefined} value
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
function requireContextLineCount(value) {
|
|
40
|
+
if (value === undefined) {
|
|
41
|
+
return DEFAULT_CONTEXT_LINES;
|
|
42
|
+
}
|
|
43
|
+
if (!Number.isInteger(value) || value < MIN_CONTEXT_LINES || value > MAX_CONTEXT_LINES) {
|
|
44
|
+
throw new Error("source context line count must be an integer from 0 to 10");
|
|
45
|
+
}
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {string} candidate
|
|
51
|
+
* @returns {string}
|
|
52
|
+
*/
|
|
53
|
+
function cleanedReference(candidate) {
|
|
54
|
+
return fileReference(candidate.trim()).replaceAll("\\", "/");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} candidate
|
|
59
|
+
* @returns {string | undefined}
|
|
60
|
+
*/
|
|
61
|
+
function relativeCandidate(candidate) {
|
|
62
|
+
const cleaned = cleanedReference(candidate);
|
|
63
|
+
if (cleaned === "" || cleaned.startsWith("file://") || WINDOWS_DRIVE_RE.test(cleaned)) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const normalized = path.posix.normalize(cleaned.replace(LEADING_SLASHES_RE, ""));
|
|
67
|
+
if (normalized === "" || normalized === "." || normalized.startsWith("../") || normalized === "..") {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
return normalized;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {string} candidate
|
|
75
|
+
* @returns {string[]}
|
|
76
|
+
*/
|
|
77
|
+
function bundlerSuffixes(candidate) {
|
|
78
|
+
const cleaned = cleanedReference(candidate);
|
|
79
|
+
const markerSuffixes = BUNDLER_MARKERS.flatMap((marker) => {
|
|
80
|
+
const markerIndex = cleaned.lastIndexOf(marker);
|
|
81
|
+
return markerIndex === NOT_FOUND ? [] : [cleaned.slice(markerIndex + marker.length)];
|
|
82
|
+
});
|
|
83
|
+
const [first = "", ...rest] = cleaned.replace(LEADING_SLASHES_RE, "").split("/");
|
|
84
|
+
return rest.length > FIRST_PART && BUNDLER_PROJECT_SEGMENT_RE.test(first) ? [...markerSuffixes, rest.join("/")] : markerSuffixes;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {string} source
|
|
89
|
+
* @returns {string[]}
|
|
90
|
+
*/
|
|
91
|
+
function urlPathCandidates(source) {
|
|
92
|
+
if (!URL_WITH_SCHEME_RE.test(source)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const { pathname } = new URL(source);
|
|
97
|
+
return [pathname, ...bundlerSuffixes(pathname)];
|
|
98
|
+
} catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {string} source
|
|
105
|
+
* @returns {string[]}
|
|
106
|
+
*/
|
|
107
|
+
function sourceRootRelativeCandidates(source) {
|
|
108
|
+
const candidates = [source, ...bundlerSuffixes(source), ...urlPathCandidates(source)];
|
|
109
|
+
return [...new Set(candidates.map((candidate) => relativeCandidate(candidate)).filter((candidate) => candidate !== undefined))];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @param {string} source
|
|
114
|
+
* @param {string} sourceRoot
|
|
115
|
+
* @param {string} sourceMapPath
|
|
116
|
+
* @returns {string[]}
|
|
117
|
+
*/
|
|
118
|
+
function sourceContextPathCandidates(source, sourceRoot, sourceMapPath) {
|
|
119
|
+
return [
|
|
120
|
+
...new Set([
|
|
121
|
+
path.resolve(path.dirname(sourceMapPath), source),
|
|
122
|
+
path.join(sourceRoot, source),
|
|
123
|
+
...sourceRootRelativeCandidates(source).map((relativeSource) => path.join(sourceRoot, relativeSource))
|
|
124
|
+
])
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @param {string} sourceRoot
|
|
130
|
+
* @returns {Promise<string>}
|
|
131
|
+
*/
|
|
132
|
+
async function requireSourceRoot(sourceRoot) {
|
|
133
|
+
if (sourceRoot.trim() === "") {
|
|
134
|
+
throw new Error("source context root must be a non-empty directory path");
|
|
135
|
+
}
|
|
136
|
+
const requestedSourceRoot = path.resolve(sourceRoot);
|
|
137
|
+
if (!(await pathExists(requestedSourceRoot)) || !(await isDirectory(requestedSourceRoot))) {
|
|
138
|
+
throw new Error("source context root must resolve to an existing directory");
|
|
139
|
+
}
|
|
140
|
+
return realPath(requestedSourceRoot);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param {readonly string[]} candidates
|
|
145
|
+
* @param {string} sourceRoot
|
|
146
|
+
* @returns {Promise<string>}
|
|
147
|
+
*/
|
|
148
|
+
async function readableSourcePath(candidates, sourceRoot) {
|
|
149
|
+
const [candidate, ...rest] = candidates;
|
|
150
|
+
if (candidate === undefined) {
|
|
151
|
+
throw new Error("original source file is not readable under the source context root");
|
|
152
|
+
}
|
|
153
|
+
const resolved = await safeResolve(candidate, sourceRoot);
|
|
154
|
+
if (resolved !== undefined && (await pathExists(resolved)) && (await isFile(resolved))) {
|
|
155
|
+
return resolved;
|
|
156
|
+
}
|
|
157
|
+
return readableSourcePath(rest, sourceRoot);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {string} sourcePath
|
|
162
|
+
* @returns {Promise<string[]>}
|
|
163
|
+
*/
|
|
164
|
+
async function readContextSourceLines(sourcePath) {
|
|
165
|
+
const size = await byteSize(sourcePath);
|
|
166
|
+
if (size > MAX_SOURCE_CONTEXT_FILE_BYTES) {
|
|
167
|
+
throw new Error("source context file is too large for local report output");
|
|
168
|
+
}
|
|
169
|
+
const text = await readText(sourcePath);
|
|
170
|
+
return text.split(LINE_BREAK_RE);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @param {readonly string[]} sourceLines
|
|
175
|
+
* @param {number} originalLine
|
|
176
|
+
* @param {number} contextLines
|
|
177
|
+
* @returns {{ readonly lines: readonly SourceContextLine[], readonly startLine: number }}
|
|
178
|
+
*/
|
|
179
|
+
function contextAround(sourceLines, originalLine, contextLines) {
|
|
180
|
+
const startLine = Math.max(FIRST_LINE, originalLine - contextLines);
|
|
181
|
+
const endLine = Math.min(sourceLines.length, originalLine + contextLines);
|
|
182
|
+
/** @type {SourceContextLine[]} */
|
|
183
|
+
const lines = [];
|
|
184
|
+
for (let line = startLine; line <= endLine; line += FIRST_LINE) {
|
|
185
|
+
lines.push({ highlighted: line === originalLine, line, text: sourceLines[line - FIRST_LINE] ?? "" });
|
|
186
|
+
}
|
|
187
|
+
return { lines, startLine };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {OriginalPosition} original
|
|
192
|
+
* @param {(SourceContextOptions & { readonly sourceMapPath: string }) | undefined} options
|
|
193
|
+
* @returns {Promise<SourceContext | undefined>}
|
|
194
|
+
*/
|
|
195
|
+
async function sourceContextForOriginalPosition(original, options) {
|
|
196
|
+
if (options === undefined || options.sourceRoot === "") {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const sourceRoot = await requireSourceRoot(options.sourceRoot);
|
|
200
|
+
const sourcePath = await readableSourcePath(
|
|
201
|
+
sourceContextPathCandidates(original.source, sourceRoot, options.sourceMapPath),
|
|
202
|
+
sourceRoot
|
|
203
|
+
);
|
|
204
|
+
const contextLines = requireContextLineCount(options.contextLines);
|
|
205
|
+
const sourceLines = await readContextSourceLines(sourcePath);
|
|
206
|
+
const { lines, startLine } = contextAround(sourceLines, original.line, contextLines);
|
|
207
|
+
return { lines, source: relativeTo(sourceRoot, sourcePath), startLine };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export { sourceContextForOriginalPosition };
|