@kaitencloud/server 1.0.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/dist/index.mjs ADDED
@@ -0,0 +1,2744 @@
1
+ //#region src/generated/core/bodySerializer.gen.ts
2
+ const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
3
+ //#endregion
4
+ //#region src/generated/core/serverSentEvents.gen.ts
5
+ function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
6
+ let lastEventId;
7
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
8
+ const createStream = async function* () {
9
+ let retryDelay = sseDefaultRetryDelay ?? 3e3;
10
+ let attempt = 0;
11
+ const signal = options.signal ?? new AbortController().signal;
12
+ while (true) {
13
+ if (signal.aborted) break;
14
+ attempt++;
15
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
16
+ if (lastEventId !== void 0) headers.set("Last-Event-ID", lastEventId);
17
+ try {
18
+ const requestInit = {
19
+ redirect: "follow",
20
+ ...options,
21
+ body: options.serializedBody,
22
+ headers,
23
+ signal
24
+ };
25
+ let request = new Request(url, requestInit);
26
+ if (onRequest) request = await onRequest(url, requestInit);
27
+ const response = await (options.fetch ?? globalThis.fetch)(request);
28
+ if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
29
+ if (!response.body) throw new Error("No body in SSE response");
30
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
31
+ let buffer = "";
32
+ const abortHandler = () => {
33
+ try {
34
+ reader.cancel();
35
+ } catch {}
36
+ };
37
+ signal.addEventListener("abort", abortHandler);
38
+ try {
39
+ while (true) {
40
+ const { done, value } = await reader.read();
41
+ if (done) break;
42
+ buffer += value;
43
+ buffer = buffer.replace(/\r\n?/g, "\n");
44
+ const chunks = buffer.split("\n\n");
45
+ buffer = chunks.pop() ?? "";
46
+ for (const chunk of chunks) {
47
+ const lines = chunk.split("\n");
48
+ const dataLines = [];
49
+ let eventName;
50
+ for (const line of lines) if (line.startsWith("data:")) dataLines.push(line.replace(/^data:\s*/, ""));
51
+ else if (line.startsWith("event:")) eventName = line.replace(/^event:\s*/, "");
52
+ else if (line.startsWith("id:")) lastEventId = line.replace(/^id:\s*/, "");
53
+ else if (line.startsWith("retry:")) {
54
+ const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
55
+ if (!Number.isNaN(parsed)) retryDelay = parsed;
56
+ }
57
+ let data;
58
+ let parsedJson = false;
59
+ if (dataLines.length) {
60
+ const rawData = dataLines.join("\n");
61
+ try {
62
+ data = JSON.parse(rawData);
63
+ parsedJson = true;
64
+ } catch {
65
+ data = rawData;
66
+ }
67
+ }
68
+ if (parsedJson) {
69
+ if (responseValidator) await responseValidator(data);
70
+ if (responseTransformer) data = await responseTransformer(data);
71
+ }
72
+ onSseEvent?.({
73
+ data,
74
+ event: eventName,
75
+ id: lastEventId,
76
+ retry: retryDelay
77
+ });
78
+ if (dataLines.length) yield data;
79
+ }
80
+ }
81
+ } finally {
82
+ signal.removeEventListener("abort", abortHandler);
83
+ reader.releaseLock();
84
+ }
85
+ break;
86
+ } catch (error) {
87
+ onSseError?.(error);
88
+ if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) break;
89
+ const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
90
+ await sleep(backoff);
91
+ }
92
+ }
93
+ };
94
+ return { stream: createStream() };
95
+ }
96
+ //#endregion
97
+ //#region src/generated/core/pathSerializer.gen.ts
98
+ const separatorArrayExplode = (style) => {
99
+ switch (style) {
100
+ case "label": return ".";
101
+ case "matrix": return ";";
102
+ case "simple": return ",";
103
+ default: return "&";
104
+ }
105
+ };
106
+ const separatorArrayNoExplode = (style) => {
107
+ switch (style) {
108
+ case "form": return ",";
109
+ case "pipeDelimited": return "|";
110
+ case "spaceDelimited": return "%20";
111
+ default: return ",";
112
+ }
113
+ };
114
+ const separatorObjectExplode = (style) => {
115
+ switch (style) {
116
+ case "label": return ".";
117
+ case "matrix": return ";";
118
+ case "simple": return ",";
119
+ default: return "&";
120
+ }
121
+ };
122
+ const serializeArrayParam = ({ allowReserved, explode, name, style, value }) => {
123
+ if (!explode) {
124
+ const joinedValues = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
125
+ switch (style) {
126
+ case "label": return `.${joinedValues}`;
127
+ case "matrix": return `;${name}=${joinedValues}`;
128
+ case "simple": return joinedValues;
129
+ default: return `${name}=${joinedValues}`;
130
+ }
131
+ }
132
+ const separator = separatorArrayExplode(style);
133
+ const joinedValues = value.map((v) => {
134
+ if (style === "label" || style === "simple") return allowReserved ? v : encodeURIComponent(v);
135
+ return serializePrimitiveParam({
136
+ allowReserved,
137
+ name,
138
+ value: v
139
+ });
140
+ }).join(separator);
141
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
142
+ };
143
+ const serializePrimitiveParam = ({ allowReserved, name, value }) => {
144
+ if (value === void 0 || value === null) return "";
145
+ if (typeof value === "object") throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");
146
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
147
+ };
148
+ const serializeObjectParam = ({ allowReserved, explode, name, style, value, valueOnly }) => {
149
+ if (value instanceof Date) return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
150
+ if (style !== "deepObject" && !explode) {
151
+ let values = [];
152
+ Object.entries(value).forEach(([key, v]) => {
153
+ values = [
154
+ ...values,
155
+ key,
156
+ allowReserved ? v : encodeURIComponent(v)
157
+ ];
158
+ });
159
+ const joinedValues = values.join(",");
160
+ switch (style) {
161
+ case "form": return `${name}=${joinedValues}`;
162
+ case "label": return `.${joinedValues}`;
163
+ case "matrix": return `;${name}=${joinedValues}`;
164
+ default: return joinedValues;
165
+ }
166
+ }
167
+ const separator = separatorObjectExplode(style);
168
+ const joinedValues = Object.entries(value).map(([key, v]) => serializePrimitiveParam({
169
+ allowReserved,
170
+ name: style === "deepObject" ? `${name}[${key}]` : key,
171
+ value: v
172
+ })).join(separator);
173
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
174
+ };
175
+ //#endregion
176
+ //#region src/generated/core/utils.gen.ts
177
+ const PATH_PARAM_RE = /\{[^{}]+\}/g;
178
+ const defaultPathSerializer = ({ path, url: _url }) => {
179
+ let url = _url;
180
+ const matches = _url.match(PATH_PARAM_RE);
181
+ if (matches) for (const match of matches) {
182
+ let explode = false;
183
+ let name = match.substring(1, match.length - 1);
184
+ let style = "simple";
185
+ if (name.endsWith("*")) {
186
+ explode = true;
187
+ name = name.substring(0, name.length - 1);
188
+ }
189
+ if (name.startsWith(".")) {
190
+ name = name.substring(1);
191
+ style = "label";
192
+ } else if (name.startsWith(";")) {
193
+ name = name.substring(1);
194
+ style = "matrix";
195
+ }
196
+ const value = path[name];
197
+ if (value === void 0 || value === null) continue;
198
+ if (Array.isArray(value)) {
199
+ url = url.replace(match, serializeArrayParam({
200
+ explode,
201
+ name,
202
+ style,
203
+ value
204
+ }));
205
+ continue;
206
+ }
207
+ if (typeof value === "object") {
208
+ url = url.replace(match, serializeObjectParam({
209
+ explode,
210
+ name,
211
+ style,
212
+ value,
213
+ valueOnly: true
214
+ }));
215
+ continue;
216
+ }
217
+ if (style === "matrix") {
218
+ url = url.replace(match, `;${serializePrimitiveParam({
219
+ name,
220
+ value
221
+ })}`);
222
+ continue;
223
+ }
224
+ const replaceValue = encodeURIComponent(style === "label" ? `.${value}` : value);
225
+ url = url.replace(match, replaceValue);
226
+ }
227
+ return url;
228
+ };
229
+ const getUrl = ({ baseUrl, path, query, querySerializer, url: _url }) => {
230
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
231
+ let url = (baseUrl ?? "") + pathUrl;
232
+ if (path) url = defaultPathSerializer({
233
+ path,
234
+ url
235
+ });
236
+ let search = query ? querySerializer(query) : "";
237
+ if (search.startsWith("?")) search = search.substring(1);
238
+ if (search) url += `?${search}`;
239
+ return url;
240
+ };
241
+ function getValidRequestBody(options) {
242
+ const hasBody = options.body !== void 0;
243
+ if (hasBody && options.bodySerializer) {
244
+ if ("serializedBody" in options) return options.serializedBody !== void 0 && options.serializedBody !== "" ? options.serializedBody : null;
245
+ return options.body !== "" ? options.body : null;
246
+ }
247
+ if (hasBody) return options.body;
248
+ }
249
+ //#endregion
250
+ //#region src/generated/core/auth.gen.ts
251
+ const getAuthToken = async (auth, callback) => {
252
+ const token = typeof callback === "function" ? await callback(auth) : callback;
253
+ if (!token) return;
254
+ if (auth.scheme === "bearer") return `Bearer ${token}`;
255
+ if (auth.scheme === "basic") return `Basic ${btoa(token)}`;
256
+ return token;
257
+ };
258
+ //#endregion
259
+ //#region src/generated/client/utils.gen.ts
260
+ const createQuerySerializer = ({ parameters = {}, ...args } = {}) => {
261
+ const querySerializer = (queryParams) => {
262
+ const search = [];
263
+ if (queryParams && typeof queryParams === "object") for (const name in queryParams) {
264
+ const value = queryParams[name];
265
+ if (value === void 0 || value === null) continue;
266
+ const options = parameters[name] || args;
267
+ if (Array.isArray(value)) {
268
+ const serializedArray = serializeArrayParam({
269
+ allowReserved: options.allowReserved,
270
+ explode: true,
271
+ name,
272
+ style: "form",
273
+ value,
274
+ ...options.array
275
+ });
276
+ if (serializedArray) search.push(serializedArray);
277
+ } else if (typeof value === "object") {
278
+ const serializedObject = serializeObjectParam({
279
+ allowReserved: options.allowReserved,
280
+ explode: true,
281
+ name,
282
+ style: "deepObject",
283
+ value,
284
+ ...options.object
285
+ });
286
+ if (serializedObject) search.push(serializedObject);
287
+ } else {
288
+ const serializedPrimitive = serializePrimitiveParam({
289
+ allowReserved: options.allowReserved,
290
+ name,
291
+ value
292
+ });
293
+ if (serializedPrimitive) search.push(serializedPrimitive);
294
+ }
295
+ }
296
+ return search.join("&");
297
+ };
298
+ return querySerializer;
299
+ };
300
+ /**
301
+ * Infers parseAs value from provided Content-Type header.
302
+ */
303
+ const getParseAs = (contentType) => {
304
+ if (!contentType) return "stream";
305
+ const cleanContent = contentType.split(";")[0]?.trim();
306
+ if (!cleanContent) return;
307
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) return "json";
308
+ if (cleanContent === "multipart/form-data") return "formData";
309
+ if ([
310
+ "application/",
311
+ "audio/",
312
+ "image/",
313
+ "video/"
314
+ ].some((type) => cleanContent.startsWith(type))) return "blob";
315
+ if (cleanContent.startsWith("text/")) return "text";
316
+ };
317
+ const checkForExistence = (options, name) => {
318
+ if (!name) return false;
319
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) return true;
320
+ return false;
321
+ };
322
+ async function setAuthParams(options) {
323
+ for (const auth of options.security ?? []) {
324
+ if (checkForExistence(options, auth.name)) continue;
325
+ const token = await getAuthToken(auth, options.auth);
326
+ if (!token) continue;
327
+ const name = auth.name ?? "Authorization";
328
+ switch (auth.in) {
329
+ case "query":
330
+ if (!options.query) options.query = {};
331
+ options.query[name] = token;
332
+ break;
333
+ case "cookie":
334
+ options.headers.append("Cookie", `${name}=${token}`);
335
+ break;
336
+ default: options.headers.set(name, token);
337
+ }
338
+ }
339
+ }
340
+ const buildUrl = (options) => getUrl({
341
+ baseUrl: options.baseUrl,
342
+ path: options.path,
343
+ query: options.query,
344
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
345
+ url: options.url
346
+ });
347
+ const mergeConfigs = (a, b) => {
348
+ const config = {
349
+ ...a,
350
+ ...b
351
+ };
352
+ if (config.baseUrl?.endsWith("/")) config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
353
+ config.headers = mergeHeaders(a.headers, b.headers);
354
+ return config;
355
+ };
356
+ const headersEntries = (headers) => {
357
+ const entries = [];
358
+ headers.forEach((value, key) => {
359
+ entries.push([key, value]);
360
+ });
361
+ return entries;
362
+ };
363
+ const mergeHeaders = (...headers) => {
364
+ const mergedHeaders = new Headers();
365
+ for (const header of headers) {
366
+ if (!header) continue;
367
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
368
+ for (const [key, value] of iterator) if (value === null) mergedHeaders.delete(key);
369
+ else if (Array.isArray(value)) for (const v of value) mergedHeaders.append(key, v);
370
+ else if (value !== void 0) mergedHeaders.set(key, typeof value === "object" ? JSON.stringify(value) : value);
371
+ }
372
+ return mergedHeaders;
373
+ };
374
+ var Interceptors = class {
375
+ fns = [];
376
+ clear() {
377
+ this.fns = [];
378
+ }
379
+ eject(id) {
380
+ const index = this.getInterceptorIndex(id);
381
+ if (this.fns[index]) this.fns[index] = null;
382
+ }
383
+ exists(id) {
384
+ const index = this.getInterceptorIndex(id);
385
+ return Boolean(this.fns[index]);
386
+ }
387
+ getInterceptorIndex(id) {
388
+ if (typeof id === "number") return this.fns[id] ? id : -1;
389
+ return this.fns.indexOf(id);
390
+ }
391
+ update(id, fn) {
392
+ const index = this.getInterceptorIndex(id);
393
+ if (this.fns[index]) {
394
+ this.fns[index] = fn;
395
+ return id;
396
+ }
397
+ return false;
398
+ }
399
+ use(fn) {
400
+ this.fns.push(fn);
401
+ return this.fns.length - 1;
402
+ }
403
+ };
404
+ const createInterceptors = () => ({
405
+ error: new Interceptors(),
406
+ request: new Interceptors(),
407
+ response: new Interceptors()
408
+ });
409
+ const defaultQuerySerializer = createQuerySerializer({
410
+ allowReserved: false,
411
+ array: {
412
+ explode: true,
413
+ style: "form"
414
+ },
415
+ object: {
416
+ explode: true,
417
+ style: "deepObject"
418
+ }
419
+ });
420
+ const defaultHeaders = { "Content-Type": "application/json" };
421
+ const createConfig = (override = {}) => ({
422
+ ...jsonBodySerializer,
423
+ headers: defaultHeaders,
424
+ parseAs: "auto",
425
+ querySerializer: defaultQuerySerializer,
426
+ ...override
427
+ });
428
+ //#endregion
429
+ //#region src/generated/client/client.gen.ts
430
+ const createClient = (config = {}) => {
431
+ let _config = mergeConfigs(createConfig(), config);
432
+ const getConfig = () => ({ ..._config });
433
+ const setConfig = (config) => {
434
+ _config = mergeConfigs(_config, config);
435
+ return getConfig();
436
+ };
437
+ const interceptors = createInterceptors();
438
+ const beforeRequest = async (options) => {
439
+ const opts = {
440
+ ..._config,
441
+ ...options,
442
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
443
+ headers: mergeHeaders(_config.headers, options.headers),
444
+ serializedBody: void 0
445
+ };
446
+ if (opts.security) await setAuthParams(opts);
447
+ if (opts.requestValidator) await opts.requestValidator(opts);
448
+ if (opts.body !== void 0 && opts.bodySerializer) opts.serializedBody = opts.bodySerializer(opts.body);
449
+ if (opts.body === void 0 || opts.serializedBody === "") opts.headers.delete("Content-Type");
450
+ const resolvedOpts = opts;
451
+ return {
452
+ opts: resolvedOpts,
453
+ url: buildUrl(resolvedOpts)
454
+ };
455
+ };
456
+ const request = async (options) => {
457
+ const throwOnError = options.throwOnError ?? _config.throwOnError;
458
+ const responseStyle = options.responseStyle ?? _config.responseStyle;
459
+ let request;
460
+ let response;
461
+ try {
462
+ const { opts, url } = await beforeRequest(options);
463
+ const requestInit = {
464
+ redirect: "follow",
465
+ ...opts,
466
+ body: getValidRequestBody(opts)
467
+ };
468
+ request = new Request(url, requestInit);
469
+ for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
470
+ const _fetch = opts.fetch;
471
+ response = await _fetch(request);
472
+ for (const fn of interceptors.response.fns) if (fn) response = await fn(response, request, opts);
473
+ const result = {
474
+ request,
475
+ response
476
+ };
477
+ if (response.ok) {
478
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
479
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
480
+ let emptyData;
481
+ switch (parseAs) {
482
+ case "arrayBuffer":
483
+ case "blob":
484
+ case "text":
485
+ emptyData = await response[parseAs]();
486
+ break;
487
+ case "formData":
488
+ emptyData = new FormData();
489
+ break;
490
+ case "stream":
491
+ emptyData = response.body;
492
+ break;
493
+ default: emptyData = {};
494
+ }
495
+ return opts.responseStyle === "data" ? emptyData : {
496
+ data: emptyData,
497
+ ...result
498
+ };
499
+ }
500
+ let data;
501
+ switch (parseAs) {
502
+ case "arrayBuffer":
503
+ case "blob":
504
+ case "formData":
505
+ case "text":
506
+ data = await response[parseAs]();
507
+ break;
508
+ case "json": {
509
+ const text = await response.text();
510
+ data = text ? JSON.parse(text) : {};
511
+ break;
512
+ }
513
+ case "stream": return opts.responseStyle === "data" ? response.body : {
514
+ data: response.body,
515
+ ...result
516
+ };
517
+ }
518
+ if (parseAs === "json") {
519
+ if (opts.responseValidator) await opts.responseValidator(data);
520
+ if (opts.responseTransformer) data = await opts.responseTransformer(data);
521
+ }
522
+ return opts.responseStyle === "data" ? data : {
523
+ data,
524
+ ...result
525
+ };
526
+ }
527
+ const textError = await response.text();
528
+ let jsonError;
529
+ try {
530
+ jsonError = JSON.parse(textError);
531
+ } catch {}
532
+ throw jsonError ?? textError;
533
+ } catch (error) {
534
+ let finalError = error;
535
+ for (const fn of interceptors.error.fns) if (fn) finalError = await fn(finalError, response, request, options);
536
+ finalError = finalError || {};
537
+ if (throwOnError) throw finalError;
538
+ return responseStyle === "data" ? void 0 : {
539
+ error: finalError,
540
+ request,
541
+ response
542
+ };
543
+ }
544
+ };
545
+ const makeMethodFn = (method) => (options) => request({
546
+ ...options,
547
+ method
548
+ });
549
+ const makeSseFn = (method) => async (options) => {
550
+ const { opts, url } = await beforeRequest(options);
551
+ return createSseClient({
552
+ ...opts,
553
+ body: opts.body,
554
+ method,
555
+ onRequest: async (url, init) => {
556
+ let request = new Request(url, init);
557
+ for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
558
+ return request;
559
+ },
560
+ serializedBody: getValidRequestBody(opts),
561
+ url
562
+ });
563
+ };
564
+ const _buildUrl = (options) => buildUrl({
565
+ ..._config,
566
+ ...options
567
+ });
568
+ return {
569
+ buildUrl: _buildUrl,
570
+ connect: makeMethodFn("CONNECT"),
571
+ delete: makeMethodFn("DELETE"),
572
+ get: makeMethodFn("GET"),
573
+ getConfig,
574
+ head: makeMethodFn("HEAD"),
575
+ interceptors,
576
+ options: makeMethodFn("OPTIONS"),
577
+ patch: makeMethodFn("PATCH"),
578
+ post: makeMethodFn("POST"),
579
+ put: makeMethodFn("PUT"),
580
+ request,
581
+ setConfig,
582
+ sse: {
583
+ connect: makeSseFn("CONNECT"),
584
+ delete: makeSseFn("DELETE"),
585
+ get: makeSseFn("GET"),
586
+ head: makeSseFn("HEAD"),
587
+ options: makeSseFn("OPTIONS"),
588
+ patch: makeSseFn("PATCH"),
589
+ post: makeSseFn("POST"),
590
+ put: makeSseFn("PUT"),
591
+ trace: makeSseFn("TRACE")
592
+ },
593
+ trace: makeMethodFn("TRACE")
594
+ };
595
+ };
596
+ //#endregion
597
+ //#region src/errors.ts
598
+ /**
599
+ * Thrown when the API responds with an error status. Carries the HTTP `status`
600
+ * and the parsed {@link KaitenApiError} body. Narrow with `instanceof KaitenError`
601
+ * or the `kind === "api"` discriminant.
602
+ */
603
+ var KaitenError = class extends Error {
604
+ kind = "api";
605
+ status;
606
+ detail;
607
+ /** Stable, machine-readable error code, such as `License.NotFound`. */
608
+ code;
609
+ /** Correlation id of the API's log entry for this failure. */
610
+ errorId;
611
+ errors;
612
+ raw;
613
+ constructor(apiError) {
614
+ super(apiError.title);
615
+ this.name = "KaitenError";
616
+ this.status = apiError.status;
617
+ this.detail = apiError.detail;
618
+ this.code = apiError.code;
619
+ this.errorId = apiError.errorId;
620
+ this.errors = apiError.errors;
621
+ this.raw = apiError;
622
+ }
623
+ };
624
+ /**
625
+ * Thrown when the request never reached the API (offline, DNS, abort) — there
626
+ * is no HTTP status. Narrow with `instanceof KaitenNetworkError` or the
627
+ * `kind === "network"` discriminant.
628
+ */
629
+ var KaitenNetworkError = class extends Error {
630
+ kind = "network";
631
+ cause;
632
+ constructor(message, cause) {
633
+ super(message);
634
+ this.name = "KaitenNetworkError";
635
+ this.cause = cause;
636
+ }
637
+ };
638
+ const isRecord = (value) => typeof value === "object" && value !== null;
639
+ /**
640
+ * Converts whatever the generated client rejected with into a real `Error`.
641
+ *
642
+ * The generated transport throws the *parsed response body* (or the raw text
643
+ * when it is not JSON), so without this the value reaching a `catch` has no
644
+ * stack, no `message`, and does not satisfy `instanceof Error`.
645
+ */
646
+ function toKaitenError(error, response) {
647
+ if (error instanceof KaitenError || error instanceof KaitenNetworkError) return error;
648
+ if (!response) {
649
+ if (error instanceof Error) return new KaitenNetworkError(error.message, error);
650
+ return new KaitenNetworkError("Request to the Kaiten API failed", error);
651
+ }
652
+ if (isRecord(error) && typeof error["title"] === "string") {
653
+ const body = error;
654
+ return new KaitenError({
655
+ ...body,
656
+ status: typeof body.status === "number" ? body.status : response.status
657
+ });
658
+ }
659
+ const detail = typeof error === "string" && error.length > 0 ? error : isRecord(error) && typeof error["detail"] === "string" ? error["detail"] : void 0;
660
+ return new KaitenError({
661
+ title: response.statusText || `HTTP ${response.status}`,
662
+ status: response.status,
663
+ ...detail === void 0 ? {} : { detail }
664
+ });
665
+ }
666
+ /** The code the API returns when a usage report would cross the entitlement's limit. */
667
+ const THRESHOLD_EXCEEDED = "ReportEntitlementUsageMetric.ThresholdExceeded";
668
+ /**
669
+ * True when the API refused a usage report because the entitlement's threshold
670
+ * is already reached: HTTP 409 with the code
671
+ * `ReportEntitlementUsageMetric.ThresholdExceeded`.
672
+ *
673
+ * `POST /instances/{instanceSlug}/entitlements/{entitlementSlug}/usage` answers
674
+ * that way when the increment would cross the license limit. That response is
675
+ * the enforcement signal the whole metering path exists to produce, so it gets a
676
+ * named predicate. Other operations answer 409 for other conflicts, such as a
677
+ * slug already taken: the code tells them apart, so the predicate is safe in a
678
+ * shared error handler.
679
+ */
680
+ function isThresholdExceeded(error) {
681
+ return error instanceof KaitenError && error.status === 409 && error.code === THRESHOLD_EXCEEDED;
682
+ }
683
+ //#endregion
684
+ //#region src/webhooks.ts
685
+ /** Thrown when a webhook cannot be attributed to Kaiten. */
686
+ var KaitenWebhookVerificationError = class extends Error {
687
+ kind = "webhook-verification";
688
+ constructor(message) {
689
+ super(message);
690
+ this.name = "KaitenWebhookVerificationError";
691
+ }
692
+ };
693
+ const DEFAULT_TOLERANCE_SECONDS = 300;
694
+ function readHeader(headers, ...names) {
695
+ for (const name of names) {
696
+ const value = headers instanceof Headers ? headers.get(name) : headers[name] ?? headers[name.toLowerCase()] ?? headers[name.toUpperCase()];
697
+ const resolved = Array.isArray(value) ? value[0] : value;
698
+ if (typeof resolved === "string" && resolved.length > 0) return resolved;
699
+ }
700
+ }
701
+ function base64ToBytes(value) {
702
+ const binary = atob(value);
703
+ const bytes = new Uint8Array(new ArrayBuffer(binary.length));
704
+ for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
705
+ return bytes;
706
+ }
707
+ function bytesToBase64(bytes) {
708
+ let binary = "";
709
+ for (const byte of bytes) binary += String.fromCharCode(byte);
710
+ return btoa(binary);
711
+ }
712
+ /**
713
+ * Compares two strings without leaking where they first differ.
714
+ *
715
+ * Hand-written rather than `node:crypto.timingSafeEqual` for two reasons: that
716
+ * function **throws** on unequal lengths (unlike the `hmac.Equal` the reference
717
+ * implementation uses), so a signature of the wrong length would surface as an
718
+ * unhandled RangeError — a 500 where a 401 belongs; and importing `node:crypto`
719
+ * would make this package Node-only, where today it touches nothing outside the
720
+ * web platform and runs unchanged on Deno, Bun and edge runtimes.
721
+ */
722
+ function constantTimeEquals(left, right) {
723
+ if (left.length !== right.length) return false;
724
+ let diff = 0;
725
+ for (let i = 0; i < left.length; i += 1) diff |= left.charCodeAt(i) ^ right.charCodeAt(i);
726
+ return diff === 0;
727
+ }
728
+ /**
729
+ * Verifies a Kaiten webhook and returns its typed payload.
730
+ *
731
+ * Throws {@link KaitenWebhookVerificationError} when the request cannot be
732
+ * attributed to Kaiten — respond `400`/`401` and do not process the body.
733
+ *
734
+ * ```ts
735
+ * app.post("/kaiten", express.raw({ type: "application/json" }), async (req, res) => {
736
+ * let event;
737
+ * try {
738
+ * event = await verifyKaitenWebhook({
739
+ * payload: req.body, // the RAW bytes, not a parsed object
740
+ * headers: req.headers,
741
+ * secret: process.env.KAITEN_WEBHOOK_SECRET!,
742
+ * });
743
+ * } catch {
744
+ * return res.sendStatus(401);
745
+ * }
746
+ *
747
+ * switch (event.type) {
748
+ * case "com.kaiten.customer.v1.created":
749
+ * // `event` is narrowed to the customer-created payload here.
750
+ * break;
751
+ * }
752
+ * res.sendStatus(204);
753
+ * });
754
+ * ```
755
+ */
756
+ async function verifyKaitenWebhook(input) {
757
+ const { headers, secret, toleranceSeconds = DEFAULT_TOLERANCE_SECONDS } = input;
758
+ const id = readHeader(headers, "svix-id", "webhook-id");
759
+ const timestamp = readHeader(headers, "svix-timestamp", "webhook-timestamp");
760
+ const signatureHeader = readHeader(headers, "svix-signature", "webhook-signature");
761
+ if (!id || !timestamp || !signatureHeader) throw new KaitenWebhookVerificationError("Kaiten webhook: missing signature headers (svix-id, svix-timestamp, svix-signature).");
762
+ const sentAt = Number.parseInt(timestamp, 10);
763
+ if (!Number.isFinite(sentAt)) throw new KaitenWebhookVerificationError("Kaiten webhook: timestamp is not a number.");
764
+ const nowSeconds = Math.floor((input.now ?? Date.now()) / 1e3);
765
+ const drift = Math.abs(nowSeconds - sentAt);
766
+ if (drift > toleranceSeconds) throw new KaitenWebhookVerificationError(`Kaiten webhook: timestamp is ${drift}s away from now, outside the ${toleranceSeconds}s tolerance.`);
767
+ if (!secret) throw new KaitenWebhookVerificationError("Kaiten webhook: no signing secret supplied.");
768
+ const rawSecret = secret.startsWith("whsec_") ? secret.slice(6) : secret;
769
+ const payload = typeof input.payload === "string" ? input.payload : new TextDecoder().decode(input.payload);
770
+ const key = await crypto.subtle.importKey("raw", base64ToBytes(rawSecret), {
771
+ name: "HMAC",
772
+ hash: "SHA-256"
773
+ }, false, ["sign"]);
774
+ const digest = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`${id}.${timestamp}.${payload}`));
775
+ const expected = bytesToBase64(new Uint8Array(digest));
776
+ if (!signatureHeader.split(" ").some((entry) => {
777
+ const [version, signature] = entry.split(",");
778
+ if (version !== "v1" || !signature) return false;
779
+ return constantTimeEquals(signature, expected);
780
+ })) throw new KaitenWebhookVerificationError("Kaiten webhook: no signature in the request matched the payload.");
781
+ let parsed;
782
+ try {
783
+ parsed = JSON.parse(payload);
784
+ } catch {
785
+ throw new KaitenWebhookVerificationError("Kaiten webhook: signature is valid but the body is not JSON.");
786
+ }
787
+ if (!parsed || typeof parsed !== "object" || typeof parsed.type !== "string") throw new KaitenWebhookVerificationError("Kaiten webhook: signature is valid but the body carries no `type`.");
788
+ return parsed;
789
+ }
790
+ /** Narrows a verified event to one `com.kaiten.*` type. */
791
+ function isKaitenWebhookOfType(event, type) {
792
+ return event.type === type;
793
+ }
794
+ /** True when the value is a verification failure, for a typed `catch`. */
795
+ function isWebhookVerificationError(error) {
796
+ return error instanceof KaitenWebhookVerificationError;
797
+ }
798
+ //#endregion
799
+ //#region src/generated/client.gen.ts
800
+ const client = createClient(createConfig({ baseUrl: "/api" }));
801
+ //#endregion
802
+ //#region src/generated/sdk.gen.ts
803
+ var Components = class {
804
+ /**
805
+ * List components
806
+ *
807
+ * Returns a cursor-paginated page of components for the current organization.
808
+ */
809
+ static listComponents(options) {
810
+ return (options?.client ?? client).get({
811
+ security: [{
812
+ scheme: "bearer",
813
+ type: "http"
814
+ }],
815
+ url: "/components",
816
+ ...options
817
+ });
818
+ }
819
+ /**
820
+ * Create a new component
821
+ *
822
+ * Create a new standalone component. Optionally derive it from a previous component version.
823
+ */
824
+ static createComponent(options) {
825
+ return (options.client ?? client).post({
826
+ security: [{
827
+ scheme: "bearer",
828
+ type: "http"
829
+ }],
830
+ url: "/components",
831
+ ...options,
832
+ headers: {
833
+ "Content-Type": "application/json",
834
+ ...options.headers
835
+ }
836
+ });
837
+ }
838
+ /**
839
+ * Delete a component
840
+ *
841
+ * Delete a component by slug if it is not linked to any release.
842
+ */
843
+ static deleteComponent(options) {
844
+ return (options.client ?? client).delete({
845
+ security: [{
846
+ scheme: "bearer",
847
+ type: "http"
848
+ }],
849
+ url: "/components/{componentSlug}",
850
+ ...options
851
+ });
852
+ }
853
+ /**
854
+ * Get a component by slug
855
+ *
856
+ * Returns a single component by its slug.
857
+ */
858
+ static getComponent(options) {
859
+ return (options.client ?? client).get({
860
+ security: [{
861
+ scheme: "bearer",
862
+ type: "http"
863
+ }],
864
+ url: "/components/{componentSlug}",
865
+ ...options
866
+ });
867
+ }
868
+ /**
869
+ * Update a component
870
+ *
871
+ * Update a component in place when unlinked, or create a new version when it is already linked to releases.
872
+ */
873
+ static updateComponent(options) {
874
+ return (options.client ?? client).put({
875
+ security: [{
876
+ scheme: "bearer",
877
+ type: "http"
878
+ }],
879
+ url: "/components/{componentSlug}",
880
+ ...options,
881
+ headers: {
882
+ "Content-Type": "application/json",
883
+ ...options.headers
884
+ }
885
+ });
886
+ }
887
+ };
888
+ var Connectors = class {
889
+ /**
890
+ * List registered connectors
891
+ *
892
+ * Returns every registered connector with its version and settings schema, ordered by name. The registry is platform-wide rather than per-organization and holds one row per connector, so the response is not paginated.
893
+ */
894
+ static listConnectors(options) {
895
+ return (options?.client ?? client).get({
896
+ security: [{
897
+ scheme: "bearer",
898
+ type: "http"
899
+ }],
900
+ url: "/connectors",
901
+ ...options
902
+ });
903
+ }
904
+ /**
905
+ * Get connector registration
906
+ *
907
+ * Retrieves a registered connector resource including version and settings schema
908
+ */
909
+ static getConnector(options) {
910
+ return (options.client ?? client).get({
911
+ security: [{
912
+ scheme: "bearer",
913
+ type: "http"
914
+ }],
915
+ url: "/connectors/{connectorName}",
916
+ ...options
917
+ });
918
+ }
919
+ /**
920
+ * Deactivate connector
921
+ *
922
+ * Deactivates a connector for the authenticated organization. Idempotent, and never refused for an unregistered or unlicensed connector: an organization must always be able to stop using something.
923
+ */
924
+ static deactivateConnector(options) {
925
+ return (options.client ?? client).delete({
926
+ security: [{
927
+ scheme: "bearer",
928
+ type: "http"
929
+ }],
930
+ url: "/connectors/{connectorName}/activation",
931
+ ...options
932
+ });
933
+ }
934
+ /**
935
+ * Activate connector
936
+ *
937
+ * Activates a registered connector for the authenticated organization. Idempotent: activating an already-active connector succeeds without changing when it was first activated. Refused when the organization's licence does not include the connector.
938
+ */
939
+ static activateConnector(options) {
940
+ return (options.client ?? client).put({
941
+ security: [{
942
+ scheme: "bearer",
943
+ type: "http"
944
+ }],
945
+ url: "/connectors/{connectorName}/activation",
946
+ ...options
947
+ });
948
+ }
949
+ /**
950
+ * Delete connector settings
951
+ *
952
+ * Delete connector settings for the authenticated organization
953
+ */
954
+ static deleteConnectorSettings(options) {
955
+ return (options.client ?? client).delete({
956
+ security: [{
957
+ scheme: "bearer",
958
+ type: "http"
959
+ }],
960
+ url: "/connectors/{connectorName}/settings",
961
+ ...options
962
+ });
963
+ }
964
+ /**
965
+ * Get connector settings
966
+ *
967
+ * Get settings for a connector scoped to the authenticated organization. Write-only fields (flagged `writeOnly` in the connector settings schema) are returned redacted as `***`.
968
+ */
969
+ static getConnectorSettings(options) {
970
+ return (options.client ?? client).get({
971
+ security: [{
972
+ scheme: "bearer",
973
+ type: "http"
974
+ }],
975
+ url: "/connectors/{connectorName}/settings",
976
+ ...options
977
+ });
978
+ }
979
+ /**
980
+ * Upsert connector settings
981
+ *
982
+ * Create or update connector settings for the authenticated organization. Write-only fields (flagged `writeOnly` in the connector settings schema) may be omitted or sent as `***` to keep the stored value; they are returned redacted.
983
+ */
984
+ static updateConnectorSettings(options) {
985
+ return (options.client ?? client).put({
986
+ security: [{
987
+ scheme: "bearer",
988
+ type: "http"
989
+ }],
990
+ url: "/connectors/{connectorName}/settings",
991
+ ...options,
992
+ headers: {
993
+ "Content-Type": "application/json",
994
+ ...options.headers
995
+ }
996
+ });
997
+ }
998
+ /**
999
+ * Get connector settings schema
1000
+ *
1001
+ * Get the JSON schema used to validate connector settings payloads
1002
+ */
1003
+ static getConnectorSettingsSchema(options) {
1004
+ return (options.client ?? client).get({
1005
+ security: [{
1006
+ scheme: "bearer",
1007
+ type: "http"
1008
+ }],
1009
+ url: "/connectors/{connectorName}/settings/schema",
1010
+ ...options
1011
+ });
1012
+ }
1013
+ /**
1014
+ * Get connector state for this organization
1015
+ *
1016
+ * Returns whether the connector is registered in this deployment, whether the authenticated organization's licence includes it, and whether the organization has activated it. Answers 200 with `available: false` for a connector this deployment does not have.
1017
+ */
1018
+ static getConnectorState(options) {
1019
+ return (options.client ?? client).get({
1020
+ security: [{
1021
+ scheme: "bearer",
1022
+ type: "http"
1023
+ }],
1024
+ url: "/connectors/{connectorName}/state",
1025
+ ...options
1026
+ });
1027
+ }
1028
+ };
1029
+ var Customers = class {
1030
+ /**
1031
+ * List customers
1032
+ *
1033
+ * Returns a cursor-paginated page of customers for the current organization.
1034
+ */
1035
+ static listCustomers(options) {
1036
+ return (options?.client ?? client).get({
1037
+ security: [{
1038
+ scheme: "bearer",
1039
+ type: "http"
1040
+ }],
1041
+ url: "/customers",
1042
+ ...options
1043
+ });
1044
+ }
1045
+ /**
1046
+ * Create a new customer
1047
+ *
1048
+ * Create a new customer with the provided details.
1049
+ */
1050
+ static createCustomer(options) {
1051
+ return (options.client ?? client).post({
1052
+ security: [{
1053
+ scheme: "bearer",
1054
+ type: "http"
1055
+ }],
1056
+ url: "/customers",
1057
+ ...options,
1058
+ headers: {
1059
+ "Content-Type": "application/json",
1060
+ ...options.headers
1061
+ }
1062
+ });
1063
+ }
1064
+ /**
1065
+ * Delete a customer
1066
+ *
1067
+ * Delete a customer by their slug.
1068
+ */
1069
+ static deleteCustomer(options) {
1070
+ return (options.client ?? client).delete({
1071
+ security: [{
1072
+ scheme: "bearer",
1073
+ type: "http"
1074
+ }],
1075
+ url: "/customers/{customerSlug}",
1076
+ ...options
1077
+ });
1078
+ }
1079
+ /**
1080
+ * Get a customer by slug
1081
+ *
1082
+ * Returns a single customer by their slug.
1083
+ */
1084
+ static getCustomer(options) {
1085
+ return (options.client ?? client).get({
1086
+ security: [{
1087
+ scheme: "bearer",
1088
+ type: "http"
1089
+ }],
1090
+ url: "/customers/{customerSlug}",
1091
+ ...options
1092
+ });
1093
+ }
1094
+ /**
1095
+ * Update a customer
1096
+ *
1097
+ * Update a customer's details. Slug and integrations are not renameable/settable through this endpoint -- omit them, or send the values already on record.
1098
+ */
1099
+ static updateCustomer(options) {
1100
+ return (options.client ?? client).put({
1101
+ security: [{
1102
+ scheme: "bearer",
1103
+ type: "http"
1104
+ }],
1105
+ url: "/customers/{customerSlug}",
1106
+ ...options,
1107
+ headers: {
1108
+ "Content-Type": "application/json",
1109
+ ...options.headers
1110
+ }
1111
+ });
1112
+ }
1113
+ /**
1114
+ * Delete a customer integration
1115
+ *
1116
+ * Delete a single integration for a customer
1117
+ */
1118
+ static deleteCustomerIntegration(options) {
1119
+ return (options.client ?? client).delete({
1120
+ security: [{
1121
+ scheme: "bearer",
1122
+ type: "http"
1123
+ }],
1124
+ url: "/customers/{customerSlug}/integrations/{integrationName}",
1125
+ ...options
1126
+ });
1127
+ }
1128
+ /**
1129
+ * Get a customer integration
1130
+ *
1131
+ * Retrieve a single integration for a customer
1132
+ */
1133
+ static getCustomerIntegration(options) {
1134
+ return (options.client ?? client).get({
1135
+ security: [{
1136
+ scheme: "bearer",
1137
+ type: "http"
1138
+ }],
1139
+ url: "/customers/{customerSlug}/integrations/{integrationName}",
1140
+ ...options
1141
+ });
1142
+ }
1143
+ /**
1144
+ * Create a customer integration
1145
+ *
1146
+ * Create a single integration for a customer
1147
+ */
1148
+ static createCustomerIntegration(options) {
1149
+ return (options.client ?? client).post({
1150
+ security: [{
1151
+ scheme: "bearer",
1152
+ type: "http"
1153
+ }],
1154
+ url: "/customers/{customerSlug}/integrations/{integrationName}",
1155
+ ...options,
1156
+ headers: {
1157
+ "Content-Type": "application/json",
1158
+ ...options.headers
1159
+ }
1160
+ });
1161
+ }
1162
+ /**
1163
+ * Update a customer integration
1164
+ *
1165
+ * Update a single integration for a customer
1166
+ */
1167
+ static updateCustomerIntegration(options) {
1168
+ return (options.client ?? client).put({
1169
+ security: [{
1170
+ scheme: "bearer",
1171
+ type: "http"
1172
+ }],
1173
+ url: "/customers/{customerSlug}/integrations/{integrationName}",
1174
+ ...options,
1175
+ headers: {
1176
+ "Content-Type": "application/json",
1177
+ ...options.headers
1178
+ }
1179
+ });
1180
+ }
1181
+ /**
1182
+ * Get a customer by integration external ID
1183
+ *
1184
+ * Resolve a customer through one of its integrations using adapter + external ID.
1185
+ */
1186
+ static getCustomerIntegrationByExternalId(options) {
1187
+ return (options.client ?? client).get({
1188
+ security: [{
1189
+ scheme: "bearer",
1190
+ type: "http"
1191
+ }],
1192
+ url: "/integration/{adapter}/customer/{externalId}",
1193
+ ...options
1194
+ });
1195
+ }
1196
+ /**
1197
+ * Upsert a customer by integration external ID
1198
+ *
1199
+ * Create or partially update a customer resolved through adapter + external ID. Missing fields are left unchanged.
1200
+ */
1201
+ static upsertCustomerIntegrationByExternalId(options) {
1202
+ return (options.client ?? client).patch({
1203
+ security: [{
1204
+ scheme: "bearer",
1205
+ type: "http"
1206
+ }],
1207
+ url: "/integration/{adapter}/customer/{externalId}",
1208
+ ...options,
1209
+ headers: {
1210
+ "Content-Type": "application/json",
1211
+ ...options.headers
1212
+ }
1213
+ });
1214
+ }
1215
+ };
1216
+ var DeploymentZones = class {
1217
+ /**
1218
+ * List deployment zones
1219
+ *
1220
+ * Returns a cursor-paginated page of deployment zones for the current organization. A deployment zone is one place a customer runs a release -- a target they name and classify themselves, holding the release currently on it. It is not an installation of Kaiten; that sense of the term belongs to operations and is not reachable through this API.
1221
+ */
1222
+ static listDeploymentZones(options) {
1223
+ return (options?.client ?? client).get({
1224
+ security: [{
1225
+ scheme: "bearer",
1226
+ type: "http"
1227
+ }],
1228
+ url: "/deployment-zones",
1229
+ ...options
1230
+ });
1231
+ }
1232
+ /**
1233
+ * Create a new deployment zone
1234
+ *
1235
+ * Create a new deployment zone with the provided details. Supplying releaseId records the zone's first deployment. A deployment zone is one place a customer runs a release -- a target they name and classify themselves, holding the release currently on it. It is not an installation of Kaiten; that sense of the term belongs to operations and is not reachable through this API.
1236
+ */
1237
+ static createDeploymentZone(options) {
1238
+ return (options.client ?? client).post({
1239
+ security: [{
1240
+ scheme: "bearer",
1241
+ type: "http"
1242
+ }],
1243
+ url: "/deployment-zones",
1244
+ ...options,
1245
+ headers: {
1246
+ "Content-Type": "application/json",
1247
+ ...options.headers
1248
+ }
1249
+ });
1250
+ }
1251
+ /**
1252
+ * Delete a deployment zone
1253
+ *
1254
+ * Delete a deployment zone by their slug.
1255
+ */
1256
+ static deleteDeploymentZone(options) {
1257
+ return (options.client ?? client).delete({
1258
+ security: [{
1259
+ scheme: "bearer",
1260
+ type: "http"
1261
+ }],
1262
+ url: "/deployment-zones/{deploymentZoneSlug}",
1263
+ ...options
1264
+ });
1265
+ }
1266
+ /**
1267
+ * Get a deployment zone by slug
1268
+ *
1269
+ * Returns a single deployment zone by their slug.
1270
+ */
1271
+ static getDeploymentZoneBySlug(options) {
1272
+ return (options.client ?? client).get({
1273
+ security: [{
1274
+ scheme: "bearer",
1275
+ type: "http"
1276
+ }],
1277
+ url: "/deployment-zones/{deploymentZoneSlug}",
1278
+ ...options
1279
+ });
1280
+ }
1281
+ /**
1282
+ * Update a deployment zone
1283
+ *
1284
+ * Update a deployment zone's details. Changing releaseId records a deployment: the zone's current release becomes the new one and the change is appended to its deployment history, including when the new release is one the zone already ran (a rollback). Omitting releaseId, or echoing back the current one, leaves the history untouched.
1285
+ */
1286
+ static updateDeploymentZone(options) {
1287
+ return (options.client ?? client).put({
1288
+ security: [{
1289
+ scheme: "bearer",
1290
+ type: "http"
1291
+ }],
1292
+ url: "/deployment-zones/{deploymentZoneSlug}",
1293
+ ...options,
1294
+ headers: {
1295
+ "Content-Type": "application/json",
1296
+ ...options.headers
1297
+ }
1298
+ });
1299
+ }
1300
+ /**
1301
+ * Get a release by slug
1302
+ *
1303
+ * Returns a single release by their slug.
1304
+ */
1305
+ static getReleaseBySlug(options) {
1306
+ return (options.client ?? client).get({
1307
+ security: [{
1308
+ scheme: "bearer",
1309
+ type: "http"
1310
+ }],
1311
+ url: "/releases/{releaseSlug}",
1312
+ ...options
1313
+ });
1314
+ }
1315
+ };
1316
+ var EntitlementGroups = class {
1317
+ /**
1318
+ * List all entitlement groups
1319
+ *
1320
+ * Returns a cursor-paginated page of entitlement groups for the current organization.
1321
+ */
1322
+ static listEntitlementGroups(options) {
1323
+ return (options?.client ?? client).get({
1324
+ security: [{
1325
+ scheme: "bearer",
1326
+ type: "http"
1327
+ }],
1328
+ url: "/entitlement-groups",
1329
+ ...options
1330
+ });
1331
+ }
1332
+ /**
1333
+ * Create a new entitlement group
1334
+ *
1335
+ * Create a new entitlement group to aggregate entitlements
1336
+ */
1337
+ static createEntitlementGroup(options) {
1338
+ return (options.client ?? client).post({
1339
+ security: [{
1340
+ scheme: "bearer",
1341
+ type: "http"
1342
+ }],
1343
+ url: "/entitlement-groups",
1344
+ ...options,
1345
+ headers: {
1346
+ "Content-Type": "application/json",
1347
+ ...options.headers
1348
+ }
1349
+ });
1350
+ }
1351
+ /**
1352
+ * Delete an entitlement group
1353
+ *
1354
+ * Delete an entitlement group by its slug. This does not delete the member entitlements.
1355
+ */
1356
+ static deleteEntitlementGroup(options) {
1357
+ return (options.client ?? client).delete({
1358
+ security: [{
1359
+ scheme: "bearer",
1360
+ type: "http"
1361
+ }],
1362
+ url: "/entitlement-groups/{entitlementGroupSlug}",
1363
+ ...options
1364
+ });
1365
+ }
1366
+ /**
1367
+ * Get entitlement group by slug
1368
+ *
1369
+ * Retrieve details of a specific entitlement group by its slug
1370
+ */
1371
+ static getEntitlementGroup(options) {
1372
+ return (options.client ?? client).get({
1373
+ security: [{
1374
+ scheme: "bearer",
1375
+ type: "http"
1376
+ }],
1377
+ url: "/entitlement-groups/{entitlementGroupSlug}",
1378
+ ...options
1379
+ });
1380
+ }
1381
+ /**
1382
+ * Update an entitlement group
1383
+ *
1384
+ * Update an existing entitlement group with the provided details
1385
+ */
1386
+ static updateEntitlementGroup(options) {
1387
+ return (options.client ?? client).put({
1388
+ security: [{
1389
+ scheme: "bearer",
1390
+ type: "http"
1391
+ }],
1392
+ url: "/entitlement-groups/{entitlementGroupSlug}",
1393
+ ...options,
1394
+ headers: {
1395
+ "Content-Type": "application/json",
1396
+ ...options.headers
1397
+ }
1398
+ });
1399
+ }
1400
+ /**
1401
+ * Add an entitlement to a group
1402
+ *
1403
+ * Add an existing entitlement as a member of an entitlement group
1404
+ */
1405
+ static addEntitlementToGroup(options) {
1406
+ return (options.client ?? client).post({
1407
+ security: [{
1408
+ scheme: "bearer",
1409
+ type: "http"
1410
+ }],
1411
+ url: "/entitlement-groups/{entitlementGroupSlug}/entitlements",
1412
+ ...options,
1413
+ headers: {
1414
+ "Content-Type": "application/json",
1415
+ ...options.headers
1416
+ }
1417
+ });
1418
+ }
1419
+ /**
1420
+ * Remove an entitlement from a group
1421
+ *
1422
+ * Remove an entitlement from an entitlement group. The entitlement itself is not deleted.
1423
+ */
1424
+ static removeEntitlementFromGroup(options) {
1425
+ return (options.client ?? client).delete({
1426
+ security: [{
1427
+ scheme: "bearer",
1428
+ type: "http"
1429
+ }],
1430
+ url: "/entitlement-groups/{entitlementGroupSlug}/entitlements/{entitlementSlug}",
1431
+ ...options
1432
+ });
1433
+ }
1434
+ /**
1435
+ * Get aggregated usage for an entitlement group
1436
+ *
1437
+ * Retrieve the aggregated usage metrics of all member entitlements for a given instance
1438
+ */
1439
+ static getEntitlementGroupUsage(options) {
1440
+ return (options.client ?? client).get({
1441
+ security: [{
1442
+ scheme: "bearer",
1443
+ type: "http"
1444
+ }],
1445
+ url: "/entitlement-groups/{entitlementGroupSlug}/usage",
1446
+ ...options
1447
+ });
1448
+ }
1449
+ };
1450
+ var Entitlements = class {
1451
+ /**
1452
+ * List all entitlements
1453
+ *
1454
+ * Returns a cursor-paginated page of entitlements for the current organization.
1455
+ */
1456
+ static listEntitlements(options) {
1457
+ return (options?.client ?? client).get({
1458
+ security: [{
1459
+ scheme: "bearer",
1460
+ type: "http"
1461
+ }],
1462
+ url: "/entitlements",
1463
+ ...options
1464
+ });
1465
+ }
1466
+ /**
1467
+ * Create a new entitlement
1468
+ *
1469
+ * Create a new entitlement with the provided details
1470
+ */
1471
+ static createEntitlement(options) {
1472
+ return (options.client ?? client).post({
1473
+ security: [{
1474
+ scheme: "bearer",
1475
+ type: "http"
1476
+ }],
1477
+ url: "/entitlements",
1478
+ ...options,
1479
+ headers: {
1480
+ "Content-Type": "application/json",
1481
+ ...options.headers
1482
+ }
1483
+ });
1484
+ }
1485
+ /**
1486
+ * Delete an entitlement
1487
+ *
1488
+ * Delete an entitlement by its slug
1489
+ */
1490
+ static deleteEntitlement(options) {
1491
+ return (options.client ?? client).delete({
1492
+ security: [{
1493
+ scheme: "bearer",
1494
+ type: "http"
1495
+ }],
1496
+ url: "/entitlements/{entitlementSlug}",
1497
+ ...options
1498
+ });
1499
+ }
1500
+ /**
1501
+ * Get entitlement by slug
1502
+ *
1503
+ * Retrieve details of a specific entitlement by its slug
1504
+ */
1505
+ static getEntitlement(options) {
1506
+ return (options.client ?? client).get({
1507
+ security: [{
1508
+ scheme: "bearer",
1509
+ type: "http"
1510
+ }],
1511
+ url: "/entitlements/{entitlementSlug}",
1512
+ ...options
1513
+ });
1514
+ }
1515
+ /**
1516
+ * Update an entitlement
1517
+ *
1518
+ * Update an existing entitlement with the provided details
1519
+ */
1520
+ static updateEntitlement(options) {
1521
+ return (options.client ?? client).put({
1522
+ security: [{
1523
+ scheme: "bearer",
1524
+ type: "http"
1525
+ }],
1526
+ url: "/entitlements/{entitlementSlug}",
1527
+ ...options,
1528
+ headers: {
1529
+ "Content-Type": "application/json",
1530
+ ...options.headers
1531
+ }
1532
+ });
1533
+ }
1534
+ };
1535
+ var Featureflags = class {
1536
+ /**
1537
+ * Get a list of feature flags
1538
+ *
1539
+ * Returns a cursor-paginated page of feature flags for the given organization.
1540
+ */
1541
+ static getFeatureFlags(options) {
1542
+ return (options?.client ?? client).get({
1543
+ security: [{
1544
+ scheme: "bearer",
1545
+ type: "http"
1546
+ }],
1547
+ url: "/feature-flags",
1548
+ ...options
1549
+ });
1550
+ }
1551
+ /**
1552
+ * Create a new featureflag
1553
+ *
1554
+ * Create a new featureflag with the provided details
1555
+ */
1556
+ static createFeatureFlag(options) {
1557
+ return (options.client ?? client).post({
1558
+ security: [{
1559
+ scheme: "bearer",
1560
+ type: "http"
1561
+ }],
1562
+ url: "/feature-flags",
1563
+ ...options,
1564
+ headers: {
1565
+ "Content-Type": "application/json",
1566
+ ...options.headers
1567
+ }
1568
+ });
1569
+ }
1570
+ /**
1571
+ * Get the targeting context schema
1572
+ *
1573
+ * Returns the identifiers a targeting rule may read, with their types and descriptions, including the organization's own entitlement slugs. Intended for an editor: it is what autocomplete and hover documentation are built from. The set is not closed — a rule may also target on attributes the caller supplies in its own evaluation context.
1574
+ */
1575
+ static getTargetingContext(options) {
1576
+ return (options?.client ?? client).get({
1577
+ security: [{
1578
+ scheme: "bearer",
1579
+ type: "http"
1580
+ }],
1581
+ url: "/feature-flags/targeting/context",
1582
+ ...options
1583
+ });
1584
+ }
1585
+ /**
1586
+ * Check a targeting rule
1587
+ *
1588
+ * Runs the same check create and update run before accepting a targeting rule, and reports what it found without writing anything. A rule that references a fact or an entitlement that does not exist does not fail loudly at evaluation — it simply never matches — so this is what lets an editor say so while the rule is being written. A rejected rule is a 200 carrying `valid: false`, not a client error.
1589
+ */
1590
+ static lintTargetingRule(options) {
1591
+ return (options.client ?? client).post({
1592
+ security: [{
1593
+ scheme: "bearer",
1594
+ type: "http"
1595
+ }],
1596
+ url: "/feature-flags/targeting/lint",
1597
+ ...options,
1598
+ headers: {
1599
+ "Content-Type": "application/json",
1600
+ ...options.headers
1601
+ }
1602
+ });
1603
+ }
1604
+ /**
1605
+ * Rehearse a targeting rule against a context
1606
+ *
1607
+ * Runs a rule the way an evaluation would, without a flag and without writing anything: the context is enriched from the same sources (license, entitlements, instance, customer, deployment zone), anything the caller forged under __kaiten is discarded the same way, and the same engine answers. The response carries the enriched facts so an author can see exactly what the rule read — which is usually the answer to why it did or did not match. Nothing is metered or audited: this is authoring, not serving.
1608
+ */
1609
+ static testTargetingRule(options) {
1610
+ return (options.client ?? client).post({
1611
+ security: [{
1612
+ scheme: "bearer",
1613
+ type: "http"
1614
+ }],
1615
+ url: "/feature-flags/targeting/test",
1616
+ ...options,
1617
+ headers: {
1618
+ "Content-Type": "application/json",
1619
+ ...options.headers
1620
+ }
1621
+ });
1622
+ }
1623
+ /**
1624
+ * Delete a featureflag
1625
+ *
1626
+ * Delete a featureflag with the provided details
1627
+ */
1628
+ static deleteFeatureFlag(options) {
1629
+ return (options.client ?? client).delete({
1630
+ security: [{
1631
+ scheme: "bearer",
1632
+ type: "http"
1633
+ }],
1634
+ url: "/feature-flags/{featureFlagSlug}",
1635
+ ...options
1636
+ });
1637
+ }
1638
+ /**
1639
+ * Get a feature flag by slug
1640
+ *
1641
+ * Get a feature flag with the provided slug
1642
+ */
1643
+ static getFeatureFlag(options) {
1644
+ return (options.client ?? client).get({
1645
+ security: [{
1646
+ scheme: "bearer",
1647
+ type: "http"
1648
+ }],
1649
+ url: "/feature-flags/{featureFlagSlug}",
1650
+ ...options
1651
+ });
1652
+ }
1653
+ /**
1654
+ * Update a featureflag
1655
+ *
1656
+ * Update a featureflag with the provided details
1657
+ */
1658
+ static updateFeatureFlag(options) {
1659
+ return (options.client ?? client).put({
1660
+ security: [{
1661
+ scheme: "bearer",
1662
+ type: "http"
1663
+ }],
1664
+ url: "/feature-flags/{featureFlagSlug}",
1665
+ ...options,
1666
+ headers: {
1667
+ "Content-Type": "application/json",
1668
+ ...options.headers
1669
+ }
1670
+ });
1671
+ }
1672
+ };
1673
+ var Instances = class {
1674
+ /**
1675
+ * List all instances
1676
+ *
1677
+ * Returns a cursor-paginated page of instances for the current organization.
1678
+ */
1679
+ static getInstances(options) {
1680
+ return (options?.client ?? client).get({
1681
+ security: [{
1682
+ scheme: "bearer",
1683
+ type: "http"
1684
+ }],
1685
+ url: "/instances",
1686
+ ...options
1687
+ });
1688
+ }
1689
+ /**
1690
+ * Create a new instance
1691
+ *
1692
+ * Create a new instance with the provided details
1693
+ */
1694
+ static createInstance(options) {
1695
+ return (options.client ?? client).post({
1696
+ security: [{
1697
+ scheme: "bearer",
1698
+ type: "http"
1699
+ }],
1700
+ url: "/instances",
1701
+ ...options,
1702
+ headers: {
1703
+ "Content-Type": "application/json",
1704
+ ...options.headers
1705
+ }
1706
+ });
1707
+ }
1708
+ /**
1709
+ * Delete an instance
1710
+ *
1711
+ * Delete an instance with the provided slug
1712
+ */
1713
+ static deleteInstance(options) {
1714
+ return (options.client ?? client).delete({
1715
+ security: [{
1716
+ scheme: "bearer",
1717
+ type: "http"
1718
+ }],
1719
+ url: "/instances/{instanceSlug}",
1720
+ ...options
1721
+ });
1722
+ }
1723
+ /**
1724
+ * Get an instance by slug
1725
+ *
1726
+ * Retrieve an instance by their unique slug
1727
+ */
1728
+ static getInstance(options) {
1729
+ return (options.client ?? client).get({
1730
+ security: [{
1731
+ scheme: "bearer",
1732
+ type: "http"
1733
+ }],
1734
+ url: "/instances/{instanceSlug}",
1735
+ ...options
1736
+ });
1737
+ }
1738
+ /**
1739
+ * Patch an instance
1740
+ *
1741
+ * Partially update an instance. Currently supports the operational status and the commercial lifecycle stage.
1742
+ */
1743
+ static patchInstance(options) {
1744
+ return (options.client ?? client).patch({
1745
+ security: [{
1746
+ scheme: "bearer",
1747
+ type: "http"
1748
+ }],
1749
+ url: "/instances/{instanceSlug}",
1750
+ ...options,
1751
+ headers: {
1752
+ "Content-Type": "application/json",
1753
+ ...options.headers
1754
+ }
1755
+ });
1756
+ }
1757
+ /**
1758
+ * Update an instance
1759
+ *
1760
+ * Update an instance with the provided details
1761
+ */
1762
+ static updateInstance(options) {
1763
+ return (options.client ?? client).put({
1764
+ security: [{
1765
+ scheme: "bearer",
1766
+ type: "http"
1767
+ }],
1768
+ url: "/instances/{instanceSlug}",
1769
+ ...options,
1770
+ headers: {
1771
+ "Content-Type": "application/json",
1772
+ ...options.headers
1773
+ }
1774
+ });
1775
+ }
1776
+ /**
1777
+ * List audit trail entries for an instance
1778
+ *
1779
+ * Returns audit trail events for a given instance, optionally filtered by event name and time range. Results are cursor-paginated (default limit: 50, max: 200) — pass the previous response's nextCursor as the cursor parameter to fetch the next page.
1780
+ */
1781
+ static getAuditTrails(options) {
1782
+ return (options.client ?? client).get({
1783
+ security: [{
1784
+ scheme: "bearer",
1785
+ type: "http"
1786
+ }],
1787
+ url: "/instances/{instanceSlug}/audit-trails",
1788
+ ...options
1789
+ });
1790
+ }
1791
+ /**
1792
+ * List all entitlements usage metrics
1793
+ *
1794
+ * Retrieve a list of all entitlements usage metrics for a specific instance
1795
+ */
1796
+ static getEntitlementsUsageMetrics(options) {
1797
+ return (options.client ?? client).get({
1798
+ security: [{
1799
+ scheme: "bearer",
1800
+ type: "http"
1801
+ }],
1802
+ url: "/instances/{instanceSlug}/entitlements/usage",
1803
+ ...options
1804
+ });
1805
+ }
1806
+ /**
1807
+ * Get entitlement usage metrics for an instance
1808
+ *
1809
+ * Retrieve the usage metrics for a specific entitlement in a given instance
1810
+ */
1811
+ static getEntitlementUsageMetrics(options) {
1812
+ return (options.client ?? client).get({
1813
+ security: [{
1814
+ scheme: "bearer",
1815
+ type: "http"
1816
+ }],
1817
+ url: "/instances/{instanceSlug}/entitlements/{entitlementSlug}/usage",
1818
+ ...options
1819
+ });
1820
+ }
1821
+ /**
1822
+ * Report entitlement usage metric for an instance
1823
+ *
1824
+ * Report a usage metric for a specific entitlement in a given instance. This endpoint allows you to report the usage of an entitlement, including optional metadata and a timestamp.
1825
+ */
1826
+ static reportEntitlementUsageMetric(options) {
1827
+ return (options.client ?? client).post({
1828
+ security: [{
1829
+ scheme: "bearer",
1830
+ type: "http"
1831
+ }],
1832
+ url: "/instances/{instanceSlug}/entitlements/{entitlementSlug}/usage",
1833
+ ...options,
1834
+ headers: {
1835
+ "Content-Type": "application/json",
1836
+ ...options.headers
1837
+ }
1838
+ });
1839
+ }
1840
+ /**
1841
+ * Delete an instance integration
1842
+ *
1843
+ * Delete a single integration for an instance
1844
+ */
1845
+ static deleteInstanceIntegration(options) {
1846
+ return (options.client ?? client).delete({
1847
+ security: [{
1848
+ scheme: "bearer",
1849
+ type: "http"
1850
+ }],
1851
+ url: "/instances/{instanceSlug}/integrations/{integrationName}",
1852
+ ...options
1853
+ });
1854
+ }
1855
+ /**
1856
+ * Get an instance integration
1857
+ *
1858
+ * Retrieve a single integration for an instance
1859
+ */
1860
+ static getInstanceIntegration(options) {
1861
+ return (options.client ?? client).get({
1862
+ security: [{
1863
+ scheme: "bearer",
1864
+ type: "http"
1865
+ }],
1866
+ url: "/instances/{instanceSlug}/integrations/{integrationName}",
1867
+ ...options
1868
+ });
1869
+ }
1870
+ /**
1871
+ * Create an instance integration
1872
+ *
1873
+ * Create a single integration for an instance
1874
+ */
1875
+ static createInstanceIntegration(options) {
1876
+ return (options.client ?? client).post({
1877
+ security: [{
1878
+ scheme: "bearer",
1879
+ type: "http"
1880
+ }],
1881
+ url: "/instances/{instanceSlug}/integrations/{integrationName}",
1882
+ ...options,
1883
+ headers: {
1884
+ "Content-Type": "application/json",
1885
+ ...options.headers
1886
+ }
1887
+ });
1888
+ }
1889
+ /**
1890
+ * Update an instance integration
1891
+ *
1892
+ * Update a single integration for an instance
1893
+ */
1894
+ static updateInstanceIntegration(options) {
1895
+ return (options.client ?? client).put({
1896
+ security: [{
1897
+ scheme: "bearer",
1898
+ type: "http"
1899
+ }],
1900
+ url: "/instances/{instanceSlug}/integrations/{integrationName}",
1901
+ ...options,
1902
+ headers: {
1903
+ "Content-Type": "application/json",
1904
+ ...options.headers
1905
+ }
1906
+ });
1907
+ }
1908
+ /**
1909
+ * Get an instance by integration external ID
1910
+ *
1911
+ * Resolve an instance through one of its integrations using adapter + external ID.
1912
+ */
1913
+ static getInstanceIntegrationByExternalId(options) {
1914
+ return (options.client ?? client).get({
1915
+ security: [{
1916
+ scheme: "bearer",
1917
+ type: "http"
1918
+ }],
1919
+ url: "/integration/{adapter}/instance/{externalId}",
1920
+ ...options
1921
+ });
1922
+ }
1923
+ /**
1924
+ * Upsert an instance by integration external ID
1925
+ *
1926
+ * Create or partially update an instance resolved through adapter + external ID. Missing fields are left unchanged.
1927
+ */
1928
+ static upsertInstanceIntegrationByExternalId(options) {
1929
+ return (options.client ?? client).patch({
1930
+ security: [{
1931
+ scheme: "bearer",
1932
+ type: "http"
1933
+ }],
1934
+ url: "/integration/{adapter}/instance/{externalId}",
1935
+ ...options,
1936
+ headers: {
1937
+ "Content-Type": "application/json",
1938
+ ...options.headers
1939
+ }
1940
+ });
1941
+ }
1942
+ };
1943
+ var Integrations = class {
1944
+ /**
1945
+ * Get a customer by integration external ID
1946
+ *
1947
+ * Resolve a customer through one of its integrations using adapter + external ID.
1948
+ */
1949
+ static getCustomerIntegrationByExternalId(options) {
1950
+ return (options.client ?? client).get({
1951
+ security: [{
1952
+ scheme: "bearer",
1953
+ type: "http"
1954
+ }],
1955
+ url: "/integration/{adapter}/customer/{externalId}",
1956
+ ...options
1957
+ });
1958
+ }
1959
+ /**
1960
+ * Upsert a customer by integration external ID
1961
+ *
1962
+ * Create or partially update a customer resolved through adapter + external ID. Missing fields are left unchanged.
1963
+ */
1964
+ static upsertCustomerIntegrationByExternalId(options) {
1965
+ return (options.client ?? client).patch({
1966
+ security: [{
1967
+ scheme: "bearer",
1968
+ type: "http"
1969
+ }],
1970
+ url: "/integration/{adapter}/customer/{externalId}",
1971
+ ...options,
1972
+ headers: {
1973
+ "Content-Type": "application/json",
1974
+ ...options.headers
1975
+ }
1976
+ });
1977
+ }
1978
+ /**
1979
+ * Get an instance by integration external ID
1980
+ *
1981
+ * Resolve an instance through one of its integrations using adapter + external ID.
1982
+ */
1983
+ static getInstanceIntegrationByExternalId(options) {
1984
+ return (options.client ?? client).get({
1985
+ security: [{
1986
+ scheme: "bearer",
1987
+ type: "http"
1988
+ }],
1989
+ url: "/integration/{adapter}/instance/{externalId}",
1990
+ ...options
1991
+ });
1992
+ }
1993
+ /**
1994
+ * Upsert an instance by integration external ID
1995
+ *
1996
+ * Create or partially update an instance resolved through adapter + external ID. Missing fields are left unchanged.
1997
+ */
1998
+ static upsertInstanceIntegrationByExternalId(options) {
1999
+ return (options.client ?? client).patch({
2000
+ security: [{
2001
+ scheme: "bearer",
2002
+ type: "http"
2003
+ }],
2004
+ url: "/integration/{adapter}/instance/{externalId}",
2005
+ ...options,
2006
+ headers: {
2007
+ "Content-Type": "application/json",
2008
+ ...options.headers
2009
+ }
2010
+ });
2011
+ }
2012
+ };
2013
+ var LicenseFamilies = class {
2014
+ /**
2015
+ * List license families
2016
+ *
2017
+ * Returns a cursor-paginated page of license families for the current organization, each with the version it currently resolves to: the family's default version, or its highest-numbered published version. A family whose versions are all drafts or all archived is still listed, with no current version.
2018
+ */
2019
+ static listLicenseFamilies(options) {
2020
+ return (options?.client ?? client).get({
2021
+ security: [{
2022
+ scheme: "bearer",
2023
+ type: "http"
2024
+ }],
2025
+ url: "/license-families",
2026
+ ...options
2027
+ });
2028
+ }
2029
+ /**
2030
+ * Get a license family by slug
2031
+ *
2032
+ * Resolves a license family to the version it currently serves, returned as currentVersion: the family's default version if it has one, otherwise its highest-numbered PUBLISHED version. This is the stable address for "the current version of this product", so a caller never has to name a version slug.
2033
+ *
2034
+ * A family with a default keeps serving it when a newer version is published -- the default is what the vendor puts forward, and superseding it is an explicit act (make another version the default, or unset it). A family without a default follows publication: the newest PUBLISHED version wins.
2035
+ *
2036
+ * Returns 404 GetLicenseFamily.NoPublishedVersion when the family exists but has no PUBLISHED version, since there is nothing to resolve to. Use ?include=versions to read such a family anyway: with the history requested, the family is returned with its versions and no currentVersion. Use ?version=N for explicit access to one version, including draft and archived ones.
2037
+ */
2038
+ static getLicenseFamily(options) {
2039
+ return (options.client ?? client).get({
2040
+ querySerializer: { parameters: { include: { array: { explode: false } } } },
2041
+ security: [{
2042
+ scheme: "bearer",
2043
+ type: "http"
2044
+ }],
2045
+ url: "/license-families/{familySlug}",
2046
+ ...options
2047
+ });
2048
+ }
2049
+ };
2050
+ var Licenses = class {
2051
+ /**
2052
+ * GetUser all licenses
2053
+ *
2054
+ * Returns a cursor-paginated page of licenses for the current organization.
2055
+ */
2056
+ static getLicenses(options) {
2057
+ return (options?.client ?? client).get({
2058
+ security: [{
2059
+ scheme: "bearer",
2060
+ type: "http"
2061
+ }],
2062
+ url: "/licenses",
2063
+ ...options
2064
+ });
2065
+ }
2066
+ /**
2067
+ * Create a new license
2068
+ *
2069
+ * Create a new license with the provided details. Without familySlug or familyId this creates a new license family and the license becomes its version 1. With one of them it adds the next version to that family (familySlug names it by slug, familyId by identifier; sent together they must agree), and the version number is assigned by the server as the next one in the family's sequence. The version starts PUBLISHED, or DRAFT when lifecycleState says so; ARCHIVED is refused (422 CreateLicense.LifecycleStateNotSettable), because a version is archived with archive-license once it has been on sale.
2070
+ *
2071
+ * Where the deployment limits how many licenses an organization may have, only a new family counts against that limit (409 CreateLicense.EntitlementLimitReached once it is reached): a new version of an existing family never does.
2072
+ */
2073
+ static createLicense(options) {
2074
+ return (options.client ?? client).post({
2075
+ security: [{
2076
+ scheme: "bearer",
2077
+ type: "http"
2078
+ }],
2079
+ url: "/licenses",
2080
+ ...options,
2081
+ headers: {
2082
+ "Content-Type": "application/json",
2083
+ ...options.headers
2084
+ }
2085
+ });
2086
+ }
2087
+ /**
2088
+ * Delete a license
2089
+ *
2090
+ * Delete a license with the provided details. Deleting the last version of a license family also deletes the family, and frees its slug for a new product to take. A deleted version's number is not reused by the next version of its family.
2091
+ */
2092
+ static deleteLicense(options) {
2093
+ return (options.client ?? client).delete({
2094
+ security: [{
2095
+ scheme: "bearer",
2096
+ type: "http"
2097
+ }],
2098
+ url: "/licenses/{licenseSlug}",
2099
+ ...options
2100
+ });
2101
+ }
2102
+ /**
2103
+ * Get a license by slug
2104
+ *
2105
+ * Retrieve a license by their unique slug
2106
+ */
2107
+ static getLicense(options) {
2108
+ return (options.client ?? client).get({
2109
+ security: [{
2110
+ scheme: "bearer",
2111
+ type: "http"
2112
+ }],
2113
+ url: "/licenses/{licenseSlug}",
2114
+ ...options
2115
+ });
2116
+ }
2117
+ /**
2118
+ * Update a license
2119
+ *
2120
+ * Update a license with the provided details
2121
+ */
2122
+ static updateLicense(options) {
2123
+ return (options.client ?? client).put({
2124
+ security: [{
2125
+ scheme: "bearer",
2126
+ type: "http"
2127
+ }],
2128
+ url: "/licenses/{licenseSlug}",
2129
+ ...options,
2130
+ headers: {
2131
+ "Content-Type": "application/json",
2132
+ ...options.headers
2133
+ }
2134
+ });
2135
+ }
2136
+ /**
2137
+ * Archive a license version
2138
+ *
2139
+ * Withdraws a PUBLISHED license version from sale: its family stops resolving to it and no instance can be assigned to it any more, while instances already on it keep it. Only a published version can be archived (409 ArchiveLicense.NotPublished) -- a draft that was never on sale is deleted instead -- and not while it is its family's default (409 ArchiveLicense.DefaultMustBePublished): make another version the default, or unset it, first. Emits LICENSE_ARCHIVED.
2140
+ */
2141
+ static archiveLicense(options) {
2142
+ return (options.client ?? client).post({
2143
+ security: [{
2144
+ scheme: "bearer",
2145
+ type: "http"
2146
+ }],
2147
+ url: "/licenses/{licenseSlug}/archive",
2148
+ ...options
2149
+ });
2150
+ }
2151
+ /**
2152
+ * Get all entitlements for a license
2153
+ *
2154
+ * Returns a cursor-paginated page of entitlements granted by a license, identified by its unique slug.
2155
+ */
2156
+ static getLicenseEntitlements(options) {
2157
+ return (options.client ?? client).get({
2158
+ security: [{
2159
+ scheme: "bearer",
2160
+ type: "http"
2161
+ }],
2162
+ url: "/licenses/{licenseSlug}/entitlements",
2163
+ ...options
2164
+ });
2165
+ }
2166
+ /**
2167
+ * Associate an entitlement with a license
2168
+ *
2169
+ * Associate an entitlement with a license by providing the license slug and entitlement details
2170
+ */
2171
+ static associateEntitlementWithLicense(options) {
2172
+ return (options.client ?? client).post({
2173
+ security: [{
2174
+ scheme: "bearer",
2175
+ type: "http"
2176
+ }],
2177
+ url: "/licenses/{licenseSlug}/entitlements",
2178
+ ...options,
2179
+ headers: {
2180
+ "Content-Type": "application/json",
2181
+ ...options.headers
2182
+ }
2183
+ });
2184
+ }
2185
+ /**
2186
+ * Delete a license entitlement
2187
+ *
2188
+ * Delete a license entitlement with the provided details
2189
+ */
2190
+ static deleteLicenseEntitlement(options) {
2191
+ return (options.client ?? client).delete({
2192
+ security: [{
2193
+ scheme: "bearer",
2194
+ type: "http"
2195
+ }],
2196
+ url: "/licenses/{licenseSlug}/entitlements/{entitlementSlug}",
2197
+ ...options
2198
+ });
2199
+ }
2200
+ /**
2201
+ * Get a license entitlement
2202
+ *
2203
+ * Retrieve a entitlement for a license by their unique slugs
2204
+ */
2205
+ static getLicenseEntitlement(options) {
2206
+ return (options.client ?? client).get({
2207
+ security: [{
2208
+ scheme: "bearer",
2209
+ type: "http"
2210
+ }],
2211
+ url: "/licenses/{licenseSlug}/entitlements/{entitlementSlug}",
2212
+ ...options
2213
+ });
2214
+ }
2215
+ /**
2216
+ * Update an license entitlement
2217
+ *
2218
+ * Update an license entitlement with the provided details
2219
+ */
2220
+ static updateLicenseEntitlement(options) {
2221
+ return (options.client ?? client).put({
2222
+ security: [{
2223
+ scheme: "bearer",
2224
+ type: "http"
2225
+ }],
2226
+ url: "/licenses/{licenseSlug}/entitlements/{entitlementSlug}",
2227
+ ...options,
2228
+ headers: {
2229
+ "Content-Type": "application/json",
2230
+ ...options.headers
2231
+ }
2232
+ });
2233
+ }
2234
+ /**
2235
+ * Publish a license version
2236
+ *
2237
+ * Puts a DRAFT license version on sale: it becomes PUBLISHED, so it can be made its family's default, and its family resolves to it when the family has no default and this is its highest published version. Only a draft can be published (409 PublishLicense.NotADraft); an archived version goes back on sale with unarchive-license. Emits LICENSE_PUBLISHED.
2238
+ */
2239
+ static publishLicense(options) {
2240
+ return (options.client ?? client).post({
2241
+ security: [{
2242
+ scheme: "bearer",
2243
+ type: "http"
2244
+ }],
2245
+ url: "/licenses/{licenseSlug}/publish",
2246
+ ...options
2247
+ });
2248
+ }
2249
+ /**
2250
+ * Unarchive a license version
2251
+ *
2252
+ * Puts an ARCHIVED license version back on sale: it is PUBLISHED again, can be assigned to instances, and can be what its family resolves to. Only an archived version can be unarchived (409 UnarchiveLicense.NotArchived). Emits LICENSE_UNARCHIVED.
2253
+ */
2254
+ static unarchiveLicense(options) {
2255
+ return (options.client ?? client).post({
2256
+ security: [{
2257
+ scheme: "bearer",
2258
+ type: "http"
2259
+ }],
2260
+ url: "/licenses/{licenseSlug}/unarchive",
2261
+ ...options
2262
+ });
2263
+ }
2264
+ };
2265
+ var MetadataFields = class {
2266
+ /**
2267
+ * List active metadata fields for a resource type
2268
+ *
2269
+ * Returns a cursor-paginated page of the active (non-archived) metadata fields declared for the org and the given resource type, ordered by displayOrder then createdAt.
2270
+ */
2271
+ static listMetadataFields(options) {
2272
+ return (options.client ?? client).get({
2273
+ security: [{
2274
+ scheme: "bearer",
2275
+ type: "http"
2276
+ }],
2277
+ url: "/metadata-fields",
2278
+ ...options
2279
+ });
2280
+ }
2281
+ /**
2282
+ * Create a metadata field
2283
+ *
2284
+ * Declares a typed metadata field for a given resource type (DEPLOYMENT_ZONE, INSTANCE). The json_schema is validated against JSON Schema 2020-12 before insertion. Restricted to write:metadata_fields scope (admin-only policy).
2285
+ */
2286
+ static createMetadataField(options) {
2287
+ return (options.client ?? client).post({
2288
+ security: [{
2289
+ scheme: "bearer",
2290
+ type: "http"
2291
+ }],
2292
+ url: "/metadata-fields",
2293
+ ...options,
2294
+ headers: {
2295
+ "Content-Type": "application/json",
2296
+ ...options.headers
2297
+ }
2298
+ });
2299
+ }
2300
+ /**
2301
+ * Reorder metadata fields
2302
+ *
2303
+ * Sets the displayOrder of the listed fields to their position in the array (0-indexed). All ids must belong to the same organization, resource type, and be non-archived; the entire reorder is applied in a single transaction.
2304
+ */
2305
+ static reorderMetadataFields(options) {
2306
+ return (options.client ?? client).post({
2307
+ security: [{
2308
+ scheme: "bearer",
2309
+ type: "http"
2310
+ }],
2311
+ url: "/metadata-fields/reorder",
2312
+ ...options,
2313
+ headers: {
2314
+ "Content-Type": "application/json",
2315
+ ...options.headers
2316
+ }
2317
+ });
2318
+ }
2319
+ /**
2320
+ * Update a metadata field
2321
+ *
2322
+ * Updates label and json_schema. `key` and `resourceType` are immutable, and `displayOrder` belongs to POST /metadata-fields/reorder. The new json_schema is validated against JSON Schema 2020-12 and the transition rules: type changes, cardinality changes, and free-string ↔ enum toggles are rejected with 422.
2323
+ */
2324
+ static updateMetadataField(options) {
2325
+ return (options.client ?? client).patch({
2326
+ security: [{
2327
+ scheme: "bearer",
2328
+ type: "http"
2329
+ }],
2330
+ url: "/metadata-fields/{id}",
2331
+ ...options,
2332
+ headers: {
2333
+ "Content-Type": "application/json",
2334
+ ...options.headers
2335
+ }
2336
+ });
2337
+ }
2338
+ /**
2339
+ * Archive a metadata field
2340
+ *
2341
+ * Soft-deletes a metadata field. The row stays in the DB (its archived_at is set) so historic metadata is still interpretable; the field stops appearing in the active schema composition.
2342
+ */
2343
+ static archiveMetadataField(options) {
2344
+ return (options.client ?? client).post({
2345
+ security: [{
2346
+ scheme: "bearer",
2347
+ type: "http"
2348
+ }],
2349
+ url: "/metadata-fields/{id}/archive",
2350
+ ...options
2351
+ });
2352
+ }
2353
+ /**
2354
+ * Preview the impact of a metadata field schema change
2355
+ *
2356
+ * Computes, server-side, how many existing resources of this field's resource type carry a value under this field's key that would NOT satisfy the supplied candidate JSON Schema, plus a small sample. Read-only — does not mutate the field. Replaces the former client-side dry-run that pulled every resource's metadata.
2357
+ */
2358
+ static dryRunMetadataField(options) {
2359
+ return (options.client ?? client).post({
2360
+ security: [{
2361
+ scheme: "bearer",
2362
+ type: "http"
2363
+ }],
2364
+ url: "/metadata-fields/{id}/dry-run",
2365
+ ...options,
2366
+ headers: {
2367
+ "Content-Type": "application/json",
2368
+ ...options.headers
2369
+ }
2370
+ });
2371
+ }
2372
+ /**
2373
+ * Unarchive a metadata field
2374
+ *
2375
+ * Restores a previously archived metadata field (clears its archived_at). The field re-enters the active schema composition. Returns 409 if an active field already uses the same key for this resource type, or 404 if the field does not exist or is not archived.
2376
+ */
2377
+ static unarchiveMetadataField(options) {
2378
+ return (options.client ?? client).post({
2379
+ security: [{
2380
+ scheme: "bearer",
2381
+ type: "http"
2382
+ }],
2383
+ url: "/metadata-fields/{id}/unarchive",
2384
+ ...options
2385
+ });
2386
+ }
2387
+ };
2388
+ var OfrepCore = class {
2389
+ /**
2390
+ * OFREP bulk flag evaluation contract
2391
+ *
2392
+ * OFREP bulk evaluation request.
2393
+ * The endpoint is called by the client providers to evaluate all flags at once.
2394
+ */
2395
+ static evaluateFlagsBulk(options) {
2396
+ return (options?.client ?? client).post({
2397
+ security: [{
2398
+ scheme: "bearer",
2399
+ type: "http"
2400
+ }],
2401
+ url: "/ofrep/v1/evaluate/flags",
2402
+ ...options,
2403
+ headers: {
2404
+ "Content-Type": "application/json",
2405
+ ...options?.headers
2406
+ }
2407
+ });
2408
+ }
2409
+ /**
2410
+ * OFREP single flag evaluation contract
2411
+ *
2412
+ * EvaluateVariant a single feature flag for a given key
2413
+ */
2414
+ static evaluateFlag(options) {
2415
+ return (options.client ?? client).post({
2416
+ security: [{
2417
+ scheme: "bearer",
2418
+ type: "http"
2419
+ }],
2420
+ url: "/ofrep/v1/evaluate/flags/{key}",
2421
+ ...options,
2422
+ headers: {
2423
+ "Content-Type": "application/json",
2424
+ ...options.headers
2425
+ }
2426
+ });
2427
+ }
2428
+ };
2429
+ var OpenFeature = class {
2430
+ /**
2431
+ * Get OpenFeature manifest
2432
+ *
2433
+ * Returns a manifest of all feature flags that have a fallback_value set in their metadata
2434
+ */
2435
+ static getOpenfeatureManifest(options) {
2436
+ return (options?.client ?? client).get({
2437
+ security: [{
2438
+ scheme: "bearer",
2439
+ type: "http"
2440
+ }],
2441
+ url: "/openfeature/v0/manifest",
2442
+ ...options
2443
+ });
2444
+ }
2445
+ };
2446
+ var Releases = class {
2447
+ /**
2448
+ * List releases
2449
+ *
2450
+ * Returns a cursor-paginated page of releases for the current organization.
2451
+ */
2452
+ static listReleases(options) {
2453
+ return (options?.client ?? client).get({
2454
+ security: [{
2455
+ scheme: "bearer",
2456
+ type: "http"
2457
+ }],
2458
+ url: "/releases",
2459
+ ...options
2460
+ });
2461
+ }
2462
+ /**
2463
+ * Create a new release
2464
+ *
2465
+ * Create a new release with the provided details and link the requested components. A release is immutable: there is no update endpoint, and the component list cannot change afterwards. Correcting one means deleting it and creating a new one, which starts a new deployment history.
2466
+ */
2467
+ static createRelease(options) {
2468
+ return (options.client ?? client).post({
2469
+ security: [{
2470
+ scheme: "bearer",
2471
+ type: "http"
2472
+ }],
2473
+ url: "/releases",
2474
+ ...options,
2475
+ headers: {
2476
+ "Content-Type": "application/json",
2477
+ ...options.headers
2478
+ }
2479
+ });
2480
+ }
2481
+ /**
2482
+ * Delete a release
2483
+ *
2484
+ * Delete a release by their slug. Since a release is immutable, this plus a fresh create is the only way to change one -- and it discards the deployment history recorded against the old release. A release still deployed to a zone cannot be deleted (409).
2485
+ */
2486
+ static deleteRelease(options) {
2487
+ return (options.client ?? client).delete({
2488
+ security: [{
2489
+ scheme: "bearer",
2490
+ type: "http"
2491
+ }],
2492
+ url: "/releases/{releaseSlug}",
2493
+ ...options
2494
+ });
2495
+ }
2496
+ };
2497
+ var ServiceAccounts = class {
2498
+ /**
2499
+ * List all service accounts
2500
+ *
2501
+ * Returns a cursor-paginated page of service accounts (machine users) for the current organization.
2502
+ */
2503
+ static getServiceAccounts(options) {
2504
+ return (options?.client ?? client).get({
2505
+ security: [{
2506
+ scheme: "bearer",
2507
+ type: "http"
2508
+ }],
2509
+ url: "/service-accounts",
2510
+ ...options
2511
+ });
2512
+ }
2513
+ /**
2514
+ * Create a new service account
2515
+ *
2516
+ * Create a new service account (machine user) with the provided name. Service accounts can be used to generate API tokens for programmatic access.
2517
+ */
2518
+ static createServiceAccount(options) {
2519
+ return (options.client ?? client).post({
2520
+ security: [{
2521
+ scheme: "bearer",
2522
+ type: "http"
2523
+ }],
2524
+ url: "/service-accounts",
2525
+ ...options,
2526
+ headers: {
2527
+ "Content-Type": "application/json",
2528
+ ...options.headers
2529
+ }
2530
+ });
2531
+ }
2532
+ /**
2533
+ * Get a service account by slug
2534
+ *
2535
+ * Retrieve details of a specific service account (machine user) by its slug.
2536
+ */
2537
+ static getServiceAccount(options) {
2538
+ return (options.client ?? client).get({
2539
+ security: [{
2540
+ scheme: "bearer",
2541
+ type: "http"
2542
+ }],
2543
+ url: "/service-accounts/{serviceAccountSlug}",
2544
+ ...options
2545
+ });
2546
+ }
2547
+ /**
2548
+ * Update a service account
2549
+ *
2550
+ * Update the name of a service account (machine user) by its slug.
2551
+ */
2552
+ static updateServiceAccount(options) {
2553
+ return (options.client ?? client).put({
2554
+ security: [{
2555
+ scheme: "bearer",
2556
+ type: "http"
2557
+ }],
2558
+ url: "/service-accounts/{serviceAccountSlug}",
2559
+ ...options,
2560
+ headers: {
2561
+ "Content-Type": "application/json",
2562
+ ...options.headers
2563
+ }
2564
+ });
2565
+ }
2566
+ /**
2567
+ * List all tokens for a service account
2568
+ *
2569
+ * Returns a cursor-paginated page of API tokens associated with a service account. The organization context is derived from the authenticated user's JWT token. Token secret values are never returned, only metadata.
2570
+ */
2571
+ static getServiceAccountTokens(options) {
2572
+ return (options.client ?? client).get({
2573
+ security: [{
2574
+ scheme: "bearer",
2575
+ type: "http"
2576
+ }],
2577
+ url: "/service-accounts/{serviceAccountSlug}/tokens",
2578
+ ...options
2579
+ });
2580
+ }
2581
+ /**
2582
+ * Create a new token for a service account
2583
+ *
2584
+ * Create a new API token for a service account. The token value is only returned once upon creation and cannot be retrieved again. The organization context is derived from the authenticated user's JWT token.
2585
+ */
2586
+ static createServiceAccountToken(options) {
2587
+ return (options.client ?? client).post({
2588
+ security: [{
2589
+ scheme: "bearer",
2590
+ type: "http"
2591
+ }],
2592
+ url: "/service-accounts/{serviceAccountSlug}/tokens",
2593
+ ...options,
2594
+ headers: {
2595
+ "Content-Type": "application/json",
2596
+ ...options.headers
2597
+ }
2598
+ });
2599
+ }
2600
+ /**
2601
+ * Revoke a token for a service account
2602
+ *
2603
+ * Revoke an API token for a service account. Once revoked, the token can no longer be used for authentication. The organization context is derived from the authenticated user's JWT token.
2604
+ */
2605
+ static deleteServiceAccountToken(options) {
2606
+ return (options.client ?? client).delete({
2607
+ security: [{
2608
+ scheme: "bearer",
2609
+ type: "http"
2610
+ }],
2611
+ url: "/service-accounts/{serviceAccountSlug}/tokens/{tokenSlug}",
2612
+ ...options
2613
+ });
2614
+ }
2615
+ };
2616
+ var Notifications = class {
2617
+ /**
2618
+ * Read the caller's notification preferences
2619
+ *
2620
+ * Every notifiable event, with this user's effective value per channel: their own choice where they made one, the catalogue default otherwise. Events absent from the catalogue of a deployment never appear, which is what keeps high-volume system events out of the feed.
2621
+ */
2622
+ static getNotificationPreferences(options) {
2623
+ return (options?.client ?? client).get({
2624
+ security: [{
2625
+ scheme: "bearer",
2626
+ type: "http"
2627
+ }],
2628
+ url: "/v1/notification-preferences",
2629
+ ...options
2630
+ });
2631
+ }
2632
+ /**
2633
+ * Set the caller's notification preferences
2634
+ *
2635
+ * Stores the signed-in user's choices and answers with the whole matrix. A value that equals the catalogue default is stored as no row at all, so a later change to that default still reaches this user.
2636
+ */
2637
+ static putNotificationPreferences(options) {
2638
+ return (options.client ?? client).put({
2639
+ security: [{
2640
+ scheme: "bearer",
2641
+ type: "http"
2642
+ }],
2643
+ url: "/v1/notification-preferences",
2644
+ ...options,
2645
+ headers: {
2646
+ "Content-Type": "application/json",
2647
+ ...options.headers
2648
+ }
2649
+ });
2650
+ }
2651
+ /**
2652
+ * List the caller's notifications
2653
+ *
2654
+ * Returns the signed-in user's notification feed, newest first, with the unread count. Notifications are a view over this organization's audit trail, narrowed to the events the user subscribes to; the id of a notification is the id of the audit trail entry it reports.
2655
+ */
2656
+ static listNotifications(options) {
2657
+ return (options?.client ?? client).get({
2658
+ security: [{
2659
+ scheme: "bearer",
2660
+ type: "http"
2661
+ }],
2662
+ url: "/v1/notifications",
2663
+ ...options
2664
+ });
2665
+ }
2666
+ /**
2667
+ * Mark notifications read
2668
+ *
2669
+ * Marks the given notifications read for the signed-in user, or all of them with all: true. Ids belonging to another organization are ignored rather than rejected, so a retry of a partially applied call is safe.
2670
+ */
2671
+ static markNotificationsRead(options) {
2672
+ return (options.client ?? client).post({
2673
+ security: [{
2674
+ scheme: "bearer",
2675
+ type: "http"
2676
+ }],
2677
+ url: "/v1/notifications/mark-read",
2678
+ ...options,
2679
+ headers: {
2680
+ "Content-Type": "application/json",
2681
+ ...options.headers
2682
+ }
2683
+ });
2684
+ }
2685
+ };
2686
+ //#endregion
2687
+ //#region src/index.ts
2688
+ /**
2689
+ * Puts a base URL in the shape the contract is served under.
2690
+ *
2691
+ * The OpenAPI document mounts every operation below `/api` (`servers: - url:
2692
+ * /api`), and the operation paths are emitted bare (`/customers`), so a base URL
2693
+ * without that prefix 404s on every call. This follows the convention the
2694
+ * platform's own usage reporter already uses: require an absolute URL, drop a
2695
+ * trailing slash, append `/api` when it is not already there.
2696
+ *
2697
+ * Appending rather than rejecting accepts a bare origin as it is, and leaves a
2698
+ * gateway that already terminates on `/api` untouched.
2699
+ */
2700
+ function normalizeBaseUrl(raw) {
2701
+ let parsed;
2702
+ try {
2703
+ parsed = new URL(raw.trim());
2704
+ } catch {
2705
+ throw new TypeError(`Kaiten baseUrl must be an absolute URL (received ${JSON.stringify(raw)}).`);
2706
+ }
2707
+ if (!parsed.protocol || !parsed.host) throw new TypeError(`Kaiten baseUrl must be an absolute URL (received ${JSON.stringify(raw)}).`);
2708
+ const path = parsed.pathname.replace(/\/+$/, "");
2709
+ parsed.pathname = path.endsWith("/api") ? path : `${path}/api`;
2710
+ return `${parsed.origin}${parsed.pathname}`;
2711
+ }
2712
+ /**
2713
+ * Create a Bearer-authenticated client to pass to the generated resource
2714
+ * classes via their `{ client }` option. Each call to the factory yields an
2715
+ * independent client, so a single process can talk to the API with several
2716
+ * tokens.
2717
+ *
2718
+ * Failed calls **throw**. The generated resource methods are typed
2719
+ * `ThrowOnError extends boolean = false`, which would otherwise resolve
2720
+ * `{ data: undefined, error }` on every failure — so a caller reading `data`
2721
+ * sees a successful-looking `undefined`, and the 409 that
2722
+ * `Instances.reportEntitlementUsageMetric` answers with when an entitlement
2723
+ * threshold is reached reads as success. Errors are normalized to
2724
+ * {@link KaitenError} / {@link KaitenNetworkError}; use {@link isThresholdExceeded}
2725
+ * to detect the threshold case.
2726
+ */
2727
+ function createKaitenClient(config) {
2728
+ if (typeof config.baseUrl !== "string" || config.baseUrl.trim() === "") throw new TypeError("Kaiten baseUrl is required: the URL of your Kaiten API.");
2729
+ const client = createClient(createConfig({
2730
+ baseUrl: normalizeBaseUrl(config.baseUrl),
2731
+ throwOnError: true,
2732
+ ...config.fetch ? { fetch: config.fetch } : {}
2733
+ }));
2734
+ client.interceptors.request.use(async (request) => {
2735
+ const token = typeof config.token === "function" ? await config.token() : config.token;
2736
+ const headers = new Headers(request.headers);
2737
+ headers.set("Authorization", `Bearer ${token}`);
2738
+ return new Request(request, { headers });
2739
+ });
2740
+ client.interceptors.error.use((error, response) => toKaitenError(error, response));
2741
+ return client;
2742
+ }
2743
+ //#endregion
2744
+ export { Components, Connectors, Customers, DeploymentZones, EntitlementGroups, Entitlements, Featureflags, Instances, Integrations, KaitenError, KaitenNetworkError, KaitenWebhookVerificationError, LicenseFamilies, Licenses, MetadataFields, Notifications, OfrepCore, OpenFeature, Releases, ServiceAccounts, createKaitenClient, isKaitenWebhookOfType, isThresholdExceeded, isWebhookVerificationError, toKaitenError, verifyKaitenWebhook };