@logbrew/sdk 0.1.37 → 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 (103) 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 +35 -2984
  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-breadcrumbs.cjs +143 -0
  33. package/issue-diagnostics.cjs +94 -582
  34. package/issue-evidence.cjs +256 -0
  35. package/issue-exception.cjs +268 -0
  36. package/issue-stack-frames.cjs +220 -0
  37. package/issue-stack-text.cjs +101 -0
  38. package/issue-stack.cjs +188 -225
  39. package/issue-text.cjs +72 -0
  40. package/log-context.cjs +87 -67
  41. package/metric-validation.cjs +95 -0
  42. package/network-milestone.cjs +155 -0
  43. package/null-value.cjs +4 -0
  44. package/opentelemetry-bridge.cjs +330 -0
  45. package/opentelemetry-context.cjs +245 -0
  46. package/opentelemetry-exceptions.cjs +69 -0
  47. package/opentelemetry-keys.cjs +183 -0
  48. package/opentelemetry-span.cjs +286 -0
  49. package/opentelemetry-summary.cjs +213 -0
  50. package/opentelemetry-time.cjs +131 -0
  51. package/opentelemetry.cjs +99 -1068
  52. package/package.json +64 -1
  53. package/pino-destination.cjs +108 -0
  54. package/pino-record.cjs +237 -0
  55. package/product-action.cjs +163 -0
  56. package/provided-breadcrumbs.cjs +117 -0
  57. package/random-hex.cjs +29 -0
  58. package/react-native.js +1 -1
  59. package/recording-transport.cjs +68 -0
  60. package/release-artifacts-build.cjs +263 -84
  61. package/release-artifacts-common.js +347 -66
  62. package/release-artifacts-debug-id.js +178 -0
  63. package/release-artifacts-inspect.js +213 -0
  64. package/release-artifacts-issue-event.js +99 -0
  65. package/release-artifacts-manifest-artifact.js +107 -0
  66. package/release-artifacts-manifest.js +77 -0
  67. package/release-artifacts-mappings.js +265 -0
  68. package/release-artifacts-prepare.js +297 -0
  69. package/release-artifacts-source-context.js +210 -0
  70. package/release-artifacts-symbolication.js +272 -421
  71. package/release-artifacts-upload-files.js +122 -0
  72. package/release-artifacts-upload-request.js +246 -0
  73. package/release-artifacts-upload.js +155 -300
  74. package/release-artifacts-urls.js +49 -0
  75. package/release-artifacts.js +189 -662
  76. package/retry-delay.cjs +32 -0
  77. package/sdk-error.cjs +36 -0
  78. package/span-validation.cjs +191 -0
  79. package/stored-events.cjs +243 -0
  80. package/support-ticket.cjs +232 -122
  81. package/telemetry-context.cjs +343 -251
  82. package/trace-context.cjs +376 -179
  83. package/transport-error.cjs +23 -0
  84. package/types/client.d.ts +67 -0
  85. package/types/delivery.d.ts +125 -0
  86. package/types/issues.d.ts +249 -0
  87. package/types/logging.d.ts +175 -0
  88. package/types/opentelemetry.d.ts +205 -0
  89. package/types/product.d.ts +128 -0
  90. package/types/recording-transport.d.ts +15 -0
  91. package/types/sdk-error.d.ts +9 -0
  92. package/types/telemetry.d.ts +171 -0
  93. package/types/trace-context.d.ts +110 -0
  94. package/types/transport-error.d.ts +10 -0
  95. package/utf8.cjs +37 -0
  96. package/validation.cjs +327 -0
  97. package/vite-release-artifacts-config.cjs +120 -0
  98. package/vite-release-artifacts.cjs +199 -99
  99. package/vite-release-artifacts.d.cts +65 -40
  100. package/vite-release-artifacts.d.ts +65 -40
  101. package/vite-release-artifacts.js +2 -2
  102. package/winston-info.cjs +205 -0
  103. package/winston.cjs +189 -290
package/validation.cjs ADDED
@@ -0,0 +1,327 @@
1
+ const { SdkError } = require("./sdk-error.cjs");
2
+
3
+ /**
4
+ * @template Value
5
+ * @typedef {Value extends readonly (infer Item)[]
6
+ * ? readonly DeepReadonly<Item>[]
7
+ * : Value extends object ? { readonly [Key in keyof Value]: DeepReadonly<Value[Key]> } : Value} DeepReadonly
8
+ */
9
+
10
+ /**
11
+ * @typedef {(...args: readonly never[]) => unknown} Callable
12
+ */
13
+
14
+ const ZERO_TRACE_ID = "00000000000000000000000000000000";
15
+ const ZERO_SPAN_ID = "0000000000000000";
16
+ const TRACE_ID_PATTERN = /^[0-9a-fA-F]{32}$/u;
17
+ const SPAN_ID_PATTERN = /^[0-9a-fA-F]{16}$/u;
18
+ const TRACE_FLAGS_PATTERN = /^[0-9a-fA-F]{2}$/u;
19
+ const NEGATIVE_OFFSET_PATTERN = /.+-.+/u;
20
+ const RFC3339_TIMESTAMP_PATTERN =
21
+ /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,9})?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/u;
22
+ const EPOCH_MS = 0;
23
+ const YEAR_ZERO = 0;
24
+ const FIRST_MONTH = 1;
25
+ const MIN_POSITIVE_INTEGER = 1;
26
+ const MIN_NON_NEGATIVE_INTEGER = 0;
27
+ const NO_UNKNOWN_KEYS = 0;
28
+ const FIRST_CODE_POINT = 0;
29
+ const LAST_C0_CONTROL = 31;
30
+ const FIRST_C1_CONTROL = 127;
31
+ const LAST_C1_CONTROL = 159;
32
+
33
+ /**
34
+ * @param {unknown} value
35
+ * @returns {value is Readonly<Record<string, unknown>>}
36
+ */
37
+ function isRecord(value) {
38
+ return typeof value === "object" && value !== null && !Array.isArray(value);
39
+ }
40
+
41
+ /**
42
+ * @param {unknown} value
43
+ * @returns {value is readonly unknown[]}
44
+ */
45
+ function isList(value) {
46
+ return Array.isArray(value);
47
+ }
48
+
49
+ /**
50
+ * @param {string} label
51
+ * @param {unknown} value
52
+ * @returns {Readonly<Record<string, unknown>>}
53
+ */
54
+ function requireObject(label, value) {
55
+ if (!isRecord(value)) {
56
+ throw new SdkError("validation_error", `${label} must be an object`);
57
+ }
58
+ return value;
59
+ }
60
+
61
+ /**
62
+ * @param {string} label
63
+ * @param {Readonly<Record<string, unknown>>} value
64
+ * @param {Readonly<ReadonlySet<string>>} allowed
65
+ * @returns {void}
66
+ */
67
+ function rejectUnknownKeys(label, value, allowed) {
68
+ const unknown = Object.keys(value).filter((key) => !allowed.has(key));
69
+ if (unknown.length > NO_UNKNOWN_KEYS) {
70
+ unknown.sort();
71
+ throw new SdkError("validation_error", `${label} has unsupported fields: ${unknown.join(", ")}`);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * @param {string} value
77
+ * @returns {boolean}
78
+ */
79
+ function hasUnicodeControlCharacter(value) {
80
+ return [...value].some((character) => {
81
+ const code = character.codePointAt(FIRST_CODE_POINT);
82
+ return code !== undefined && (code <= LAST_C0_CONTROL || (code >= FIRST_C1_CONTROL && code <= LAST_C1_CONTROL));
83
+ });
84
+ }
85
+
86
+ /**
87
+ * @template Value
88
+ * @template {string} Key
89
+ * @param {Key} key
90
+ * @param {Value | undefined} value
91
+ * @returns {{ [Field in Key]?: Value }}
92
+ */
93
+ function optionalEntry(key, value) {
94
+ /** @type {{ [Field in Key]?: Value }} */
95
+ const entry = {};
96
+ if (value !== undefined) {
97
+ entry[key] = value;
98
+ }
99
+ return entry;
100
+ }
101
+
102
+ /**
103
+ * @param {string} label
104
+ * @param {unknown} value
105
+ * @returns {string}
106
+ */
107
+ function requireNonEmpty(label, value) {
108
+ if (typeof value !== "string" || value.trim() === "") {
109
+ throw new SdkError("validation_error", `${label} must be non-empty`);
110
+ }
111
+ return value;
112
+ }
113
+
114
+ /** @type {(value: unknown) => boolean} */
115
+ const isTruthy = Boolean;
116
+
117
+ /**
118
+ * @param {unknown} value
119
+ * @returns {value is Callable}
120
+ */
121
+ function isCallable(value) {
122
+ return typeof value === "function";
123
+ }
124
+
125
+ /**
126
+ * @param {unknown} value
127
+ * @returns {value is Readonly<Record<string, unknown>>}
128
+ */
129
+ function isObjectValue(value) {
130
+ return typeof value === "object" && value !== null;
131
+ }
132
+
133
+ /**
134
+ * @param {unknown} value
135
+ * @param {string} key
136
+ * @returns {unknown}
137
+ */
138
+ function optionalProperty(value, key) {
139
+ if (value === undefined || value === null) {
140
+ return undefined;
141
+ }
142
+ return Reflect.get(new Object(value), key);
143
+ }
144
+
145
+ /**
146
+ * @param {unknown} value
147
+ * @returns {string | undefined}
148
+ */
149
+ function stringOrUndefined(value) {
150
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
151
+ }
152
+
153
+ /**
154
+ * @template {string} Allowed
155
+ * @param {string} value
156
+ * @param {Readonly<ReadonlySet<Allowed>>} allowedValues
157
+ * @returns {value is Allowed}
158
+ */
159
+ function isAllowedValue(value, allowedValues) {
160
+ /** @type {ReadonlySet<string>} */
161
+ const values = allowedValues;
162
+ return values.has(value);
163
+ }
164
+
165
+ /**
166
+ * @template {string} Allowed
167
+ * @param {string} label
168
+ * @param {unknown} value
169
+ * @param {Readonly<ReadonlySet<Allowed>>} allowedValues
170
+ * @returns {Allowed}
171
+ */
172
+ function requireAllowedValue(label, value, allowedValues) {
173
+ const text = requireNonEmpty(label, value);
174
+ if (!isAllowedValue(text, allowedValues)) {
175
+ throw new SdkError("validation_error", `${label} must be one of: ${[...allowedValues].join(", ")}`);
176
+ }
177
+ return text;
178
+ }
179
+
180
+ /**
181
+ * @param {string} label
182
+ * @param {unknown} value
183
+ * @returns {number}
184
+ */
185
+ function requireFiniteNumber(label, value) {
186
+ if (typeof value !== "number" || !Number.isFinite(value)) {
187
+ throw new SdkError("validation_error", `${label} must be a finite number`);
188
+ }
189
+ return value;
190
+ }
191
+
192
+ /**
193
+ * @param {string} label
194
+ * @param {unknown} value
195
+ * @returns {number}
196
+ */
197
+ function requirePositiveInteger(label, value) {
198
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < MIN_POSITIVE_INTEGER) {
199
+ throw new SdkError("validation_error", `${label} must be a positive integer`);
200
+ }
201
+ return value;
202
+ }
203
+
204
+ /**
205
+ * @param {string} label
206
+ * @param {unknown} value
207
+ * @returns {number}
208
+ */
209
+ function requireNonNegativeInteger(label, value) {
210
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < MIN_NON_NEGATIVE_INTEGER) {
211
+ throw new SdkError("validation_error", `${label} must be a non-negative integer`);
212
+ }
213
+ return value;
214
+ }
215
+
216
+ /**
217
+ * @param {unknown} traceId
218
+ * @returns {string}
219
+ */
220
+ function requireTraceId(traceId) {
221
+ if (typeof traceId !== "string" || !TRACE_ID_PATTERN.test(traceId)) {
222
+ throw new SdkError("validation_error", "traceId must be 32 lowercase or uppercase hex characters");
223
+ }
224
+ if (traceId.toLowerCase() === ZERO_TRACE_ID) {
225
+ throw new SdkError("validation_error", "traceId must not be all zeros");
226
+ }
227
+ return traceId;
228
+ }
229
+
230
+ /**
231
+ * @param {string} label
232
+ * @param {unknown} spanId
233
+ * @returns {string}
234
+ */
235
+ function requireSpanId(label, spanId) {
236
+ if (typeof spanId !== "string" || !SPAN_ID_PATTERN.test(spanId)) {
237
+ throw new SdkError("validation_error", `${label} must be 16 lowercase or uppercase hex characters`);
238
+ }
239
+ if (spanId.toLowerCase() === ZERO_SPAN_ID) {
240
+ throw new SdkError("validation_error", `${label} must not be all zeros`);
241
+ }
242
+ return spanId;
243
+ }
244
+
245
+ /**
246
+ * @param {unknown} traceFlags
247
+ * @returns {string}
248
+ */
249
+ function requireTraceFlags(traceFlags) {
250
+ if (typeof traceFlags !== "string" || !TRACE_FLAGS_PATTERN.test(traceFlags)) {
251
+ throw new SdkError("validation_error", "traceFlags must be 2 lowercase or uppercase hex characters");
252
+ }
253
+ return traceFlags;
254
+ }
255
+
256
+ /**
257
+ * @param {string} timestamp
258
+ * @returns {boolean}
259
+ */
260
+ function hasTimezone(timestamp) {
261
+ if (timestamp.endsWith("Z")) {
262
+ return true;
263
+ }
264
+ const [, timePortion] = timestamp.split("T");
265
+ return timePortion !== undefined && (timePortion.includes("+") || NEGATIVE_OFFSET_PATTERN.test(timePortion));
266
+ }
267
+
268
+ /**
269
+ * @param {string} timestamp
270
+ * @returns {boolean}
271
+ */
272
+ function isCalendarDate(timestamp) {
273
+ const parts = RFC3339_TIMESTAMP_PATTERN.exec(timestamp)?.groups;
274
+ if (parts === undefined) {
275
+ return false;
276
+ }
277
+ const year = Number(parts["year"]);
278
+ const monthIndex = Number(parts["month"]) - FIRST_MONTH;
279
+ const day = Number(parts["day"]);
280
+ const calendar = new Date(EPOCH_MS);
281
+ calendar.setUTCFullYear(year, monthIndex, day);
282
+ return year !== YEAR_ZERO
283
+ && calendar.getUTCFullYear() === year
284
+ && calendar.getUTCMonth() === monthIndex
285
+ && calendar.getUTCDate() === day;
286
+ }
287
+
288
+ /**
289
+ * @param {unknown} timestamp
290
+ * @returns {string}
291
+ */
292
+ function requireTimestamp(timestamp) {
293
+ const text = requireNonEmpty("timestamp", timestamp);
294
+ if (!hasTimezone(text)) {
295
+ throw new SdkError("validation_error", `timestamp must include a timezone offset: ${text}`);
296
+ }
297
+ if (!isCalendarDate(text)) {
298
+ throw new SdkError("validation_error", `invalid timestamp: ${text}`);
299
+ }
300
+ return text;
301
+ }
302
+
303
+ module.exports = {
304
+ ZERO_SPAN_ID,
305
+ ZERO_TRACE_ID,
306
+ hasUnicodeControlCharacter,
307
+ isAllowedValue,
308
+ isCallable,
309
+ isList,
310
+ isObjectValue,
311
+ isRecord,
312
+ isTruthy,
313
+ optionalEntry,
314
+ optionalProperty,
315
+ rejectUnknownKeys,
316
+ requireAllowedValue,
317
+ requireFiniteNumber,
318
+ requireNonEmpty,
319
+ requireNonNegativeInteger,
320
+ requireObject,
321
+ requirePositiveInteger,
322
+ requireSpanId,
323
+ requireTimestamp,
324
+ requireTraceFlags,
325
+ requireTraceId,
326
+ stringOrUndefined
327
+ };
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+
6
+ /**
7
+ * @typedef {{ readonly build?: unknown, readonly esbuild?: unknown, readonly root?: unknown }} ViteUserConfig
8
+ * @typedef {{
9
+ * build?: { rolldownOptions?: { output: { keepNames: true } }, sourcemap?: "hidden" },
10
+ * esbuild?: { keepNames: true }
11
+ * }} ViteConfigChanges
12
+ */
13
+
14
+ const ROLLDOWN_VITE_MAJOR = 8;
15
+ const UNKNOWN_VITE_MAJOR = 0;
16
+ const DECIMAL = 10;
17
+
18
+ /**
19
+ * @param {unknown} manifest
20
+ * @returns {unknown}
21
+ */
22
+ function packageVersion(manifest) {
23
+ return typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "version") : undefined;
24
+ }
25
+
26
+ /**
27
+ * @param {unknown} root
28
+ * @returns {string | undefined}
29
+ */
30
+ function lookupRoot(root) {
31
+ const hasRoot = Boolean(root);
32
+ if (!hasRoot) {
33
+ return process.cwd();
34
+ }
35
+ return typeof root === "string" ? path.resolve(root) : undefined;
36
+ }
37
+
38
+ /**
39
+ * @param {unknown} root
40
+ * @returns {number}
41
+ */
42
+ function viteMajorVersion(root) {
43
+ const lookup = lookupRoot(root);
44
+ if (lookup === undefined) {
45
+ return UNKNOWN_VITE_MAJOR;
46
+ }
47
+ try {
48
+ const manifestPath = require.resolve("vite/package.json", { paths: [lookup] });
49
+ /** @type {unknown} */
50
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
51
+ const major = Number.parseInt(String(packageVersion(manifest)), DECIMAL);
52
+ return Number.isNaN(major) ? UNKNOWN_VITE_MAJOR : major;
53
+ } catch {
54
+ return UNKNOWN_VITE_MAJOR;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @param {unknown} value
60
+ * @param {string} key
61
+ * @returns {unknown}
62
+ */
63
+ function field(value, key) {
64
+ return typeof value === "object" && value !== null ? Reflect.get(value, key) : undefined;
65
+ }
66
+
67
+ /**
68
+ * @param {unknown} build
69
+ * @param {number} viteMajor
70
+ * @returns {boolean}
71
+ */
72
+ function needsRolldownKeepNames(build, viteMajor) {
73
+ const output = field(field(build, "rolldownOptions"), "output");
74
+ return viteMajor >= ROLLDOWN_VITE_MAJOR && !Array.isArray(output) && field(output, "keepNames") === undefined;
75
+ }
76
+
77
+ /**
78
+ * @param {unknown} esbuild
79
+ * @param {number} viteMajor
80
+ * @returns {boolean}
81
+ */
82
+ function needsEsbuildKeepNames(esbuild, viteMajor) {
83
+ return viteMajor < ROLLDOWN_VITE_MAJOR && esbuild !== false && field(esbuild, "keepNames") === undefined;
84
+ }
85
+
86
+ /**
87
+ * @param {boolean} sourceMap
88
+ * @param {boolean} modernNames
89
+ * @returns {ViteConfigChanges}
90
+ */
91
+ function buildChanges(sourceMap, modernNames) {
92
+ if (!sourceMap && !modernNames) {
93
+ return {};
94
+ }
95
+ return {
96
+ build: {
97
+ ...(sourceMap ? { sourcemap: "hidden" } : {}),
98
+ ...(modernNames ? { rolldownOptions: { output: { keepNames: true } } } : {})
99
+ }
100
+ };
101
+ }
102
+
103
+ /**
104
+ * @param {ViteUserConfig} config
105
+ * @param {boolean} enableSourceMaps
106
+ * @returns {ViteConfigChanges | null}
107
+ */
108
+ function viteConfigChanges(config, enableSourceMaps) {
109
+ const sourceMap = enableSourceMaps && field(config.build, "sourcemap") === undefined;
110
+ const keepNames = field(config.build, "minify") === undefined;
111
+ const viteMajor = viteMajorVersion(config.root);
112
+ const modernNames = keepNames && needsRolldownKeepNames(config.build, viteMajor);
113
+ const legacyNames = keepNames && needsEsbuildKeepNames(config.esbuild, viteMajor);
114
+ if (!sourceMap && !modernNames && !legacyNames) {
115
+ return null;
116
+ }
117
+ return { ...buildChanges(sourceMap, modernNames), ...(legacyNames ? { esbuild: { keepNames: true } } : {}) };
118
+ }
119
+
120
+ module.exports = { viteConfigChanges };