@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.
- 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 +35 -2984
- 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-breadcrumbs.cjs +143 -0
- package/issue-diagnostics.cjs +94 -582
- package/issue-evidence.cjs +256 -0
- package/issue-exception.cjs +268 -0
- package/issue-stack-frames.cjs +220 -0
- package/issue-stack-text.cjs +101 -0
- package/issue-stack.cjs +188 -225
- package/issue-text.cjs +72 -0
- package/log-context.cjs +87 -67
- 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 +64 -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/sdk-error.cjs +36 -0
- package/span-validation.cjs +191 -0
- package/stored-events.cjs +243 -0
- package/support-ticket.cjs +232 -122
- package/telemetry-context.cjs +343 -251
- package/trace-context.cjs +376 -179
- package/transport-error.cjs +23 -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 +327 -0
- 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 -290
package/support-ticket.cjs
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
const { SdkError } = require("./sdk-error.cjs");
|
|
2
|
+
const { isRecord, requireAllowedValue, requireNonEmpty, requireTraceId } = require("./validation.cjs");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @import { SupportTicketCategory, SupportTicketDraft, SupportTicketSource } from "./index.cjs"
|
|
6
|
+
* @typedef {string | number | boolean | null | undefined | SanitizedDiagnosticsValue[] | SanitizedDiagnostics} SanitizedDiagnosticsValue
|
|
7
|
+
* @typedef {{ [key: string]: SanitizedDiagnosticsValue }} SanitizedDiagnostics
|
|
8
|
+
* @typedef {Omit<SupportTicketDraft, "diagnostics"> & { diagnostics?: SanitizedDiagnostics }} SanitizedSupportTicketDraft
|
|
9
|
+
* @typedef {Omit<SanitizedSupportTicketDraft, "category" | "description" | "source" | "title">} SupportTicketContext
|
|
10
|
+
* @typedef {(child: unknown, childKey: string) => SanitizedDiagnosticsValue} SanitizeChild
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** @type {ReadonlySet<SupportTicketSource>} */
|
|
1
14
|
const SUPPORT_TICKET_SOURCES = new Set(["cli", "sdk", "website", "docs", "mobile"]);
|
|
15
|
+
/** @type {ReadonlySet<SupportTicketCategory>} */
|
|
2
16
|
const SUPPORT_TICKET_CATEGORIES = new Set([
|
|
3
17
|
"sdk_install_failure",
|
|
4
18
|
"ingest_failure",
|
|
@@ -11,165 +25,261 @@ const SUPPORT_TICKET_CATEGORIES = new Set([
|
|
|
11
25
|
"billing_question",
|
|
12
26
|
"other"
|
|
13
27
|
]);
|
|
28
|
+
const SENSITIVE_KEY_PARTS = [
|
|
29
|
+
"apikey",
|
|
30
|
+
"auth",
|
|
31
|
+
"authorization",
|
|
32
|
+
"authtoken",
|
|
33
|
+
"bearer",
|
|
34
|
+
"clientsecret",
|
|
35
|
+
"connectionstring",
|
|
36
|
+
"cookie",
|
|
37
|
+
"credential",
|
|
38
|
+
"dsn",
|
|
39
|
+
"email",
|
|
40
|
+
"password",
|
|
41
|
+
"passwd",
|
|
42
|
+
"privatekey",
|
|
43
|
+
"refreshtoken",
|
|
44
|
+
"secret",
|
|
45
|
+
"session",
|
|
46
|
+
"setcookie",
|
|
47
|
+
"token"
|
|
48
|
+
];
|
|
14
49
|
const SUPPORT_DIAGNOSTICS_MAX_DEPTH = 5;
|
|
15
50
|
const SUPPORT_DIAGNOSTICS_MAX_ARRAY_LENGTH = 20;
|
|
16
51
|
const SUPPORT_DIAGNOSTICS_MAX_STRING_LENGTH = 500;
|
|
52
|
+
const ROOT_DEPTH = 0;
|
|
53
|
+
const DEPTH_STEP = 1;
|
|
54
|
+
const TEXT_START = 0;
|
|
55
|
+
const KEY_SEPARATOR_PATTERN = /[^a-z0-9]/giu;
|
|
56
|
+
const SENSITIVE_ASSIGNMENT_PATTERN = /(?:authorization|api[_-]?key|token|secret|password|passwd|cookie)\s*[:=]/iu;
|
|
57
|
+
const BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/-]+=*/iu;
|
|
58
|
+
const LOGBREW_KEY_PATTERN = /\blbw_(?:ingest|client|api)_[A-Za-z0-9._-]+/iu;
|
|
59
|
+
const VENDOR_KEY_PATTERN = /\b(?:github_pat|ghp|gho|npm|pypi|sk_live|sk_test|xox[baprs]|AKIA)[A-Za-z0-9._-]+/u;
|
|
60
|
+
const LOCAL_PATH_PATTERN = /^(?:\/Users\/|\/home\/|\/var\/folders\/|[A-Za-z]:\\)/u;
|
|
61
|
+
const QUERY_OR_FRAGMENT_PATTERN = /[?#]/u;
|
|
17
62
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @param {string} key
|
|
65
|
+
* @returns {boolean}
|
|
66
|
+
*/
|
|
67
|
+
function isSensitiveSupportKey(key) {
|
|
68
|
+
if (key === "") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const normalized = key.replaceAll(KEY_SEPARATOR_PATTERN, "").toLowerCase();
|
|
72
|
+
return SENSITIVE_KEY_PARTS.some((needle) => normalized.includes(needle));
|
|
73
|
+
}
|
|
23
74
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
addOptionalSupportString(draft, "environment", "support ticket environment", input.environment, requireNonEmpty);
|
|
35
|
-
addOptionalSupportString(draft, "runtime", "support ticket runtime", input.runtime, requireNonEmpty);
|
|
36
|
-
addOptionalSupportString(draft, "framework", "support ticket framework", input.framework, requireNonEmpty);
|
|
37
|
-
addOptionalSupportString(draft, "sdk_package", "support ticket sdkPackage", input.sdkPackage, requireNonEmpty);
|
|
38
|
-
addOptionalSupportString(draft, "sdk_version", "support ticket sdkVersion", input.sdkVersion, requireNonEmpty);
|
|
39
|
-
addOptionalSupportString(draft, "release", "support ticket release", input.release, requireNonEmpty);
|
|
40
|
-
if (input.traceId !== undefined) {
|
|
41
|
-
requireTraceId(input.traceId);
|
|
42
|
-
draft.trace_id = input.traceId.toLowerCase();
|
|
43
|
-
}
|
|
44
|
-
addOptionalSupportString(draft, "event_id", "support ticket eventId", input.eventId, requireNonEmpty);
|
|
45
|
-
if (input.diagnostics !== undefined) {
|
|
46
|
-
draft.diagnostics = sanitizeSupportDiagnostics(input.diagnostics, SdkError);
|
|
47
|
-
}
|
|
75
|
+
/**
|
|
76
|
+
* @param {string} value
|
|
77
|
+
* @returns {boolean}
|
|
78
|
+
*/
|
|
79
|
+
function isSensitiveSupportString(value) {
|
|
80
|
+
return SENSITIVE_ASSIGNMENT_PATTERN.test(value)
|
|
81
|
+
|| BEARER_PATTERN.test(value)
|
|
82
|
+
|| LOGBREW_KEY_PATTERN.test(value)
|
|
83
|
+
|| VENDOR_KEY_PATTERN.test(value);
|
|
84
|
+
}
|
|
48
85
|
|
|
49
|
-
|
|
50
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @param {string} value
|
|
88
|
+
* @returns {string}
|
|
89
|
+
*/
|
|
90
|
+
function redactUrl(value) {
|
|
91
|
+
try {
|
|
92
|
+
const url = new URL(value);
|
|
93
|
+
return `[redacted-url]${url.pathname || "/"}`;
|
|
94
|
+
} catch {
|
|
95
|
+
const [beforeQuery = value] = value.split(QUERY_OR_FRAGMENT_PATTERN);
|
|
96
|
+
return beforeQuery;
|
|
97
|
+
}
|
|
51
98
|
}
|
|
52
99
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
100
|
+
/**
|
|
101
|
+
* @param {string} value
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
function sanitizeSupportDiagnosticString(value) {
|
|
105
|
+
const trimmed = value.trim();
|
|
106
|
+
if (trimmed === "") {
|
|
107
|
+
return "";
|
|
108
|
+
}
|
|
109
|
+
if (isSensitiveSupportString(trimmed)) {
|
|
110
|
+
return "[redacted]";
|
|
111
|
+
}
|
|
112
|
+
const urlRedacted = redactUrl(LOCAL_PATH_PATTERN.test(trimmed) ? "[redacted-path]" : trimmed);
|
|
113
|
+
return urlRedacted.length > SUPPORT_DIAGNOSTICS_MAX_STRING_LENGTH
|
|
114
|
+
? `${urlRedacted.slice(TEXT_START, SUPPORT_DIAGNOSTICS_MAX_STRING_LENGTH)}...`
|
|
115
|
+
: urlRedacted;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {Readonly<Error>} error
|
|
120
|
+
* @returns {SanitizedDiagnostics}
|
|
121
|
+
*/
|
|
122
|
+
function errorDiagnostics(error) {
|
|
123
|
+
return { name: error.name || "Error" };
|
|
56
124
|
}
|
|
57
125
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
126
|
+
/**
|
|
127
|
+
* @param {unknown} value
|
|
128
|
+
* @returns {SanitizedDiagnosticsValue}
|
|
129
|
+
*/
|
|
130
|
+
function sanitizeSupportDiagnosticScalar(value) {
|
|
131
|
+
if (value === null || (typeof value === "number" && Number.isFinite(value)) || typeof value === "boolean") {
|
|
132
|
+
return value;
|
|
61
133
|
}
|
|
62
|
-
|
|
134
|
+
return typeof value === "string" ? sanitizeSupportDiagnosticString(value) : undefined;
|
|
63
135
|
}
|
|
64
136
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
137
|
+
/**
|
|
138
|
+
* @param {readonly unknown[]} value
|
|
139
|
+
* @param {SanitizeChild} sanitizeChild
|
|
140
|
+
* @returns {SanitizedDiagnosticsValue[]}
|
|
141
|
+
*/
|
|
142
|
+
function sanitizeSupportDiagnosticList(value, sanitizeChild) {
|
|
143
|
+
return value.slice(TEXT_START, SUPPORT_DIAGNOSTICS_MAX_ARRAY_LENGTH).map((item) => sanitizeChild(item, ""));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @param {Readonly<Record<string, unknown>>} value
|
|
148
|
+
* @param {SanitizeChild} sanitizeChild
|
|
149
|
+
* @returns {SanitizedDiagnostics}
|
|
150
|
+
*/
|
|
151
|
+
function sanitizeSupportDiagnosticRecord(value, sanitizeChild) {
|
|
152
|
+
/** @type {SanitizedDiagnostics} */
|
|
153
|
+
const safe = {};
|
|
154
|
+
for (const [childKey, childValue] of Object.entries(value)) {
|
|
155
|
+
const sanitized = sanitizeChild(childValue, childKey);
|
|
156
|
+
if (sanitized !== undefined) {
|
|
157
|
+
safe[childKey] = sanitized;
|
|
158
|
+
}
|
|
68
159
|
}
|
|
69
|
-
return
|
|
160
|
+
return safe;
|
|
70
161
|
}
|
|
71
162
|
|
|
163
|
+
/**
|
|
164
|
+
* @param {unknown} value
|
|
165
|
+
* @param {number} depth
|
|
166
|
+
* @param {string} key
|
|
167
|
+
* @returns {SanitizedDiagnosticsValue}
|
|
168
|
+
*/
|
|
72
169
|
function sanitizeSupportDiagnosticValue(value, depth, key) {
|
|
73
170
|
if (isSensitiveSupportKey(key)) {
|
|
74
171
|
return "[redacted]";
|
|
75
172
|
}
|
|
76
173
|
if (value instanceof Error) {
|
|
77
|
-
return
|
|
174
|
+
return errorDiagnostics(value);
|
|
78
175
|
}
|
|
79
|
-
if (
|
|
80
|
-
return value;
|
|
176
|
+
if (!Array.isArray(value) && !isRecord(value)) {
|
|
177
|
+
return sanitizeSupportDiagnosticScalar(value);
|
|
81
178
|
}
|
|
82
|
-
if (
|
|
83
|
-
return
|
|
179
|
+
if (depth >= SUPPORT_DIAGNOSTICS_MAX_DEPTH) {
|
|
180
|
+
return "[max-depth]";
|
|
84
181
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
182
|
+
const childDepth = depth + DEPTH_STEP;
|
|
183
|
+
return isRecord(value)
|
|
184
|
+
? sanitizeSupportDiagnosticRecord(value, (child, childKey) => sanitizeSupportDiagnosticValue(child, childDepth, childKey))
|
|
185
|
+
: sanitizeSupportDiagnosticList(value, (child, childKey) => sanitizeSupportDiagnosticValue(child, childDepth, childKey));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {unknown} diagnostics
|
|
190
|
+
* @returns {{ diagnostics?: SanitizedDiagnostics }}
|
|
191
|
+
*/
|
|
192
|
+
function optionalDiagnostics(diagnostics) {
|
|
193
|
+
if (diagnostics === undefined) {
|
|
194
|
+
return {};
|
|
92
195
|
}
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
for (const [childKey, childValue] of Object.entries(value)) {
|
|
99
|
-
const sanitized = sanitizeSupportDiagnosticValue(childValue, depth + 1, childKey);
|
|
100
|
-
if (sanitized !== undefined) {
|
|
101
|
-
safe[childKey] = sanitized;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return safe;
|
|
196
|
+
if (!isRecord(diagnostics)) {
|
|
197
|
+
throw new SdkError("validation_error", "support ticket diagnostics must be an object");
|
|
198
|
+
}
|
|
199
|
+
if (diagnostics instanceof Error) {
|
|
200
|
+
return { diagnostics: errorDiagnostics(diagnostics) };
|
|
105
201
|
}
|
|
106
|
-
return
|
|
202
|
+
return {
|
|
203
|
+
diagnostics: sanitizeSupportDiagnosticRecord(
|
|
204
|
+
diagnostics,
|
|
205
|
+
(child, childKey) => sanitizeSupportDiagnosticValue(child, ROOT_DEPTH + DEPTH_STEP, childKey)
|
|
206
|
+
)
|
|
207
|
+
};
|
|
107
208
|
}
|
|
108
209
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"auth",
|
|
117
|
-
"authorization",
|
|
118
|
-
"authtoken",
|
|
119
|
-
"bearer",
|
|
120
|
-
"clientsecret",
|
|
121
|
-
"connectionstring",
|
|
122
|
-
"cookie",
|
|
123
|
-
"credential",
|
|
124
|
-
"dsn",
|
|
125
|
-
"email",
|
|
126
|
-
"password",
|
|
127
|
-
"passwd",
|
|
128
|
-
"privatekey",
|
|
129
|
-
"refreshtoken",
|
|
130
|
-
"secret",
|
|
131
|
-
"session",
|
|
132
|
-
"setcookie",
|
|
133
|
-
"token"
|
|
134
|
-
].some((needle) => normalized.includes(needle));
|
|
210
|
+
/**
|
|
211
|
+
* @param {string} label
|
|
212
|
+
* @param {unknown} value
|
|
213
|
+
* @returns {string}
|
|
214
|
+
*/
|
|
215
|
+
function requiredSupportString(label, value) {
|
|
216
|
+
return requireNonEmpty(label, value).trim();
|
|
135
217
|
}
|
|
136
218
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
219
|
+
/**
|
|
220
|
+
* @template {string} Key
|
|
221
|
+
* @param {Key} key
|
|
222
|
+
* @param {string} label
|
|
223
|
+
* @param {unknown} value
|
|
224
|
+
* @returns {{ [Field in Key]?: string }}
|
|
225
|
+
*/
|
|
226
|
+
function optionalSupportString(key, label, value) {
|
|
227
|
+
/** @type {{ [Field in Key]?: string }} */
|
|
228
|
+
const field = {};
|
|
229
|
+
if (value !== undefined) {
|
|
230
|
+
field[key] = requiredSupportString(label, value);
|
|
141
231
|
}
|
|
142
|
-
|
|
143
|
-
return "[redacted]";
|
|
144
|
-
}
|
|
145
|
-
const pathRedacted = redactLocalPath(trimmed);
|
|
146
|
-
const urlRedacted = redactUrl(pathRedacted);
|
|
147
|
-
return urlRedacted.length > SUPPORT_DIAGNOSTICS_MAX_STRING_LENGTH
|
|
148
|
-
? `${urlRedacted.slice(0, SUPPORT_DIAGNOSTICS_MAX_STRING_LENGTH)}...`
|
|
149
|
-
: urlRedacted;
|
|
232
|
+
return field;
|
|
150
233
|
}
|
|
151
234
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
235
|
+
/**
|
|
236
|
+
* @param {unknown} traceId
|
|
237
|
+
* @returns {{ trace_id?: string }}
|
|
238
|
+
*/
|
|
239
|
+
function optionalTraceId(traceId) {
|
|
240
|
+
return traceId === undefined ? {} : { trace_id: requireTraceId(traceId).toLowerCase() };
|
|
157
241
|
}
|
|
158
242
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
243
|
+
/**
|
|
244
|
+
* @param {Readonly<Record<string, unknown>>} input
|
|
245
|
+
* @returns {SupportTicketContext}
|
|
246
|
+
*/
|
|
247
|
+
function supportTicketContext(input) {
|
|
248
|
+
return {
|
|
249
|
+
...optionalSupportString("project_id", "support ticket projectId", input["projectId"]),
|
|
250
|
+
...optionalSupportString("environment", "support ticket environment", input["environment"]),
|
|
251
|
+
...optionalSupportString("runtime", "support ticket runtime", input["runtime"]),
|
|
252
|
+
...optionalSupportString("framework", "support ticket framework", input["framework"]),
|
|
253
|
+
...optionalSupportString("sdk_package", "support ticket sdkPackage", input["sdkPackage"]),
|
|
254
|
+
...optionalSupportString("sdk_version", "support ticket sdkVersion", input["sdkVersion"]),
|
|
255
|
+
...optionalSupportString("release", "support ticket release", input["release"]),
|
|
256
|
+
...optionalTraceId(input["traceId"]),
|
|
257
|
+
...optionalSupportString("event_id", "support ticket eventId", input["eventId"]),
|
|
258
|
+
...optionalDiagnostics(input["diagnostics"])
|
|
259
|
+
};
|
|
164
260
|
}
|
|
165
261
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
262
|
+
/**
|
|
263
|
+
* @param {unknown} input
|
|
264
|
+
* @returns {SanitizedSupportTicketDraft}
|
|
265
|
+
*/
|
|
266
|
+
function createSupportTicketDraft(input) {
|
|
267
|
+
if (!isRecord(input)) {
|
|
268
|
+
throw new SdkError("validation_error", "support ticket draft input must be an object");
|
|
172
269
|
}
|
|
270
|
+
const source = requireAllowedValue("support ticket source", input["source"], SUPPORT_TICKET_SOURCES);
|
|
271
|
+
const category = requireAllowedValue("support ticket category", input["category"], SUPPORT_TICKET_CATEGORIES);
|
|
272
|
+
const title = requiredSupportString("support ticket title", input["title"]);
|
|
273
|
+
const description = requiredSupportString("support ticket description", input["description"]);
|
|
274
|
+
return {
|
|
275
|
+
source,
|
|
276
|
+
|
|
277
|
+
category,
|
|
278
|
+
title,
|
|
279
|
+
|
|
280
|
+
description,
|
|
281
|
+
...supportTicketContext(input)
|
|
282
|
+
};
|
|
173
283
|
}
|
|
174
284
|
|
|
175
|
-
module.exports = {
|
|
285
|
+
module.exports = { createSupportTicketDraft };
|