@elmohq/sdk 0.0.0-claim → 0.1.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/LICENSE.md +21 -0
- package/README.md +325 -2
- package/dist/calls/index.d.mts +288 -0
- package/dist/calls/index.d.mts.map +1 -0
- package/dist/calls/index.mjs +390 -0
- package/dist/calls/index.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +1029 -0
- package/dist/index.mjs.map +1 -0
- package/dist/request-options-DWYI_Ldj.d.mts +1550 -0
- package/dist/request-options-DWYI_Ldj.d.mts.map +1 -0
- package/dist/tools-7Hs5J2xb.d.mts +1945 -0
- package/dist/tools-7Hs5J2xb.d.mts.map +1 -0
- package/dist/tools-SwP0sK8H.mjs +2458 -0
- package/dist/tools-SwP0sK8H.mjs.map +1 -0
- package/dist/types/index.d.mts +2 -0
- package/dist/types/index.mjs +1 -0
- package/package.json +59 -2
- package/src/calls/brands-analytics-get.ts +33 -0
- package/src/calls/brands-citations-domains-list.ts +36 -0
- package/src/calls/brands-citations-urls-list.ts +32 -0
- package/src/calls/brands-create.ts +19 -0
- package/src/calls/brands-get.ts +19 -0
- package/src/calls/brands-list.ts +18 -0
- package/src/calls/brands-opportunities-get.ts +42 -0
- package/src/calls/brands-prompt-performance-list.ts +39 -0
- package/src/calls/brands-query-fanout-get.ts +30 -0
- package/src/calls/brands-tags-list.ts +28 -0
- package/src/calls/brands-update.ts +20 -0
- package/src/calls/competitors-create.ts +23 -0
- package/src/calls/competitors-delete.ts +19 -0
- package/src/calls/competitors-get.ts +19 -0
- package/src/calls/competitors-list.ts +23 -0
- package/src/calls/competitors-update.ts +24 -0
- package/src/calls/index.ts +33 -0
- package/src/calls/me-get.ts +18 -0
- package/src/calls/models-list.ts +20 -0
- package/src/calls/organizations-billing-get.ts +37 -0
- package/src/calls/organizations-get.ts +24 -0
- package/src/calls/organizations-list.ts +27 -0
- package/src/calls/prompts-create.ts +27 -0
- package/src/calls/prompts-delete.ts +28 -0
- package/src/calls/prompts-get.ts +23 -0
- package/src/calls/prompts-list.ts +28 -0
- package/src/calls/prompts-runs-get.ts +27 -0
- package/src/calls/prompts-runs-list.ts +30 -0
- package/src/calls/prompts-snapshot-get.ts +28 -0
- package/src/calls/prompts-update.ts +29 -0
- package/src/calls/reports-create.ts +31 -0
- package/src/calls/reports-get.ts +27 -0
- package/src/calls/reports-list.ts +28 -0
- package/src/calls/tools-analyze.ts +26 -0
- package/src/client.ts +662 -0
- package/src/index.ts +21 -0
- package/src/internal/binding/rest/binding.ts +127 -0
- package/src/internal/binding/rest/errors.ts +107 -0
- package/src/internal/binding/rest/path.ts +9 -0
- package/src/internal/binding/rest/url.ts +97 -0
- package/src/internal/codec/json.ts +66 -0
- package/src/internal/codec/registry.ts +55 -0
- package/src/internal/core/backoff.ts +170 -0
- package/src/internal/core/body.ts +54 -0
- package/src/internal/core/browser.ts +11 -0
- package/src/internal/core/call-promise.ts +145 -0
- package/src/internal/core/callable.ts +11 -0
- package/src/internal/core/client.ts +89 -0
- package/src/internal/core/config.ts +84 -0
- package/src/internal/core/credentials.ts +40 -0
- package/src/internal/core/dispatch.ts +227 -0
- package/src/internal/core/env.ts +68 -0
- package/src/internal/core/errors.ts +431 -0
- package/src/internal/core/features.ts +60 -0
- package/src/internal/core/lazy-promise.ts +39 -0
- package/src/internal/core/metadata.ts +79 -0
- package/src/internal/core/params.ts +98 -0
- package/src/internal/core/protocol.ts +17 -0
- package/src/internal/core/read-reply.ts +7 -0
- package/src/internal/core/text.ts +7 -0
- package/src/internal/core/types.ts +556 -0
- package/src/internal/feature/auth.ts +201 -0
- package/src/internal/feature/interceptors.ts +36 -0
- package/src/internal/feature/logger.ts +222 -0
- package/src/internal/feature/retry.ts +165 -0
- package/src/internal/feature/rules.ts +54 -0
- package/src/internal/feature/timeout.ts +146 -0
- package/src/internal/feature/validate.ts +74 -0
- package/src/internal/page/page.ts +402 -0
- package/src/internal/transport/fetch.ts +82 -0
- package/src/resources/analytics.ts +363 -0
- package/src/resources/brands.ts +285 -0
- package/src/resources/competitors.ts +212 -0
- package/src/resources/identity.ts +48 -0
- package/src/resources/models.ts +32 -0
- package/src/resources/opportunities.ts +79 -0
- package/src/resources/organizations.ts +181 -0
- package/src/resources/prompts.ts +292 -0
- package/src/resources/reports.ts +211 -0
- package/src/resources/runs.ts +123 -0
- package/src/resources/shared/auth.ts +13 -0
- package/src/resources/shared/request-options.ts +26 -0
- package/src/resources/shared/resource.ts +23 -0
- package/src/resources/shared/rule.ts +25 -0
- package/src/resources/snapshots.ts +54 -0
- package/src/resources/tags.ts +46 -0
- package/src/resources/tools.ts +68 -0
- package/src/types/analytics.ts +497 -0
- package/src/types/brands.ts +228 -0
- package/src/types/competitors.ts +196 -0
- package/src/types/identity.ts +55 -0
- package/src/types/index.ts +163 -0
- package/src/types/models.ts +40 -0
- package/src/types/opportunities.ts +84 -0
- package/src/types/organizations.ts +157 -0
- package/src/types/prompts.ts +231 -0
- package/src/types/reports.ts +266 -0
- package/src/types/runs.ts +131 -0
- package/src/types/shared/brand-id-path.ts +2 -0
- package/src/types/shared/conflict-error.ts +7 -0
- package/src/types/shared/error.ts +29 -0
- package/src/types/shared/limit.ts +8 -0
- package/src/types/shared/mention-entry.ts +21 -0
- package/src/types/shared/model-filter.ts +15 -0
- package/src/types/shared/not-found-error.ts +4 -0
- package/src/types/shared/page.ts +7 -0
- package/src/types/shared/pagination.ts +7 -0
- package/src/types/shared/validation-error.ts +4 -0
- package/src/types/snapshots.ts +88 -0
- package/src/types/tags.ts +47 -0
- package/src/types/tools.ts +78 -0
|
@@ -0,0 +1,2458 @@
|
|
|
1
|
+
//#region src/internal/core/backoff.ts
|
|
2
|
+
function jitterShare(jitter) {
|
|
3
|
+
if (typeof jitter === "number") return Math.min(1, Math.max(0, jitter));
|
|
4
|
+
if (jitter === "equal") return .5;
|
|
5
|
+
return jitter === true || jitter === "full" ? 1 : 0;
|
|
6
|
+
}
|
|
7
|
+
function backoffDelay(retry, options = {}) {
|
|
8
|
+
const { delay = 500, jitter = true, maxDelay = 3e4, strategy = "exponential" } = options;
|
|
9
|
+
const growth = strategy === "constant" ? delay : delay && delay * 2 ** retry;
|
|
10
|
+
const capped = Math.min(growth, maxDelay);
|
|
11
|
+
const share = jitterShare(jitter);
|
|
12
|
+
return share ? capped * (1 - share) + Math.random() * capped * share : capped;
|
|
13
|
+
}
|
|
14
|
+
function exceedsMaxRetryAfter(delay, max) {
|
|
15
|
+
return delay !== void 0 && delay > (max ?? 6e4);
|
|
16
|
+
}
|
|
17
|
+
const TIMER_LIMIT = 2147483647;
|
|
18
|
+
function sleep(ms, signal) {
|
|
19
|
+
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
20
|
+
if (ms <= 0) return Promise.resolve();
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const timer = setTimeout(() => {
|
|
23
|
+
signal?.removeEventListener("abort", onAbort);
|
|
24
|
+
resolve();
|
|
25
|
+
}, Math.min(ms, TIMER_LIMIT));
|
|
26
|
+
function onAbort() {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
reject(signal.reason);
|
|
29
|
+
}
|
|
30
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const RETRY_AFTER_HEADERS = [
|
|
34
|
+
{
|
|
35
|
+
name: "retry-after-ms",
|
|
36
|
+
unit: "millisecond"
|
|
37
|
+
},
|
|
38
|
+
{ name: "retry-after" },
|
|
39
|
+
{ name: "x-ratelimit-reset-after" },
|
|
40
|
+
{
|
|
41
|
+
kind: "moment",
|
|
42
|
+
name: "x-ratelimit-reset"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
kind: "moment",
|
|
46
|
+
name: "x-rate-limit-reset"
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
const ASCTIME = /^[a-z]{3} ([a-z]{3}) +(\d\d?) (\d\d:\d\d:\d\d) (\d{4})$/i;
|
|
50
|
+
const MOMENT = /^(?:(\d{4})-(\d\d)-(\d\d)[t ]|(?:[a-z]+, ?)?(\d\d?)[ -]([a-z]{3})[ -](\d\d|\d{4}) )([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d|60)(?:\.(\d{1,3})\d*)?)? ?(?:z|gmt|utc?|([+-])([01]\d|2[0-3]):?([0-5]\d))$/i;
|
|
51
|
+
const MONTHS = "janfebmaraprmayjunjulaugsepoctnovdec";
|
|
52
|
+
function moment(value, now) {
|
|
53
|
+
const match = MOMENT.exec(value.replace(ASCTIME, "$2 $1 $4 $3 GMT"));
|
|
54
|
+
if (!match) return void 0;
|
|
55
|
+
const year = match[6] ?? match[1];
|
|
56
|
+
const day = +(match[4] ?? match[3]);
|
|
57
|
+
const month = match[2] ? +match[2] - 1 : MONTHS.indexOf(match[5].toLowerCase()) / 3;
|
|
58
|
+
let full = +year;
|
|
59
|
+
if (year.length < 3) {
|
|
60
|
+
const present = new Date(now).getUTCFullYear();
|
|
61
|
+
full += present - present % 100;
|
|
62
|
+
if (full > present + 50) full -= 100;
|
|
63
|
+
}
|
|
64
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
65
|
+
date.setUTCFullYear(full, month, day);
|
|
66
|
+
if (!full || date.getUTCMonth() !== month || date.getUTCDate() !== day) return void 0;
|
|
67
|
+
const zone = (match[11] === "-" ? -1 : 1) * (+(match[12] ?? 0) * 60 + +(match[13] ?? 0));
|
|
68
|
+
const seconds = (+match[7] * 60 + +match[8] - zone) * 60 + +(match[9] ?? 0);
|
|
69
|
+
return date.getTime() + seconds * 1e3 + +(match[10] ?? "").padEnd(3, "0");
|
|
70
|
+
}
|
|
71
|
+
const NUMBER = /^[0-9]+(?:\.[0-9]+)?$/;
|
|
72
|
+
function parseRetryAfter(value, header = { name: "retry-after" }, now = Date.now()) {
|
|
73
|
+
if (!value) return void 0;
|
|
74
|
+
if (NUMBER.test(value)) {
|
|
75
|
+
const number = Number(value);
|
|
76
|
+
const ms = header.unit === "millisecond" ? number : number * 1e3;
|
|
77
|
+
return Math.max(0, header.kind === "moment" ? ms - now : ms);
|
|
78
|
+
}
|
|
79
|
+
const date = moment(value, now);
|
|
80
|
+
if (date === void 0) return void 0;
|
|
81
|
+
return Math.max(0, date - now);
|
|
82
|
+
}
|
|
83
|
+
function retryAfterDelay(response, headers = RETRY_AFTER_HEADERS, now = Date.now()) {
|
|
84
|
+
const clock = moment(response.headers.get("date") ?? "", now) ?? now;
|
|
85
|
+
for (const header of headers) {
|
|
86
|
+
const delay = parseRetryAfter(response.headers.get(header.name), header, clock);
|
|
87
|
+
if (delay !== void 0) return delay;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/internal/core/errors.ts
|
|
92
|
+
/** The base of every error this SDK throws, including one from a call that never arrived. */
|
|
93
|
+
var ElmoError = class extends Error {
|
|
94
|
+
/** The class's name. Compare it where `instanceof` fails, such as across two copies of this SDK. */
|
|
95
|
+
name = "ElmoError";
|
|
96
|
+
};
|
|
97
|
+
function refusedInput(held, rule, got) {
|
|
98
|
+
return new ElmoError(`${held} ${rule}, and got ${got}, so the request was not sent.`);
|
|
99
|
+
}
|
|
100
|
+
/** Thrown before the request goes out, when no credential satisfied the call. */
|
|
101
|
+
var MissingCredentialError = class extends ElmoError {
|
|
102
|
+
name = "MissingCredentialError";
|
|
103
|
+
/** Credential options that would have satisfied the call. */
|
|
104
|
+
schemes;
|
|
105
|
+
constructor(message, schemes = []) {
|
|
106
|
+
super(message);
|
|
107
|
+
this.schemes = schemes;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
function unsendable(held) {
|
|
111
|
+
return `${held} holds a line break or another character a header cannot carry, so the request was not sent.`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Thrown when the caller called the request off before the API answered.
|
|
115
|
+
*
|
|
116
|
+
* Not a {@link TransportError}, so code that retries or reports a failed
|
|
117
|
+
* connection leaves a call the caller cancelled alone.
|
|
118
|
+
*/
|
|
119
|
+
var AbortError = class extends ElmoError {
|
|
120
|
+
constructor(cause) {
|
|
121
|
+
super("The request was called off before the API answered.", { cause });
|
|
122
|
+
this.name = "AbortError";
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const TRANSPORT_MESSAGES = {
|
|
126
|
+
connect: "The request never reached the API.",
|
|
127
|
+
other: "The connection failed before the whole reply arrived.",
|
|
128
|
+
timeout: "The API did not answer in time."
|
|
129
|
+
};
|
|
130
|
+
/** Thrown when no whole answer arrived, so there is no reply to go on. */
|
|
131
|
+
var TransportError = class extends ElmoError {
|
|
132
|
+
kind;
|
|
133
|
+
/**
|
|
134
|
+
* Whether the API can have acted on the request. After `'no'`, the call is
|
|
135
|
+
* safe to send again, whatever its method.
|
|
136
|
+
*/
|
|
137
|
+
reachedServer;
|
|
138
|
+
/** How far the request got. */
|
|
139
|
+
stage;
|
|
140
|
+
constructor(failure, cause, message) {
|
|
141
|
+
const unreached = failure === "connect";
|
|
142
|
+
const stated = typeof failure === "string" ? {
|
|
143
|
+
cause,
|
|
144
|
+
reachedServer: unreached ? "no" : "maybe",
|
|
145
|
+
stage: unreached ? "connect" : "receive"
|
|
146
|
+
} : failure;
|
|
147
|
+
const kind = typeof failure === "string" ? failure : failure.reachedServer === "no" ? "connect" : "other";
|
|
148
|
+
super(message ?? TRANSPORT_MESSAGES[kind], stated);
|
|
149
|
+
this.kind = kind;
|
|
150
|
+
this.name = "TransportError";
|
|
151
|
+
this.reachedServer = stated.reachedServer;
|
|
152
|
+
this.stage = stated.stage;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
function calledOffWith(reason) {
|
|
156
|
+
return reason instanceof AbortError || reason instanceof TransportError ? reason : new AbortError(reason);
|
|
157
|
+
}
|
|
158
|
+
const TIMEOUT_CODES = ["ECONNABORTED", "ETIMEDOUT"];
|
|
159
|
+
function codeOf(error) {
|
|
160
|
+
let current = error;
|
|
161
|
+
for (let depth = 0; current instanceof Error && depth < 5; depth++) {
|
|
162
|
+
const { code } = current;
|
|
163
|
+
if (typeof code === "string") return code;
|
|
164
|
+
current = current.cause;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const UNREACHED = {
|
|
168
|
+
EAI_AGAIN: "resolve",
|
|
169
|
+
ECONNREFUSED: "connect",
|
|
170
|
+
ENOTFOUND: "resolve",
|
|
171
|
+
UND_ERR_CONNECT_TIMEOUT: "connect"
|
|
172
|
+
};
|
|
173
|
+
function failureOf(error) {
|
|
174
|
+
const stated = error ?? {};
|
|
175
|
+
if (stated.reachedServer && stated.stage) return stated;
|
|
176
|
+
const stage = UNREACHED[codeOf(error) ?? ""];
|
|
177
|
+
return {
|
|
178
|
+
aborted: error instanceof Error && error.name === "AbortError",
|
|
179
|
+
cause: error,
|
|
180
|
+
reachedServer: stage ? "no" : "maybe",
|
|
181
|
+
stage: stage ?? "receive"
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function classifyError(error) {
|
|
185
|
+
if (error instanceof TransportError) return error.kind;
|
|
186
|
+
const failure = failureOf(error);
|
|
187
|
+
if (failure.aborted) return "abort";
|
|
188
|
+
if (error instanceof Error && error.name === "TimeoutError") return "timeout";
|
|
189
|
+
if (failure.reachedServer === "no") return "connect";
|
|
190
|
+
return TIMEOUT_CODES.includes(codeOf(error) ?? "") ? "timeout" : "other";
|
|
191
|
+
}
|
|
192
|
+
const USERINFO_RE = /^([a-z][a-z\d+.-]*:\/\/)[^/?#@]*@/i;
|
|
193
|
+
function safeAddress(url) {
|
|
194
|
+
return (url.split("?")[0] ?? "").replace(USERINFO_RE, "$1");
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Thrown when a call waited on the API for as long as it allowed, from sending
|
|
198
|
+
* the request to the last byte of the reply.
|
|
199
|
+
*
|
|
200
|
+
* A reply with status 408 is an {@link APIError}, not one of these.
|
|
201
|
+
*/
|
|
202
|
+
var TimeoutError = class extends TransportError {
|
|
203
|
+
/** Milliseconds the call was allowed to wait on the API. */
|
|
204
|
+
timeoutMs;
|
|
205
|
+
constructor(timeout, cause, target) {
|
|
206
|
+
super("timeout", cause, timeout === void 0 ? TRANSPORT_MESSAGES.timeout : `${target ?? "The request"} timed out after ${timeout} ms waiting on the API. Pass a larger \`timeout\` with the call, or \`timeout: false\` to wait as long as it takes.`);
|
|
207
|
+
this.name = "TimeoutError";
|
|
208
|
+
this.timeoutMs = timeout;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const CODE_KEYS = [
|
|
212
|
+
"code",
|
|
213
|
+
"error_code",
|
|
214
|
+
"errorCode",
|
|
215
|
+
"error_type",
|
|
216
|
+
"errorType"
|
|
217
|
+
];
|
|
218
|
+
function statedCode(bag) {
|
|
219
|
+
for (const key of CODE_KEYS) {
|
|
220
|
+
const value = bag[key];
|
|
221
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
222
|
+
if (typeof value === "number") return value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function describeCode(error) {
|
|
226
|
+
if (!error || typeof error !== "object") return void 0;
|
|
227
|
+
const body = error;
|
|
228
|
+
const direct = statedCode(body);
|
|
229
|
+
if (direct !== void 0) return direct;
|
|
230
|
+
for (const value of Object.values(body)) if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
231
|
+
const nested = statedCode(value);
|
|
232
|
+
if (nested !== void 0) return nested;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const MAX_MESSAGE_BODY = 200;
|
|
236
|
+
function oneLine(text) {
|
|
237
|
+
return text.replace(/\s+/g, " ").trim();
|
|
238
|
+
}
|
|
239
|
+
function shorten(text) {
|
|
240
|
+
const line = oneLine(text);
|
|
241
|
+
if (line.length <= MAX_MESSAGE_BODY) return line;
|
|
242
|
+
const cut = line.slice(0, MAX_MESSAGE_BODY);
|
|
243
|
+
const space = cut.lastIndexOf(" ");
|
|
244
|
+
return `${(space > MAX_MESSAGE_BODY / 2 ? cut.slice(0, space) : cut).trimEnd()}…`;
|
|
245
|
+
}
|
|
246
|
+
const MESSAGE_KEYS = [
|
|
247
|
+
"message",
|
|
248
|
+
"error_message",
|
|
249
|
+
"errorMessage",
|
|
250
|
+
"error",
|
|
251
|
+
"detail",
|
|
252
|
+
"title",
|
|
253
|
+
"description"
|
|
254
|
+
];
|
|
255
|
+
function statedMessage(bag) {
|
|
256
|
+
for (const key of MESSAGE_KEYS) {
|
|
257
|
+
const value = bag[key];
|
|
258
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function describeStatedFailure(error) {
|
|
262
|
+
if (typeof error === "string") return shorten(error.trim()) || void 0;
|
|
263
|
+
if (!error || typeof error !== "object") return void 0;
|
|
264
|
+
const body = error;
|
|
265
|
+
const direct = statedMessage(body);
|
|
266
|
+
if (direct) return shorten(direct);
|
|
267
|
+
for (const value of Object.values(body)) if (value && typeof value === "object") {
|
|
268
|
+
const nested = statedMessage(value);
|
|
269
|
+
if (nested) return shorten(nested);
|
|
270
|
+
}
|
|
271
|
+
const json = JSON.stringify(error);
|
|
272
|
+
return json && json !== "{}" && json !== "[]" ? shorten(json) : void 0;
|
|
273
|
+
}
|
|
274
|
+
function isStructured(body) {
|
|
275
|
+
return typeof body === "object" && body !== null && !(body instanceof Blob);
|
|
276
|
+
}
|
|
277
|
+
const REQUEST_ID_FALLBACKS = ["x-correlation-id", "cf-ray"];
|
|
278
|
+
const REQUEST_ID_NAME = /(?:^|-)request-?id$/;
|
|
279
|
+
function requestIdOf(response) {
|
|
280
|
+
let named;
|
|
281
|
+
response.headers.forEach((value, name) => {
|
|
282
|
+
if (!named && value && REQUEST_ID_NAME.test(name)) named = value;
|
|
283
|
+
});
|
|
284
|
+
if (named) return named;
|
|
285
|
+
for (const header of REQUEST_ID_FALLBACKS) {
|
|
286
|
+
const value = response.headers.get(header);
|
|
287
|
+
if (value) return value;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** A failure the API answered with, so there is a status and a reply to read. */
|
|
291
|
+
var APIError = class extends ElmoError {
|
|
292
|
+
/**
|
|
293
|
+
* The decoded failure body. `undefined` where the reply carried none, or
|
|
294
|
+
* carried text such as a proxy's page, which is in {@link APIError.text}.
|
|
295
|
+
*/
|
|
296
|
+
body;
|
|
297
|
+
/** The API's own error code, read from the failure body. `undefined` where it carried none. */
|
|
298
|
+
code;
|
|
299
|
+
headers;
|
|
300
|
+
/** The request id to quote when reporting this failure. */
|
|
301
|
+
requestId;
|
|
302
|
+
/**
|
|
303
|
+
* The reply that carried this failure. Its body is already read, so take it
|
|
304
|
+
* from {@link APIError.body} or {@link APIError.text}.
|
|
305
|
+
*/
|
|
306
|
+
response;
|
|
307
|
+
/** Milliseconds the API asked to wait before trying again. */
|
|
308
|
+
retryAfterMs;
|
|
309
|
+
status;
|
|
310
|
+
/**
|
|
311
|
+
* The failure body where the API sent text rather than JSON, such as a
|
|
312
|
+
* proxy's page. The message holds only its start.
|
|
313
|
+
*/
|
|
314
|
+
text;
|
|
315
|
+
constructor(status, body, response, note) {
|
|
316
|
+
const reason = response.statusText ? `${status} ${response.statusText}` : `${status}`;
|
|
317
|
+
const requestId = requestIdOf(response);
|
|
318
|
+
const url = response.url ? ` for "${safeAddress(response.url)}"` : "";
|
|
319
|
+
const where = requestId ? `${url} (request id "${requestId}")` : url;
|
|
320
|
+
const said = describeStatedFailure(body);
|
|
321
|
+
const tail = note ? `. ${note}${said ? ` The API said: ${said}` : ""}` : said ? `: ${said}` : ".";
|
|
322
|
+
super(`The API answered ${reason}${where}${tail}`);
|
|
323
|
+
this.body = isStructured(body) ? body : void 0;
|
|
324
|
+
this.code = describeCode(body);
|
|
325
|
+
this.headers = response.headers;
|
|
326
|
+
this.name = "APIError";
|
|
327
|
+
this.requestId = requestId;
|
|
328
|
+
this.response = response;
|
|
329
|
+
this.retryAfterMs = retryAfterDelay(response);
|
|
330
|
+
this.status = status;
|
|
331
|
+
this.text = typeof body === "string" ? body : void 0;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
var UnsupportedInteractionError = class extends ElmoError {
|
|
335
|
+
interaction;
|
|
336
|
+
transport;
|
|
337
|
+
constructor(transport, interaction) {
|
|
338
|
+
super(`Transport "${transport}" cannot send this call. It has no "${interaction}" method.`);
|
|
339
|
+
this.interaction = interaction;
|
|
340
|
+
this.name = "UnsupportedInteractionError";
|
|
341
|
+
this.transport = transport;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
function unansweredError(error) {
|
|
345
|
+
if (error instanceof ElmoError) return error;
|
|
346
|
+
const kind = classifyError(error);
|
|
347
|
+
if (kind === "abort") return new AbortError(error);
|
|
348
|
+
if (kind === "timeout") return new TimeoutError(void 0, error);
|
|
349
|
+
return new TransportError(failureOf(error));
|
|
350
|
+
}
|
|
351
|
+
function unsendableHeader(name) {
|
|
352
|
+
return new ElmoError(unsendable(`Header \`${name}\``));
|
|
353
|
+
}
|
|
354
|
+
function unsendableAddress(address, problem, fix) {
|
|
355
|
+
return new ElmoError(`"${address}" ${problem}, so the request was not sent. ${fix}`);
|
|
356
|
+
}
|
|
357
|
+
/** A reply from the API that this SDK could not read, whatever its status. */
|
|
358
|
+
var DecodeError = class extends ElmoError {
|
|
359
|
+
/** Where the value sat, or absent where the whole reply failed. */
|
|
360
|
+
at;
|
|
361
|
+
/** The request id to quote when reporting this failure. */
|
|
362
|
+
requestId;
|
|
363
|
+
/** The reply. Its body is already read. */
|
|
364
|
+
response;
|
|
365
|
+
/** The reply's status. `undefined` where there is no {@link DecodeError.response}. */
|
|
366
|
+
status;
|
|
367
|
+
/** What the API sent. The message holds only a short form of it. */
|
|
368
|
+
value;
|
|
369
|
+
constructor(message, options = {}) {
|
|
370
|
+
const requestId = options.response && requestIdOf(options.response);
|
|
371
|
+
super(requestId ? `${message} The request id is "${requestId}".` : message, { cause: options.cause });
|
|
372
|
+
this.at = options.at;
|
|
373
|
+
this.name = "DecodeError";
|
|
374
|
+
this.requestId = requestId;
|
|
375
|
+
this.response = options.response;
|
|
376
|
+
this.status = options.response?.status;
|
|
377
|
+
this.value = options.value;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
function emptyPathParameter(name, url) {
|
|
381
|
+
return new ElmoError(`Path parameter \`${name}\` is empty. \`${url}\` cannot be sent without it.`);
|
|
382
|
+
}
|
|
383
|
+
function sent(value) {
|
|
384
|
+
if (value === void 0) return "nothing";
|
|
385
|
+
if (typeof value === "string") return `"${shorten(value)}"`;
|
|
386
|
+
if (value === null || typeof value !== "object") return shorten(String(value));
|
|
387
|
+
try {
|
|
388
|
+
return shorten(JSON.stringify(value) ?? String(value));
|
|
389
|
+
} catch {
|
|
390
|
+
return shorten(String(value));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function unreadableValue(at, value, cause, response) {
|
|
394
|
+
return new DecodeError(`Could not read ${at === void 0 ? "the reply" : `\`${at}\` from the reply`}: the API sent ${sent(value)}.`, {
|
|
395
|
+
at,
|
|
396
|
+
cause,
|
|
397
|
+
response,
|
|
398
|
+
value
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
//#region src/internal/codec/registry.ts
|
|
403
|
+
function charsetOf(contentType) {
|
|
404
|
+
return contentType?.match(/;\s*charset\s*=\s*"?([^";\s]+)/i)?.[1];
|
|
405
|
+
}
|
|
406
|
+
function decoderFor(label, fatal) {
|
|
407
|
+
try {
|
|
408
|
+
return new TextDecoder(label, { fatal });
|
|
409
|
+
} catch {
|
|
410
|
+
return new TextDecoder("utf-8", { fatal });
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async function readText(raw, json = false) {
|
|
414
|
+
return decoderFor(json ? void 0 : charsetOf(raw.headers.get("content-type")), raw.ok).decode(await raw.arrayBuffer());
|
|
415
|
+
}
|
|
416
|
+
function essenceOf(mediaType) {
|
|
417
|
+
return mediaType.split(";", 1)[0].trim().toLowerCase();
|
|
418
|
+
}
|
|
419
|
+
function selectCodec(codecs, mediaType) {
|
|
420
|
+
if (!mediaType) return void 0;
|
|
421
|
+
const essence = essenceOf(mediaType);
|
|
422
|
+
const format = essence.replace(/\/.*\+/, "/");
|
|
423
|
+
return codecs.find((codec) => codec.mediaTypes.some((candidate) => [essence, format].includes(essenceOf(candidate))));
|
|
424
|
+
}
|
|
425
|
+
function encodeNamedBody(codecs, mediaType, options) {
|
|
426
|
+
if (options.body === void 0) return void 0;
|
|
427
|
+
if (options.bodySerializer) return {
|
|
428
|
+
contentType: mediaType,
|
|
429
|
+
payload: options.bodySerializer(options.body)
|
|
430
|
+
};
|
|
431
|
+
if (options.bodySerializer === null) return {
|
|
432
|
+
contentType: mediaType,
|
|
433
|
+
payload: options.body
|
|
434
|
+
};
|
|
435
|
+
const codec = selectCodec(codecs, mediaType);
|
|
436
|
+
if (!codec) return {
|
|
437
|
+
contentType: mediaType,
|
|
438
|
+
payload: options.body
|
|
439
|
+
};
|
|
440
|
+
return {
|
|
441
|
+
contentType: codec.contentType,
|
|
442
|
+
payload: codec.encode(options.body)
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
//#endregion
|
|
446
|
+
//#region src/internal/core/text.ts
|
|
447
|
+
function scalarText(value) {
|
|
448
|
+
return value instanceof Date ? value.toISOString() : void 0;
|
|
449
|
+
}
|
|
450
|
+
function toText(value) {
|
|
451
|
+
return typeof value === "string" ? value : scalarText(value) ?? String(value);
|
|
452
|
+
}
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region src/internal/core/metadata.ts
|
|
455
|
+
function entriesOf(source) {
|
|
456
|
+
if (typeof source[Symbol.iterator] === "function") return source;
|
|
457
|
+
return Object.entries(source);
|
|
458
|
+
}
|
|
459
|
+
function metadataText(value) {
|
|
460
|
+
if (Array.isArray(value)) return value.map(toText).join(",");
|
|
461
|
+
if (typeof value !== "object" || value === null || scalarText(value) !== void 0) return toText(value);
|
|
462
|
+
const pairs = [];
|
|
463
|
+
for (const [key, item] of Object.entries(value)) if (item !== void 0 && item !== null) pairs.push(key, toText(item));
|
|
464
|
+
return pairs.join(",");
|
|
465
|
+
}
|
|
466
|
+
function mergeMetadata(...sources) {
|
|
467
|
+
const merged = {};
|
|
468
|
+
for (const source of sources) {
|
|
469
|
+
if (!source) continue;
|
|
470
|
+
const seen = /* @__PURE__ */ new Set();
|
|
471
|
+
for (const [key, value] of entriesOf(source)) {
|
|
472
|
+
const name = key.toLowerCase();
|
|
473
|
+
if (value === void 0) continue;
|
|
474
|
+
if (value === null) {
|
|
475
|
+
delete merged[name];
|
|
476
|
+
seen.add(name);
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
const text = metadataText(value);
|
|
480
|
+
const held = seen.has(name) ? merged[name] : void 0;
|
|
481
|
+
seen.add(name);
|
|
482
|
+
if (held === void 0) merged[name] = text;
|
|
483
|
+
else merged[name] = Array.isArray(held) ? [...held, text] : [held, text];
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return merged;
|
|
487
|
+
}
|
|
488
|
+
const FIELD_VALUE = /^[\t\x20-\x7e\x80-\xff]*$/;
|
|
489
|
+
function isFieldValue(value) {
|
|
490
|
+
return FIELD_VALUE.test(value);
|
|
491
|
+
}
|
|
492
|
+
function metadataPairs(meta) {
|
|
493
|
+
const pairs = [];
|
|
494
|
+
for (const [name, value] of Object.entries(meta)) {
|
|
495
|
+
if (value === void 0) continue;
|
|
496
|
+
if (Array.isArray(value)) {
|
|
497
|
+
for (const item of value) pairs.push([name, item]);
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
pairs.push([name, value]);
|
|
501
|
+
}
|
|
502
|
+
return pairs;
|
|
503
|
+
}
|
|
504
|
+
function unsendableName(meta) {
|
|
505
|
+
for (const [name, value] of metadataPairs(meta)) if (!isFieldValue(value)) return name;
|
|
506
|
+
}
|
|
507
|
+
function metadataHeaders(meta) {
|
|
508
|
+
const headers = new Headers();
|
|
509
|
+
for (const [name, value] of metadataPairs(meta)) headers.append(name, value);
|
|
510
|
+
return headers;
|
|
511
|
+
}
|
|
512
|
+
function metadataValue(value) {
|
|
513
|
+
if (value === void 0) return void 0;
|
|
514
|
+
return Array.isArray(value) ? value.join(", ") : value;
|
|
515
|
+
}
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/internal/core/config.ts
|
|
518
|
+
function foldRetry(sources, merged) {
|
|
519
|
+
if (!sources.some((source) => source?.["retry"] !== void 0)) return merged;
|
|
520
|
+
let retry;
|
|
521
|
+
for (const source of sources) {
|
|
522
|
+
const own = source?.["retry"];
|
|
523
|
+
const count = source?.["maxRetries"];
|
|
524
|
+
const counted = typeof count === "number" && Number.isFinite(count);
|
|
525
|
+
if (own === false) retry = false;
|
|
526
|
+
else if (own !== void 0 || counted) {
|
|
527
|
+
const rules = {
|
|
528
|
+
...typeof retry === "object" && retry,
|
|
529
|
+
...typeof own === "object" && own
|
|
530
|
+
};
|
|
531
|
+
if (counted && (typeof own !== "object" || !own || !("maxRetries" in own))) rules["maxRetries"] = count;
|
|
532
|
+
retry = rules;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
merged["retry"] = retry;
|
|
536
|
+
delete merged["maxRetries"];
|
|
537
|
+
return merged;
|
|
538
|
+
}
|
|
539
|
+
const MERGED_LAYERS = ["path", "query"];
|
|
540
|
+
function mergeLayers(sources, merged) {
|
|
541
|
+
for (const key of MERGED_LAYERS) {
|
|
542
|
+
const layers = sources.filter((source) => source?.[key]);
|
|
543
|
+
if (!layers.length) continue;
|
|
544
|
+
const layer = {};
|
|
545
|
+
for (const source of layers) for (const [name, value] of Object.entries(source[key])) if (value !== void 0) layer[name] = value;
|
|
546
|
+
merged[key] = layer;
|
|
547
|
+
}
|
|
548
|
+
return merged;
|
|
549
|
+
}
|
|
550
|
+
function merge(sources, keepAccessors) {
|
|
551
|
+
const merged = {};
|
|
552
|
+
for (const source of sources) {
|
|
553
|
+
if (!source) continue;
|
|
554
|
+
if (keepAccessors) {
|
|
555
|
+
for (const [key, held] of Object.entries(Object.getOwnPropertyDescriptors(source))) if (held.get || held.value !== void 0) Object.defineProperty(merged, key, held);
|
|
556
|
+
} else for (const key of Object.keys(source)) {
|
|
557
|
+
const value = source[key];
|
|
558
|
+
if (value !== void 0) merged[key] = value;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
merged.headers = mergeMetadata(...sources.map((source) => source?.headers));
|
|
562
|
+
return foldRetry(sources, mergeLayers(sources, merged));
|
|
563
|
+
}
|
|
564
|
+
function mergeConfigs(...sources) {
|
|
565
|
+
return merge(sources, false);
|
|
566
|
+
}
|
|
567
|
+
function createConfig(overrides = {}) {
|
|
568
|
+
return mergeConfigs({
|
|
569
|
+
errors: "throw",
|
|
570
|
+
headers: {}
|
|
571
|
+
}, overrides);
|
|
572
|
+
}
|
|
573
|
+
function baseURLOf(options, fallback) {
|
|
574
|
+
return options.baseURL ?? fallback;
|
|
575
|
+
}
|
|
576
|
+
function mergeDefaults(...sources) {
|
|
577
|
+
return merge(sources, true);
|
|
578
|
+
}
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/internal/core/credentials.ts
|
|
581
|
+
const LAYER_ALIASES = {
|
|
582
|
+
defaultHeaders: "headers",
|
|
583
|
+
defaultPath: "path",
|
|
584
|
+
defaultQuery: "query"
|
|
585
|
+
};
|
|
586
|
+
function applyAliases(config, aliases) {
|
|
587
|
+
let applied;
|
|
588
|
+
for (const [alias, canonical] of Object.entries(aliases ? {
|
|
589
|
+
...LAYER_ALIASES,
|
|
590
|
+
...aliases
|
|
591
|
+
} : LAYER_ALIASES)) {
|
|
592
|
+
if (!(alias in config)) continue;
|
|
593
|
+
applied ??= { ...config };
|
|
594
|
+
if (applied[canonical] === void 0) applied[canonical] = applied[alias];
|
|
595
|
+
delete applied[alias];
|
|
596
|
+
}
|
|
597
|
+
return applied ?? config;
|
|
598
|
+
}
|
|
599
|
+
function applyCredentials(config, credentials) {
|
|
600
|
+
if (!credentials) return config;
|
|
601
|
+
let applied;
|
|
602
|
+
for (const [name, spec] of Object.entries(credentials)) {
|
|
603
|
+
if (spec.option === false || config[name] !== void 0 || !(name in config)) continue;
|
|
604
|
+
applied ??= { ...config };
|
|
605
|
+
delete applied[name];
|
|
606
|
+
}
|
|
607
|
+
return applied ?? config;
|
|
608
|
+
}
|
|
609
|
+
//#endregion
|
|
610
|
+
//#region src/internal/core/body.ts
|
|
611
|
+
function discardBody(result) {
|
|
612
|
+
const { response } = result ?? {};
|
|
613
|
+
if (response && !response.bodyUsed) response.body?.cancel().catch(() => {});
|
|
614
|
+
}
|
|
615
|
+
function isStreamed(body) {
|
|
616
|
+
if (typeof body !== "object" || body === null) return false;
|
|
617
|
+
return typeof body.getReader === "function" || Symbol.asyncIterator in body;
|
|
618
|
+
}
|
|
619
|
+
function replyWith(body, response) {
|
|
620
|
+
const reply = new Response(body, {
|
|
621
|
+
headers: response.headers,
|
|
622
|
+
status: response.status,
|
|
623
|
+
statusText: response.statusText
|
|
624
|
+
});
|
|
625
|
+
Object.defineProperty(reply, "redirected", { value: response.redirected });
|
|
626
|
+
Object.defineProperty(reply, "url", { value: response.url });
|
|
627
|
+
return reply;
|
|
628
|
+
}
|
|
629
|
+
async function bufferReply(response, signal) {
|
|
630
|
+
if (response.body === null) return response;
|
|
631
|
+
const reader = response.body.getReader();
|
|
632
|
+
function cancel() {
|
|
633
|
+
reader.cancel(signal?.reason).catch(() => {});
|
|
634
|
+
}
|
|
635
|
+
if (signal?.aborted) cancel();
|
|
636
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
637
|
+
const parts = [];
|
|
638
|
+
try {
|
|
639
|
+
for (;;) {
|
|
640
|
+
const step = await reader.read();
|
|
641
|
+
if (step.done) break;
|
|
642
|
+
parts.push(step.value);
|
|
643
|
+
}
|
|
644
|
+
} finally {
|
|
645
|
+
signal?.removeEventListener("abort", cancel);
|
|
646
|
+
}
|
|
647
|
+
if (signal?.aborted) throw signal.reason;
|
|
648
|
+
return replyWith(new ReadableStream({ start(controller) {
|
|
649
|
+
for (const part of parts) controller.enqueue(part);
|
|
650
|
+
controller.close();
|
|
651
|
+
} }), response);
|
|
652
|
+
}
|
|
653
|
+
//#endregion
|
|
654
|
+
//#region src/internal/core/features.ts
|
|
655
|
+
var FeatureRunner = class {
|
|
656
|
+
features;
|
|
657
|
+
constructor(features = []) {
|
|
658
|
+
this.features = features;
|
|
659
|
+
}
|
|
660
|
+
async options(options, callable, ctx) {
|
|
661
|
+
for (const feature of this.features) await feature.onOptions?.(options, callable, ctx);
|
|
662
|
+
}
|
|
663
|
+
async prepare(request, ctx) {
|
|
664
|
+
for (const feature of this.features) await feature.onPrepare?.(request, ctx);
|
|
665
|
+
}
|
|
666
|
+
async request(request, ctx) {
|
|
667
|
+
for (const feature of this.features) await feature.onRequest?.(request, ctx);
|
|
668
|
+
}
|
|
669
|
+
send(core, ctx, hook = "onSend") {
|
|
670
|
+
let next = core;
|
|
671
|
+
for (let i = this.features.length - 1; i >= 0; i--) {
|
|
672
|
+
const feature = this.features[i];
|
|
673
|
+
if (!feature[hook]) continue;
|
|
674
|
+
const downstream = next;
|
|
675
|
+
next = (request) => feature[hook](request, downstream, ctx);
|
|
676
|
+
}
|
|
677
|
+
return next;
|
|
678
|
+
}
|
|
679
|
+
async result(result, request, ctx) {
|
|
680
|
+
let current = result;
|
|
681
|
+
for (let i = this.features.length - 1; i >= 0; i--) current = await this.features[i].onResult?.(current, request, ctx) ?? current;
|
|
682
|
+
return current;
|
|
683
|
+
}
|
|
684
|
+
async error(error, request, ctx) {
|
|
685
|
+
let current = error;
|
|
686
|
+
for (let i = this.features.length - 1; i >= 0; i--) current = await this.features[i].onError?.(current, request, ctx) ?? current;
|
|
687
|
+
return current;
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
//#endregion
|
|
691
|
+
//#region src/internal/core/protocol.ts
|
|
692
|
+
function onlyProtocol(protocols, _interaction) {
|
|
693
|
+
return Object.values(protocols)[0];
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region src/internal/core/dispatch.ts
|
|
697
|
+
async function readReply$1(setup, sent, request, from) {
|
|
698
|
+
const { binding, ctx, runner } = sent;
|
|
699
|
+
try {
|
|
700
|
+
const raw = from ?? sent.result.response;
|
|
701
|
+
let result = request.options.unread || !raw ? sent.result : await binding.readResult(raw, request, setup.codecs);
|
|
702
|
+
result = await runner.result(result, request, ctx);
|
|
703
|
+
if (request.options.unread) return result.response;
|
|
704
|
+
const failure = binding.readError?.(result, request) ?? result.error;
|
|
705
|
+
if (request.options.raw) return failure === void 0 ? result : {
|
|
706
|
+
...result,
|
|
707
|
+
error: failure
|
|
708
|
+
};
|
|
709
|
+
if (failure !== void 0) {
|
|
710
|
+
if (request.options.errors !== "return" && !request.options.envelope) throw failure;
|
|
711
|
+
return {
|
|
712
|
+
data: void 0,
|
|
713
|
+
error: await runner.error(failure, request, ctx),
|
|
714
|
+
ok: false,
|
|
715
|
+
status: result.status
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
return request.options.errors === "return" || request.options.envelope ? {
|
|
719
|
+
data: result.data,
|
|
720
|
+
error: void 0,
|
|
721
|
+
ok: true,
|
|
722
|
+
status: result.status
|
|
723
|
+
} : result.data;
|
|
724
|
+
} catch (error) {
|
|
725
|
+
throw await runner.error(error, request, ctx);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
function rejectUnsendable(transport, request) {
|
|
729
|
+
throw new UnsupportedInteractionError(transport.name, request.interaction);
|
|
730
|
+
}
|
|
731
|
+
function shellOf(request) {
|
|
732
|
+
if (request.options.unread) return request;
|
|
733
|
+
return {
|
|
734
|
+
...request,
|
|
735
|
+
options: {
|
|
736
|
+
...request.options,
|
|
737
|
+
unread: true
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
function transportFor(setup, named, fallback) {
|
|
742
|
+
if (named === void 0) return fallback;
|
|
743
|
+
if (typeof named !== "string") return named;
|
|
744
|
+
const found = setup.transports?.(named);
|
|
745
|
+
if (!found) throw new ElmoError(`This client carries no transport named "${named}".`);
|
|
746
|
+
return found;
|
|
747
|
+
}
|
|
748
|
+
async function sendRequest(setup, request) {
|
|
749
|
+
const protocol = onlyProtocol(setup.protocols, request.interaction);
|
|
750
|
+
const { binding } = protocol;
|
|
751
|
+
const transport = transportFor(setup, request.options["transport"], protocol.transport);
|
|
752
|
+
const runner = new FeatureRunner(setup.features);
|
|
753
|
+
const ctx = {
|
|
754
|
+
binding,
|
|
755
|
+
transport
|
|
756
|
+
};
|
|
757
|
+
const { unary } = transport;
|
|
758
|
+
if (request.interaction !== "unary" || !unary) rejectUnsendable(transport, request);
|
|
759
|
+
try {
|
|
760
|
+
if (!binding.readResult) throw new ElmoError(`The "${binding.name}" binding reads no reply, so it cannot answer this call.`);
|
|
761
|
+
const send = async (attempt) => {
|
|
762
|
+
await runner.request(attempt, ctx);
|
|
763
|
+
const unsendable = unsendableName(attempt.meta);
|
|
764
|
+
if (unsendable !== void 0) throw unsendableHeader(unsendable);
|
|
765
|
+
attempt.log?.sending();
|
|
766
|
+
let raw;
|
|
767
|
+
try {
|
|
768
|
+
raw = await unary.call(transport, attempt);
|
|
769
|
+
if (!request.options.unread) raw = await bufferReply(raw, attempt.signal);
|
|
770
|
+
} catch (error) {
|
|
771
|
+
throw unansweredError(error);
|
|
772
|
+
}
|
|
773
|
+
return binding.readResult(raw, shellOf(attempt), setup.codecs);
|
|
774
|
+
};
|
|
775
|
+
return {
|
|
776
|
+
binding,
|
|
777
|
+
ctx,
|
|
778
|
+
result: await runner.send(send, ctx)(request),
|
|
779
|
+
runner
|
|
780
|
+
};
|
|
781
|
+
} catch (error) {
|
|
782
|
+
throw await runner.error(error, request, ctx);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
async function execute(setup, request) {
|
|
786
|
+
return readReply$1(setup, await sendRequest(setup, request), request);
|
|
787
|
+
}
|
|
788
|
+
function buildRequestWithoutCookies(setup, callable, resolved) {
|
|
789
|
+
const interaction = callable.interaction ?? "unary";
|
|
790
|
+
const { binding } = onlyProtocol(setup.protocols, interaction);
|
|
791
|
+
const encoded = encodeNamedBody(setup.codecs, callable.mediaType, resolved);
|
|
792
|
+
const meta = mergeMetadata(resolved.headers);
|
|
793
|
+
if (encoded?.contentType && meta["content-type"] === void 0) meta["content-type"] = encoded.contentType;
|
|
794
|
+
const accept = callable.accept ?? setup.accept ?? binding.accept;
|
|
795
|
+
if (accept && meta["accept"] === void 0) meta["accept"] = accept;
|
|
796
|
+
return {
|
|
797
|
+
address: binding.resolveAddress(callable, resolved),
|
|
798
|
+
body: encoded?.payload,
|
|
799
|
+
callable,
|
|
800
|
+
interaction,
|
|
801
|
+
meta,
|
|
802
|
+
options: resolved,
|
|
803
|
+
signal: resolved.signal
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
async function prepare(setup, callable, options = {}) {
|
|
807
|
+
const { binding, transport } = onlyProtocol(setup.protocols, callable.interaction);
|
|
808
|
+
const resolved = mergeConfigs(setup.defaults, applyCredentials(applyAliases(options, setup.aliases), setup.credentials));
|
|
809
|
+
const runner = new FeatureRunner(setup.features);
|
|
810
|
+
const ctx = {
|
|
811
|
+
binding,
|
|
812
|
+
transport
|
|
813
|
+
};
|
|
814
|
+
await runner.options(resolved, callable, ctx);
|
|
815
|
+
const request = buildRequestWithoutCookies(setup, callable, resolved);
|
|
816
|
+
await runner.prepare(request, ctx);
|
|
817
|
+
return request;
|
|
818
|
+
}
|
|
819
|
+
async function dispatch(setup, callable, options = {}) {
|
|
820
|
+
return execute(setup, await prepare(setup, callable, options));
|
|
821
|
+
}
|
|
822
|
+
async function exchange(setup, callable, options = {}) {
|
|
823
|
+
const request = await prepare(setup, callable, options);
|
|
824
|
+
const sent = await sendRequest(setup, request);
|
|
825
|
+
let read;
|
|
826
|
+
return {
|
|
827
|
+
read: (from) => read ??= readReply$1(setup, sent, request, from),
|
|
828
|
+
requestId: () => sent.result.response && requestIdOf(sent.result.response),
|
|
829
|
+
response: sent.result.response
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
function readEnv(name) {
|
|
833
|
+
const global = globalThis;
|
|
834
|
+
return (global.process?.env?.[name] ?? global.Deno?.env?.get?.(name))?.trim() || void 0;
|
|
835
|
+
}
|
|
836
|
+
function readable(credentials) {
|
|
837
|
+
return Object.keys(credentials).filter((name) => credentials[name].variable && credentials[name].option !== false);
|
|
838
|
+
}
|
|
839
|
+
function envDefaults(base, env = {}, credentials = {}) {
|
|
840
|
+
const reads = /* @__PURE__ */ new WeakMap();
|
|
841
|
+
const held = readable(credentials);
|
|
842
|
+
function resolve() {
|
|
843
|
+
const read = {};
|
|
844
|
+
for (const [option, variable] of Object.entries(env)) {
|
|
845
|
+
const value = readEnv(variable) ?? base[option];
|
|
846
|
+
if (value !== void 0) read[option] = value;
|
|
847
|
+
}
|
|
848
|
+
if (held.length) {
|
|
849
|
+
const tokens = {};
|
|
850
|
+
for (const name of held) tokens[name] = readEnv(credentials[name].variable);
|
|
851
|
+
Object.assign(read, tokens);
|
|
852
|
+
const environment = base.environment;
|
|
853
|
+
if (environment !== void 0) read.environment = environment;
|
|
854
|
+
}
|
|
855
|
+
return read;
|
|
856
|
+
}
|
|
857
|
+
function resolvedFor(holder) {
|
|
858
|
+
let read = reads.get(holder);
|
|
859
|
+
if (!read) {
|
|
860
|
+
read = resolve();
|
|
861
|
+
reads.set(holder, read);
|
|
862
|
+
}
|
|
863
|
+
return read;
|
|
864
|
+
}
|
|
865
|
+
const decided = [
|
|
866
|
+
...Object.keys(env),
|
|
867
|
+
...held,
|
|
868
|
+
...held.length ? ["environment"] : []
|
|
869
|
+
];
|
|
870
|
+
const defaults = { ...base };
|
|
871
|
+
for (const key of decided) Object.defineProperty(defaults, key, {
|
|
872
|
+
configurable: true,
|
|
873
|
+
enumerable: true,
|
|
874
|
+
get() {
|
|
875
|
+
return resolvedFor(this)[key];
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
return defaults;
|
|
879
|
+
}
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/internal/core/client.ts
|
|
882
|
+
function clientOf(setup) {
|
|
883
|
+
return Object.defineProperty({
|
|
884
|
+
call(callable, options) {
|
|
885
|
+
return dispatch(setup, callable, options);
|
|
886
|
+
},
|
|
887
|
+
exchange(callable, options) {
|
|
888
|
+
return exchange(setup, callable, options);
|
|
889
|
+
},
|
|
890
|
+
prepare(callable, options = {}) {
|
|
891
|
+
return prepare(setup, callable, options);
|
|
892
|
+
},
|
|
893
|
+
resolveAddress(callable, options = {}) {
|
|
894
|
+
const { binding } = onlyProtocol(setup.protocols, callable.interaction);
|
|
895
|
+
return binding.resolveAddress(callable, mergeConfigs(setup.defaults, options));
|
|
896
|
+
}
|
|
897
|
+
}, "setup", { value: setup });
|
|
898
|
+
}
|
|
899
|
+
function createClient(setup) {
|
|
900
|
+
return clientOf({
|
|
901
|
+
...setup,
|
|
902
|
+
defaults: envDefaults(setup.defaults, setup.env, setup.credentials)
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
function clientFor(args, fallback) {
|
|
906
|
+
const { client, key: _key, ...args_ } = args ?? {};
|
|
907
|
+
const base = client ?? fallback;
|
|
908
|
+
if (!base) throw new ElmoError("This SDK has no client of its own. Pass one as `client`.");
|
|
909
|
+
const config = applyCredentials(applyAliases(args_, base.setup.aliases), base.setup.credentials);
|
|
910
|
+
if (client && !Object.keys(config).length) return client;
|
|
911
|
+
const defaults = mergeDefaults(base.setup.defaults, config);
|
|
912
|
+
base.setup.guard?.(defaults);
|
|
913
|
+
return clientOf({
|
|
914
|
+
...base.setup,
|
|
915
|
+
defaults
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
function withClient(source, client, key = "client") {
|
|
919
|
+
const derived = Object.create(Object.getPrototypeOf(source));
|
|
920
|
+
derived[key] = client;
|
|
921
|
+
return derived;
|
|
922
|
+
}
|
|
923
|
+
//#endregion
|
|
924
|
+
//#region src/internal/core/read-reply.ts
|
|
925
|
+
async function readReply(read, value, _response) {
|
|
926
|
+
return await read(value);
|
|
927
|
+
}
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region src/internal/feature/validate.ts
|
|
930
|
+
async function runValidator(validate, value, options, response) {
|
|
931
|
+
if (!validate || options["validate"] === false) return value;
|
|
932
|
+
return await readReply(validate, value, response);
|
|
933
|
+
}
|
|
934
|
+
function validatorsOf(callable) {
|
|
935
|
+
return callable.validators;
|
|
936
|
+
}
|
|
937
|
+
function validateFeature() {
|
|
938
|
+
return {
|
|
939
|
+
name: "validate",
|
|
940
|
+
async onOptions(options, callable) {
|
|
941
|
+
const validate = validatorsOf(callable)?.request;
|
|
942
|
+
if (!validate || options["validate"] === false) return;
|
|
943
|
+
Object.assign(options, await validate(options));
|
|
944
|
+
},
|
|
945
|
+
async onResult(result, request) {
|
|
946
|
+
const validators = validatorsOf(request.callable);
|
|
947
|
+
if (!validators) return result;
|
|
948
|
+
if (result.error !== void 0 && result.error !== null) result.error = await runValidator(validators.error, result.error, request.options, result.response);
|
|
949
|
+
else if (result.data !== void 0) result.data = await runValidator(validators.response, result.data, request.options, result.response);
|
|
950
|
+
return result;
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function decoded(at, value, read) {
|
|
955
|
+
let result;
|
|
956
|
+
try {
|
|
957
|
+
result = read(value);
|
|
958
|
+
} catch (cause) {
|
|
959
|
+
throw unreadableValue(at, value, cause);
|
|
960
|
+
}
|
|
961
|
+
if (result instanceof Date && Number.isNaN(result.getTime())) throw unreadableValue(at, value);
|
|
962
|
+
return result;
|
|
963
|
+
}
|
|
964
|
+
function reviving(revive) {
|
|
965
|
+
return (data) => {
|
|
966
|
+
if (data != null) revive(data);
|
|
967
|
+
return data;
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
//#endregion
|
|
971
|
+
//#region src/resources/shared/auth.ts
|
|
972
|
+
/**
|
|
973
|
+
* An instance admin key from `ADMIN_API_KEYS`, or an organization key (`elmo_…`) issued from the
|
|
974
|
+
* dashboard.
|
|
975
|
+
*/
|
|
976
|
+
const apiKeyRequirements = [{
|
|
977
|
+
key: "apiKey",
|
|
978
|
+
scheme: "bearer",
|
|
979
|
+
type: "http"
|
|
980
|
+
}];
|
|
981
|
+
//#endregion
|
|
982
|
+
//#region src/resources/shared/resource.ts
|
|
983
|
+
var ElmoResource = class {
|
|
984
|
+
/** The client every call on this SDK dispatches through. */
|
|
985
|
+
client;
|
|
986
|
+
constructor(client) {
|
|
987
|
+
this.client = client;
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* The same calls, with different options.
|
|
991
|
+
*
|
|
992
|
+
* Options given here layer over the ones already in force. Headers, path
|
|
993
|
+
* parameters and query parameters merge per name. Everything else replaces.
|
|
994
|
+
* What this was called on does not change.
|
|
995
|
+
*/
|
|
996
|
+
withOptions(options) {
|
|
997
|
+
return withClient(this, clientFor(options, this.client));
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
//#endregion
|
|
1001
|
+
//#region src/internal/core/lazy-promise.ts
|
|
1002
|
+
var LazyPromise = class extends Promise {
|
|
1003
|
+
answer;
|
|
1004
|
+
constructor() {
|
|
1005
|
+
super(() => {});
|
|
1006
|
+
}
|
|
1007
|
+
answered() {
|
|
1008
|
+
return this.answer ??= this.settle();
|
|
1009
|
+
}
|
|
1010
|
+
then(onFulfilled, onRejected) {
|
|
1011
|
+
return this.answered().then(onFulfilled, onRejected);
|
|
1012
|
+
}
|
|
1013
|
+
catch(onRejected) {
|
|
1014
|
+
return this.answered().catch(onRejected);
|
|
1015
|
+
}
|
|
1016
|
+
finally(onFinally) {
|
|
1017
|
+
return this.answered().finally(onFinally);
|
|
1018
|
+
}
|
|
1019
|
+
static get [Symbol.species]() {
|
|
1020
|
+
return Promise;
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
function unattended(promise) {
|
|
1024
|
+
promise.catch(() => {});
|
|
1025
|
+
return promise;
|
|
1026
|
+
}
|
|
1027
|
+
//#endregion
|
|
1028
|
+
//#region src/internal/core/call-promise.ts
|
|
1029
|
+
function awaitedResult(client, options, result) {
|
|
1030
|
+
if ((options.errors ?? client.setup.defaults.errors) === "return") return result;
|
|
1031
|
+
if (result.ok === false) throw result.error;
|
|
1032
|
+
return result.data;
|
|
1033
|
+
}
|
|
1034
|
+
/** A call already sent, whose reply is not yet read. */
|
|
1035
|
+
var CallPromise = class extends LazyPromise {
|
|
1036
|
+
client;
|
|
1037
|
+
exchange;
|
|
1038
|
+
options;
|
|
1039
|
+
envelope;
|
|
1040
|
+
constructor(client, callable, options = {}) {
|
|
1041
|
+
super();
|
|
1042
|
+
this.client = client;
|
|
1043
|
+
this.options = options;
|
|
1044
|
+
this.exchange = unattended(client.exchange(callable, {
|
|
1045
|
+
...options,
|
|
1046
|
+
envelope: true
|
|
1047
|
+
}));
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* The whole result envelope. A failure of the call is returned on it, not
|
|
1051
|
+
* thrown. What one of your own functions throws, such as a hook, is thrown
|
|
1052
|
+
* as it is.
|
|
1053
|
+
*/
|
|
1054
|
+
result() {
|
|
1055
|
+
return this.envelope ??= this.read();
|
|
1056
|
+
}
|
|
1057
|
+
/** The payload alone, with a failure thrown rather than handed back. */
|
|
1058
|
+
async unwrap() {
|
|
1059
|
+
const result = await this.result();
|
|
1060
|
+
if (result.ok === false) throw result.error;
|
|
1061
|
+
return result.data;
|
|
1062
|
+
}
|
|
1063
|
+
async read() {
|
|
1064
|
+
try {
|
|
1065
|
+
return await this.decode();
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
if (!(error instanceof ElmoError)) throw error;
|
|
1068
|
+
return {
|
|
1069
|
+
error,
|
|
1070
|
+
ok: false
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
settle() {
|
|
1075
|
+
return this.result().then((result) => awaitedResult(this.client, this.options, result));
|
|
1076
|
+
}
|
|
1077
|
+
async decode() {
|
|
1078
|
+
return (await this.exchange).read();
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
/** A call already sent, whose `Response` can be read as well as its payload. */
|
|
1082
|
+
var RestCallPromise = class extends CallPromise {
|
|
1083
|
+
claimed = false;
|
|
1084
|
+
unread;
|
|
1085
|
+
/**
|
|
1086
|
+
* The `Response` itself, with its body unread and yours to read once. An
|
|
1087
|
+
* error status does not throw here. A call that got no response does.
|
|
1088
|
+
*/
|
|
1089
|
+
asResponse() {
|
|
1090
|
+
return this.unread ??= this.claim();
|
|
1091
|
+
}
|
|
1092
|
+
/** The decoded body, the `Response` that carried it, and the request id. */
|
|
1093
|
+
async withResponse() {
|
|
1094
|
+
const data = await this;
|
|
1095
|
+
const exchange = await this.exchange;
|
|
1096
|
+
return {
|
|
1097
|
+
data,
|
|
1098
|
+
requestId: exchange.requestId(),
|
|
1099
|
+
response: exchange.response
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
async decode() {
|
|
1103
|
+
const exchange = await this.exchange;
|
|
1104
|
+
const { response } = exchange;
|
|
1105
|
+
if (!this.claimed || !response) return super.decode();
|
|
1106
|
+
if (!response.bodyUsed) return exchange.read(response.clone());
|
|
1107
|
+
throw new ElmoError("The body of this call was already read through asResponse(). Use withResponse() instead, which gives the body and the reply from one call.");
|
|
1108
|
+
}
|
|
1109
|
+
async claim() {
|
|
1110
|
+
const { response } = await this.exchange;
|
|
1111
|
+
if (!response) throw new ElmoError("This call was answered without a `Response`, so there is none to hand back.");
|
|
1112
|
+
if (!response.bodyUsed) this.claimed = true;
|
|
1113
|
+
return response;
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
function callPromise(client, callable, options = {}) {
|
|
1117
|
+
return new RestCallPromise(client, callable, options);
|
|
1118
|
+
}
|
|
1119
|
+
//#endregion
|
|
1120
|
+
//#region src/internal/core/callable.ts
|
|
1121
|
+
function callable(descriptor) {
|
|
1122
|
+
return {
|
|
1123
|
+
interaction: "unary",
|
|
1124
|
+
...descriptor
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
//#endregion
|
|
1128
|
+
//#region src/internal/core/params.ts
|
|
1129
|
+
const LAYERS = ["path", "query"];
|
|
1130
|
+
function mergeParams(inputs, options) {
|
|
1131
|
+
const merged = {
|
|
1132
|
+
...inputs,
|
|
1133
|
+
...options
|
|
1134
|
+
};
|
|
1135
|
+
if (inputs && options) for (const layer of LAYERS) {
|
|
1136
|
+
const declared = inputs[layer];
|
|
1137
|
+
const given = options[layer];
|
|
1138
|
+
if (!declared || !given) continue;
|
|
1139
|
+
const both = { ...declared };
|
|
1140
|
+
for (const [name, value] of Object.entries(given)) if (value !== void 0) both[name] = value;
|
|
1141
|
+
merged[layer] = both;
|
|
1142
|
+
}
|
|
1143
|
+
return merged;
|
|
1144
|
+
}
|
|
1145
|
+
const placed = /* @__PURE__ */ new WeakMap();
|
|
1146
|
+
function placements(fields) {
|
|
1147
|
+
let known = placed.get(fields);
|
|
1148
|
+
if (!known) {
|
|
1149
|
+
const built = /* @__PURE__ */ new Map();
|
|
1150
|
+
for (const layer of Object.keys(fields)) {
|
|
1151
|
+
const names = fields[layer];
|
|
1152
|
+
if (typeof names === "string") built.set(names, {
|
|
1153
|
+
in: layer,
|
|
1154
|
+
map: names
|
|
1155
|
+
});
|
|
1156
|
+
else if (Array.isArray(names)) for (const key of names) built.set(key, {
|
|
1157
|
+
in: layer,
|
|
1158
|
+
map: key
|
|
1159
|
+
});
|
|
1160
|
+
else if (names) for (const [key, wire] of Object.entries(names)) built.set(key, {
|
|
1161
|
+
in: layer,
|
|
1162
|
+
map: wire
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
known = built;
|
|
1166
|
+
placed.set(fields, built);
|
|
1167
|
+
}
|
|
1168
|
+
return known;
|
|
1169
|
+
}
|
|
1170
|
+
function placeParams(options, fields, extras) {
|
|
1171
|
+
const named = placements(fields);
|
|
1172
|
+
const grouped = {};
|
|
1173
|
+
const given = {};
|
|
1174
|
+
for (const [key, value] of Object.entries(options ?? {})) {
|
|
1175
|
+
const place = named.get(key);
|
|
1176
|
+
if (!place) {
|
|
1177
|
+
if (extras === void 0) given[key] = value;
|
|
1178
|
+
else (grouped[extras] ??= {})[key] = value;
|
|
1179
|
+
continue;
|
|
1180
|
+
}
|
|
1181
|
+
if (place.in === "whole") {
|
|
1182
|
+
grouped["body"] = value;
|
|
1183
|
+
continue;
|
|
1184
|
+
}
|
|
1185
|
+
(grouped[place.in] ??= {})[place.map] = value;
|
|
1186
|
+
}
|
|
1187
|
+
return mergeParams(grouped, given);
|
|
1188
|
+
}
|
|
1189
|
+
function groupParams(options, layer) {
|
|
1190
|
+
if (layer === void 0) return { ...options };
|
|
1191
|
+
if (!options || !Object.keys(options).length) return {};
|
|
1192
|
+
return { [layer]: { ...options } };
|
|
1193
|
+
}
|
|
1194
|
+
//#endregion
|
|
1195
|
+
//#region src/resources/analytics.ts
|
|
1196
|
+
const getBrandAnalyticsFields = { path: ["brandId"] };
|
|
1197
|
+
function reviveDateRange(value) {
|
|
1198
|
+
if (value.start != null) value.start = decoded("DateRange.start", value.start, (raw) => new Date(raw));
|
|
1199
|
+
if (value.end != null) value.end = decoded("DateRange.end", value.end, (raw) => new Date(raw));
|
|
1200
|
+
}
|
|
1201
|
+
function reviveBrandAnalytics(value) {
|
|
1202
|
+
if (value.range != null) reviveDateRange(value.range);
|
|
1203
|
+
}
|
|
1204
|
+
const getBrandAnalyticsDescriptor = /* @__PURE__ */ callable({
|
|
1205
|
+
address: "/brands/{brandId}/analytics",
|
|
1206
|
+
auth: apiKeyRequirements,
|
|
1207
|
+
method: "get",
|
|
1208
|
+
returns: "json",
|
|
1209
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrandAnalytics) }
|
|
1210
|
+
});
|
|
1211
|
+
const listBrandCitationDomainsFields = { path: ["brandId"] };
|
|
1212
|
+
function reviveCitationDomainList(value) {
|
|
1213
|
+
if (value.range != null) reviveDateRange(value.range);
|
|
1214
|
+
}
|
|
1215
|
+
const listBrandCitationDomainsDescriptor = /* @__PURE__ */ callable({
|
|
1216
|
+
address: "/brands/{brandId}/citations/domains",
|
|
1217
|
+
auth: apiKeyRequirements,
|
|
1218
|
+
method: "get",
|
|
1219
|
+
returns: "json",
|
|
1220
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCitationDomainList) }
|
|
1221
|
+
});
|
|
1222
|
+
const listBrandCitationUrlsFields = { path: ["brandId"] };
|
|
1223
|
+
function reviveCitationUrlList(value) {
|
|
1224
|
+
if (value.range != null) reviveDateRange(value.range);
|
|
1225
|
+
}
|
|
1226
|
+
const listBrandCitationURLsDescriptor = /* @__PURE__ */ callable({
|
|
1227
|
+
address: "/brands/{brandId}/citations/urls",
|
|
1228
|
+
auth: apiKeyRequirements,
|
|
1229
|
+
method: "get",
|
|
1230
|
+
returns: "json",
|
|
1231
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCitationUrlList) }
|
|
1232
|
+
});
|
|
1233
|
+
const listBrandPromptPerformanceFields = { path: ["brandId"] };
|
|
1234
|
+
function revivePromptPerformance(value) {
|
|
1235
|
+
if (value.lastRunAt != null) value.lastRunAt = decoded("PromptPerformance.lastRunAt", value.lastRunAt, (raw) => new Date(raw));
|
|
1236
|
+
if (value.firstEvaluatedAt != null) value.firstEvaluatedAt = decoded("PromptPerformance.firstEvaluatedAt", value.firstEvaluatedAt, (raw) => new Date(raw));
|
|
1237
|
+
}
|
|
1238
|
+
function revivePromptPerformanceList(value) {
|
|
1239
|
+
if (value.range != null) reviveDateRange(value.range);
|
|
1240
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
1241
|
+
revivePromptPerformance(item);
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
const listBrandPromptPerformanceDescriptor = /* @__PURE__ */ callable({
|
|
1245
|
+
address: "/brands/{brandId}/prompt-performance",
|
|
1246
|
+
auth: apiKeyRequirements,
|
|
1247
|
+
method: "get",
|
|
1248
|
+
returns: "json",
|
|
1249
|
+
validators: { response: /* @__PURE__ */ reviving(revivePromptPerformanceList) }
|
|
1250
|
+
});
|
|
1251
|
+
const getBrandQueryFanoutFields = { path: ["brandId"] };
|
|
1252
|
+
function reviveBrandQueryFanout(value) {
|
|
1253
|
+
if (value.range != null) reviveDateRange(value.range);
|
|
1254
|
+
}
|
|
1255
|
+
const getBrandQueryFanoutDescriptor = /* @__PURE__ */ callable({
|
|
1256
|
+
address: "/brands/{brandId}/query-fanout",
|
|
1257
|
+
auth: apiKeyRequirements,
|
|
1258
|
+
method: "get",
|
|
1259
|
+
returns: "json",
|
|
1260
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrandQueryFanout) }
|
|
1261
|
+
});
|
|
1262
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1263
|
+
var Analytics = class extends ElmoResource {
|
|
1264
|
+
/**
|
|
1265
|
+
* Get a brand's analytics
|
|
1266
|
+
*
|
|
1267
|
+
* Visibility, share of voice, the per-model breakdown and the citation totals for one window, in
|
|
1268
|
+
* one request.
|
|
1269
|
+
*
|
|
1270
|
+
* The long lists — cited domains and URLs, sub-queries, per-prompt results — are endpoints of
|
|
1271
|
+
* their own. Everything else is always included.
|
|
1272
|
+
*
|
|
1273
|
+
* @param brandId Brand identifier.
|
|
1274
|
+
*/
|
|
1275
|
+
get(brandId, params, options) {
|
|
1276
|
+
return callPromise(options?.client ?? this.client, getBrandAnalyticsDescriptor, mergeParams(placeParams({
|
|
1277
|
+
...params,
|
|
1278
|
+
brandId
|
|
1279
|
+
}, getBrandAnalyticsFields, "query"), options));
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1283
|
+
var Domains = class extends ElmoResource {
|
|
1284
|
+
/**
|
|
1285
|
+
* List cited domains
|
|
1286
|
+
*
|
|
1287
|
+
* Domains the engines cited when answering this brand's prompts, categorized and compared against
|
|
1288
|
+
* the equal-length window immediately before this one.
|
|
1289
|
+
*
|
|
1290
|
+
* @param brandId Brand identifier.
|
|
1291
|
+
*/
|
|
1292
|
+
list(brandId, params, options) {
|
|
1293
|
+
return callPromise(options?.client ?? this.client, listBrandCitationDomainsDescriptor, mergeParams(placeParams({
|
|
1294
|
+
...params,
|
|
1295
|
+
brandId
|
|
1296
|
+
}, listBrandCitationDomainsFields, "query"), options));
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1300
|
+
var URLs = class extends ElmoResource {
|
|
1301
|
+
/**
|
|
1302
|
+
* List cited URLs
|
|
1303
|
+
*
|
|
1304
|
+
* Individual pages the engines cited, with their category and page type.
|
|
1305
|
+
*
|
|
1306
|
+
* @param brandId Brand identifier.
|
|
1307
|
+
*/
|
|
1308
|
+
list(brandId, params, options) {
|
|
1309
|
+
return callPromise(options?.client ?? this.client, listBrandCitationURLsDescriptor, mergeParams(placeParams({
|
|
1310
|
+
...params,
|
|
1311
|
+
brandId
|
|
1312
|
+
}, listBrandCitationUrlsFields, "query"), options));
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
var Citations = class extends ElmoResource {
|
|
1316
|
+
_domains;
|
|
1317
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1318
|
+
get domains() {
|
|
1319
|
+
return this._domains ??= new Domains(this.client);
|
|
1320
|
+
}
|
|
1321
|
+
_urls;
|
|
1322
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1323
|
+
get urls() {
|
|
1324
|
+
return this._urls ??= new URLs(this.client);
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1328
|
+
var PromptPerformance = class extends ElmoResource {
|
|
1329
|
+
/**
|
|
1330
|
+
* List prompt performance
|
|
1331
|
+
*
|
|
1332
|
+
* Per-prompt mention rates over the window. The analytics counterpart to `GET /prompts?brandId=`,
|
|
1333
|
+
* which returns prompt configuration rather than results.
|
|
1334
|
+
*
|
|
1335
|
+
* A prompt the brand stopped tracking is not sampled, so it has no results over the window and
|
|
1336
|
+
* does not appear here.
|
|
1337
|
+
*
|
|
1338
|
+
* @param brandId Brand identifier.
|
|
1339
|
+
*/
|
|
1340
|
+
list(brandId, params, options) {
|
|
1341
|
+
return callPromise(options?.client ?? this.client, listBrandPromptPerformanceDescriptor, mergeParams(placeParams({
|
|
1342
|
+
...params,
|
|
1343
|
+
brandId
|
|
1344
|
+
}, listBrandPromptPerformanceFields, "query"), options));
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1348
|
+
var QueryFanout = class extends ElmoResource {
|
|
1349
|
+
/**
|
|
1350
|
+
* Get query fan-out
|
|
1351
|
+
*
|
|
1352
|
+
* The searches engines ran while answering this brand's prompts. Engines that don't expose their
|
|
1353
|
+
* searches still contribute runs, so `coverageRate` is the honest denominator.
|
|
1354
|
+
*
|
|
1355
|
+
* @param brandId Brand identifier.
|
|
1356
|
+
*/
|
|
1357
|
+
get(brandId, params, options) {
|
|
1358
|
+
return callPromise(options?.client ?? this.client, getBrandQueryFanoutDescriptor, mergeParams(placeParams({
|
|
1359
|
+
...params,
|
|
1360
|
+
brandId
|
|
1361
|
+
}, getBrandQueryFanoutFields, "query"), options));
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
//#endregion
|
|
1365
|
+
//#region src/resources/opportunities.ts
|
|
1366
|
+
const getBrandOpportunitiesFields = { path: ["brandId"] };
|
|
1367
|
+
function reviveBrandOpportunities(value) {
|
|
1368
|
+
if (value.generatedAt != null) value.generatedAt = decoded("BrandOpportunities.generatedAt", value.generatedAt, (raw) => new Date(raw));
|
|
1369
|
+
}
|
|
1370
|
+
const getBrandOpportunitiesDescriptor = /* @__PURE__ */ callable({
|
|
1371
|
+
address: "/brands/{brandId}/opportunities",
|
|
1372
|
+
auth: apiKeyRequirements,
|
|
1373
|
+
method: "get",
|
|
1374
|
+
returns: "json",
|
|
1375
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrandOpportunities) }
|
|
1376
|
+
});
|
|
1377
|
+
/** Where a brand could win more citations, and why */
|
|
1378
|
+
var Opportunities = class extends ElmoResource {
|
|
1379
|
+
/**
|
|
1380
|
+
* Get the latest opportunities report
|
|
1381
|
+
*
|
|
1382
|
+
* **Experimental — the response shape may still change.**
|
|
1383
|
+
*
|
|
1384
|
+
* The brand's Opportunities report: a prioritized set of ways to get cited more often, with the
|
|
1385
|
+
* tracked prompts and cited pages behind each one. The same analysis the dashboard shows, from
|
|
1386
|
+
* the same code.
|
|
1387
|
+
*
|
|
1388
|
+
* Generation is inline and synchronous. A stored report is served while it is fresh and
|
|
1389
|
+
* regenerated when it is not, so there is nothing to poll for and no way to be handed a stale one
|
|
1390
|
+
* — but a request that triggers a generation waits for it. The freshness window bounds the cost:
|
|
1391
|
+
* however many callers ask, one generation per brand per window. There is deliberately no `POST`,
|
|
1392
|
+
* which would spend provider budget with nothing metering it per call.
|
|
1393
|
+
*
|
|
1394
|
+
* @experimental
|
|
1395
|
+
* @param brandId Brand identifier.
|
|
1396
|
+
*/
|
|
1397
|
+
get(brandId, options) {
|
|
1398
|
+
return callPromise(options?.client ?? this.client, getBrandOpportunitiesDescriptor, mergeParams(placeParams({ brandId }, getBrandOpportunitiesFields, "query"), options));
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
//#endregion
|
|
1402
|
+
//#region src/resources/shared/rule.ts
|
|
1403
|
+
const nameRule = {
|
|
1404
|
+
min: 1,
|
|
1405
|
+
name: "name",
|
|
1406
|
+
of: "characters"
|
|
1407
|
+
};
|
|
1408
|
+
const domainsRule = {
|
|
1409
|
+
min: 1,
|
|
1410
|
+
name: "domains",
|
|
1411
|
+
of: "items"
|
|
1412
|
+
};
|
|
1413
|
+
const brandNameRule = {
|
|
1414
|
+
min: 1,
|
|
1415
|
+
name: "brandName",
|
|
1416
|
+
of: "characters"
|
|
1417
|
+
};
|
|
1418
|
+
const valueRule = {
|
|
1419
|
+
min: 1,
|
|
1420
|
+
name: "value",
|
|
1421
|
+
of: "characters"
|
|
1422
|
+
};
|
|
1423
|
+
//#endregion
|
|
1424
|
+
//#region src/resources/tags.ts
|
|
1425
|
+
const listBrandTagsFields = { path: ["brandId"] };
|
|
1426
|
+
const listBrandTagsDescriptor = /* @__PURE__ */ callable({
|
|
1427
|
+
address: "/brands/{brandId}/tags",
|
|
1428
|
+
auth: apiKeyRequirements,
|
|
1429
|
+
method: "get",
|
|
1430
|
+
returns: "json"
|
|
1431
|
+
});
|
|
1432
|
+
/** The tags in use on a brand's prompts */
|
|
1433
|
+
var Tags = class extends ElmoResource {
|
|
1434
|
+
/**
|
|
1435
|
+
* List a brand's tags
|
|
1436
|
+
*
|
|
1437
|
+
* Every tag in use on the brand's prompts, with how many carry each — enough to build the same
|
|
1438
|
+
* filter the dashboard shows without paging the whole prompt list to derive it.
|
|
1439
|
+
*
|
|
1440
|
+
* Tags are not a resource of their own: a tag exists exactly as long as some prompt carries it.
|
|
1441
|
+
* `branded` and `unbranded` are computed by Elmo and always listed.
|
|
1442
|
+
*
|
|
1443
|
+
* @param brandId Brand identifier.
|
|
1444
|
+
*/
|
|
1445
|
+
list(brandId, options) {
|
|
1446
|
+
return callPromise(options?.client ?? this.client, listBrandTagsDescriptor, mergeParams(placeParams({ brandId }, listBrandTagsFields, "query"), options));
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
//#endregion
|
|
1450
|
+
//#region src/internal/page/page.ts
|
|
1451
|
+
function readPath(value, path) {
|
|
1452
|
+
if (!path) return value;
|
|
1453
|
+
let current = value;
|
|
1454
|
+
for (const key of path.split(".")) {
|
|
1455
|
+
if (current === null || typeof current !== "object") return void 0;
|
|
1456
|
+
current = current[key];
|
|
1457
|
+
}
|
|
1458
|
+
return current;
|
|
1459
|
+
}
|
|
1460
|
+
function readItems(data, pagination) {
|
|
1461
|
+
const items = readPath(data, pagination.items);
|
|
1462
|
+
return Array.isArray(items) ? items : [];
|
|
1463
|
+
}
|
|
1464
|
+
function withPosition(options, pagination, value) {
|
|
1465
|
+
const name = pagination.param;
|
|
1466
|
+
if (!name) return options;
|
|
1467
|
+
if ((pagination.in ?? "query") === "body") return {
|
|
1468
|
+
...options,
|
|
1469
|
+
body: {
|
|
1470
|
+
...options.body,
|
|
1471
|
+
[name]: value
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
return {
|
|
1475
|
+
...options,
|
|
1476
|
+
query: {
|
|
1477
|
+
...options.query,
|
|
1478
|
+
[name]: value
|
|
1479
|
+
}
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
function resumeAt(walk, pagination, param) {
|
|
1483
|
+
if (pagination.style === "link") {
|
|
1484
|
+
const options = { ...walk.options };
|
|
1485
|
+
delete options.query;
|
|
1486
|
+
return {
|
|
1487
|
+
...walk,
|
|
1488
|
+
descriptor: {
|
|
1489
|
+
...walk.descriptor,
|
|
1490
|
+
address: param
|
|
1491
|
+
},
|
|
1492
|
+
options
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
const options = withPosition(walk.options, pagination, param);
|
|
1496
|
+
if (pagination.style === "cursor") return {
|
|
1497
|
+
...walk,
|
|
1498
|
+
cursor: param,
|
|
1499
|
+
options
|
|
1500
|
+
};
|
|
1501
|
+
return {
|
|
1502
|
+
...walk,
|
|
1503
|
+
options,
|
|
1504
|
+
position: param
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
function readCount(data, path) {
|
|
1508
|
+
if (!path) return void 0;
|
|
1509
|
+
const value = readPath(data, path);
|
|
1510
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
1511
|
+
return value;
|
|
1512
|
+
}
|
|
1513
|
+
function startOf(pagination) {
|
|
1514
|
+
return pagination.start ?? (pagination.style === "page" ? 1 : 0);
|
|
1515
|
+
}
|
|
1516
|
+
function stepCounted(walk, pagination, result, count, limit) {
|
|
1517
|
+
if (!count) return void 0;
|
|
1518
|
+
const size = readCount(result.data, pagination.size) ?? limit;
|
|
1519
|
+
const position = walk.position + (pagination.style === "page" ? 1 : size || count);
|
|
1520
|
+
const start = startOf(pagination);
|
|
1521
|
+
const pages = pagination.style === "page" ? readCount(result.data, pagination.pages) : void 0;
|
|
1522
|
+
const total = readCount(result.data, pagination.total);
|
|
1523
|
+
if (pages === void 0 && total === void 0 && size !== void 0 && count < size) return;
|
|
1524
|
+
if (pages !== void 0 && position - start >= pages) return void 0;
|
|
1525
|
+
if (total !== void 0) {
|
|
1526
|
+
if ((pagination.style === "page" ? (position - start) * (size ?? count) : position) >= total) return void 0;
|
|
1527
|
+
}
|
|
1528
|
+
return position;
|
|
1529
|
+
}
|
|
1530
|
+
const STEPPERS = { page: stepCounted };
|
|
1531
|
+
const SCHEME_RE = /^[a-z][a-z\d+.-]*:/i;
|
|
1532
|
+
function pageURL(address) {
|
|
1533
|
+
if (typeof address !== "string") return void 0;
|
|
1534
|
+
try {
|
|
1535
|
+
const url = new URL(address, globalThis.location?.href);
|
|
1536
|
+
return url.origin === "null" ? void 0 : url;
|
|
1537
|
+
} catch {
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
function followLink(client, walk, link) {
|
|
1542
|
+
const own = pageURL(client.resolveAddress(walk.descriptor, walk.options));
|
|
1543
|
+
if (!own) {
|
|
1544
|
+
if (!SCHEME_RE.test(link) && !link.startsWith("//")) return link;
|
|
1545
|
+
throw new ElmoError("Pagination stopped: the next page names a host, and no base URL says which host this client sends its credentials to.");
|
|
1546
|
+
}
|
|
1547
|
+
const target = new URL(link, own);
|
|
1548
|
+
if (target.origin !== own.origin) throw new ElmoError(`Pagination stopped: the next page is on ${target.origin}, and this client sends its credentials only to ${own.origin}.`);
|
|
1549
|
+
return SCHEME_RE.test(link) ? link : target.href;
|
|
1550
|
+
}
|
|
1551
|
+
function saysMore(data, pagination) {
|
|
1552
|
+
return !pagination.more || readPath(data, pagination.more) !== false;
|
|
1553
|
+
}
|
|
1554
|
+
function stepWalk(client, walk, pagination, result, count, limit) {
|
|
1555
|
+
const step = STEPPERS[pagination.style];
|
|
1556
|
+
if (!step) throw new ElmoError(`Cannot walk "${walk.descriptor.address}": this client does not page by "${pagination.style}".`);
|
|
1557
|
+
if (!saysMore(result.data, pagination)) return void 0;
|
|
1558
|
+
const next = step(walk, pagination, result, count, limit);
|
|
1559
|
+
return pagination.style === "link" && next !== void 0 ? followLink(client, walk, next) : next;
|
|
1560
|
+
}
|
|
1561
|
+
async function* walkFrom(page, maxPages) {
|
|
1562
|
+
let current = page;
|
|
1563
|
+
for (let index = 1;; index++) {
|
|
1564
|
+
for (const item of current.data) yield item;
|
|
1565
|
+
if (index >= maxPages || !current.hasNextPage()) return;
|
|
1566
|
+
current = await current.getNextPage();
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
async function loadPage(client, walk, pagination, limit, maxPages) {
|
|
1570
|
+
const result = await client.call(walk.descriptor, walk.options);
|
|
1571
|
+
if (result.error !== void 0) throw result.error;
|
|
1572
|
+
const data = readItems(result.data, pagination);
|
|
1573
|
+
const param = stepWalk(client, walk, pagination, result, data.length, limit);
|
|
1574
|
+
const page = {
|
|
1575
|
+
[Symbol.asyncIterator]: () => walkFrom(page, maxPages),
|
|
1576
|
+
body: result.data,
|
|
1577
|
+
data,
|
|
1578
|
+
getNextPage: () => {
|
|
1579
|
+
if (param === void 0) return Promise.reject(new ElmoError(`"${walk.descriptor.address}" has no page after this one. Check \`hasNextPage()\` first.`));
|
|
1580
|
+
return loadPage(client, resumeAt(walk, pagination, param), pagination, limit, maxPages);
|
|
1581
|
+
},
|
|
1582
|
+
hasNextPage: () => param !== void 0,
|
|
1583
|
+
nextPageParam: param,
|
|
1584
|
+
status: result.status
|
|
1585
|
+
};
|
|
1586
|
+
return page;
|
|
1587
|
+
}
|
|
1588
|
+
function maxPagesFor(client, options) {
|
|
1589
|
+
return options["maxPages"] ?? client.setup.defaults["maxPages"] ?? 1e3;
|
|
1590
|
+
}
|
|
1591
|
+
function openedAt(options, pagination) {
|
|
1592
|
+
if (!pagination.param) return void 0;
|
|
1593
|
+
return options[pagination.in ?? "query"]?.[pagination.param];
|
|
1594
|
+
}
|
|
1595
|
+
function paginationOf(callable) {
|
|
1596
|
+
if (callable.pagination) return callable.pagination;
|
|
1597
|
+
throw new ElmoError(`"${callable.address}" is not a paged call, so it has no pages to walk.`);
|
|
1598
|
+
}
|
|
1599
|
+
function openWalk(callable, options) {
|
|
1600
|
+
const pagination = paginationOf(callable);
|
|
1601
|
+
const opened = openedAt(options, pagination);
|
|
1602
|
+
return {
|
|
1603
|
+
cursor: pagination.style === "cursor" ? opened : void 0,
|
|
1604
|
+
descriptor: callable,
|
|
1605
|
+
options: {
|
|
1606
|
+
...options,
|
|
1607
|
+
raw: true
|
|
1608
|
+
},
|
|
1609
|
+
position: typeof opened === "number" && Number.isFinite(opened) ? opened : startOf(pagination)
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
function pageStream(load, maxPages) {
|
|
1613
|
+
return { async *[Symbol.asyncIterator]() {
|
|
1614
|
+
let current = await load();
|
|
1615
|
+
for (let index = 1;; index++) {
|
|
1616
|
+
yield current;
|
|
1617
|
+
if (index >= maxPages || !current.hasNextPage()) return;
|
|
1618
|
+
current = await current.getNextPage();
|
|
1619
|
+
}
|
|
1620
|
+
} };
|
|
1621
|
+
}
|
|
1622
|
+
function requestedLimit(options, pagination) {
|
|
1623
|
+
if (!pagination.limitParam) return void 0;
|
|
1624
|
+
const layer = options[pagination.in ?? "query"];
|
|
1625
|
+
const limit = Number(layer?.[pagination.limitParam]);
|
|
1626
|
+
return Number.isFinite(limit) && limit > 0 ? limit : void 0;
|
|
1627
|
+
}
|
|
1628
|
+
/**
|
|
1629
|
+
* A paginated call. Awaiting it gives the first page, or its result envelope
|
|
1630
|
+
* under the `'return'` error mode. Iterating it gives every item on every page,
|
|
1631
|
+
* and throws on a failed page under either mode.
|
|
1632
|
+
*/
|
|
1633
|
+
var PagePromise = class extends LazyPromise {
|
|
1634
|
+
envelope;
|
|
1635
|
+
callable;
|
|
1636
|
+
client;
|
|
1637
|
+
limit;
|
|
1638
|
+
maxPages;
|
|
1639
|
+
options;
|
|
1640
|
+
pagination;
|
|
1641
|
+
project;
|
|
1642
|
+
first;
|
|
1643
|
+
constructor(client, callable, options, project) {
|
|
1644
|
+
super();
|
|
1645
|
+
this.callable = callable;
|
|
1646
|
+
this.client = client;
|
|
1647
|
+
this.options = options;
|
|
1648
|
+
this.pagination = paginationOf(callable);
|
|
1649
|
+
this.limit = requestedLimit(options, this.pagination);
|
|
1650
|
+
this.maxPages = maxPagesFor(client, options);
|
|
1651
|
+
this.project = project;
|
|
1652
|
+
const opened = openWalk(this.callable, this.options);
|
|
1653
|
+
const param = options["pageParam"];
|
|
1654
|
+
this.first = unattended(loadPage(this.client, param === void 0 ? opened : resumeAt(opened, this.pagination, param), this.pagination, this.limit, this.maxPages));
|
|
1655
|
+
}
|
|
1656
|
+
/** Every item, page after page, up to `maxPages`. */
|
|
1657
|
+
async *[Symbol.asyncIterator]() {
|
|
1658
|
+
yield* walkFrom(await this.first, this.maxPages);
|
|
1659
|
+
}
|
|
1660
|
+
/** Every page, up to `maxPages`. */
|
|
1661
|
+
iterPages() {
|
|
1662
|
+
return pageStream(() => this.first, this.maxPages);
|
|
1663
|
+
}
|
|
1664
|
+
/**
|
|
1665
|
+
* The whole result envelope. A failure of the call is returned on it, not
|
|
1666
|
+
* thrown. What one of your own functions throws, such as a hook, is thrown
|
|
1667
|
+
* as it is.
|
|
1668
|
+
*/
|
|
1669
|
+
result() {
|
|
1670
|
+
return this.envelope ??= this.read();
|
|
1671
|
+
}
|
|
1672
|
+
/** The page alone, with a failure thrown rather than handed back. */
|
|
1673
|
+
async unwrap() {
|
|
1674
|
+
const result = await this.result();
|
|
1675
|
+
if (result.ok === false) throw result.error;
|
|
1676
|
+
return result.data;
|
|
1677
|
+
}
|
|
1678
|
+
async read() {
|
|
1679
|
+
try {
|
|
1680
|
+
const page = await this.first;
|
|
1681
|
+
return {
|
|
1682
|
+
data: this.project(page),
|
|
1683
|
+
ok: true,
|
|
1684
|
+
status: page.status
|
|
1685
|
+
};
|
|
1686
|
+
} catch (error) {
|
|
1687
|
+
if (!(error instanceof ElmoError)) throw error;
|
|
1688
|
+
return {
|
|
1689
|
+
error,
|
|
1690
|
+
ok: false,
|
|
1691
|
+
status: error instanceof APIError ? error.status : void 0
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
settle() {
|
|
1696
|
+
return this.result().then((result) => awaitedResult(this.client, this.options, result));
|
|
1697
|
+
}
|
|
1698
|
+
};
|
|
1699
|
+
function pages(client, callable, options = {}) {
|
|
1700
|
+
return new PagePromise(client, callable, options, (page) => page);
|
|
1701
|
+
}
|
|
1702
|
+
//#endregion
|
|
1703
|
+
//#region src/resources/brands.ts
|
|
1704
|
+
function reviveBrand(value) {
|
|
1705
|
+
if (value.createdAt != null) value.createdAt = decoded("Brand.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
1706
|
+
if (value.updatedAt != null) value.updatedAt = decoded("Brand.updatedAt", value.updatedAt, (raw) => new Date(raw));
|
|
1707
|
+
}
|
|
1708
|
+
function reviveBrandsList(value) {
|
|
1709
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
1710
|
+
reviveBrand(item);
|
|
1711
|
+
});
|
|
1712
|
+
if (value.brands != null) value.brands.forEach((item) => {
|
|
1713
|
+
reviveBrand(item);
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
const listBrandsDescriptor = /* @__PURE__ */ callable({
|
|
1717
|
+
address: "/brands",
|
|
1718
|
+
auth: apiKeyRequirements,
|
|
1719
|
+
method: "get",
|
|
1720
|
+
pagination: {
|
|
1721
|
+
items: "data",
|
|
1722
|
+
limitParam: "limit",
|
|
1723
|
+
pages: "pagination.totalPages",
|
|
1724
|
+
param: "page",
|
|
1725
|
+
size: "pagination.limit",
|
|
1726
|
+
style: "page",
|
|
1727
|
+
total: "pagination.total"
|
|
1728
|
+
},
|
|
1729
|
+
returns: "json",
|
|
1730
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrandsList) }
|
|
1731
|
+
});
|
|
1732
|
+
const createBrandDescriptor = /* @__PURE__ */ callable({
|
|
1733
|
+
address: "/brands",
|
|
1734
|
+
auth: apiKeyRequirements,
|
|
1735
|
+
mediaType: "application/json",
|
|
1736
|
+
method: "post",
|
|
1737
|
+
returns: "json",
|
|
1738
|
+
rules: [
|
|
1739
|
+
{
|
|
1740
|
+
min: 1,
|
|
1741
|
+
name: "id",
|
|
1742
|
+
of: "characters"
|
|
1743
|
+
},
|
|
1744
|
+
nameRule,
|
|
1745
|
+
domainsRule
|
|
1746
|
+
],
|
|
1747
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrand) }
|
|
1748
|
+
});
|
|
1749
|
+
const getBrandFields = { path: ["brandId"] };
|
|
1750
|
+
const getBrandDescriptor = /* @__PURE__ */ callable({
|
|
1751
|
+
address: "/brands/{brandId}",
|
|
1752
|
+
auth: apiKeyRequirements,
|
|
1753
|
+
method: "get",
|
|
1754
|
+
returns: "json",
|
|
1755
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrand) }
|
|
1756
|
+
});
|
|
1757
|
+
const updateBrandFields = { path: ["brandId"] };
|
|
1758
|
+
const updateBrandDescriptor = /* @__PURE__ */ callable({
|
|
1759
|
+
address: "/brands/{brandId}",
|
|
1760
|
+
auth: apiKeyRequirements,
|
|
1761
|
+
mediaType: "application/json",
|
|
1762
|
+
method: "patch",
|
|
1763
|
+
returns: "json",
|
|
1764
|
+
rules: [brandNameRule, domainsRule],
|
|
1765
|
+
validators: { response: /* @__PURE__ */ reviving(reviveBrand) }
|
|
1766
|
+
});
|
|
1767
|
+
/** Manage brand records */
|
|
1768
|
+
var Brands = class extends ElmoResource {
|
|
1769
|
+
/** Create a brand */
|
|
1770
|
+
create(params, options) {
|
|
1771
|
+
return callPromise(options?.client ?? this.client, createBrandDescriptor, mergeParams(groupParams(params, "body"), options));
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* Get a brand
|
|
1775
|
+
*
|
|
1776
|
+
* @param brandId Brand identifier
|
|
1777
|
+
*/
|
|
1778
|
+
get(brandId, options) {
|
|
1779
|
+
return callPromise(options?.client ?? this.client, getBrandDescriptor, mergeParams(placeParams({ brandId }, getBrandFields, "query"), options));
|
|
1780
|
+
}
|
|
1781
|
+
list(params, options) {
|
|
1782
|
+
return pages(options?.client ?? this.client, listBrandsDescriptor, mergeParams(groupParams(params, "query"), options));
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Update a brand
|
|
1786
|
+
*
|
|
1787
|
+
* @param brandId Brand identifier
|
|
1788
|
+
*/
|
|
1789
|
+
update(brandId, params, options) {
|
|
1790
|
+
return callPromise(options?.client ?? this.client, updateBrandDescriptor, mergeParams(placeParams({
|
|
1791
|
+
...params,
|
|
1792
|
+
brandId
|
|
1793
|
+
}, updateBrandFields, "body"), options));
|
|
1794
|
+
}
|
|
1795
|
+
_analytics;
|
|
1796
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1797
|
+
get analytics() {
|
|
1798
|
+
return this._analytics ??= new Analytics(this.client);
|
|
1799
|
+
}
|
|
1800
|
+
_citations;
|
|
1801
|
+
get citations() {
|
|
1802
|
+
return this._citations ??= new Citations(this.client);
|
|
1803
|
+
}
|
|
1804
|
+
_opportunities;
|
|
1805
|
+
/** Where a brand could win more citations, and why */
|
|
1806
|
+
get opportunities() {
|
|
1807
|
+
return this._opportunities ??= new Opportunities(this.client);
|
|
1808
|
+
}
|
|
1809
|
+
_promptPerformance;
|
|
1810
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1811
|
+
get promptPerformance() {
|
|
1812
|
+
return this._promptPerformance ??= new PromptPerformance(this.client);
|
|
1813
|
+
}
|
|
1814
|
+
_queryFanout;
|
|
1815
|
+
/** Aggregated visibility, share of voice, citations, and query fan-out for a brand */
|
|
1816
|
+
get queryFanout() {
|
|
1817
|
+
return this._queryFanout ??= new QueryFanout(this.client);
|
|
1818
|
+
}
|
|
1819
|
+
_tags;
|
|
1820
|
+
/** The tags in use on a brand's prompts */
|
|
1821
|
+
get tags() {
|
|
1822
|
+
return this._tags ??= new Tags(this.client);
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
//#endregion
|
|
1826
|
+
//#region src/resources/competitors.ts
|
|
1827
|
+
function reviveCompetitor(value) {
|
|
1828
|
+
if (value.createdAt != null) value.createdAt = decoded("Competitor.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
1829
|
+
if (value.updatedAt != null) value.updatedAt = decoded("Competitor.updatedAt", value.updatedAt, (raw) => new Date(raw));
|
|
1830
|
+
}
|
|
1831
|
+
function reviveCompetitorsList(value) {
|
|
1832
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
1833
|
+
reviveCompetitor(item);
|
|
1834
|
+
});
|
|
1835
|
+
if (value.competitors != null) value.competitors.forEach((item) => {
|
|
1836
|
+
reviveCompetitor(item);
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
const listCompetitorsDescriptor = /* @__PURE__ */ callable({
|
|
1840
|
+
address: "/competitors",
|
|
1841
|
+
auth: apiKeyRequirements,
|
|
1842
|
+
method: "get",
|
|
1843
|
+
pagination: {
|
|
1844
|
+
items: "data",
|
|
1845
|
+
limitParam: "limit",
|
|
1846
|
+
pages: "pagination.totalPages",
|
|
1847
|
+
param: "page",
|
|
1848
|
+
size: "pagination.limit",
|
|
1849
|
+
style: "page",
|
|
1850
|
+
total: "pagination.total"
|
|
1851
|
+
},
|
|
1852
|
+
returns: "json",
|
|
1853
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCompetitorsList) }
|
|
1854
|
+
});
|
|
1855
|
+
const createCompetitorDescriptor = /* @__PURE__ */ callable({
|
|
1856
|
+
address: "/competitors",
|
|
1857
|
+
auth: apiKeyRequirements,
|
|
1858
|
+
mediaType: "application/json",
|
|
1859
|
+
method: "post",
|
|
1860
|
+
returns: "json",
|
|
1861
|
+
rules: [{
|
|
1862
|
+
min: 1,
|
|
1863
|
+
name: "brandId",
|
|
1864
|
+
of: "characters"
|
|
1865
|
+
}, nameRule],
|
|
1866
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCompetitor) }
|
|
1867
|
+
});
|
|
1868
|
+
const deleteCompetitorFields = { path: ["competitorId"] };
|
|
1869
|
+
const deleteCompetitorDescriptor = /* @__PURE__ */ callable({
|
|
1870
|
+
address: "/competitors/{competitorId}",
|
|
1871
|
+
auth: apiKeyRequirements,
|
|
1872
|
+
method: "delete",
|
|
1873
|
+
returns: "json",
|
|
1874
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCompetitor) }
|
|
1875
|
+
});
|
|
1876
|
+
const getCompetitorFields = { path: ["competitorId"] };
|
|
1877
|
+
const getCompetitorDescriptor = /* @__PURE__ */ callable({
|
|
1878
|
+
address: "/competitors/{competitorId}",
|
|
1879
|
+
auth: apiKeyRequirements,
|
|
1880
|
+
method: "get",
|
|
1881
|
+
returns: "json",
|
|
1882
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCompetitor) }
|
|
1883
|
+
});
|
|
1884
|
+
const updateCompetitorFields = { path: ["competitorId"] };
|
|
1885
|
+
const updateCompetitorDescriptor = /* @__PURE__ */ callable({
|
|
1886
|
+
address: "/competitors/{competitorId}",
|
|
1887
|
+
auth: apiKeyRequirements,
|
|
1888
|
+
mediaType: "application/json",
|
|
1889
|
+
method: "patch",
|
|
1890
|
+
returns: "json",
|
|
1891
|
+
rules: [nameRule],
|
|
1892
|
+
validators: { response: /* @__PURE__ */ reviving(reviveCompetitor) }
|
|
1893
|
+
});
|
|
1894
|
+
/** Manage brand competitors */
|
|
1895
|
+
var Competitors = class extends ElmoResource {
|
|
1896
|
+
/** Add a competitor */
|
|
1897
|
+
create(params, options) {
|
|
1898
|
+
return callPromise(options?.client ?? this.client, createCompetitorDescriptor, mergeParams(groupParams(params, "body"), options));
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Delete a competitor
|
|
1902
|
+
*
|
|
1903
|
+
* @param competitorId Competitor identifier (UUID)
|
|
1904
|
+
*/
|
|
1905
|
+
delete(competitorId, options) {
|
|
1906
|
+
return callPromise(options?.client ?? this.client, deleteCompetitorDescriptor, mergeParams(placeParams({ competitorId }, deleteCompetitorFields, "query"), options));
|
|
1907
|
+
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Get a competitor
|
|
1910
|
+
*
|
|
1911
|
+
* @param competitorId Competitor identifier (UUID)
|
|
1912
|
+
*/
|
|
1913
|
+
get(competitorId, options) {
|
|
1914
|
+
return callPromise(options?.client ?? this.client, getCompetitorDescriptor, mergeParams(placeParams({ competitorId }, getCompetitorFields, "query"), options));
|
|
1915
|
+
}
|
|
1916
|
+
list(params, options) {
|
|
1917
|
+
return pages(options?.client ?? this.client, listCompetitorsDescriptor, mergeParams(groupParams(params, "query"), options));
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Update a competitor
|
|
1921
|
+
*
|
|
1922
|
+
* @param competitorId Competitor identifier (UUID)
|
|
1923
|
+
*/
|
|
1924
|
+
update(competitorId, params, options) {
|
|
1925
|
+
return callPromise(options?.client ?? this.client, updateCompetitorDescriptor, mergeParams(placeParams({
|
|
1926
|
+
...params,
|
|
1927
|
+
competitorId
|
|
1928
|
+
}, updateCompetitorFields, "body"), options));
|
|
1929
|
+
}
|
|
1930
|
+
};
|
|
1931
|
+
//#endregion
|
|
1932
|
+
//#region src/resources/identity.ts
|
|
1933
|
+
function reviveApiKeyIdentity(value) {
|
|
1934
|
+
if (value.createdAt != null) value.createdAt = decoded("ApiKeyIdentity.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
1935
|
+
if (value.expiresAt != null) value.expiresAt = decoded("ApiKeyIdentity.expiresAt", value.expiresAt, (raw) => new Date(raw));
|
|
1936
|
+
if (value.lastUsedAt != null) value.lastUsedAt = decoded("ApiKeyIdentity.lastUsedAt", value.lastUsedAt, (raw) => new Date(raw));
|
|
1937
|
+
}
|
|
1938
|
+
const getMeDescriptor = /* @__PURE__ */ callable({
|
|
1939
|
+
address: "/me",
|
|
1940
|
+
auth: apiKeyRequirements,
|
|
1941
|
+
method: "get",
|
|
1942
|
+
returns: "json",
|
|
1943
|
+
validators: { response: /* @__PURE__ */ reviving(reviveApiKeyIdentity) }
|
|
1944
|
+
});
|
|
1945
|
+
/** What the calling key is and what it may reach */
|
|
1946
|
+
var Me = class extends ElmoResource {
|
|
1947
|
+
/**
|
|
1948
|
+
* Describe the calling key
|
|
1949
|
+
*
|
|
1950
|
+
* What this key is, which organization and brands it reaches, and which scopes it holds. Requires
|
|
1951
|
+
* no scope, so it is always safe to call first when wiring up an integration.
|
|
1952
|
+
*/
|
|
1953
|
+
get(options) {
|
|
1954
|
+
return callPromise(options?.client ?? this.client, getMeDescriptor, options);
|
|
1955
|
+
}
|
|
1956
|
+
};
|
|
1957
|
+
//#endregion
|
|
1958
|
+
//#region src/resources/models.ts
|
|
1959
|
+
const listModelsDescriptor = /* @__PURE__ */ callable({
|
|
1960
|
+
address: "/models",
|
|
1961
|
+
auth: apiKeyRequirements,
|
|
1962
|
+
method: "get",
|
|
1963
|
+
returns: "json"
|
|
1964
|
+
});
|
|
1965
|
+
/** The answer engines this deployment can track */
|
|
1966
|
+
var Models = class extends ElmoResource {
|
|
1967
|
+
/**
|
|
1968
|
+
* List trackable models
|
|
1969
|
+
*
|
|
1970
|
+
* The answer engines this deployment can track, so a client can build a model filter without
|
|
1971
|
+
* hardcoding ids that differ between deployments.
|
|
1972
|
+
*
|
|
1973
|
+
* Requires no scope.
|
|
1974
|
+
*/
|
|
1975
|
+
list(options) {
|
|
1976
|
+
return callPromise(options?.client ?? this.client, listModelsDescriptor, options);
|
|
1977
|
+
}
|
|
1978
|
+
};
|
|
1979
|
+
//#endregion
|
|
1980
|
+
//#region src/resources/organizations.ts
|
|
1981
|
+
const getOrganizationBillingFields = { path: ["organizationId"] };
|
|
1982
|
+
function reviveBillingPlan(value) {
|
|
1983
|
+
if (value.periodEnd != null) value.periodEnd = decoded("BillingPlan.periodEnd", value.periodEnd, (raw) => new Date(raw));
|
|
1984
|
+
}
|
|
1985
|
+
function reviveOrganizationBilling(value) {
|
|
1986
|
+
if (value.plan != null) reviveBillingPlan(value.plan);
|
|
1987
|
+
}
|
|
1988
|
+
const getOrganizationBillingDescriptor = /* @__PURE__ */ callable({
|
|
1989
|
+
address: "/organizations/{organizationId}/billing",
|
|
1990
|
+
auth: apiKeyRequirements,
|
|
1991
|
+
method: "get",
|
|
1992
|
+
returns: "json",
|
|
1993
|
+
validators: { response: /* @__PURE__ */ reviving(reviveOrganizationBilling) }
|
|
1994
|
+
});
|
|
1995
|
+
function reviveOrganization(value) {
|
|
1996
|
+
if (value.createdAt != null) value.createdAt = decoded("Organization.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
1997
|
+
}
|
|
1998
|
+
function reviveOrganizationList(value) {
|
|
1999
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
2000
|
+
reviveOrganization(item);
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
const listOrganizationsDescriptor = /* @__PURE__ */ callable({
|
|
2004
|
+
address: "/organizations",
|
|
2005
|
+
auth: apiKeyRequirements,
|
|
2006
|
+
method: "get",
|
|
2007
|
+
pagination: {
|
|
2008
|
+
items: "data",
|
|
2009
|
+
limitParam: "limit",
|
|
2010
|
+
pages: "pagination.totalPages",
|
|
2011
|
+
param: "page",
|
|
2012
|
+
size: "pagination.limit",
|
|
2013
|
+
style: "page",
|
|
2014
|
+
total: "pagination.total"
|
|
2015
|
+
},
|
|
2016
|
+
returns: "json",
|
|
2017
|
+
validators: { response: /* @__PURE__ */ reviving(reviveOrganizationList) }
|
|
2018
|
+
});
|
|
2019
|
+
const getOrganizationFields = { path: ["organizationId"] };
|
|
2020
|
+
const getOrganizationDescriptor = /* @__PURE__ */ callable({
|
|
2021
|
+
address: "/organizations/{organizationId}",
|
|
2022
|
+
auth: apiKeyRequirements,
|
|
2023
|
+
method: "get",
|
|
2024
|
+
returns: "json",
|
|
2025
|
+
validators: { response: /* @__PURE__ */ reviving(reviveOrganization) }
|
|
2026
|
+
});
|
|
2027
|
+
/** Organizations, their plan limits, and their usage */
|
|
2028
|
+
var Billing = class extends ElmoResource {
|
|
2029
|
+
/**
|
|
2030
|
+
* Get billing state
|
|
2031
|
+
*
|
|
2032
|
+
* The organization's plan, its limits, and how much of each limit is already spent — enough for
|
|
2033
|
+
* an integration to know a write will be rejected before attempting it.
|
|
2034
|
+
*
|
|
2035
|
+
* This endpoint is read-only by construction. No API key of any kind can change a subscription,
|
|
2036
|
+
* an add-on quantity, or a payment method; there is no billing write endpoint and no billing
|
|
2037
|
+
* write scope. Stripe identifiers, invoices, and payment methods are never returned.
|
|
2038
|
+
*
|
|
2039
|
+
* Deployments without billing answer `200` with `billingEnabled: false`, a null plan, and null
|
|
2040
|
+
* limits, so callers need no special case.
|
|
2041
|
+
*/
|
|
2042
|
+
get(organizationId, options) {
|
|
2043
|
+
return callPromise(options?.client ?? this.client, getOrganizationBillingDescriptor, mergeParams(placeParams({ organizationId }, getOrganizationBillingFields, "query"), options));
|
|
2044
|
+
}
|
|
2045
|
+
};
|
|
2046
|
+
/** Organizations, their plan limits, and their usage */
|
|
2047
|
+
var Organizations = class extends ElmoResource {
|
|
2048
|
+
/**
|
|
2049
|
+
* Get an organization
|
|
2050
|
+
*
|
|
2051
|
+
* No scope required. An organization outside the key's reach answers `404`, identically to one
|
|
2052
|
+
* that does not exist.
|
|
2053
|
+
*/
|
|
2054
|
+
get(organizationId, options) {
|
|
2055
|
+
return callPromise(options?.client ?? this.client, getOrganizationDescriptor, mergeParams(placeParams({ organizationId }, getOrganizationFields, "query"), options));
|
|
2056
|
+
}
|
|
2057
|
+
/**
|
|
2058
|
+
* One entry for an organization key — the one it acts inside. Every organization for an instance
|
|
2059
|
+
* admin key. No scope required: a key can only ever see the organization it is already bound to.
|
|
2060
|
+
*/
|
|
2061
|
+
list(params, options) {
|
|
2062
|
+
return pages(options?.client ?? this.client, listOrganizationsDescriptor, mergeParams(groupParams(params, "query"), options));
|
|
2063
|
+
}
|
|
2064
|
+
_billing;
|
|
2065
|
+
/** Organizations, their plan limits, and their usage */
|
|
2066
|
+
get billing() {
|
|
2067
|
+
return this._billing ??= new Billing(this.client);
|
|
2068
|
+
}
|
|
2069
|
+
};
|
|
2070
|
+
//#endregion
|
|
2071
|
+
//#region src/resources/runs.ts
|
|
2072
|
+
const listPromptRunsFields = { path: ["promptId"] };
|
|
2073
|
+
function reviveRunSummary(value) {
|
|
2074
|
+
if (value.createdAt != null) value.createdAt = decoded("RunSummary.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2075
|
+
}
|
|
2076
|
+
function reviveRunList(value) {
|
|
2077
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
2078
|
+
reviveRunSummary(item);
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
const listPromptRunsDescriptor = /* @__PURE__ */ callable({
|
|
2082
|
+
address: "/prompts/{promptId}/runs",
|
|
2083
|
+
auth: apiKeyRequirements,
|
|
2084
|
+
method: "get",
|
|
2085
|
+
pagination: {
|
|
2086
|
+
items: "data",
|
|
2087
|
+
limitParam: "limit",
|
|
2088
|
+
pages: "pagination.totalPages",
|
|
2089
|
+
param: "page",
|
|
2090
|
+
size: "pagination.limit",
|
|
2091
|
+
style: "page",
|
|
2092
|
+
total: "pagination.total"
|
|
2093
|
+
},
|
|
2094
|
+
returns: "json",
|
|
2095
|
+
validators: { response: /* @__PURE__ */ reviving(reviveRunList) }
|
|
2096
|
+
});
|
|
2097
|
+
const getRunFields = { path: ["promptId", "runId"] };
|
|
2098
|
+
function reviveRun(value) {
|
|
2099
|
+
if (value.createdAt != null) value.createdAt = decoded("Run.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2100
|
+
}
|
|
2101
|
+
const getRunDescriptor = /* @__PURE__ */ callable({
|
|
2102
|
+
address: "/prompts/{promptId}/runs/{runId}",
|
|
2103
|
+
auth: apiKeyRequirements,
|
|
2104
|
+
method: "get",
|
|
2105
|
+
returns: "json",
|
|
2106
|
+
validators: { response: /* @__PURE__ */ reviving(reviveRun) }
|
|
2107
|
+
});
|
|
2108
|
+
/** Individual model answers behind the aggregates */
|
|
2109
|
+
var Runs = class extends ElmoResource {
|
|
2110
|
+
/**
|
|
2111
|
+
* Get a run
|
|
2112
|
+
*
|
|
2113
|
+
* One model answer, with its text normalized out of the provider’s response and its citations in
|
|
2114
|
+
* the order the engine listed them. A run belonging to some other prompt answers `404`. The
|
|
2115
|
+
* provider’s raw payload is deliberately not exposed — its shape belongs to the provider, not to
|
|
2116
|
+
* this API.
|
|
2117
|
+
*/
|
|
2118
|
+
get(promptId, runId, options) {
|
|
2119
|
+
return callPromise(options?.client ?? this.client, getRunDescriptor, mergeParams(placeParams({
|
|
2120
|
+
promptId,
|
|
2121
|
+
runId
|
|
2122
|
+
}, getRunFields, "query"), options));
|
|
2123
|
+
}
|
|
2124
|
+
/**
|
|
2125
|
+
* List runs for a prompt
|
|
2126
|
+
*
|
|
2127
|
+
* Individual model answers behind the aggregates, newest first, without their text — the list
|
|
2128
|
+
* stays small enough to page through. Fetch `prompts.runs.get()` for the answer itself.
|
|
2129
|
+
*/
|
|
2130
|
+
list(promptId, params, options) {
|
|
2131
|
+
return pages(options?.client ?? this.client, listPromptRunsDescriptor, mergeParams(placeParams({
|
|
2132
|
+
...params,
|
|
2133
|
+
promptId
|
|
2134
|
+
}, listPromptRunsFields, "query"), options));
|
|
2135
|
+
}
|
|
2136
|
+
};
|
|
2137
|
+
//#endregion
|
|
2138
|
+
//#region src/resources/snapshots.ts
|
|
2139
|
+
const getPromptSnapshotFields = { path: ["promptId"] };
|
|
2140
|
+
const getPromptSnapshotDescriptor = /* @__PURE__ */ callable({
|
|
2141
|
+
address: "/prompts/{promptId}/snapshot",
|
|
2142
|
+
auth: apiKeyRequirements,
|
|
2143
|
+
method: "get",
|
|
2144
|
+
returns: "json"
|
|
2145
|
+
});
|
|
2146
|
+
/** Aggregated analytics snapshots for prompts */
|
|
2147
|
+
var Snapshot = class extends ElmoResource {
|
|
2148
|
+
/**
|
|
2149
|
+
* Get an aggregated snapshot of mention and citation analytics for a specific prompt over a date
|
|
2150
|
+
* range. Use this to identify competitive gaps, track brand visibility trends, and discover top
|
|
2151
|
+
* cited URLs.
|
|
2152
|
+
*
|
|
2153
|
+
* @param promptId The ID of the prompt
|
|
2154
|
+
*/
|
|
2155
|
+
get(promptId, params, options) {
|
|
2156
|
+
return callPromise(options?.client ?? this.client, getPromptSnapshotDescriptor, mergeParams(placeParams({
|
|
2157
|
+
...params,
|
|
2158
|
+
promptId
|
|
2159
|
+
}, getPromptSnapshotFields, "query"), options));
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
//#endregion
|
|
2163
|
+
//#region src/resources/prompts.ts
|
|
2164
|
+
function revivePrompt(value) {
|
|
2165
|
+
if (value.createdAt != null) value.createdAt = decoded("Prompt.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2166
|
+
if (value.updatedAt != null) value.updatedAt = decoded("Prompt.updatedAt", value.updatedAt, (raw) => new Date(raw));
|
|
2167
|
+
}
|
|
2168
|
+
const listPromptsDescriptor = /* @__PURE__ */ callable({
|
|
2169
|
+
address: "/prompts",
|
|
2170
|
+
auth: apiKeyRequirements,
|
|
2171
|
+
method: "get",
|
|
2172
|
+
pagination: {
|
|
2173
|
+
items: "data",
|
|
2174
|
+
limitParam: "limit",
|
|
2175
|
+
pages: "pagination.totalPages",
|
|
2176
|
+
param: "page",
|
|
2177
|
+
size: "pagination.limit",
|
|
2178
|
+
style: "page",
|
|
2179
|
+
total: "pagination.total"
|
|
2180
|
+
},
|
|
2181
|
+
returns: "json",
|
|
2182
|
+
validators: { response: (data) => {
|
|
2183
|
+
const value = data;
|
|
2184
|
+
if (value == null) return value;
|
|
2185
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
2186
|
+
revivePrompt(item);
|
|
2187
|
+
});
|
|
2188
|
+
if (value.prompts != null) value.prompts.forEach((item) => {
|
|
2189
|
+
revivePrompt(item);
|
|
2190
|
+
});
|
|
2191
|
+
return value;
|
|
2192
|
+
} }
|
|
2193
|
+
});
|
|
2194
|
+
const createPromptDescriptor = /* @__PURE__ */ callable({
|
|
2195
|
+
address: "/prompts",
|
|
2196
|
+
auth: apiKeyRequirements,
|
|
2197
|
+
mediaType: "application/json",
|
|
2198
|
+
method: "post",
|
|
2199
|
+
returns: "json",
|
|
2200
|
+
rules: [valueRule],
|
|
2201
|
+
validators: { response: /* @__PURE__ */ reviving(revivePrompt) }
|
|
2202
|
+
});
|
|
2203
|
+
const deletePromptFields = { path: ["promptId"] };
|
|
2204
|
+
const deletePromptDescriptor = /* @__PURE__ */ callable({
|
|
2205
|
+
address: "/prompts/{promptId}",
|
|
2206
|
+
auth: apiKeyRequirements,
|
|
2207
|
+
method: "delete",
|
|
2208
|
+
returns: "json",
|
|
2209
|
+
validators: { response: (data) => {
|
|
2210
|
+
const value = data;
|
|
2211
|
+
if (value == null) return value;
|
|
2212
|
+
if (value.createdAt != null) value.createdAt = decoded("createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2213
|
+
if (value.updatedAt != null) value.updatedAt = decoded("updatedAt", value.updatedAt, (raw) => new Date(raw));
|
|
2214
|
+
return value;
|
|
2215
|
+
} }
|
|
2216
|
+
});
|
|
2217
|
+
const getPromptFields = { path: ["promptId"] };
|
|
2218
|
+
const getPromptDescriptor = /* @__PURE__ */ callable({
|
|
2219
|
+
address: "/prompts/{promptId}",
|
|
2220
|
+
auth: apiKeyRequirements,
|
|
2221
|
+
method: "get",
|
|
2222
|
+
returns: "json",
|
|
2223
|
+
validators: { response: /* @__PURE__ */ reviving(revivePrompt) }
|
|
2224
|
+
});
|
|
2225
|
+
const updatePromptFields = { path: ["promptId"] };
|
|
2226
|
+
const updatePromptDescriptor = /* @__PURE__ */ callable({
|
|
2227
|
+
address: "/prompts/{promptId}",
|
|
2228
|
+
auth: apiKeyRequirements,
|
|
2229
|
+
mediaType: "application/json",
|
|
2230
|
+
method: "patch",
|
|
2231
|
+
returns: "json",
|
|
2232
|
+
rules: [valueRule],
|
|
2233
|
+
validators: { response: /* @__PURE__ */ reviving(revivePrompt) }
|
|
2234
|
+
});
|
|
2235
|
+
/** Manage brand prompts */
|
|
2236
|
+
var Prompts = class extends ElmoResource {
|
|
2237
|
+
/**
|
|
2238
|
+
* Create a new prompt
|
|
2239
|
+
*
|
|
2240
|
+
* Create a new prompt for a brand. This will automatically schedule the prompt for execution.
|
|
2241
|
+
*/
|
|
2242
|
+
create(params, options) {
|
|
2243
|
+
return callPromise(options?.client ?? this.client, createPromptDescriptor, mergeParams(groupParams(params, "body"), options));
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* Delete a prompt
|
|
2247
|
+
*
|
|
2248
|
+
* Permanently delete a prompt and cancel all related scheduled jobs. This will also cascade
|
|
2249
|
+
* delete all associated prompt runs.
|
|
2250
|
+
*
|
|
2251
|
+
* Requires an instance admin key; organization keys receive `403`. The dashboard has no delete
|
|
2252
|
+
* either — stop tracking a prompt with `prompts.update()` and `enabled: false`, which keeps its
|
|
2253
|
+
* history and frees the plan slot.
|
|
2254
|
+
*
|
|
2255
|
+
* @param promptId The ID of the prompt to delete
|
|
2256
|
+
*/
|
|
2257
|
+
delete(promptId, options) {
|
|
2258
|
+
return callPromise(options?.client ?? this.client, deletePromptDescriptor, mergeParams(placeParams({ promptId }, deletePromptFields, "query"), options));
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* Get a prompt
|
|
2262
|
+
*
|
|
2263
|
+
* Retrieve a specific prompt by ID
|
|
2264
|
+
*
|
|
2265
|
+
* @param promptId The ID of the prompt
|
|
2266
|
+
*/
|
|
2267
|
+
get(promptId, options) {
|
|
2268
|
+
return callPromise(options?.client ?? this.client, getPromptDescriptor, mergeParams(placeParams({ promptId }, getPromptFields, "query"), options));
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* List all prompts
|
|
2272
|
+
*
|
|
2273
|
+
* Retrieve a paginated list of all prompts across all brands
|
|
2274
|
+
*/
|
|
2275
|
+
list(params, options) {
|
|
2276
|
+
return pages(options?.client ?? this.client, listPromptsDescriptor, mergeParams(groupParams(params, "query"), options));
|
|
2277
|
+
}
|
|
2278
|
+
/**
|
|
2279
|
+
* Update a prompt
|
|
2280
|
+
*
|
|
2281
|
+
* Update a prompt's properties. Only provided fields will be updated. Toggling `enabled`
|
|
2282
|
+
* schedules or unschedules the recurring run job.
|
|
2283
|
+
*
|
|
2284
|
+
* @param promptId The ID of the prompt to update
|
|
2285
|
+
*/
|
|
2286
|
+
update(promptId, params, options) {
|
|
2287
|
+
return callPromise(options?.client ?? this.client, updatePromptDescriptor, mergeParams(placeParams({
|
|
2288
|
+
...params,
|
|
2289
|
+
promptId
|
|
2290
|
+
}, updatePromptFields, "body"), options));
|
|
2291
|
+
}
|
|
2292
|
+
_runs;
|
|
2293
|
+
/** Individual model answers behind the aggregates */
|
|
2294
|
+
get runs() {
|
|
2295
|
+
return this._runs ??= new Runs(this.client);
|
|
2296
|
+
}
|
|
2297
|
+
_snapshot;
|
|
2298
|
+
/** Aggregated analytics snapshots for prompts */
|
|
2299
|
+
get snapshot() {
|
|
2300
|
+
return this._snapshot ??= new Snapshot(this.client);
|
|
2301
|
+
}
|
|
2302
|
+
};
|
|
2303
|
+
//#endregion
|
|
2304
|
+
//#region src/resources/reports.ts
|
|
2305
|
+
function reviveReportSummary(value) {
|
|
2306
|
+
if (value.createdAt != null) value.createdAt = decoded("ReportSummary.createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2307
|
+
if (value.completedAt != null) value.completedAt = decoded("ReportSummary.completedAt", value.completedAt, (raw) => new Date(raw));
|
|
2308
|
+
}
|
|
2309
|
+
const listReportsDescriptor = /* @__PURE__ */ callable({
|
|
2310
|
+
address: "/reports",
|
|
2311
|
+
auth: apiKeyRequirements,
|
|
2312
|
+
method: "get",
|
|
2313
|
+
pagination: {
|
|
2314
|
+
items: "data",
|
|
2315
|
+
limitParam: "limit",
|
|
2316
|
+
pages: "pagination.totalPages",
|
|
2317
|
+
param: "page",
|
|
2318
|
+
size: "pagination.limit",
|
|
2319
|
+
style: "page",
|
|
2320
|
+
total: "pagination.total"
|
|
2321
|
+
},
|
|
2322
|
+
returns: "json",
|
|
2323
|
+
validators: { response: (data) => {
|
|
2324
|
+
const value = data;
|
|
2325
|
+
if (value == null) return value;
|
|
2326
|
+
if (value.data != null) value.data.forEach((item) => {
|
|
2327
|
+
reviveReportSummary(item);
|
|
2328
|
+
});
|
|
2329
|
+
if (value.reports != null) value.reports.forEach((item) => {
|
|
2330
|
+
reviveReportSummary(item);
|
|
2331
|
+
});
|
|
2332
|
+
return value;
|
|
2333
|
+
} }
|
|
2334
|
+
});
|
|
2335
|
+
const createReportDescriptor = /* @__PURE__ */ callable({
|
|
2336
|
+
address: "/reports",
|
|
2337
|
+
auth: apiKeyRequirements,
|
|
2338
|
+
mediaType: "application/json",
|
|
2339
|
+
method: "post",
|
|
2340
|
+
returns: "json",
|
|
2341
|
+
rules: [
|
|
2342
|
+
brandNameRule,
|
|
2343
|
+
{
|
|
2344
|
+
max: 10,
|
|
2345
|
+
name: "brandAliases",
|
|
2346
|
+
of: "items"
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
min: 1,
|
|
2350
|
+
name: "brandWebsite",
|
|
2351
|
+
of: "characters"
|
|
2352
|
+
}
|
|
2353
|
+
],
|
|
2354
|
+
validators: { response: (data) => {
|
|
2355
|
+
const value = data;
|
|
2356
|
+
if (value == null) return value;
|
|
2357
|
+
if (value.createdAt != null) value.createdAt = decoded("createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2358
|
+
return value;
|
|
2359
|
+
} }
|
|
2360
|
+
});
|
|
2361
|
+
const getReportFields = { path: ["reportId"] };
|
|
2362
|
+
const getReportDescriptor = /* @__PURE__ */ callable({
|
|
2363
|
+
address: "/reports/{reportId}",
|
|
2364
|
+
auth: apiKeyRequirements,
|
|
2365
|
+
method: "get",
|
|
2366
|
+
returns: "json",
|
|
2367
|
+
validators: { response: (data) => {
|
|
2368
|
+
const value = data;
|
|
2369
|
+
if (value == null) return value;
|
|
2370
|
+
if (value.createdAt != null) value.createdAt = decoded("createdAt", value.createdAt, (raw) => new Date(raw));
|
|
2371
|
+
if (value.completedAt != null) value.completedAt = decoded("completedAt", value.completedAt, (raw) => new Date(raw));
|
|
2372
|
+
return value;
|
|
2373
|
+
} }
|
|
2374
|
+
});
|
|
2375
|
+
/** Generate and retrieve AI Share of Voice reports */
|
|
2376
|
+
var Reports = class extends ElmoResource {
|
|
2377
|
+
/**
|
|
2378
|
+
* Create a report
|
|
2379
|
+
*
|
|
2380
|
+
* Create a new AI Share of Voice report and queue it for generation. The report will evaluate the
|
|
2381
|
+
* brand across multiple AI engines (ChatGPT, Claude, Google AI) using generated and optional
|
|
2382
|
+
* custom prompts.
|
|
2383
|
+
*
|
|
2384
|
+
* Requires an instance admin key; organization keys receive `403`.
|
|
2385
|
+
*/
|
|
2386
|
+
create(params, options) {
|
|
2387
|
+
return callPromise(options?.client ?? this.client, createReportDescriptor, mergeParams(groupParams(params, "body"), options));
|
|
2388
|
+
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Get report status and data
|
|
2391
|
+
*
|
|
2392
|
+
* Poll a report's status. When completed, returns per-prompt snapshot data with raw mention
|
|
2393
|
+
* counts. Consumers are responsible for computing SoV and other derived metrics from the raw
|
|
2394
|
+
* data.
|
|
2395
|
+
*
|
|
2396
|
+
* Requires an instance admin key; organization keys receive `403`.
|
|
2397
|
+
*
|
|
2398
|
+
* @param reportId The ID of the report
|
|
2399
|
+
*/
|
|
2400
|
+
get(reportId, params, options) {
|
|
2401
|
+
return callPromise(options?.client ?? this.client, getReportDescriptor, mergeParams(placeParams({
|
|
2402
|
+
...params,
|
|
2403
|
+
reportId
|
|
2404
|
+
}, getReportFields, "query"), options));
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Retrieve a paginated list of all reports, ordered by creation date (newest first).
|
|
2408
|
+
*
|
|
2409
|
+
* Requires an instance admin key; organization keys receive `403`.
|
|
2410
|
+
*/
|
|
2411
|
+
list(params, options) {
|
|
2412
|
+
return pages(options?.client ?? this.client, listReportsDescriptor, mergeParams(groupParams(params, "query"), options));
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
//#endregion
|
|
2416
|
+
//#region src/resources/tools.ts
|
|
2417
|
+
const analyzeBrandDescriptor = /* @__PURE__ */ callable({
|
|
2418
|
+
address: "/tools/analyze",
|
|
2419
|
+
auth: apiKeyRequirements,
|
|
2420
|
+
mediaType: "application/json",
|
|
2421
|
+
method: "post",
|
|
2422
|
+
returns: "json",
|
|
2423
|
+
rules: [
|
|
2424
|
+
{
|
|
2425
|
+
min: 1,
|
|
2426
|
+
name: "website",
|
|
2427
|
+
of: "characters"
|
|
2428
|
+
},
|
|
2429
|
+
{
|
|
2430
|
+
max: 100,
|
|
2431
|
+
min: 0,
|
|
2432
|
+
name: "maxCompetitors"
|
|
2433
|
+
},
|
|
2434
|
+
{
|
|
2435
|
+
max: 100,
|
|
2436
|
+
min: 0,
|
|
2437
|
+
name: "maxPrompts"
|
|
2438
|
+
}
|
|
2439
|
+
]
|
|
2440
|
+
});
|
|
2441
|
+
/** One-shot helpers (e.g. brand analysis) that don't persist anything */
|
|
2442
|
+
var Tools = class extends ElmoResource {
|
|
2443
|
+
/**
|
|
2444
|
+
* Analyze a website
|
|
2445
|
+
*
|
|
2446
|
+
* Run brand analysis without persisting anything. Returns suggested additional domains, aliases,
|
|
2447
|
+
* competitors, and prompts.
|
|
2448
|
+
*
|
|
2449
|
+
* Requires an instance admin key; organization keys receive `403`.
|
|
2450
|
+
*/
|
|
2451
|
+
analyze(params, options) {
|
|
2452
|
+
return callPromise(options?.client ?? this.client, analyzeBrandDescriptor, mergeParams(groupParams(params, "body"), options));
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
//#endregion
|
|
2456
|
+
export { getBrandOpportunitiesFields as $, listModelsDescriptor as A, selectCodec as At, updateCompetitorDescriptor as B, emptyPathParameter as Bt, Organizations as C, isFieldValue as Ct, getOrganizationFields as D, toText as Dt, getOrganizationDescriptor as E, scalarText as Et, deleteCompetitorDescriptor as F, MissingCredentialError as Ft, getBrandFields as G, unansweredError as Gt, Brands as H, isStructured as Ht, deleteCompetitorFields as I, TimeoutError as It, updateBrandFields as J, TIMER_LIMIT as Jt, listBrandsDescriptor as K, unsendable as Kt, getCompetitorDescriptor as L, TransportError as Lt, getMeDescriptor as M, AbortError as Mt, Competitors as N, DecodeError as Nt, listOrganizationsDescriptor as O, essenceOf as Ot, createCompetitorDescriptor as P, ElmoError as Pt, getBrandOpportunitiesDescriptor as Q, sleep as Qt, getCompetitorFields as R, calledOffWith as Rt, listPromptRunsFields as S, createConfig as St, getOrganizationBillingFields as T, metadataValue as Tt, createBrandDescriptor as U, refusedInput as Ut, updateCompetitorFields as V, failureOf as Vt, getBrandDescriptor as W, safeAddress as Wt, listBrandTagsDescriptor as X, exceedsMaxRetryAfter as Xt, pages as Y, backoffDelay as Yt, listBrandTagsFields as Z, retryAfterDelay as Zt, getPromptSnapshotDescriptor as _, createClient as _t, getReportDescriptor as a, listBrandCitationDomainsFields as at, getRunFields as b, replyWith as bt, Prompts as c, listBrandPromptPerformanceDescriptor as ct, deletePromptFields as d, mergeParams as dt, getBrandAnalyticsDescriptor as et, getPromptDescriptor as f, placeParams as ft, updatePromptFields as g, clientFor as gt, updatePromptDescriptor as h, validateFeature as ht, createReportDescriptor as i, listBrandCitationDomainsDescriptor as it, Me as j, APIError as jt, Models as k, readText as kt, createPromptDescriptor as l, listBrandPromptPerformanceFields as lt, listPromptsDescriptor as m, ElmoResource as mt, analyzeBrandDescriptor as n, getBrandQueryFanoutDescriptor as nt, getReportFields as o, listBrandCitationURLsDescriptor as ot, getPromptFields as p, callPromise as pt, updateBrandDescriptor as q, unsendableAddress as qt, Reports as r, getBrandQueryFanoutFields as rt, listReportsDescriptor as s, listBrandCitationUrlsFields as st, Tools as t, getBrandAnalyticsFields as tt, deletePromptDescriptor as u, groupParams as ut, getPromptSnapshotFields as v, discardBody as vt, getOrganizationBillingDescriptor as w, metadataHeaders as wt, listPromptRunsDescriptor as x, baseURLOf as xt, getRunDescriptor as y, isStreamed as yt, listCompetitorsDescriptor as z, classifyError as zt };
|
|
2457
|
+
|
|
2458
|
+
//# sourceMappingURL=tools-SwP0sK8H.mjs.map
|