@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.
Files changed (90) hide show
  1. package/automatic-delivery.cjs +271 -0
  2. package/batch-sender.cjs +164 -0
  3. package/bounded-number.cjs +34 -0
  4. package/browser-breadcrumbs.cjs +346 -136
  5. package/capture-support.cjs +100 -0
  6. package/client-options.cjs +292 -0
  7. package/client-report.cjs +232 -0
  8. package/client.cjs +447 -0
  9. package/console-arguments.cjs +151 -0
  10. package/console-capture.cjs +194 -0
  11. package/core.cjs +30 -2810
  12. package/delivery-health.cjs +133 -0
  13. package/error-causes.cjs +130 -0
  14. package/error-details.cjs +124 -0
  15. package/error-issue.cjs +187 -0
  16. package/event-clone.cjs +55 -0
  17. package/event-metadata.cjs +40 -0
  18. package/event-pipeline.cjs +325 -0
  19. package/event-queue.cjs +306 -0
  20. package/event-store.cjs +237 -0
  21. package/event-validation.cjs +159 -0
  22. package/examples/agent-timeline.cjs +57 -46
  23. package/examples/agent-timeline.mjs +41 -35
  24. package/examples/index.mjs +122 -94
  25. package/examples/readme-example.cjs +36 -27
  26. package/examples/readme-example.mjs +21 -17
  27. package/examples/real-user-smoke.cjs +41 -32
  28. package/examples/real-user-smoke.mjs +26 -22
  29. package/exception-chain.cjs +205 -0
  30. package/index.d.ts +144 -1076
  31. package/index.js +1 -1
  32. package/issue-exception.cjs +13 -8
  33. package/metric-validation.cjs +95 -0
  34. package/network-milestone.cjs +155 -0
  35. package/null-value.cjs +4 -0
  36. package/opentelemetry-bridge.cjs +330 -0
  37. package/opentelemetry-context.cjs +245 -0
  38. package/opentelemetry-exceptions.cjs +69 -0
  39. package/opentelemetry-keys.cjs +183 -0
  40. package/opentelemetry-span.cjs +286 -0
  41. package/opentelemetry-summary.cjs +213 -0
  42. package/opentelemetry-time.cjs +131 -0
  43. package/opentelemetry.cjs +99 -1068
  44. package/package.json +55 -1
  45. package/pino-destination.cjs +108 -0
  46. package/pino-record.cjs +237 -0
  47. package/product-action.cjs +163 -0
  48. package/provided-breadcrumbs.cjs +117 -0
  49. package/random-hex.cjs +29 -0
  50. package/react-native.js +1 -1
  51. package/recording-transport.cjs +68 -0
  52. package/release-artifacts-build.cjs +263 -84
  53. package/release-artifacts-common.js +347 -66
  54. package/release-artifacts-debug-id.js +178 -0
  55. package/release-artifacts-inspect.js +213 -0
  56. package/release-artifacts-issue-event.js +99 -0
  57. package/release-artifacts-manifest-artifact.js +107 -0
  58. package/release-artifacts-manifest.js +77 -0
  59. package/release-artifacts-mappings.js +265 -0
  60. package/release-artifacts-prepare.js +297 -0
  61. package/release-artifacts-source-context.js +210 -0
  62. package/release-artifacts-symbolication.js +272 -421
  63. package/release-artifacts-upload-files.js +122 -0
  64. package/release-artifacts-upload-request.js +246 -0
  65. package/release-artifacts-upload.js +155 -300
  66. package/release-artifacts-urls.js +49 -0
  67. package/release-artifacts.js +189 -662
  68. package/retry-delay.cjs +32 -0
  69. package/span-validation.cjs +191 -0
  70. package/stored-events.cjs +243 -0
  71. package/types/client.d.ts +67 -0
  72. package/types/delivery.d.ts +125 -0
  73. package/types/issues.d.ts +249 -0
  74. package/types/logging.d.ts +175 -0
  75. package/types/opentelemetry.d.ts +205 -0
  76. package/types/product.d.ts +128 -0
  77. package/types/recording-transport.d.ts +15 -0
  78. package/types/sdk-error.d.ts +9 -0
  79. package/types/telemetry.d.ts +171 -0
  80. package/types/trace-context.d.ts +110 -0
  81. package/types/transport-error.d.ts +10 -0
  82. package/utf8.cjs +37 -0
  83. package/validation.cjs +49 -1
  84. package/vite-release-artifacts-config.cjs +120 -0
  85. package/vite-release-artifacts.cjs +199 -99
  86. package/vite-release-artifacts.d.cts +65 -40
  87. package/vite-release-artifacts.d.ts +65 -40
  88. package/vite-release-artifacts.js +2 -2
  89. package/winston-info.cjs +205 -0
  90. 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 };