@elmohq/sdk 0.2.0 → 0.2.1

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.
@@ -1,4 +1,4 @@
1
- //#region src/internal/core/backoff.ts
1
+ // src/internal/core/backoff.ts
2
2
  function jitterShare(jitter) {
3
3
  if (typeof jitter === "number") return Math.min(1, Math.max(0, jitter));
4
4
  if (jitter === "equal") return .5;
@@ -87,8 +87,7 @@ function retryAfterDelay(response, headers = RETRY_AFTER_HEADERS, now = Date.now
87
87
  if (delay !== void 0) return delay;
88
88
  }
89
89
  }
90
- //#endregion
91
- //#region src/internal/core/errors.ts
90
+ // src/internal/core/errors.ts
92
91
  /** The base of every error this SDK throws, including one from a call that never arrived. */
93
92
  var ElmoError = class extends Error {
94
93
  /** The class's name. Compare it where `instanceof` fails, such as across two copies of this SDK. */
@@ -398,8 +397,7 @@ function unreadableValue(at, value, cause, response) {
398
397
  value
399
398
  });
400
399
  }
401
- //#endregion
402
- //#region src/internal/codec/registry.ts
400
+ // src/internal/codec/registry.ts
403
401
  function charsetOf(contentType) {
404
402
  return contentType?.match(/;\s*charset\s*=\s*"?([^";\s]+)/i)?.[1];
405
403
  }
@@ -442,16 +440,14 @@ function encodeNamedBody(codecs, mediaType, options) {
442
440
  payload: codec.encode(options.body)
443
441
  };
444
442
  }
445
- //#endregion
446
- //#region src/internal/core/text.ts
443
+ // src/internal/core/text.ts
447
444
  function scalarText(value) {
448
445
  return value instanceof Date ? value.toISOString() : void 0;
449
446
  }
450
447
  function toText(value) {
451
448
  return typeof value === "string" ? value : scalarText(value) ?? String(value);
452
449
  }
453
- //#endregion
454
- //#region src/internal/core/metadata.ts
450
+ // src/internal/core/metadata.ts
455
451
  function entriesOf(source) {
456
452
  if (typeof source[Symbol.iterator] === "function") return source;
457
453
  return Object.entries(source);
@@ -513,8 +509,7 @@ function metadataValue(value) {
513
509
  if (value === void 0) return void 0;
514
510
  return Array.isArray(value) ? value.join(", ") : value;
515
511
  }
516
- //#endregion
517
- //#region src/internal/core/config.ts
512
+ // src/internal/core/config.ts
518
513
  function foldRetry(sources, merged) {
519
514
  if (!sources.some((source) => source?.["retry"] !== void 0)) return merged;
520
515
  let retry;
@@ -576,8 +571,7 @@ function baseURLOf(options, fallback) {
576
571
  function mergeDefaults(...sources) {
577
572
  return merge(sources, true);
578
573
  }
579
- //#endregion
580
- //#region src/internal/core/credentials.ts
574
+ // src/internal/core/credentials.ts
581
575
  const LAYER_ALIASES = {
582
576
  defaultHeaders: "headers",
583
577
  defaultPath: "path",
@@ -606,8 +600,7 @@ function applyCredentials(config, credentials) {
606
600
  }
607
601
  return applied ?? config;
608
602
  }
609
- //#endregion
610
- //#region src/internal/core/body.ts
603
+ // src/internal/core/body.ts
611
604
  function discardBody(result) {
612
605
  const { response } = result ?? {};
613
606
  if (response && !response.bodyUsed) response.body?.cancel().catch(() => {});
@@ -650,8 +643,7 @@ async function bufferReply(response, signal) {
650
643
  controller.close();
651
644
  } }), response);
652
645
  }
653
- //#endregion
654
- //#region src/internal/core/features.ts
646
+ // src/internal/core/features.ts
655
647
  var FeatureRunner = class {
656
648
  features;
657
649
  constructor(features = []) {
@@ -687,13 +679,11 @@ var FeatureRunner = class {
687
679
  return current;
688
680
  }
689
681
  };
690
- //#endregion
691
- //#region src/internal/core/protocol.ts
682
+ // src/internal/core/protocol.ts
692
683
  function onlyProtocol(protocols, _interaction) {
693
684
  return Object.values(protocols)[0];
694
685
  }
695
- //#endregion
696
- //#region src/internal/core/dispatch.ts
686
+ // src/internal/core/dispatch.ts
697
687
  async function readReply$1(setup, sent, request, from) {
698
688
  const { binding, ctx, runner } = sent;
699
689
  try {
@@ -876,8 +866,7 @@ function envDefaults(base, env = {}, credentials = {}) {
876
866
  });
877
867
  return defaults;
878
868
  }
879
- //#endregion
880
- //#region src/internal/core/client.ts
869
+ // src/internal/core/client.ts
881
870
  function clientOf(setup) {
882
871
  return Object.defineProperty({
883
872
  call(callable, options) {
@@ -919,13 +908,11 @@ function withClient(source, client, key = "client") {
919
908
  derived[key] = client;
920
909
  return derived;
921
910
  }
922
- //#endregion
923
- //#region src/internal/core/read-reply.ts
911
+ // src/internal/core/read-reply.ts
924
912
  async function readReply(read, value, _response) {
925
913
  return await read(value);
926
914
  }
927
- //#endregion
928
- //#region src/internal/feature/validate.ts
915
+ // src/internal/feature/validate.ts
929
916
  async function runValidator(validate, value, options, response) {
930
917
  if (!validate || options["validate"] === false) return value;
931
918
  return await readReply(validate, value, response);
@@ -966,8 +953,7 @@ function reviving(revive) {
966
953
  return data;
967
954
  };
968
955
  }
969
- //#endregion
970
- //#region src/resources/shared/auth.ts
956
+ // src/resources/shared/auth.ts
971
957
  /**
972
958
  * An instance admin key from `ADMIN_API_KEYS`, or an organization key (`elmo_…`) issued from the
973
959
  * dashboard.
@@ -977,8 +963,7 @@ const apiKeyRequirements = [{
977
963
  scheme: "bearer",
978
964
  type: "http"
979
965
  }];
980
- //#endregion
981
- //#region src/resources/shared/resource.ts
966
+ // src/resources/shared/resource.ts
982
967
  var ElmoResource = class {
983
968
  /** The client every call on this SDK dispatches through. */
984
969
  client;
@@ -996,8 +981,7 @@ var ElmoResource = class {
996
981
  return withClient(this, clientFor(options, this.client));
997
982
  }
998
983
  };
999
- //#endregion
1000
- //#region src/internal/core/lazy-promise.ts
984
+ // src/internal/core/lazy-promise.ts
1001
985
  var LazyPromise = class extends Promise {
1002
986
  answer;
1003
987
  constructor() {
@@ -1023,8 +1007,7 @@ function unattended(promise) {
1023
1007
  promise.catch(() => {});
1024
1008
  return promise;
1025
1009
  }
1026
- //#endregion
1027
- //#region src/internal/core/call-promise.ts
1010
+ // src/internal/core/call-promise.ts
1028
1011
  function awaitedResult(client, options, result) {
1029
1012
  if ((options.errors ?? client.setup.defaults.errors) === "return") return result;
1030
1013
  if (result.ok === false) throw result.error;
@@ -1115,16 +1098,266 @@ var RestCallPromise = class extends CallPromise {
1115
1098
  function callPromise(client, callable, options = {}) {
1116
1099
  return new RestCallPromise(client, callable, options);
1117
1100
  }
1118
- //#endregion
1119
- //#region src/internal/core/callable.ts
1101
+ // src/internal/core/callable.ts
1120
1102
  function callable(descriptor) {
1121
1103
  return {
1122
1104
  interaction: "unary",
1123
1105
  ...descriptor
1124
1106
  };
1125
1107
  }
1126
- //#endregion
1127
- //#region src/internal/core/params.ts
1108
+ // src/internal/core/page.ts
1109
+ function readPath(value, path) {
1110
+ if (!path) return value;
1111
+ let current = value;
1112
+ for (const key of path.split(".")) {
1113
+ if (current === null || typeof current !== "object") return void 0;
1114
+ current = current[key];
1115
+ }
1116
+ return current;
1117
+ }
1118
+ function readItems(data, pagination) {
1119
+ const items = readPath(data, pagination.items);
1120
+ return Array.isArray(items) ? items : [];
1121
+ }
1122
+ function withPosition(options, pagination, value) {
1123
+ const name = pagination.param;
1124
+ if (!name) return options;
1125
+ if ((pagination.in ?? "query") === "body") return {
1126
+ ...options,
1127
+ body: {
1128
+ ...options.body,
1129
+ [name]: value
1130
+ }
1131
+ };
1132
+ return {
1133
+ ...options,
1134
+ query: {
1135
+ ...options.query,
1136
+ [name]: value
1137
+ }
1138
+ };
1139
+ }
1140
+ function resumeAt(walk, pagination, param) {
1141
+ if (pagination.style === "link") {
1142
+ const options = { ...walk.options };
1143
+ delete options.query;
1144
+ return {
1145
+ ...walk,
1146
+ descriptor: {
1147
+ ...walk.descriptor,
1148
+ address: param
1149
+ },
1150
+ options
1151
+ };
1152
+ }
1153
+ const options = withPosition(walk.options, pagination, param);
1154
+ if (pagination.style === "cursor") return {
1155
+ ...walk,
1156
+ cursor: param,
1157
+ options
1158
+ };
1159
+ return {
1160
+ ...walk,
1161
+ options,
1162
+ position: param
1163
+ };
1164
+ }
1165
+ function readCount(data, path) {
1166
+ if (!path) return void 0;
1167
+ const value = readPath(data, path);
1168
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
1169
+ return value;
1170
+ }
1171
+ function startOf(pagination) {
1172
+ return pagination.start ?? (pagination.style === "page" ? 1 : 0);
1173
+ }
1174
+ function stepCounted(walk, pagination, result, count, limit) {
1175
+ if (!count) return void 0;
1176
+ const size = readCount(result.data, pagination.size) ?? limit;
1177
+ const position = walk.position + (pagination.style === "page" ? 1 : size || count);
1178
+ const start = startOf(pagination);
1179
+ const pages = pagination.style === "page" ? readCount(result.data, pagination.pages) : void 0;
1180
+ const total = readCount(result.data, pagination.total);
1181
+ if (pages === void 0 && total === void 0 && size !== void 0 && count < size) return;
1182
+ if (pages !== void 0 && position - start >= pages) return void 0;
1183
+ if (total !== void 0) {
1184
+ if ((pagination.style === "page" ? (position - start) * (size ?? count) : position) >= total) return void 0;
1185
+ }
1186
+ return position;
1187
+ }
1188
+ const STEPPERS = { page: stepCounted };
1189
+ const SCHEME_RE = /^[a-z][a-z\d+.-]*:/i;
1190
+ function pageURL(address) {
1191
+ if (typeof address !== "string") return void 0;
1192
+ try {
1193
+ const url = new URL(address, globalThis.location?.href);
1194
+ return url.origin === "null" ? void 0 : url;
1195
+ } catch {
1196
+ return;
1197
+ }
1198
+ }
1199
+ function followLink(client, walk, link) {
1200
+ const own = pageURL(client.resolveAddress(walk.descriptor, walk.options));
1201
+ if (!own) {
1202
+ if (!SCHEME_RE.test(link) && !link.startsWith("//")) return link;
1203
+ throw new ElmoError("Pagination stopped: the next page names a host, and no base URL says which host this client sends its credentials to.");
1204
+ }
1205
+ const target = new URL(link, own);
1206
+ 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}.`);
1207
+ return SCHEME_RE.test(link) ? link : target.href;
1208
+ }
1209
+ function saysMore(data, pagination) {
1210
+ return !pagination.more || readPath(data, pagination.more) !== false;
1211
+ }
1212
+ function stepWalk(client, walk, pagination, result, count, limit) {
1213
+ const step = STEPPERS[pagination.style];
1214
+ if (!step) throw new ElmoError(`Cannot walk "${walk.descriptor.address}": this client does not page by "${pagination.style}".`);
1215
+ if (!saysMore(result.data, pagination)) return void 0;
1216
+ const next = step(walk, pagination, result, count, limit);
1217
+ return pagination.style === "link" && next !== void 0 ? followLink(client, walk, next) : next;
1218
+ }
1219
+ async function* walkFrom(page, maxPages) {
1220
+ let current = page;
1221
+ for (let index = 1;; index++) {
1222
+ for (const item of current.data) yield item;
1223
+ if (index >= maxPages || !current.hasNextPage()) return;
1224
+ current = await current.getNextPage();
1225
+ }
1226
+ }
1227
+ async function loadPage(client, walk, pagination, limit, maxPages) {
1228
+ const result = await client.call(walk.descriptor, walk.options);
1229
+ if (result.error !== void 0) throw result.error;
1230
+ const data = readItems(result.data, pagination);
1231
+ const param = stepWalk(client, walk, pagination, result, data.length, limit);
1232
+ const page = {
1233
+ [Symbol.asyncIterator]: () => walkFrom(page, maxPages),
1234
+ body: result.data,
1235
+ data,
1236
+ getNextPage: () => {
1237
+ if (param === void 0) return Promise.reject(new ElmoError(`"${walk.descriptor.address}" has no page after this one. Check \`hasNextPage()\` first.`));
1238
+ return loadPage(client, resumeAt(walk, pagination, param), pagination, limit, maxPages);
1239
+ },
1240
+ hasNextPage: () => param !== void 0,
1241
+ nextPageParam: param,
1242
+ status: result.status
1243
+ };
1244
+ return page;
1245
+ }
1246
+ function maxPagesFor(client, options) {
1247
+ return options["maxPages"] ?? client.setup.defaults["maxPages"] ?? 1e3;
1248
+ }
1249
+ function openedAt(options, pagination) {
1250
+ if (!pagination.param) return void 0;
1251
+ return options[pagination.in ?? "query"]?.[pagination.param];
1252
+ }
1253
+ function paginationOf(callable) {
1254
+ if (callable.pagination) return callable.pagination;
1255
+ throw new ElmoError(`"${callable.address}" is not a paged call, so it has no pages to walk.`);
1256
+ }
1257
+ function openWalk(callable, options) {
1258
+ const pagination = paginationOf(callable);
1259
+ const opened = openedAt(options, pagination);
1260
+ return {
1261
+ cursor: pagination.style === "cursor" ? opened : void 0,
1262
+ descriptor: callable,
1263
+ options: {
1264
+ ...options,
1265
+ raw: true
1266
+ },
1267
+ position: typeof opened === "number" && Number.isFinite(opened) ? opened : startOf(pagination)
1268
+ };
1269
+ }
1270
+ function pageStream(load, maxPages) {
1271
+ return { async *[Symbol.asyncIterator]() {
1272
+ let current = await load();
1273
+ for (let index = 1;; index++) {
1274
+ yield current;
1275
+ if (index >= maxPages || !current.hasNextPage()) return;
1276
+ current = await current.getNextPage();
1277
+ }
1278
+ } };
1279
+ }
1280
+ function requestedLimit(options, pagination) {
1281
+ if (!pagination.limitParam) return void 0;
1282
+ const layer = options[pagination.in ?? "query"];
1283
+ const limit = Number(layer?.[pagination.limitParam]);
1284
+ return Number.isFinite(limit) && limit > 0 ? limit : void 0;
1285
+ }
1286
+ /**
1287
+ * A paginated call. Awaiting it gives the first page, or its result envelope
1288
+ * under the `'return'` error mode. Iterating it gives every item on every page,
1289
+ * and throws on a failed page under either mode.
1290
+ */
1291
+ var PagePromise = class extends LazyPromise {
1292
+ envelope;
1293
+ callable;
1294
+ client;
1295
+ limit;
1296
+ maxPages;
1297
+ options;
1298
+ pagination;
1299
+ project;
1300
+ first;
1301
+ constructor(client, callable, options, project) {
1302
+ super();
1303
+ this.callable = callable;
1304
+ this.client = client;
1305
+ this.options = options;
1306
+ this.pagination = paginationOf(callable);
1307
+ this.limit = requestedLimit(options, this.pagination);
1308
+ this.maxPages = maxPagesFor(client, options);
1309
+ this.project = project;
1310
+ const opened = openWalk(this.callable, this.options);
1311
+ const param = options["pageParam"];
1312
+ this.first = unattended(loadPage(this.client, param === void 0 ? opened : resumeAt(opened, this.pagination, param), this.pagination, this.limit, this.maxPages));
1313
+ }
1314
+ /** Every item, page after page, up to `maxPages`. */
1315
+ async *[Symbol.asyncIterator]() {
1316
+ yield* walkFrom(await this.first, this.maxPages);
1317
+ }
1318
+ /** Every page, up to `maxPages`. */
1319
+ iterPages() {
1320
+ return pageStream(() => this.first, this.maxPages);
1321
+ }
1322
+ /**
1323
+ * The whole result envelope. A failure of the call is returned on it, not
1324
+ * thrown. What one of your own functions throws, such as a hook, is thrown
1325
+ * as it is.
1326
+ */
1327
+ result() {
1328
+ return this.envelope ??= this.read();
1329
+ }
1330
+ /** The page alone, with a failure thrown rather than handed back. */
1331
+ async unwrap() {
1332
+ const result = await this.result();
1333
+ if (result.ok === false) throw result.error;
1334
+ return result.data;
1335
+ }
1336
+ async read() {
1337
+ try {
1338
+ const page = await this.first;
1339
+ return {
1340
+ data: this.project(page),
1341
+ ok: true,
1342
+ status: page.status
1343
+ };
1344
+ } catch (error) {
1345
+ if (!(error instanceof ElmoError)) throw error;
1346
+ return {
1347
+ error,
1348
+ ok: false,
1349
+ status: error instanceof APIError ? error.status : void 0
1350
+ };
1351
+ }
1352
+ }
1353
+ settle() {
1354
+ return this.result().then((result) => awaitedResult(this.client, this.options, result));
1355
+ }
1356
+ };
1357
+ function pages(client, callable, options = {}) {
1358
+ return new PagePromise(client, callable, options, (page) => page);
1359
+ }
1360
+ // src/internal/core/params.ts
1128
1361
  const LAYERS = ["path", "query"];
1129
1362
  function mergeParams(inputs, options) {
1130
1363
  const merged = {
@@ -1190,8 +1423,7 @@ function groupParams(options, layer) {
1190
1423
  if (!options || !Object.keys(options).length) return {};
1191
1424
  return { [layer]: { ...options } };
1192
1425
  }
1193
- //#endregion
1194
- //#region src/resources/analytics.ts
1426
+ // src/resources/analytics.ts
1195
1427
  const getBrandAnalyticsFields = { path: ["brandId"] };
1196
1428
  function reviveDateRange(value) {
1197
1429
  if (value.start != null) value.start = decoded("DateRange.start", value.start, (raw) => new Date(raw));
@@ -1215,6 +1447,15 @@ const listBrandCitationDomainsDescriptor = /* @__PURE__ */ callable({
1215
1447
  address: "/brands/{brandId}/citations/domains",
1216
1448
  auth: apiKeyRequirements,
1217
1449
  method: "get",
1450
+ pagination: {
1451
+ items: "data",
1452
+ limitParam: "limit",
1453
+ pages: "pagination.totalPages",
1454
+ param: "page",
1455
+ size: "pagination.limit",
1456
+ style: "page",
1457
+ total: "pagination.total"
1458
+ },
1218
1459
  returns: "json",
1219
1460
  validators: { response: /* @__PURE__ */ reviving(reviveCitationDomainList) }
1220
1461
  });
@@ -1226,6 +1467,15 @@ const listBrandCitationURLsDescriptor = /* @__PURE__ */ callable({
1226
1467
  address: "/brands/{brandId}/citations/urls",
1227
1468
  auth: apiKeyRequirements,
1228
1469
  method: "get",
1470
+ pagination: {
1471
+ items: "data",
1472
+ limitParam: "limit",
1473
+ pages: "pagination.totalPages",
1474
+ param: "page",
1475
+ size: "pagination.limit",
1476
+ style: "page",
1477
+ total: "pagination.total"
1478
+ },
1229
1479
  returns: "json",
1230
1480
  validators: { response: /* @__PURE__ */ reviving(reviveCitationUrlList) }
1231
1481
  });
@@ -1255,6 +1505,15 @@ const getBrandQueryFanoutDescriptor = /* @__PURE__ */ callable({
1255
1505
  address: "/brands/{brandId}/query-fanout",
1256
1506
  auth: apiKeyRequirements,
1257
1507
  method: "get",
1508
+ pagination: {
1509
+ items: "data",
1510
+ limitParam: "limit",
1511
+ pages: "pagination.totalPages",
1512
+ param: "page",
1513
+ size: "pagination.limit",
1514
+ style: "page",
1515
+ total: "pagination.total"
1516
+ },
1258
1517
  returns: "json",
1259
1518
  validators: { response: /* @__PURE__ */ reviving(reviveBrandQueryFanout) }
1260
1519
  });
@@ -1284,12 +1543,10 @@ var Domains = class extends ElmoResource {
1284
1543
  * List cited domains
1285
1544
  *
1286
1545
  * Domains the engines cited when answering this brand's prompts, categorized and compared against
1287
- * the equal-length window immediately before this one.
1288
- *
1289
- * @param brandId Brand identifier.
1546
+ * the equal-length window immediately before this one.
1290
1547
  */
1291
1548
  list(brandId, params, options) {
1292
- return callPromise(options?.client ?? this.client, listBrandCitationDomainsDescriptor, mergeParams(placeParams({
1549
+ return pages(options?.client ?? this.client, listBrandCitationDomainsDescriptor, mergeParams(placeParams({
1293
1550
  ...params,
1294
1551
  brandId
1295
1552
  }, listBrandCitationDomainsFields, "query"), options));
@@ -1301,11 +1558,9 @@ var URLs = class extends ElmoResource {
1301
1558
  * List cited URLs
1302
1559
  *
1303
1560
  * Individual pages the engines cited, with their category and page type.
1304
- *
1305
- * @param brandId Brand identifier.
1306
1561
  */
1307
1562
  list(brandId, params, options) {
1308
- return callPromise(options?.client ?? this.client, listBrandCitationURLsDescriptor, mergeParams(placeParams({
1563
+ return pages(options?.client ?? this.client, listBrandCitationURLsDescriptor, mergeParams(placeParams({
1309
1564
  ...params,
1310
1565
  brandId
1311
1566
  }, listBrandCitationUrlsFields, "query"), options));
@@ -1350,18 +1605,15 @@ var QueryFanout = class extends ElmoResource {
1350
1605
  *
1351
1606
  * The searches engines ran while answering this brand's prompts. Engines that don't expose their
1352
1607
  * searches still contribute runs, so `coverageRate` is the honest denominator.
1353
- *
1354
- * @param brandId Brand identifier.
1355
1608
  */
1356
1609
  get(brandId, params, options) {
1357
- return callPromise(options?.client ?? this.client, getBrandQueryFanoutDescriptor, mergeParams(placeParams({
1610
+ return pages(options?.client ?? this.client, getBrandQueryFanoutDescriptor, mergeParams(placeParams({
1358
1611
  ...params,
1359
1612
  brandId
1360
1613
  }, getBrandQueryFanoutFields, "query"), options));
1361
1614
  }
1362
1615
  };
1363
- //#endregion
1364
- //#region src/resources/opportunities.ts
1616
+ // src/resources/opportunities.ts
1365
1617
  const getBrandOpportunitiesFields = { path: ["brandId"] };
1366
1618
  function reviveBrandOpportunities(value) {
1367
1619
  if (value.generatedAt != null) value.generatedAt = decoded("BrandOpportunities.generatedAt", value.generatedAt, (raw) => new Date(raw));
@@ -1398,8 +1650,7 @@ var Opportunities = class extends ElmoResource {
1398
1650
  return callPromise(options?.client ?? this.client, getBrandOpportunitiesDescriptor, mergeParams(placeParams({ brandId }, getBrandOpportunitiesFields, "query"), options));
1399
1651
  }
1400
1652
  };
1401
- //#endregion
1402
- //#region src/resources/shared/rule.ts
1653
+ // src/resources/shared/rule.ts
1403
1654
  const nameRule = {
1404
1655
  min: 1,
1405
1656
  name: "name",
@@ -1420,8 +1671,7 @@ const valueRule = {
1420
1671
  name: "value",
1421
1672
  of: "characters"
1422
1673
  };
1423
- //#endregion
1424
- //#region src/resources/tags.ts
1674
+ // src/resources/tags.ts
1425
1675
  const listBrandTagsFields = { path: ["brandId"] };
1426
1676
  const listBrandTagsDescriptor = /* @__PURE__ */ callable({
1427
1677
  address: "/brands/{brandId}/tags",
@@ -1446,261 +1696,7 @@ var Tags = class extends ElmoResource {
1446
1696
  return callPromise(options?.client ?? this.client, listBrandTagsDescriptor, mergeParams(placeParams({ brandId }, listBrandTagsFields, "query"), options));
1447
1697
  }
1448
1698
  };
1449
- //#endregion
1450
- //#region src/internal/core/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
1699
+ // src/resources/brands.ts
1704
1700
  function reviveBrand(value) {
1705
1701
  if (value.createdAt != null) value.createdAt = decoded("Brand.createdAt", value.createdAt, (raw) => new Date(raw));
1706
1702
  if (value.updatedAt != null) value.updatedAt = decoded("Brand.updatedAt", value.updatedAt, (raw) => new Date(raw));
@@ -1822,8 +1818,7 @@ var Brands = class extends ElmoResource {
1822
1818
  return this._tags ??= new Tags(this.client);
1823
1819
  }
1824
1820
  };
1825
- //#endregion
1826
- //#region src/resources/competitors.ts
1821
+ // src/resources/competitors.ts
1827
1822
  function reviveCompetitor(value) {
1828
1823
  if (value.createdAt != null) value.createdAt = decoded("Competitor.createdAt", value.createdAt, (raw) => new Date(raw));
1829
1824
  if (value.updatedAt != null) value.updatedAt = decoded("Competitor.updatedAt", value.updatedAt, (raw) => new Date(raw));
@@ -1928,8 +1923,7 @@ var Competitors = class extends ElmoResource {
1928
1923
  }, updateCompetitorFields, "body"), options));
1929
1924
  }
1930
1925
  };
1931
- //#endregion
1932
- //#region src/resources/identity.ts
1926
+ // src/resources/identity.ts
1933
1927
  function reviveApiKeyIdentity(value) {
1934
1928
  if (value.createdAt != null) value.createdAt = decoded("ApiKeyIdentity.createdAt", value.createdAt, (raw) => new Date(raw));
1935
1929
  if (value.expiresAt != null) value.expiresAt = decoded("ApiKeyIdentity.expiresAt", value.expiresAt, (raw) => new Date(raw));
@@ -1954,8 +1948,7 @@ var Me = class extends ElmoResource {
1954
1948
  return callPromise(options?.client ?? this.client, getMeDescriptor, options);
1955
1949
  }
1956
1950
  };
1957
- //#endregion
1958
- //#region src/resources/models.ts
1951
+ // src/resources/models.ts
1959
1952
  const listModelsDescriptor = /* @__PURE__ */ callable({
1960
1953
  address: "/models",
1961
1954
  auth: apiKeyRequirements,
@@ -1976,8 +1969,7 @@ var Models = class extends ElmoResource {
1976
1969
  return callPromise(options?.client ?? this.client, listModelsDescriptor, options);
1977
1970
  }
1978
1971
  };
1979
- //#endregion
1980
- //#region src/resources/organizations.ts
1972
+ // src/resources/organizations.ts
1981
1973
  const getOrganizationBillingFields = { path: ["organizationId"] };
1982
1974
  function reviveBillingPlan(value) {
1983
1975
  if (value.periodEnd != null) value.periodEnd = decoded("BillingPlan.periodEnd", value.periodEnd, (raw) => new Date(raw));
@@ -2067,8 +2059,7 @@ var Organizations = class extends ElmoResource {
2067
2059
  return this._billing ??= new Billing(this.client);
2068
2060
  }
2069
2061
  };
2070
- //#endregion
2071
- //#region src/resources/runs.ts
2062
+ // src/resources/runs.ts
2072
2063
  const listPromptRunsFields = { path: ["promptId"] };
2073
2064
  function reviveRunSummary(value) {
2074
2065
  if (value.createdAt != null) value.createdAt = decoded("RunSummary.createdAt", value.createdAt, (raw) => new Date(raw));
@@ -2134,8 +2125,7 @@ var Runs = class extends ElmoResource {
2134
2125
  }, listPromptRunsFields, "query"), options));
2135
2126
  }
2136
2127
  };
2137
- //#endregion
2138
- //#region src/resources/snapshots.ts
2128
+ // src/resources/snapshots.ts
2139
2129
  const getPromptSnapshotFields = { path: ["promptId"] };
2140
2130
  const getPromptSnapshotDescriptor = /* @__PURE__ */ callable({
2141
2131
  address: "/prompts/{promptId}/snapshot",
@@ -2159,8 +2149,7 @@ var Snapshot = class extends ElmoResource {
2159
2149
  }, getPromptSnapshotFields, "query"), options));
2160
2150
  }
2161
2151
  };
2162
- //#endregion
2163
- //#region src/resources/prompts.ts
2152
+ // src/resources/prompts.ts
2164
2153
  function revivePrompt(value) {
2165
2154
  if (value.createdAt != null) value.createdAt = decoded("Prompt.createdAt", value.createdAt, (raw) => new Date(raw));
2166
2155
  if (value.updatedAt != null) value.updatedAt = decoded("Prompt.updatedAt", value.updatedAt, (raw) => new Date(raw));
@@ -2300,8 +2289,7 @@ var Prompts = class extends ElmoResource {
2300
2289
  return this._snapshot ??= new Snapshot(this.client);
2301
2290
  }
2302
2291
  };
2303
- //#endregion
2304
- //#region src/resources/reports.ts
2292
+ // src/resources/reports.ts
2305
2293
  function reviveReportSummary(value) {
2306
2294
  if (value.createdAt != null) value.createdAt = decoded("ReportSummary.createdAt", value.createdAt, (raw) => new Date(raw));
2307
2295
  if (value.completedAt != null) value.completedAt = decoded("ReportSummary.completedAt", value.completedAt, (raw) => new Date(raw));
@@ -2412,8 +2400,7 @@ var Reports = class extends ElmoResource {
2412
2400
  return pages(options?.client ?? this.client, listReportsDescriptor, mergeParams(groupParams(params, "query"), options));
2413
2401
  }
2414
2402
  };
2415
- //#endregion
2416
- //#region src/resources/tools.ts
2403
+ // src/resources/tools.ts
2417
2404
  const analyzeBrandDescriptor = /* @__PURE__ */ callable({
2418
2405
  address: "/tools/analyze",
2419
2406
  auth: apiKeyRequirements,
@@ -2453,7 +2440,6 @@ var Tools = class extends ElmoResource {
2453
2440
  return callPromise(options?.client ?? this.client, analyzeBrandDescriptor, mergeParams(groupParams(params, "body"), options));
2454
2441
  }
2455
2442
  };
2456
- //#endregion
2457
- 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 };
2443
+ export { getBrandAnalyticsDescriptor 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, getBrandOpportunitiesFields 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, listBrandTagsFields as X, exceedsMaxRetryAfter as Xt, listBrandTagsDescriptor as Y, backoffDelay as Yt, getBrandOpportunitiesDescriptor as Z, retryAfterDelay as Zt, getPromptSnapshotDescriptor as _, createClient as _t, getReportDescriptor as a, listBrandCitationURLsDescriptor as at, getRunFields as b, replyWith as bt, Prompts as c, listBrandPromptPerformanceFields as ct, deletePromptFields as d, placeParams as dt, getBrandAnalyticsFields as et, getPromptDescriptor as f, pages as ft, updatePromptFields as g, clientFor as gt, updatePromptDescriptor as h, validateFeature as ht, createReportDescriptor as i, listBrandCitationDomainsFields as it, Me as j, APIError as jt, Models as k, readText as kt, createPromptDescriptor as l, groupParams as lt, listPromptsDescriptor as m, ElmoResource as mt, analyzeBrandDescriptor as n, getBrandQueryFanoutFields as nt, getReportFields as o, listBrandCitationUrlsFields as ot, getPromptFields as p, callPromise as pt, updateBrandDescriptor as q, unsendableAddress as qt, Reports as r, listBrandCitationDomainsDescriptor as rt, listReportsDescriptor as s, listBrandPromptPerformanceDescriptor as st, Tools as t, getBrandQueryFanoutDescriptor as tt, deletePromptDescriptor as u, mergeParams 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 };
2458
2444
 
2459
- //# sourceMappingURL=tools-B1lVtYAr.mjs.map
2445
+ //# sourceMappingURL=tools-B2xqLDiH.mjs.map