node-autotask 0.15.0 → 0.17.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.
Files changed (38) hide show
  1. package/ARCHITECTURE.md +8 -0
  2. package/N8N_MCP_MANIFEST.json +2 -2
  3. package/N8N_MCP_MANIFEST.md +3 -3
  4. package/README.md +40 -2
  5. package/capabilities.json +4 -4
  6. package/dist/capabilities.cjs +2 -2
  7. package/dist/capabilities.js +1 -1
  8. package/dist/{chunk-Z7YT72SS.cjs → chunk-4RJG73GY.cjs} +164 -81
  9. package/dist/{chunk-EWMG3HHU.cjs → chunk-5ZGXWS4E.cjs} +3 -3
  10. package/dist/{chunk-JIDR3NPV.js → chunk-6SP6GJJR.js} +3 -3
  11. package/dist/{chunk-V7QPZA7L.cjs → chunk-DQIZUZWP.cjs} +135 -135
  12. package/dist/{chunk-AXVYQPTB.js → chunk-EGR2ZLYM.js} +49 -39
  13. package/dist/{chunk-CSA6QSV6.js → chunk-HC6YWPIY.js} +104 -21
  14. package/dist/{chunk-VLIUHEPE.cjs → chunk-NQVD2XLH.cjs} +429 -419
  15. package/dist/{chunk-LH5BXQ7A.js → chunk-UV2PECAL.js} +2 -2
  16. package/dist/{index-M0qJIiRt.d.ts → index-BAFdPxjG.d.ts} +88 -7
  17. package/dist/{index-BXIwhAN4.d.cts → index-CjC0oWZX.d.cts} +88 -7
  18. package/dist/index.cjs +26 -22
  19. package/dist/index.d.cts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +8 -4
  22. package/dist/operations/index.cjs +103 -103
  23. package/dist/operations/index.d.cts +12 -6
  24. package/dist/operations/index.d.ts +12 -6
  25. package/dist/operations/index.js +2 -2
  26. package/dist/pool.cjs +8 -8
  27. package/dist/pool.d.cts +1 -1
  28. package/dist/pool.d.ts +1 -1
  29. package/dist/pool.js +4 -4
  30. package/dist/resources/index.cjs +4 -4
  31. package/dist/resources/index.d.cts +1 -1
  32. package/dist/resources/index.d.ts +1 -1
  33. package/dist/resources/index.js +3 -3
  34. package/docs/API.md +55 -9
  35. package/examples/basic.ts +2 -2
  36. package/examples/mcp-server-http.ts +5 -4
  37. package/examples/mcp-server.ts +3 -3
  38. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6;
2
2
 
3
- var _chunkEWMG3HHUcjs = require('./chunk-EWMG3HHU.cjs');
3
+ var _chunk5ZGXWS4Ecjs = require('./chunk-5ZGXWS4E.cjs');
4
4
 
5
5
  // src/auth.ts
6
6
  var AUTH_HEADERS = {
@@ -171,6 +171,7 @@ var AutotaskError = class extends Error {
171
171
 
172
172
 
173
173
 
174
+ /** Legacy unlabeled id list (issue #116) — see `AutotaskErrorOptions.resourceIds`; the labeled companion rides on `details.idRefs`. */
174
175
 
175
176
 
176
177
 
@@ -1532,6 +1533,8 @@ var DEFAULT_PAGE_SIZE = 10;
1532
1533
  var MAX_PAGE_SIZE = 500;
1533
1534
  var DEFAULT_TIMEOUT_MS = 3e4;
1534
1535
  var DEFAULT_MAX_RETRIES = 3;
1536
+ var DEFAULT_MAINTENANCE_MAX_WAIT_MS = 36e5;
1537
+ var DEFAULT_MAINTENANCE_POLL_MS = 3e4;
1535
1538
  var DEFAULT_MAX_CONCURRENT = 10;
1536
1539
  var DEFAULT_MAX_RESPONSE_BYTES = 64 * 1024 * 1024;
1537
1540
  var DEFAULT_MAX_SCAN_RECORDS = 500;
@@ -1689,6 +1692,14 @@ function resolveConfig(config) {
1689
1692
  if (!Number.isInteger(maxRetries) || maxRetries < 0) {
1690
1693
  throw new AutotaskConfigError("maxRetries must be a non-negative integer");
1691
1694
  }
1695
+ const maintenanceMaxWaitMs = _nullishCoalesce(config.maintenanceMaxWaitMs, () => ( DEFAULT_MAINTENANCE_MAX_WAIT_MS));
1696
+ if (!Number.isInteger(maintenanceMaxWaitMs) || maintenanceMaxWaitMs < 0) {
1697
+ throw new AutotaskConfigError("maintenanceMaxWaitMs must be a non-negative integer");
1698
+ }
1699
+ const maintenancePollMs = _nullishCoalesce(config.maintenancePollMs, () => ( DEFAULT_MAINTENANCE_POLL_MS));
1700
+ if (!Number.isInteger(maintenancePollMs) || maintenancePollMs <= 0) {
1701
+ throw new AutotaskConfigError("maintenancePollMs must be a positive integer");
1702
+ }
1692
1703
  const maxConcurrent = _nullishCoalesce(config.maxConcurrent, () => ( (agent ? AGENT_PROFILE.maxConcurrent : DEFAULT_MAX_CONCURRENT)));
1693
1704
  if (!Number.isInteger(maxConcurrent) || maxConcurrent <= 0) {
1694
1705
  throw new AutotaskConfigError("maxConcurrent must be a positive integer");
@@ -1822,6 +1833,8 @@ function resolveConfig(config) {
1822
1833
  pageSize: pageSizeCapped,
1823
1834
  timeoutMs,
1824
1835
  maxRetries,
1836
+ maintenanceMaxWaitMs,
1837
+ maintenancePollMs,
1825
1838
  maxConcurrent,
1826
1839
  maxResponseBytes,
1827
1840
  logger,
@@ -14755,6 +14768,10 @@ function backoffDelay(attempt) {
14755
14768
  const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
14756
14769
  return Math.floor(exp / 2 + Math.random() * (exp / 2));
14757
14770
  }
14771
+ function isMaintenancePage(err) {
14772
+ const snippet = typeof _optionalChain([err, 'access', _57 => _57.details, 'optionalAccess', _58 => _58.bodySnippet]) === "string" ? err.details.bodySnippet : "";
14773
+ return /maintenance|temporarily unavailable|service unavailable|outage|downtime|down for/i.test(snippet);
14774
+ }
14758
14775
  function parseRetryAfter(value) {
14759
14776
  if (value === null || value.length === 0) return void 0;
14760
14777
  const trimmed = value.trim();
@@ -14771,7 +14788,7 @@ function isAbortLike(err) {
14771
14788
  return typeof err === "object" && err !== null && "name" in err && err.name === "AbortError";
14772
14789
  }
14773
14790
  function isJsonMediaType(header) {
14774
- const mediaType = _nullishCoalesce(_optionalChain([header, 'access', _57 => _57.split, 'call', _58 => _58(";"), 'access', _59 => _59[0], 'optionalAccess', _60 => _60.trim, 'call', _61 => _61(), 'access', _62 => _62.toLowerCase, 'call', _63 => _63()]), () => ( ""));
14791
+ const mediaType = _nullishCoalesce(_optionalChain([header, 'access', _59 => _59.split, 'call', _60 => _60(";"), 'access', _61 => _61[0], 'optionalAccess', _62 => _62.trim, 'call', _63 => _63(), 'access', _64 => _64.toLowerCase, 'call', _65 => _65()]), () => ( ""));
14775
14792
  return mediaType.startsWith("application/json") || mediaType.endsWith("+json");
14776
14793
  }
14777
14794
  function bodySnippet(text, redactPersonalData) {
@@ -14851,6 +14868,9 @@ var HttpClient = (_class6 = class {
14851
14868
 
14852
14869
 
14853
14870
 
14871
+ /** Maintenance-window auto-retry budget + poll (issue #112 follow-up; see config). */
14872
+
14873
+
14854
14874
 
14855
14875
 
14856
14876
  /** The resolved profile (issue #4) — the agent profile changes the
@@ -14921,8 +14941,10 @@ var HttpClient = (_class6 = class {
14921
14941
  impersonationResourceId: config.impersonationResourceId
14922
14942
  };
14923
14943
  this.maxRetries = config.maxRetries;
14944
+ this.maintenanceMaxWaitMs = config.maintenanceMaxWaitMs;
14945
+ this.maintenancePollMs = config.maintenancePollMs;
14924
14946
  this.maxResponseBytes = config.maxResponseBytes;
14925
- this.perHour = _optionalChain([config, 'access', _64 => _64.rateLimit, 'optionalAccess', _65 => _65.perHour]);
14947
+ this.perHour = _optionalChain([config, 'access', _66 => _66.rateLimit, 'optionalAccess', _67 => _67.perHour]);
14926
14948
  this.tenantKey = buildTenantKey(config.userName, config.baseUrl);
14927
14949
  this.cooldownStore = config.cooldown.enabled ? _nullishCoalesce(config.cooldown.store, () => ( defaultCooldownStore())) : void 0;
14928
14950
  this.cooldownMaxMs = config.cooldown.maxMs;
@@ -14983,7 +15005,7 @@ var HttpClient = (_class6 = class {
14983
15005
  };
14984
15006
  if (next.successes >= breaker.successesToClose) {
14985
15007
  breaker.store.delete(key);
14986
- _optionalChain([this, 'access', _66 => _66.logger, 'access', _67 => _67.warn, 'optionalCall', _68 => _68(
15008
+ _optionalChain([this, 'access', _68 => _68.logger, 'access', _69 => _69.warn, 'optionalCall', _70 => _70(
14987
15009
  `[autotask] circuit breaker CLOSED for ${key} (${next.successes} probe successes)`,
14988
15010
  void 0
14989
15011
  )]);
@@ -15013,7 +15035,7 @@ var HttpClient = (_class6 = class {
15013
15035
  const failures = [...st.failures.filter((t) => t > now - breaker.failureWindowMs), now];
15014
15036
  if (failures.length >= breaker.failureThreshold) {
15015
15037
  breaker.store.set(key, { failures, openedAt: now, successes: 0, probes: 0 });
15016
- _optionalChain([this, 'access', _69 => _69.logger, 'access', _70 => _70.warn, 'optionalCall', _71 => _71(
15038
+ _optionalChain([this, 'access', _71 => _71.logger, 'access', _72 => _72.warn, 'optionalCall', _73 => _73(
15017
15039
  `[autotask] circuit breaker OPEN for ${key} (${failures.length} counted failures in ${Math.round(breaker.failureWindowMs / 1e3)}s) \u2014 refusing locally for ${Math.round(breaker.openTimeoutMs / 1e3)}s`,
15018
15040
  correlationId
15019
15041
  )]);
@@ -15128,7 +15150,7 @@ var HttpClient = (_class6 = class {
15128
15150
  return void 0;
15129
15151
  }
15130
15152
  if (res.status < 200 || res.status >= 300) {
15131
- await _optionalChain([res, 'access', _72 => _72.body, 'optionalAccess', _73 => _73.cancel, 'call', _74 => _74(), 'access', _75 => _75.catch, 'call', _76 => _76(() => void 0)]);
15153
+ await _optionalChain([res, 'access', _74 => _74.body, 'optionalAccess', _75 => _75.cancel, 'call', _76 => _76(), 'access', _77 => _77.catch, 'call', _78 => _78(() => void 0)]);
15132
15154
  return void 0;
15133
15155
  }
15134
15156
  let text;
@@ -15164,7 +15186,7 @@ var HttpClient = (_class6 = class {
15164
15186
  this.liveBaseUrl = to;
15165
15187
  this.tenantKey = buildTenantKey(this.auth.userName, to);
15166
15188
  this.breakerKey = buildBreakerKey(to);
15167
- _optionalChain([this, 'access', _77 => _77.logger, 'access', _78 => _78.warn, 'optionalCall', _79 => _79(
15189
+ _optionalChain([this, 'access', _79 => _79.logger, 'access', _80 => _80.warn, 'optionalCall', _81 => _81(
15168
15190
  `[autotask] zone re-point ${from} -> ${to} (a 401 on the stale zone base; the vendor's unauthenticated zone discovery named the tenant's current zone) \u2014 retrying the request once against the new base`,
15169
15191
  void 0
15170
15192
  )]);
@@ -15180,11 +15202,21 @@ var HttpClient = (_class6 = class {
15180
15202
  const correlationId = newCorrelationId();
15181
15203
  const timeoutMs = _nullishCoalesce(opts.timeoutMs, () => ( this.timeoutMs));
15182
15204
  const maxRetries = _nullishCoalesce(opts.maxRetries, () => ( this.maxRetries));
15205
+ const maintenanceMaxWaitMs = _nullishCoalesce(opts.maintenanceMaxWaitMs, () => ( this.maintenanceMaxWaitMs));
15206
+ const maintenancePollMs = _nullishCoalesce(opts.maintenancePollMs, () => ( this.maintenancePollMs));
15207
+ let firstMaintenanceAt;
15208
+ let maintenanceWaits = 0;
15183
15209
  const started = Date.now();
15184
- const deadlineAt = started + timeoutMs;
15210
+ let deadlineAt = started + timeoutMs;
15185
15211
  const callerSignal = _nullishCoalesce(opts.signal, () => ( ambientSignal.getStore()));
15212
+ const deadline = new AbortController();
15213
+ let deadlineTimer = setTimeout(() => deadline.abort(), timeoutMs);
15214
+ const armDeadline = (ms) => {
15215
+ clearTimeout(deadlineTimer);
15216
+ deadlineTimer = setTimeout(() => deadline.abort(), Math.max(0, ms));
15217
+ };
15186
15218
  const signal = AbortSignal.any(
15187
- callerSignal === void 0 ? [AbortSignal.timeout(timeoutMs)] : [AbortSignal.timeout(timeoutMs), callerSignal]
15219
+ callerSignal === void 0 ? [deadline.signal] : [deadline.signal, callerSignal]
15188
15220
  );
15189
15221
  const auditBody = opts.body !== void 0 ? redactAuditBody(opts.body) : void 0;
15190
15222
  const retriable = _nullishCoalesce(opts.idempotent, () => ( IDEMPOTENT_METHODS.includes(method)));
@@ -15192,7 +15224,7 @@ var HttpClient = (_class6 = class {
15192
15224
  const expectBody = _nullishCoalesce(opts.expectBody, () => ( method !== "DELETE"));
15193
15225
  const ctx = { operation: opts.operation, url, correlationId };
15194
15226
  let lastStatus;
15195
- const interrupted = () => _optionalChain([callerSignal, 'optionalAccess', _80 => _80.aborted]) ? new AutotaskAbortError(`Request aborted: ${method} ${opts.path}`, { ...ctx, suggestedAction: "The caller aborted; re-issue the call if still needed." }) : new AutotaskTimeoutError(`Request timed out after ${timeoutMs}ms: ${method} ${opts.path}`, ctx);
15227
+ const interrupted = () => _optionalChain([callerSignal, 'optionalAccess', _82 => _82.aborted]) ? new AutotaskAbortError(`Request aborted: ${method} ${opts.path}`, { ...ctx, suggestedAction: "The caller aborted; re-issue the call if still needed." }) : new AutotaskTimeoutError(`Request timed out after ${timeoutMs}ms: ${method} ${opts.path}`, ctx);
15196
15228
  const canWait = (delay) => delay <= MAX_RETRY_DELAY_MS && delay < deadlineAt - Date.now();
15197
15229
  const pause = async (delay) => {
15198
15230
  try {
@@ -15202,11 +15234,11 @@ var HttpClient = (_class6 = class {
15202
15234
  }
15203
15235
  };
15204
15236
  if (this.cooldownStore !== void 0 && !opts.bypassCooldown) {
15205
- const deadline = this.cooldownStore.get(this.tenantKey);
15206
- if (deadline !== void 0) {
15207
- const remainingMs = deadline - Date.now();
15237
+ const deadline2 = this.cooldownStore.get(this.tenantKey);
15238
+ if (deadline2 !== void 0) {
15239
+ const remainingMs = deadline2 - Date.now();
15208
15240
  if (remainingMs > 0) {
15209
- if (_optionalChain([callerSignal, 'optionalAccess', _81 => _81.aborted])) throw interrupted();
15241
+ if (_optionalChain([callerSignal, 'optionalAccess', _83 => _83.aborted])) throw interrupted();
15210
15242
  const seconds = Math.ceil(remainingMs / 1e3);
15211
15243
  const err = new RateLimitError(
15212
15244
  `Tenant is in a rate-limit cooldown; the call was NOT sent. ${seconds}s remain \u2014 do not retry before then, and narrow the query (filter/includeFields) before retrying.`,
@@ -15237,7 +15269,7 @@ var HttpClient = (_class6 = class {
15237
15269
  let breakerProbe = false;
15238
15270
  let breakerProbeKey;
15239
15271
  if (this.breaker !== void 0 && !opts.bypassCircuitBreaker) {
15240
- if (_optionalChain([callerSignal, 'optionalAccess', _82 => _82.aborted])) throw interrupted();
15272
+ if (_optionalChain([callerSignal, 'optionalAccess', _84 => _84.aborted])) throw interrupted();
15241
15273
  const now = Date.now();
15242
15274
  const st = this.breaker.store.get(this.breakerKey);
15243
15275
  if (st !== void 0 && st.openedAt !== null) {
@@ -15295,7 +15327,7 @@ var HttpClient = (_class6 = class {
15295
15327
  breakerProbeKey = this.breakerKey;
15296
15328
  }
15297
15329
  }
15298
- _optionalChain([this, 'access', _83 => _83.logger, 'access', _84 => _84.debug, 'optionalCall', _85 => _85(`[autotask] ${method} ${opts.path}`, correlationId)]);
15330
+ _optionalChain([this, 'access', _85 => _85.logger, 'access', _86 => _86.debug, 'optionalCall', _87 => _87(`[autotask] ${method} ${opts.path}`, correlationId)]);
15299
15331
  try {
15300
15332
  let attempt = 0;
15301
15333
  let outcome = null;
@@ -15315,7 +15347,7 @@ var HttpClient = (_class6 = class {
15315
15347
  if (signal.aborted || isAbortLike(err2)) throw interrupted();
15316
15348
  const delay = backoffDelay(attempt);
15317
15349
  if (attempt < maxRetries && retriable5xx && canWait(delay)) {
15318
- _optionalChain([this, 'access', _86 => _86.logger, 'access', _87 => _87.warn, 'optionalCall', _88 => _88(
15350
+ _optionalChain([this, 'access', _88 => _88.logger, 'access', _89 => _89.warn, 'optionalCall', _90 => _90(
15319
15351
  `[autotask] network error on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15320
15352
  correlationId
15321
15353
  )]);
@@ -15333,7 +15365,7 @@ var HttpClient = (_class6 = class {
15333
15365
  try {
15334
15366
  status = res.status;
15335
15367
  if (status >= 300 && status < 400) {
15336
- await _optionalChain([res, 'access', _89 => _89.body, 'optionalAccess', _90 => _90.cancel, 'call', _91 => _91(), 'access', _92 => _92.catch, 'call', _93 => _93(() => void 0)]);
15368
+ await _optionalChain([res, 'access', _91 => _91.body, 'optionalAccess', _92 => _92.cancel, 'call', _93 => _93(), 'access', _94 => _94.catch, 'call', _95 => _95(() => void 0)]);
15337
15369
  throw new ResponseRejectedError(
15338
15370
  `Refused to follow a ${status} redirect for ${method} ${opts.path}`,
15339
15371
  { ...ctx, code: "REDIRECT_BLOCKED", httpStatus: status, suggestedAction: "Check the configured zone/baseUrl; the API does not redirect." }
@@ -15394,11 +15426,28 @@ var HttpClient = (_class6 = class {
15394
15426
  httpStatus: status,
15395
15427
  suggestedAction: "The zone returned a non-JSON 2xx body; verify baseUrl points at the REST API."
15396
15428
  });
15429
+ if (err2.code === "UNEXPECTED_CONTENT_TYPE" && maintenanceMaxWaitMs > 0 && isMaintenancePage(err2)) {
15430
+ const now = Date.now();
15431
+ firstMaintenanceAt ??= now;
15432
+ const remaining = maintenanceMaxWaitMs - (now - firstMaintenanceAt);
15433
+ if (remaining > 0) {
15434
+ const wait = Math.min(maintenancePollMs, remaining);
15435
+ maintenanceWaits += 1;
15436
+ _optionalChain([this, 'access', _96 => _96.logger, 'access', _97 => _97.warn, 'optionalCall', _98 => _98(
15437
+ `[autotask] maintenance window on ${method} ${opts.path}; waiting ${Math.round(wait / 1e3)}s (retry ${maintenanceWaits}, up to ${Math.round(maintenanceMaxWaitMs / 6e4)} min)`,
15438
+ correlationId
15439
+ )]);
15440
+ deadlineAt = Date.now() + wait + timeoutMs;
15441
+ armDeadline(deadlineAt - Date.now());
15442
+ await pause(wait);
15443
+ continue;
15444
+ }
15445
+ }
15397
15446
  if (err2.code === "UNEXPECTED_CONTENT_TYPE" && retriable5xx && attempt < maxRetries) {
15398
15447
  const retryAfter = parseRetryAfter(res.headers.get("Retry-After"));
15399
15448
  const delay = retryAfter !== void 0 ? retryAfter * 1e3 : backoffDelay(attempt);
15400
15449
  if (canWait(delay)) {
15401
- _optionalChain([this, 'access', _94 => _94.logger, 'access', _95 => _95.warn, 'optionalCall', _96 => _96(
15450
+ _optionalChain([this, 'access', _99 => _99.logger, 'access', _100 => _100.warn, 'optionalCall', _101 => _101(
15402
15451
  `[autotask] non-JSON 2xx on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15403
15452
  correlationId
15404
15453
  )]);
@@ -15407,6 +15456,18 @@ var HttpClient = (_class6 = class {
15407
15456
  continue;
15408
15457
  }
15409
15458
  }
15459
+ if (maintenanceWaits > 0 && err2.code === "UNEXPECTED_CONTENT_TYPE") {
15460
+ err2.details = {
15461
+ ..._nullishCoalesce(err2.details, () => ( {})),
15462
+ maintenance: {
15463
+ waits: maintenanceWaits,
15464
+ waitedMs: Date.now() - (_nullishCoalesce(firstMaintenanceAt, () => ( Date.now()))),
15465
+ maxWaitMs: maintenanceMaxWaitMs,
15466
+ exhausted: true
15467
+ }
15468
+ };
15469
+ err2.suggestedAction = `The zone stayed in a maintenance window for ${Math.round(maintenanceMaxWaitMs / 6e4)} min \u2014 the SDK waited and retried ${maintenanceWaits} time(s) and gave up. Re-run after the window (typically under 30 min), or raise maintenanceMaxWaitMs.`;
15470
+ }
15410
15471
  attachEmptyReasonDetails(err2);
15411
15472
  throw err2;
15412
15473
  }
@@ -15430,7 +15491,7 @@ var HttpClient = (_class6 = class {
15430
15491
  const retryAfter = parseRetryAfter(res.headers.get("Retry-After"));
15431
15492
  const delay = retryAfter !== void 0 ? retryAfter * 1e3 : backoffDelay(attempt);
15432
15493
  if (canWait(delay)) {
15433
- _optionalChain([this, 'access', _97 => _97.logger, 'access', _98 => _98.warn, 'optionalCall', _99 => _99(
15494
+ _optionalChain([this, 'access', _102 => _102.logger, 'access', _103 => _103.warn, 'optionalCall', _104 => _104(
15434
15495
  `[autotask] ${status} on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15435
15496
  correlationId
15436
15497
  )]);
@@ -15443,7 +15504,7 @@ var HttpClient = (_class6 = class {
15443
15504
  const target = await this.discoverZoneBase(signal, ctx);
15444
15505
  const targetViolation = target === void 0 || this.hostPolicy === void 0 ? null : decideHostPolicy(target, this.hostPolicy);
15445
15506
  if (targetViolation !== null) {
15446
- _optionalChain([this, 'access', _100 => _100.logger, 'access', _101 => _101.warn, 'optionalCall', _102 => _102(
15507
+ _optionalChain([this, 'access', _105 => _105.logger, 'access', _106 => _106.warn, 'optionalCall', _107 => _107(
15447
15508
  `[autotask] zone re-point refused by hostPolicy (${targetViolation.bound}): ${targetViolation.origin} \u2014 the original 401 propagates, zero wire to the refused host`,
15448
15509
  void 0
15449
15510
  )]);
@@ -15481,7 +15542,7 @@ var HttpClient = (_class6 = class {
15481
15542
  threadThreshold
15482
15543
  });
15483
15544
  this.cooldownStore.set(this.tenantKey, Date.now() + durationMs);
15484
- _optionalChain([this, 'access', _103 => _103.logger, 'access', _104 => _104.warn, 'optionalCall', _105 => _105(
15545
+ _optionalChain([this, 'access', _108 => _108.logger, 'access', _109 => _109.warn, 'optionalCall', _110 => _110(
15485
15546
  `[autotask] 429 on ${method} ${opts.path} surfaces after ${attempt + 1} attempt(s); tenant cooldown armed for ${Math.round(durationMs / 1e3)}s`,
15486
15547
  correlationId
15487
15548
  )]);
@@ -15526,7 +15587,7 @@ var HttpClient = (_class6 = class {
15526
15587
  if (this.fieldCache !== void 0 && err instanceof AutotaskError) {
15527
15588
  const op = typeof opts.operation === "string" ? opts.operation : void 0;
15528
15589
  const verb = op !== void 0 ? op.slice(op.lastIndexOf(".") + 1) : "";
15529
- const drift = _optionalChain([err, 'access', _106 => _106.details, 'optionalAccess', _107 => _107.deterministic]) === true || err.code === "INVALID_RESPONSE" && META_TRIO_VERBS.has(verb);
15590
+ const drift = _optionalChain([err, 'access', _111 => _111.details, 'optionalAccess', _112 => _112.deterministic]) === true || err.code === "INVALID_RESPONSE" && META_TRIO_VERBS.has(verb);
15530
15591
  if (drift && op !== void 0) {
15531
15592
  const dot = op.indexOf(".");
15532
15593
  if (dot > 0) this.fieldCache.invalidate(op.slice(0, dot));
@@ -15534,8 +15595,9 @@ var HttpClient = (_class6 = class {
15534
15595
  }
15535
15596
  throw err;
15536
15597
  } finally {
15598
+ clearTimeout(deadlineTimer);
15537
15599
  if (!(method === "GET" || opts.idempotent === true)) {
15538
- _optionalChain([this, 'access', _108 => _108.readCache, 'optionalAccess', _109 => _109.clear, 'call', _110 => _110()]);
15600
+ _optionalChain([this, 'access', _113 => _113.readCache, 'optionalAccess', _114 => _114.clear, 'call', _115 => _115()]);
15539
15601
  const nameOp = typeof opts.operation === "string" ? opts.operation : void 0;
15540
15602
  const nameDot = nameOp !== void 0 ? nameOp.indexOf(".") : -1;
15541
15603
  if (this.resourceNameCache !== void 0 && nameOp !== void 0 && nameDot > 0 && nameOp.slice(0, nameDot) === "resources") {
@@ -15555,7 +15617,7 @@ function attachEmptyReasonDetails(err) {
15555
15617
  const resource = err.operation.slice(0, dot);
15556
15618
  const op = err.operation.slice(dot + 1);
15557
15619
  const surface = err.operation;
15558
- const stamp = _optionalChain([EMPTY_REASON_STAMPS, 'access', _111 => _111[resource], 'optionalAccess', _112 => _112[op]]);
15620
+ const stamp = _optionalChain([EMPTY_REASON_STAMPS, 'access', _116 => _116[resource], 'optionalAccess', _117 => _117[op]]);
15559
15621
  const pointer = POINTER_NOTES[surface];
15560
15622
  const isGetMiss = err instanceof NotFoundError && op === "get";
15561
15623
  if (stamp === void 0 && pointer === void 0 && !isGetMiss) return;
@@ -15594,7 +15656,7 @@ function unwrapItems(body, operation) {
15594
15656
  }
15595
15657
  return { items: body.items, pageDetails: body.pageDetails };
15596
15658
  }
15597
- function unwrapItem(body, id, operation) {
15659
+ function unwrapItem(body, id, operation, entity) {
15598
15660
  if (!isRecord2(body) || !("item" in body)) {
15599
15661
  throw new AutotaskError("Expected the item envelope { item }; got a different shape", {
15600
15662
  code: "INVALID_RESPONSE",
@@ -15610,6 +15672,7 @@ function unwrapItem(body, id, operation) {
15610
15672
  {
15611
15673
  httpStatus: 200,
15612
15674
  resourceIds: id !== void 0 ? [id] : void 0,
15675
+ ...id !== void 0 && entity !== void 0 ? { details: { idRefs: [{ entity, id }] } } : {},
15613
15676
  operation,
15614
15677
  suggestedAction: "Verify the id, or resolve the record by name first."
15615
15678
  }
@@ -15844,7 +15907,7 @@ async function expandResourceNames(client, ids, opts = {}) {
15844
15907
  continue;
15845
15908
  }
15846
15909
  }
15847
- const epoch = _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _113 => _113.epoch]), () => ( 0));
15910
+ const epoch = _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _118 => _118.epoch]), () => ( 0));
15848
15911
  const work = (async () => {
15849
15912
  try {
15850
15913
  const record = await holder.get(id, { fresh });
@@ -15930,7 +15993,7 @@ function capabilitySets() {
15930
15993
  const fieldOps = /* @__PURE__ */ new Map();
15931
15994
  const udfOps = /* @__PURE__ */ new Map();
15932
15995
  const resources = /* @__PURE__ */ new Set();
15933
- for (const rec of _chunkEWMG3HHUcjs.CAPABILITIES) {
15996
+ for (const rec of _chunk5ZGXWS4Ecjs.CAPABILITIES) {
15934
15997
  if (rec.resource === "operations") continue;
15935
15998
  resources.add(rec.resource);
15936
15999
  if (rec.operation === "getFieldInfo") fieldOps.set(rec.resource, rec);
@@ -15963,7 +16026,7 @@ async function fieldCatalog(client, opts) {
15963
16026
  }
15964
16027
  }
15965
16028
  const { fieldOps, udfOps, resources: allResources } = capabilitySets();
15966
- const includeRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _114 => _114.include]), () => ( ["fields"]));
16029
+ const includeRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _119 => _119.include]), () => ( ["fields"]));
15967
16030
  if (!Array.isArray(includeRaw) || includeRaw.length === 0) {
15968
16031
  throw new AutotaskConfigError("fieldCatalog: opts.include must be a non-empty array of (info|fields|udf)");
15969
16032
  }
@@ -15977,7 +16040,7 @@ async function fieldCatalog(client, opts) {
15977
16040
  }
15978
16041
  if (!include.includes(kind)) include.push(kind);
15979
16042
  }
15980
- const resourcesRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _115 => _115.resources]), () => ( WORKFLOW_RESOURCES));
16043
+ const resourcesRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _120 => _120.resources]), () => ( WORKFLOW_RESOURCES));
15981
16044
  if (!Array.isArray(resourcesRaw) || resourcesRaw.length === 0) {
15982
16045
  throw new AutotaskConfigError("fieldCatalog: opts.resources must be a non-empty array of plan resource keys");
15983
16046
  }
@@ -16009,7 +16072,7 @@ async function fieldCatalog(client, opts) {
16009
16072
  if (!targets.includes(key)) targets.push(key);
16010
16073
  }
16011
16074
  let fieldsFilter;
16012
- const fieldsRaw = _optionalChain([opts, 'optionalAccess', _116 => _116.fields]);
16075
+ const fieldsRaw = _optionalChain([opts, 'optionalAccess', _121 => _121.fields]);
16013
16076
  if (fieldsRaw !== void 0) {
16014
16077
  if (!Array.isArray(fieldsRaw) || fieldsRaw.length === 0) {
16015
16078
  throw new AutotaskConfigError("fieldCatalog: opts.fields must be a non-empty array of vendor field name strings");
@@ -16031,7 +16094,7 @@ async function fieldCatalog(client, opts) {
16031
16094
  `fieldCatalog: opts.labels must be a boolean (got ${typeof opts.labels})`
16032
16095
  );
16033
16096
  }
16034
- const labels = _optionalChain([opts, 'optionalAccess', _117 => _117.labels]) === true;
16097
+ const labels = _optionalChain([opts, 'optionalAccess', _122 => _122.labels]) === true;
16035
16098
  const cost = targets.length * include.length;
16036
16099
  if (cost > MAX_FIELD_CATALOG_WIRE) {
16037
16100
  throw new AutotaskConfigError(
@@ -16040,7 +16103,7 @@ async function fieldCatalog(client, opts) {
16040
16103
  );
16041
16104
  }
16042
16105
  const cache = client.http.fieldCache;
16043
- const fresh = _optionalChain([opts, 'optionalAccess', _118 => _118.fresh]) === true;
16106
+ const fresh = _optionalChain([opts, 'optionalAccess', _123 => _123.fresh]) === true;
16044
16107
  const zone = _nullishCoalesce(client.config.zone, () => ( "unknown"));
16045
16108
  const rows = [];
16046
16109
  let wireUsed = 0;
@@ -16064,11 +16127,11 @@ async function fieldCatalog(client, opts) {
16064
16127
  error: null
16065
16128
  };
16066
16129
  const fetches = {
16067
- info: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _119 => _119.getEntityInfo, 'optionalCall', _120 => _120()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getEntityInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16068
- fields: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _121 => _121.getFieldInfo, 'optionalCall', _122 => _122()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getFieldInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16069
- udf: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _123 => _123.getUdfInfo, 'optionalCall', _124 => _124()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getUdfInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" }))))
16130
+ info: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _124 => _124.getEntityInfo, 'optionalCall', _125 => _125()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getEntityInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16131
+ fields: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _126 => _126.getFieldInfo, 'optionalCall', _127 => _127()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getFieldInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16132
+ udf: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _128 => _128.getUdfInfo, 'optionalCall', _129 => _129()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getUdfInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" }))))
16070
16133
  };
16071
- if (fresh) _optionalChain([cache, 'optionalAccess', _125 => _125.invalidate, 'call', _126 => _126(resource)]);
16134
+ if (fresh) _optionalChain([cache, 'optionalAccess', _130 => _130.invalidate, 'call', _131 => _131(resource)]);
16072
16135
  let allCached = true;
16073
16136
  const ages = [];
16074
16137
  for (const kind of include) {
@@ -16121,7 +16184,7 @@ async function fieldCatalog(client, opts) {
16121
16184
  label: zone,
16122
16185
  cached: cache !== void 0,
16123
16186
  labels,
16124
- ttlMs: _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _127 => _127.ttlMs]), () => ( null)),
16187
+ ttlMs: _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _132 => _132.ttlMs]), () => ( null)),
16125
16188
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
16126
16189
  rows,
16127
16190
  wireUsed,
@@ -16286,7 +16349,7 @@ async function resolveCompositeNames(http, plan, opts = {}) {
16286
16349
  } else {
16287
16350
  for (const f of plan.labelFields) {
16288
16351
  const frow = row.fields.find((x) => x.name === f);
16289
- picklists[f] = _optionalChain([frow, 'optionalAccess', _128 => _128.picklistValues]);
16352
+ picklists[f] = _optionalChain([frow, 'optionalAccess', _133 => _133.picklistValues]);
16290
16353
  }
16291
16354
  }
16292
16355
  } catch (err) {
@@ -16297,8 +16360,8 @@ async function resolveCompositeNames(http, plan, opts = {}) {
16297
16360
  }
16298
16361
  return {
16299
16362
  section,
16300
- resourceName: (id) => _nullishCoalesce(_optionalChain([section, 'access', _129 => _129.rows, 'access', _130 => _130[`resource:${id}`], 'optionalAccess', _131 => _131.name]), () => ( null)),
16301
- recordName: (table, id) => _nullishCoalesce(_optionalChain([section, 'access', _132 => _132.rows, 'access', _133 => _133[`${table}:${id}`], 'optionalAccess', _134 => _134.name]), () => ( null)),
16363
+ resourceName: (id) => _nullishCoalesce(_optionalChain([section, 'access', _134 => _134.rows, 'access', _135 => _135[`resource:${id}`], 'optionalAccess', _136 => _136.name]), () => ( null)),
16364
+ recordName: (table, id) => _nullishCoalesce(_optionalChain([section, 'access', _137 => _137.rows, 'access', _138 => _138[`${table}:${id}`], 'optionalAccess', _139 => _139.name]), () => ( null)),
16302
16365
  labelFor: (field, value) => {
16303
16366
  if (value === null || value === void 0) return null;
16304
16367
  const values = picklists[field];
@@ -16569,8 +16632,8 @@ function validateFetchManyItems(items, cap, opName = "fetchMany", capRef = `FETC
16569
16632
  problems.push(`${at}.fields: must be an array of exact vendor field names (discover them via operations.fieldCatalog)`);
16570
16633
  continue;
16571
16634
  }
16572
- if (_optionalChain([validation, 'optionalAccess', _135 => _135.fieldCheck]) !== false) {
16573
- const authoritative = _nullishCoalesce(_optionalChain([validation, 'optionalAccess', _136 => _136.fieldSetsByResource, 'optionalAccess', _137 => _137.get, 'call', _138 => _138(resourceKey)]), () => ( fields));
16635
+ if (_optionalChain([validation, 'optionalAccess', _140 => _140.fieldCheck]) !== false) {
16636
+ const authoritative = _nullishCoalesce(_optionalChain([validation, 'optionalAccess', _141 => _141.fieldSetsByResource, 'optionalAccess', _142 => _142.get, 'call', _143 => _143(resourceKey)]), () => ( fields));
16574
16637
  for (const f of item.fields) {
16575
16638
  if (!authoritative.includes(f)) {
16576
16639
  problems.push(
@@ -16674,7 +16737,7 @@ function project2(value, fields) {
16674
16737
  return out;
16675
16738
  }
16676
16739
  function resourcePathOf(key, holder) {
16677
- const path = _optionalChain([holder, 'optionalAccess', _139 => _139.resourcePath]);
16740
+ const path = _optionalChain([holder, 'optionalAccess', _144 => _144.resourcePath]);
16678
16741
  if (typeof path !== "string" || path === "") {
16679
16742
  throw new AutotaskConfigError(`fetchByIds: the client exposes no ${key} resource path (registry drift)`, {
16680
16743
  suggestedAction: "Rebuild the client from the SDK build that ships this registry (the resource set is pinned by the plan)."
@@ -16846,7 +16909,7 @@ function blindEmptyReason(stamp) {
16846
16909
  };
16847
16910
  }
16848
16911
  function attachUpdateTargetMissReason(err, key) {
16849
- const pinned = _optionalChain([EMPTY_REASON_STAMPS, 'access', _140 => _140[key], 'optionalAccess', _141 => _141.update]);
16912
+ const pinned = _optionalChain([EMPTY_REASON_STAMPS, 'access', _145 => _145[key], 'optionalAccess', _146 => _146.update]);
16850
16913
  if (pinned === void 0) return;
16851
16914
  err.details = { ..._nullishCoalesce(err.details, () => ( {})), emptyReason: pinned };
16852
16915
  }
@@ -16930,6 +16993,19 @@ function decodeFileData(body) {
16930
16993
  { code: "INVALID_RESPONSE", category: "server" }
16931
16994
  );
16932
16995
  }
16996
+ var DEPLURAL_EXCEPTIONS = {
16997
+ tag_aliase: "tag_alias"
16998
+ };
16999
+ function entityNameFromPath(resourcePath) {
17000
+ const segment = resourcePath.slice(resourcePath.lastIndexOf("/") + 1);
17001
+ const snake = segment.replace(/([A-Z])/g, (_m, c, i) => (i > 0 ? `_` : "") + c.toLowerCase()).replace(/_{2,}/g, "_");
17002
+ if (snake.endsWith("ies")) return `${snake.slice(0, -3)}y`;
17003
+ if (snake.endsWith("s")) {
17004
+ const stripped = snake.slice(0, -1);
17005
+ return _nullishCoalesce(DEPLURAL_EXCEPTIONS[stripped], () => ( stripped));
17006
+ }
17007
+ return snake;
17008
+ }
16933
17009
  var BaseResource = class {
16934
17010
 
16935
17011
 
@@ -16939,6 +17015,10 @@ var BaseResource = class {
16939
17015
  get resourcePath() {
16940
17016
  return this.config.resourcePath;
16941
17017
  }
17018
+ /** The vendor entity this resource's ids identify (issue #116 — the `details.idRefs` label, e.g. `company`). */
17019
+ get entityName() {
17020
+ return entityNameFromPath(this.resourcePath);
17021
+ }
16942
17022
  /** Parent-scoped template (from the config); undefined for top-level resources. */
16943
17023
  get parentScopedPath() {
16944
17024
  return this.config.parentScopedPath;
@@ -17011,7 +17091,7 @@ var BaseResource = class {
17011
17091
  return (page, pageSize) => this.fetchPage(p, page, pageSize, state);
17012
17092
  }
17013
17093
  walkPageSize(params) {
17014
- return clampPageSize(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _142 => _142.maxRecords]), () => ( this.defaultPageSize)));
17094
+ return clampPageSize(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _147 => _147.maxRecords]), () => ( this.defaultPageSize)));
17015
17095
  }
17016
17096
  /** Stream items across pages (the resource `query` surface). */
17017
17097
  queryItems(params) {
@@ -17023,7 +17103,7 @@ var BaseResource = class {
17023
17103
  }
17024
17104
  /** Collect every item across all pages (the resource `queryAll` surface; 1000-page guarded). */
17025
17105
  async queryAllItems(params) {
17026
- return collectAll(this.pageFetcher(params), { pageSize: this.walkPageSize(params), maxRecords: _optionalChain([params, 'optionalAccess', _143 => _143.maxTotalRecords]) });
17106
+ return collectAll(this.pageFetcher(params), { pageSize: this.walkPageSize(params), maxRecords: _optionalChain([params, 'optionalAccess', _148 => _148.maxTotalRecords]) });
17027
17107
  }
17028
17108
  /**
17029
17109
  * `queryBounded` — server-side pagination (the MCP query surface): ONE call
@@ -17058,19 +17138,19 @@ var BaseResource = class {
17058
17138
  "queryBounded: params must be an object { filter?, limit?, latest?, includeFields? } \u2014 a bare conditions array is not accepted (wrap it: { filter: [...] })"
17059
17139
  );
17060
17140
  }
17061
- const limit = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _144 => _144.limit]), () => ( BOUNDED_QUERY_DEFAULT_LIMIT));
17141
+ const limit = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _149 => _149.limit]), () => ( BOUNDED_QUERY_DEFAULT_LIMIT));
17062
17142
  if (!Number.isInteger(limit) || limit < 1 || limit > BOUNDED_QUERY_MAX_LIMIT) {
17063
17143
  throw new AutotaskConfigError(
17064
17144
  `queryBounded: limit must be an integer 1..${BOUNDED_QUERY_MAX_LIMIT} (got ${String(limit)}) \u2014 it is the TOTAL record cap, not a page size`
17065
17145
  );
17066
17146
  }
17067
- const noteChars = _optionalChain([params, 'optionalAccess', _145 => _145.noteChars]);
17147
+ const noteChars = _optionalChain([params, 'optionalAccess', _150 => _150.noteChars]);
17068
17148
  if (noteChars !== void 0 && (!Number.isInteger(noteChars) || noteChars < 1)) {
17069
17149
  throw new AutotaskConfigError(
17070
17150
  `queryBounded: noteChars must be an integer >= 1 (got ${String(noteChars)}) \u2014 it is the per-field char cap on the untrusted-class free-text fields (absent = the raw, untruncated result)`
17071
17151
  );
17072
17152
  }
17073
- const walkParams = _optionalChain([params, 'optionalAccess', _146 => _146.fieldsPreset]) !== void 0 ? { ...params, includeFields: resolveFieldsPreset(params.fieldsPreset, this.config.key, params.includeFields) } : _nullishCoalesce(params, () => ( {}));
17153
+ const walkParams = _optionalChain([params, 'optionalAccess', _151 => _151.fieldsPreset]) !== void 0 ? { ...params, includeFields: resolveFieldsPreset(params.fieldsPreset, this.config.key, params.includeFields) } : _nullishCoalesce(params, () => ( {}));
17074
17154
  const latest = walkParams.latest;
17075
17155
  if (latest !== void 0) {
17076
17156
  if (!Number.isInteger(latest) || latest < 1 || latest > BOUNDED_QUERY_MAX_LIMIT) {
@@ -17078,7 +17158,7 @@ var BaseResource = class {
17078
17158
  `queryBounded: latest must be an integer 1..${BOUNDED_QUERY_MAX_LIMIT} (got ${String(latest)}) \u2014 it is the count of the highest-id rows to return`
17079
17159
  );
17080
17160
  }
17081
- if (_optionalChain([params, 'optionalAccess', _147 => _147.limit]) !== void 0 && limit < latest) {
17161
+ if (_optionalChain([params, 'optionalAccess', _152 => _152.limit]) !== void 0 && limit < latest) {
17082
17162
  throw new AutotaskConfigError(
17083
17163
  `queryBounded: limit (${String(limit)}) must be >= latest (${String(latest)}) \u2014 latest governs the returned count and limit is the walk window`
17084
17164
  );
@@ -17160,8 +17240,8 @@ var BaseResource = class {
17160
17240
  * speculation). */
17161
17241
  stampEmptyQueryResult(result, params) {
17162
17242
  if (result.items.length !== 0) return;
17163
- result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _148 => _148[this.config.key], 'optionalAccess', _149 => _149.query]), _optionalChain([params, 'optionalAccess', _150 => _150.filter]));
17164
- const pinnedReason = normalizedConditions(_optionalChain([params, 'optionalAccess', _151 => _151.filter])) === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _152 => _152[this.config.key], 'optionalAccess', _153 => _153.query]) : void 0;
17243
+ result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _153 => _153[this.config.key], 'optionalAccess', _154 => _154.query]), _optionalChain([params, 'optionalAccess', _155 => _155.filter]));
17244
+ const pinnedReason = normalizedConditions(_optionalChain([params, 'optionalAccess', _156 => _156.filter])) === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _157 => _157[this.config.key], 'optionalAccess', _158 => _158.query]) : void 0;
17165
17245
  if (result.blindSurface !== void 0 || pinnedReason !== void 0) {
17166
17246
  result.emptyReason = result.blindSurface !== void 0 ? blindEmptyReason(result.blindSurface) : pinnedReason;
17167
17247
  }
@@ -17312,7 +17392,7 @@ var BaseResource = class {
17312
17392
  if (result.items.length === 0) {
17313
17393
  this.stampEmptyQueryResult(result, params);
17314
17394
  } else {
17315
- result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _154 => _154[this.config.key], 'optionalAccess', _155 => _155.query]), params.filter);
17395
+ result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _159 => _159[this.config.key], 'optionalAccess', _160 => _160.query]), params.filter);
17316
17396
  }
17317
17397
  return result;
17318
17398
  }
@@ -17351,7 +17431,7 @@ var BaseResource = class {
17351
17431
  * or, on a plan-pinned blind surface, the `{ count: 0, blindSurface }`
17352
17432
  * typed sentinel (S12-C T10; see `BlindCountResult`). */
17353
17433
  async countGlobal(params) {
17354
- const conditions = normalizedConditions(_optionalChain([params, 'optionalAccess', _156 => _156.filter]));
17434
+ const conditions = normalizedConditions(_optionalChain([params, 'optionalAccess', _161 => _161.filter]));
17355
17435
  const body = {};
17356
17436
  body.filter = conditions === void 0 ? [] : buildFilter(conditions).filter;
17357
17437
  const res = await this.http.request({
@@ -17362,9 +17442,9 @@ var BaseResource = class {
17362
17442
  idempotent: true
17363
17443
  });
17364
17444
  const count = unwrapQueryCount(res, `${this.config.key}.count`);
17365
- const stamp = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _157 => _157[this.config.key], 'optionalAccess', _158 => _158.count]), _optionalChain([params, 'optionalAccess', _159 => _159.filter]));
17445
+ const stamp = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _162 => _162[this.config.key], 'optionalAccess', _163 => _163.count]), _optionalChain([params, 'optionalAccess', _164 => _164.filter]));
17366
17446
  if (count === 0) {
17367
- const pinnedReason = conditions === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _160 => _160[this.config.key], 'optionalAccess', _161 => _161.count]) : void 0;
17447
+ const pinnedReason = conditions === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _165 => _165[this.config.key], 'optionalAccess', _166 => _166.count]) : void 0;
17368
17448
  if (stamp !== void 0 || pinnedReason !== void 0) {
17369
17449
  return {
17370
17450
  count,
@@ -17395,9 +17475,9 @@ var BaseResource = class {
17395
17475
  const hit = cache.get(path);
17396
17476
  if (hit !== void 0) return hit;
17397
17477
  }
17398
- const epoch = _optionalChain([cache, 'optionalAccess', _162 => _162.epoch]);
17478
+ const epoch = _optionalChain([cache, 'optionalAccess', _167 => _167.epoch]);
17399
17479
  const res = await this.http.request({ method: "GET", path, operation });
17400
- _optionalChain([cache, 'optionalAccess', _163 => _163.set, 'call', _164 => _164(path, res, resource, epoch)]);
17480
+ _optionalChain([cache, 'optionalAccess', _168 => _168.set, 'call', _169 => _169(path, res, resource, epoch)]);
17401
17481
  return res;
17402
17482
  }
17403
17483
  /**
@@ -17436,7 +17516,7 @@ var BaseResource = class {
17436
17516
  return value;
17437
17517
  });
17438
17518
  work.catch((err) => {
17439
- if (err instanceof AutotaskError && (err.code === "INVALID_RESPONSE" || _optionalChain([err, 'access', _165 => _165.details, 'optionalAccess', _166 => _166.deterministic]) === true)) {
17519
+ if (err instanceof AutotaskError && (err.code === "INVALID_RESPONSE" || _optionalChain([err, 'access', _170 => _170.details, 'optionalAccess', _171 => _171.deterministic]) === true)) {
17440
17520
  cache.invalidate(key);
17441
17521
  }
17442
17522
  });
@@ -17446,7 +17526,7 @@ var BaseResource = class {
17446
17526
  async getGlobal(id, fresh = false) {
17447
17527
  const numeric = parseIdentifier(id, "id");
17448
17528
  const res = await this.cachedGet(`${this.resourcePath}/${numeric}`, `${this.config.key}.get`, fresh, this.config.key);
17449
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17529
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17450
17530
  }
17451
17531
  /**
17452
17532
  * V2 merge read: a FRESH single-record GET that skips response redaction
@@ -17466,9 +17546,9 @@ var BaseResource = class {
17466
17546
  path: `${this.resourcePath}/${numeric}`,
17467
17547
  operation: `${this.config.key}.get`,
17468
17548
  skipResponseRedaction: true,
17469
- maxRetries: _optionalChain([readOpts, 'optionalAccess', _167 => _167.maxRetries])
17549
+ maxRetries: _optionalChain([readOpts, 'optionalAccess', _172 => _172.maxRetries])
17470
17550
  });
17471
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17551
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17472
17552
  }
17473
17553
  /**
17474
17554
  * Issue #34 fallback merge read: a FRESH parent-scoped single-record GET
@@ -17485,15 +17565,15 @@ var BaseResource = class {
17485
17565
  path: this.scopedItemPath(parentId, numeric),
17486
17566
  operation: `${this.config.key}.get`,
17487
17567
  skipResponseRedaction: true,
17488
- maxRetries: _optionalChain([readOpts, 'optionalAccess', _168 => _168.maxRetries])
17568
+ maxRetries: _optionalChain([readOpts, 'optionalAccess', _173 => _173.maxRetries])
17489
17569
  });
17490
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17570
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17491
17571
  }
17492
17572
  /** Parent-scoped `GET .../{parentId}/<Child>/{id}` → `{ item }` unwrapped. */
17493
17573
  async getScopedRaw(parentId, id, fresh = false) {
17494
17574
  const numeric = parseIdentifier(id, "id");
17495
17575
  const res = await this.cachedGet(this.scopedItemPath(parentId, id), `${this.config.key}.get`, fresh, this.config.key);
17496
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17576
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17497
17577
  }
17498
17578
  /**
17499
17579
  * Attachment single-read: the vendor answers the model DIRECTLY (swagger),
@@ -17503,23 +17583,23 @@ var BaseResource = class {
17503
17583
  async getScopedModel(parentId, id, fresh = false) {
17504
17584
  const numeric = parseIdentifier(id, "id");
17505
17585
  const res = await this.cachedGet(this.scopedItemPath(parentId, id), `${this.config.key}.get`, fresh, this.config.key);
17506
- return this.unwrapModelLike(res, numeric);
17586
+ return this.unwrapModelLike(res, numeric, this.entityName);
17507
17587
  }
17508
- unwrapModelLike(body, id) {
17588
+ unwrapModelLike(body, id, entity) {
17509
17589
  if (!isRecord2(body)) {
17510
17590
  throw new AutotaskError(
17511
17591
  `Expected an attachment model (or { item } / { items }) envelope for ID ${id}; got a different shape`,
17512
- { code: "INVALID_RESPONSE", category: "server", resourceIds: [id] }
17592
+ { code: "INVALID_RESPONSE", category: "server", resourceIds: [id], details: { idRefs: [{ entity, id }] } }
17513
17593
  );
17514
17594
  }
17515
17595
  if (Object.keys(body).length === 0) {
17516
- throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id] });
17596
+ throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id], details: { idRefs: [{ entity, id }] } });
17517
17597
  }
17518
- if ("item" in body) return unwrapItem(body, id);
17598
+ if ("item" in body) return unwrapItem(body, id, void 0, entity);
17519
17599
  if (Array.isArray(body.items)) {
17520
17600
  const first = body.items[0];
17521
17601
  if (first === null || first === void 0) {
17522
- throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id] });
17602
+ throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id], details: { idRefs: [{ entity, id }] } });
17523
17603
  }
17524
17604
  return first;
17525
17605
  }
@@ -17867,7 +17947,7 @@ var BaseResource = class {
17867
17947
  if (!isRecord2(res)) {
17868
17948
  throw new AutotaskError(
17869
17949
  `Expected the deleted attachment model for ID ${numeric}; got a different shape`,
17870
- { code: "INVALID_RESPONSE", category: "server", resourceIds: [numeric] }
17950
+ { code: "INVALID_RESPONSE", category: "server", resourceIds: [numeric], details: { idRefs: [{ entity: this.entityName, id: numeric }] } }
17871
17951
  );
17872
17952
  }
17873
17953
  return res;
@@ -18144,7 +18224,7 @@ var BaseResource = class {
18144
18224
  current = parentId === void 0 ? await this.getGlobal(id, true) : this.config.attachmentGet ? await this.getScopedModel(parentId, id, true) : await this.getScopedRaw(parentId, id, true);
18145
18225
  } catch (err) {
18146
18226
  if (err instanceof NotFoundError) {
18147
- const updateReason = _optionalChain([EMPTY_REASON_STAMPS, 'access', _169 => _169[this.config.key], 'optionalAccess', _170 => _170.update]);
18227
+ const updateReason = _optionalChain([EMPTY_REASON_STAMPS, 'access', _174 => _174[this.config.key], 'optionalAccess', _175 => _175.update]);
18148
18228
  checks.push({
18149
18229
  name: "current-record-exists",
18150
18230
  ok: false,
@@ -18258,9 +18338,9 @@ var BaseResource = class {
18258
18338
  const resource = RESOURCE_KEY_BY_PATH[entityPath];
18259
18339
  const res = await this.cachedGet(`${entityPath}/${numeric}`, `${this.config.key}.fetchRecord`, fresh, resource);
18260
18340
  if (this.config.attachmentGet) {
18261
- return this.unwrapModelLike(res, numeric);
18341
+ return this.unwrapModelLike(res, numeric, entityNameFromPath(entityPath));
18262
18342
  }
18263
- return unwrapItem(res, numeric, `${this.config.key}.fetchRecord`);
18343
+ return unwrapItem(res, numeric, `${this.config.key}.fetchRecord`, entityNameFromPath(entityPath));
18264
18344
  }
18265
18345
  /**
18266
18346
  * `getContext` part fetch: a single-record read that degrades to `null`
@@ -18302,12 +18382,12 @@ var BaseResource = class {
18302
18382
  return null;
18303
18383
  }
18304
18384
  }
18305
- const epoch = _optionalChain([cache, 'optionalAccess', _171 => _171.epoch]);
18385
+ const epoch = _optionalChain([cache, 'optionalAccess', _176 => _176.epoch]);
18306
18386
  try {
18307
18387
  return await this.fetchRecordRaw(entityPath, referenceId);
18308
18388
  } catch (err) {
18309
18389
  if (err instanceof NotFoundError) {
18310
- _optionalChain([cache, 'optionalAccess', _172 => _172.set, 'call', _173 => _173(absentKey, CONTEXT_ABSENT_MARKER, RESOURCE_KEY_BY_PATH[entityPath], epoch)]);
18390
+ _optionalChain([cache, 'optionalAccess', _177 => _177.set, 'call', _178 => _178(absentKey, CONTEXT_ABSENT_MARKER, RESOURCE_KEY_BY_PATH[entityPath], epoch)]);
18311
18391
  return null;
18312
18392
  }
18313
18393
  throw err;
@@ -18367,6 +18447,7 @@ var BaseResource = class {
18367
18447
  {
18368
18448
  code: "RESOLUTION_AMBIGUOUS",
18369
18449
  resourceIds: ids,
18450
+ details: { idRefs: ids.map((cid) => ({ entity: this.entityName, id: cid })) },
18370
18451
  // issue #59 PR-B: the miss-channel pointer (the generic floor names
18371
18452
  // the resource's own search op — reachable only where searchFields
18372
18453
  // is non-empty, so the named op always exists here).
@@ -18423,7 +18504,7 @@ var BaseResource = class {
18423
18504
  missDetail(operator, fields) {
18424
18505
  const key = this.config.key;
18425
18506
  const probe = fields.map((field) => ({ field, op: operator, value: "" }));
18426
- const blind = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _174 => _174[key], 'optionalAccess', _175 => _175.query]), probe);
18507
+ const blind = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _179 => _179[key], 'optionalAccess', _180 => _180.query]), probe);
18427
18508
  const next = [];
18428
18509
  if (blind !== void 0) {
18429
18510
  next.push(`This surface is blind to records the API user does not own, so a miss is not proof of absence: ${blind.authority} returns the record when the id is known.`);
@@ -18503,7 +18584,7 @@ var BaseResource = class {
18503
18584
  const ids = matches.map((m) => m.id).filter((id) => typeof id === "number");
18504
18585
  throw new ResolutionError(
18505
18586
  `findBy${field}: "${value}" is ambiguous on ${this.config.key} (matched ${matches.length} records)`,
18506
- { code: "RESOLUTION_AMBIGUOUS", resourceIds: ids }
18587
+ { code: "RESOLUTION_AMBIGUOUS", resourceIds: ids, details: { idRefs: ids.map((cid) => ({ entity: this.entityName, id: cid })) } }
18507
18588
  );
18508
18589
  }
18509
18590
  return matches[0];
@@ -18696,4 +18777,6 @@ var BaseResource = class {
18696
18777
 
18697
18778
 
18698
18779
 
18699
- exports.AUTH_HEADERS = AUTH_HEADERS; exports.buildAuthHeaders = buildAuthHeaders; exports.withAuthHeaders = withAuthHeaders; exports.NoopLogger = NoopLogger; exports.REDACTED = REDACTED; exports.CREDENTIAL_HEADER_NAMES = CREDENTIAL_HEADER_NAMES; exports.isCredentialHeaderName = isCredentialHeaderName; exports.redactRecord = redactRecord; exports.SECRET_RESPONSE_FIELDS = SECRET_RESPONSE_FIELDS; exports.PERSONAL_RESPONSE_FIELDS = PERSONAL_RESPONSE_FIELDS; exports.CONFIDENTIAL_RESPONSE_FIELDS = CONFIDENTIAL_RESPONSE_FIELDS; exports.isRedactedFieldName = isRedactedFieldName; exports.redactResponseBody = redactResponseBody; exports.AutotaskError = AutotaskError; exports.AutotaskConfigError = AutotaskConfigError; exports.AutotaskNetworkError = AutotaskNetworkError; exports.AutotaskTimeoutError = AutotaskTimeoutError; exports.AutotaskAbortError = AutotaskAbortError; exports.ResponseRejectedError = ResponseRejectedError; exports.BadRequestError = BadRequestError; exports.UnauthorizedError = UnauthorizedError; exports.ForbiddenError = ForbiddenError; exports.NotFoundError = NotFoundError; exports.ConflictError = ConflictError; exports.UnprocessableEntityError = UnprocessableEntityError; exports.RateLimitError = RateLimitError; exports.ServerError = ServerError; exports.UnexpectedContentTypeError = UnexpectedContentTypeError; exports.EmptyResponseError = EmptyResponseError; exports.CircuitBreakerError = CircuitBreakerError; exports.HostPolicyDeniedError = HostPolicyDeniedError; exports.ResolutionError = ResolutionError; exports.PaginationLimitError = PaginationLimitError; exports.QueryTooLongError = QueryTooLongError; exports.parseVendorErrors = parseVendorErrors; exports.isDeterministicVendor500 = isDeterministicVendor500; exports.formatVendorDetail = formatVendorDetail; exports.CREDENTIAL_SHAPE_POINTER = CREDENTIAL_SHAPE_POINTER; exports.mergeDetails = mergeDetails; exports.errorFromStatus = errorFromStatus; exports.StaleObjectError = StaleObjectError; exports.ConfirmationRequiredError = ConfirmationRequiredError; exports.DeleteBoundaryError = DeleteBoundaryError; exports.MarkerUnsafeIdError = MarkerUnsafeIdError; exports.RecoveryTruncatedError = RecoveryTruncatedError; exports.isAutotaskError = isAutotaskError; exports.hasSurroundingQuotes = hasSurroundingQuotes; exports.credentialShapeProblem = credentialShapeProblem; exports.CREDENTIAL_ENV_LOAD_ACTION = CREDENTIAL_ENV_LOAD_ACTION; exports.MIN_PREFIX_SUMMARY_LENGTH = MIN_PREFIX_SUMMARY_LENGTH; exports.credentialValueSummary = credentialValueSummary; exports.FIELD_CACHE_KINDS = FIELD_CACHE_KINDS; exports.DEFAULT_CIRCUIT_BREAKER_WINDOW_MS = DEFAULT_CIRCUIT_BREAKER_WINDOW_MS; exports.DEFAULT_CIRCUIT_BREAKER_FAILURE_THRESHOLD = DEFAULT_CIRCUIT_BREAKER_FAILURE_THRESHOLD; exports.DEFAULT_CIRCUIT_BREAKER_OPEN_TIMEOUT_MS = DEFAULT_CIRCUIT_BREAKER_OPEN_TIMEOUT_MS; exports.DEFAULT_CIRCUIT_BREAKER_SUCCESSES_TO_CLOSE = DEFAULT_CIRCUIT_BREAKER_SUCCESSES_TO_CLOSE; exports.DEFAULT_CIRCUIT_BREAKER_MAX_ENTRIES = DEFAULT_CIRCUIT_BREAKER_MAX_ENTRIES; exports.InMemoryCircuitBreakerStore = InMemoryCircuitBreakerStore; exports.defaultCircuitBreakerStore = defaultCircuitBreakerStore; exports.resetDefaultCircuitBreakerStore = resetDefaultCircuitBreakerStore; exports.buildBreakerKey = buildBreakerKey; exports.isBreakerFailure = isBreakerFailure; exports.DEFAULT_COOLDOWN_MAX_MS = DEFAULT_COOLDOWN_MAX_MS; exports.DEFAULT_COOLDOWN_DEFAULT_MS = DEFAULT_COOLDOWN_DEFAULT_MS; exports.DEFAULT_COOLDOWN_MAX_ENTRIES = DEFAULT_COOLDOWN_MAX_ENTRIES; exports.InMemoryCooldownStore = InMemoryCooldownStore; exports.defaultCooldownStore = defaultCooldownStore; exports.resetDefaultCooldownStore = resetDefaultCooldownStore; exports.buildTenantKey = buildTenantKey; exports.cooldownDurationMs = cooldownDurationMs; exports.ZONE_CATALOG = ZONE_CATALOG; exports.ZONES = ZONES; exports.DEFAULT_ZONE = DEFAULT_ZONE; exports.AGENT_PROFILE = AGENT_PROFILE; exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE; exports.MAX_PAGE_SIZE = MAX_PAGE_SIZE; exports.DEFAULT_TIMEOUT_MS = DEFAULT_TIMEOUT_MS; exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES; exports.DEFAULT_MAX_CONCURRENT = DEFAULT_MAX_CONCURRENT; exports.DEFAULT_MAX_RESPONSE_BYTES = DEFAULT_MAX_RESPONSE_BYTES; exports.DEFAULT_MAX_SCAN_RECORDS = DEFAULT_MAX_SCAN_RECORDS; exports.DEFAULT_MAX_SCAN_PAGES = DEFAULT_MAX_SCAN_PAGES; exports.DEFAULT_READ_CACHE_TTL_MS = DEFAULT_READ_CACHE_TTL_MS; exports.DEFAULT_FIELD_CACHE_TTL_MS = DEFAULT_FIELD_CACHE_TTL_MS; exports.DEFAULT_RESOURCE_NAME_CACHE_TTL_MS = DEFAULT_RESOURCE_NAME_CACHE_TTL_MS; exports.zoneUrl = zoneUrl; exports.resolveBaseUrl = resolveBaseUrl; exports.resolveCredentials = resolveCredentials; exports.resolveConfig = resolveConfig; exports.isRecord = isRecord2; exports.assertRecord = assertRecord; exports.deepMergeParams = deepMergeParams; exports.isIdentifierCandidate = isIdentifierCandidate; exports.parseIdentifier = parseIdentifier; exports.flattenUdfs = flattenUdfs; exports.newCorrelationId = newCorrelationId; exports.redactAuditBody = redactAuditBody; exports.camelKey = camelKey; exports.FILTER_OPERATORS = FILTER_OPERATORS; exports.GROUPING_OPERATORS = GROUPING_OPERATORS; exports.MAX_OR_CONDITIONS = MAX_OR_CONDITIONS; exports.MAX_UDF_PER_QUERY = MAX_UDF_PER_QUERY; exports.MAX_QUERY_LENGTH = MAX_QUERY_LENGTH; exports.MAX_GET_LENGTH = MAX_GET_LENGTH; exports.MAX_FIELD_LENGTH = MAX_FIELD_LENGTH; exports.isFilterOperator = isFilterOperator; exports.serializeFilter = serializeFilter; exports.validateFilter = validateFilter; exports.buildFilter = buildFilter; exports.normalizedConditions = normalizedConditions; exports.RELATIONSHIP_ZONE = RELATIONSHIP_ZONE; exports.RELATIONSHIP_MAP = RELATIONSHIP_MAP; exports.BLIND_SURFACE_STAMPS = BLIND_SURFACE_STAMPS; exports.DELETE_BOUNDARY_NOTES = DELETE_BOUNDARY_NOTES; exports.MARKER_FIELDS = MARKER_FIELDS; exports.EMPTY_REASON_STAMPS = EMPTY_REASON_STAMPS; exports.BLIND_SURFACE_INVENTORY = BLIND_SURFACE_INVENTORY; exports.REACHABILITY_PROBE_DEFAULTS = REACHABILITY_PROBE_DEFAULTS; exports.CREATE_GUIDANCE = CREATE_GUIDANCE; exports.UNTRUSTED_FIELDS_BY_RESOURCE = UNTRUSTED_FIELDS_BY_RESOURCE; exports.IDEMPOTENT_METHODS = IDEMPOTENT_METHODS; exports.buildUrl = buildUrl; exports.cursorToPath = cursorToPath; exports.buildQueryRequest = buildQueryRequest; exports.runWithSignal = runWithSignal; exports.HttpClient = HttpClient; exports.unwrapItems = unwrapItems; exports.unwrapItem = unwrapItem; exports.unwrapQueryCount = unwrapQueryCount; exports.unwrapOperation = unwrapOperation; exports.passthrough = passthrough; exports.MAX_PAGES = MAX_PAGES; exports.clampPageSize = clampPageSize; exports.totalPagesFor = totalPagesFor; exports.paginate = paginate; exports.paginateItems = paginateItems; exports.collectAll = collectAll; exports.toArray = toArray; exports.FIELD_PRESETS = FIELD_PRESETS; exports.FIELD_PRESET_NAMES = FIELD_PRESET_NAMES; exports.resolveFieldsPreset = resolveFieldsPreset; exports.BOUNDED_QUERY_MAX_LIMIT = BOUNDED_QUERY_MAX_LIMIT; exports.truncateNoteChars = truncateNoteChars; exports.buildDryRunResult = buildDryRunResult; exports.mergePartialBody = mergePartialBody; exports.blindStampFor = blindStampFor; exports.decodeFileData = decodeFileData; exports.BaseResource = BaseResource; exports.EXPAND_RESOURCE_NAMES_MAX_IDS = EXPAND_RESOURCE_NAMES_MAX_IDS; exports.expandResourceNames = expandResourceNames; exports.WORKFLOW_RESOURCES = WORKFLOW_RESOURCES; exports.MAX_FIELD_CATALOG_WIRE = MAX_FIELD_CATALOG_WIRE; exports.FIELD_CATALOG_HONESTY_NOTE = FIELD_CATALOG_HONESTY_NOTE; exports.fieldCatalog = fieldCatalog; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = PICKLIST_VALUE_NOT_SERVED_NOTE; exports.TICKET_LABEL_FIELDS = TICKET_LABEL_FIELDS; exports.createNamePlan = createNamePlan; exports.addNameSibling = addNameSibling; exports.addLabelSibling = addLabelSibling; exports.resolveCompositeNames = resolveCompositeNames; exports.MODEL_FIELD_SETS = MODEL_FIELD_SETS; exports.MODEL_DATE_FIELDS = MODEL_DATE_FIELDS; exports.FETCH_MANY_MAX_ITEMS = FETCH_MANY_MAX_ITEMS; exports.validateFetchManyItems = validateFetchManyItems; exports.fetchMany = fetchMany; exports.FETCH_BY_IDS_MAX_ITEMS = FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_BY_IDS_CHUNK_SIZE = FETCH_BY_IDS_CHUNK_SIZE; exports.fetchByIds = fetchByIds;
18780
+
18781
+
18782
+ exports.AUTH_HEADERS = AUTH_HEADERS; exports.buildAuthHeaders = buildAuthHeaders; exports.withAuthHeaders = withAuthHeaders; exports.NoopLogger = NoopLogger; exports.REDACTED = REDACTED; exports.CREDENTIAL_HEADER_NAMES = CREDENTIAL_HEADER_NAMES; exports.isCredentialHeaderName = isCredentialHeaderName; exports.redactRecord = redactRecord; exports.SECRET_RESPONSE_FIELDS = SECRET_RESPONSE_FIELDS; exports.PERSONAL_RESPONSE_FIELDS = PERSONAL_RESPONSE_FIELDS; exports.CONFIDENTIAL_RESPONSE_FIELDS = CONFIDENTIAL_RESPONSE_FIELDS; exports.isRedactedFieldName = isRedactedFieldName; exports.redactResponseBody = redactResponseBody; exports.AutotaskError = AutotaskError; exports.AutotaskConfigError = AutotaskConfigError; exports.AutotaskNetworkError = AutotaskNetworkError; exports.AutotaskTimeoutError = AutotaskTimeoutError; exports.AutotaskAbortError = AutotaskAbortError; exports.ResponseRejectedError = ResponseRejectedError; exports.BadRequestError = BadRequestError; exports.UnauthorizedError = UnauthorizedError; exports.ForbiddenError = ForbiddenError; exports.NotFoundError = NotFoundError; exports.ConflictError = ConflictError; exports.UnprocessableEntityError = UnprocessableEntityError; exports.RateLimitError = RateLimitError; exports.ServerError = ServerError; exports.UnexpectedContentTypeError = UnexpectedContentTypeError; exports.EmptyResponseError = EmptyResponseError; exports.CircuitBreakerError = CircuitBreakerError; exports.HostPolicyDeniedError = HostPolicyDeniedError; exports.ResolutionError = ResolutionError; exports.PaginationLimitError = PaginationLimitError; exports.QueryTooLongError = QueryTooLongError; exports.parseVendorErrors = parseVendorErrors; exports.isDeterministicVendor500 = isDeterministicVendor500; exports.formatVendorDetail = formatVendorDetail; exports.CREDENTIAL_SHAPE_POINTER = CREDENTIAL_SHAPE_POINTER; exports.mergeDetails = mergeDetails; exports.errorFromStatus = errorFromStatus; exports.StaleObjectError = StaleObjectError; exports.ConfirmationRequiredError = ConfirmationRequiredError; exports.DeleteBoundaryError = DeleteBoundaryError; exports.MarkerUnsafeIdError = MarkerUnsafeIdError; exports.RecoveryTruncatedError = RecoveryTruncatedError; exports.isAutotaskError = isAutotaskError; exports.hasSurroundingQuotes = hasSurroundingQuotes; exports.credentialShapeProblem = credentialShapeProblem; exports.CREDENTIAL_ENV_LOAD_ACTION = CREDENTIAL_ENV_LOAD_ACTION; exports.MIN_PREFIX_SUMMARY_LENGTH = MIN_PREFIX_SUMMARY_LENGTH; exports.credentialValueSummary = credentialValueSummary; exports.FIELD_CACHE_KINDS = FIELD_CACHE_KINDS; exports.DEFAULT_CIRCUIT_BREAKER_WINDOW_MS = DEFAULT_CIRCUIT_BREAKER_WINDOW_MS; exports.DEFAULT_CIRCUIT_BREAKER_FAILURE_THRESHOLD = DEFAULT_CIRCUIT_BREAKER_FAILURE_THRESHOLD; exports.DEFAULT_CIRCUIT_BREAKER_OPEN_TIMEOUT_MS = DEFAULT_CIRCUIT_BREAKER_OPEN_TIMEOUT_MS; exports.DEFAULT_CIRCUIT_BREAKER_SUCCESSES_TO_CLOSE = DEFAULT_CIRCUIT_BREAKER_SUCCESSES_TO_CLOSE; exports.DEFAULT_CIRCUIT_BREAKER_MAX_ENTRIES = DEFAULT_CIRCUIT_BREAKER_MAX_ENTRIES; exports.InMemoryCircuitBreakerStore = InMemoryCircuitBreakerStore; exports.defaultCircuitBreakerStore = defaultCircuitBreakerStore; exports.resetDefaultCircuitBreakerStore = resetDefaultCircuitBreakerStore; exports.buildBreakerKey = buildBreakerKey; exports.isBreakerFailure = isBreakerFailure; exports.DEFAULT_COOLDOWN_MAX_MS = DEFAULT_COOLDOWN_MAX_MS; exports.DEFAULT_COOLDOWN_DEFAULT_MS = DEFAULT_COOLDOWN_DEFAULT_MS; exports.DEFAULT_COOLDOWN_MAX_ENTRIES = DEFAULT_COOLDOWN_MAX_ENTRIES; exports.InMemoryCooldownStore = InMemoryCooldownStore; exports.defaultCooldownStore = defaultCooldownStore; exports.resetDefaultCooldownStore = resetDefaultCooldownStore; exports.buildTenantKey = buildTenantKey; exports.cooldownDurationMs = cooldownDurationMs; exports.ZONE_CATALOG = ZONE_CATALOG; exports.ZONES = ZONES; exports.DEFAULT_ZONE = DEFAULT_ZONE; exports.AGENT_PROFILE = AGENT_PROFILE; exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE; exports.MAX_PAGE_SIZE = MAX_PAGE_SIZE; exports.DEFAULT_TIMEOUT_MS = DEFAULT_TIMEOUT_MS; exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES; exports.DEFAULT_MAINTENANCE_MAX_WAIT_MS = DEFAULT_MAINTENANCE_MAX_WAIT_MS; exports.DEFAULT_MAINTENANCE_POLL_MS = DEFAULT_MAINTENANCE_POLL_MS; exports.DEFAULT_MAX_CONCURRENT = DEFAULT_MAX_CONCURRENT; exports.DEFAULT_MAX_RESPONSE_BYTES = DEFAULT_MAX_RESPONSE_BYTES; exports.DEFAULT_MAX_SCAN_RECORDS = DEFAULT_MAX_SCAN_RECORDS; exports.DEFAULT_MAX_SCAN_PAGES = DEFAULT_MAX_SCAN_PAGES; exports.DEFAULT_READ_CACHE_TTL_MS = DEFAULT_READ_CACHE_TTL_MS; exports.DEFAULT_FIELD_CACHE_TTL_MS = DEFAULT_FIELD_CACHE_TTL_MS; exports.DEFAULT_RESOURCE_NAME_CACHE_TTL_MS = DEFAULT_RESOURCE_NAME_CACHE_TTL_MS; exports.zoneUrl = zoneUrl; exports.resolveBaseUrl = resolveBaseUrl; exports.resolveCredentials = resolveCredentials; exports.resolveConfig = resolveConfig; exports.isRecord = isRecord2; exports.assertRecord = assertRecord; exports.deepMergeParams = deepMergeParams; exports.isIdentifierCandidate = isIdentifierCandidate; exports.parseIdentifier = parseIdentifier; exports.flattenUdfs = flattenUdfs; exports.newCorrelationId = newCorrelationId; exports.redactAuditBody = redactAuditBody; exports.camelKey = camelKey; exports.FILTER_OPERATORS = FILTER_OPERATORS; exports.GROUPING_OPERATORS = GROUPING_OPERATORS; exports.MAX_OR_CONDITIONS = MAX_OR_CONDITIONS; exports.MAX_UDF_PER_QUERY = MAX_UDF_PER_QUERY; exports.MAX_QUERY_LENGTH = MAX_QUERY_LENGTH; exports.MAX_GET_LENGTH = MAX_GET_LENGTH; exports.MAX_FIELD_LENGTH = MAX_FIELD_LENGTH; exports.isFilterOperator = isFilterOperator; exports.serializeFilter = serializeFilter; exports.validateFilter = validateFilter; exports.buildFilter = buildFilter; exports.normalizedConditions = normalizedConditions; exports.RELATIONSHIP_ZONE = RELATIONSHIP_ZONE; exports.RELATIONSHIP_MAP = RELATIONSHIP_MAP; exports.BLIND_SURFACE_STAMPS = BLIND_SURFACE_STAMPS; exports.DELETE_BOUNDARY_NOTES = DELETE_BOUNDARY_NOTES; exports.MARKER_FIELDS = MARKER_FIELDS; exports.EMPTY_REASON_STAMPS = EMPTY_REASON_STAMPS; exports.BLIND_SURFACE_INVENTORY = BLIND_SURFACE_INVENTORY; exports.REACHABILITY_PROBE_DEFAULTS = REACHABILITY_PROBE_DEFAULTS; exports.CREATE_GUIDANCE = CREATE_GUIDANCE; exports.UNTRUSTED_FIELDS_BY_RESOURCE = UNTRUSTED_FIELDS_BY_RESOURCE; exports.IDEMPOTENT_METHODS = IDEMPOTENT_METHODS; exports.buildUrl = buildUrl; exports.cursorToPath = cursorToPath; exports.buildQueryRequest = buildQueryRequest; exports.runWithSignal = runWithSignal; exports.HttpClient = HttpClient; exports.unwrapItems = unwrapItems; exports.unwrapItem = unwrapItem; exports.unwrapQueryCount = unwrapQueryCount; exports.unwrapOperation = unwrapOperation; exports.passthrough = passthrough; exports.MAX_PAGES = MAX_PAGES; exports.clampPageSize = clampPageSize; exports.totalPagesFor = totalPagesFor; exports.paginate = paginate; exports.paginateItems = paginateItems; exports.collectAll = collectAll; exports.toArray = toArray; exports.FIELD_PRESETS = FIELD_PRESETS; exports.FIELD_PRESET_NAMES = FIELD_PRESET_NAMES; exports.resolveFieldsPreset = resolveFieldsPreset; exports.BOUNDED_QUERY_MAX_LIMIT = BOUNDED_QUERY_MAX_LIMIT; exports.truncateNoteChars = truncateNoteChars; exports.buildDryRunResult = buildDryRunResult; exports.mergePartialBody = mergePartialBody; exports.blindStampFor = blindStampFor; exports.decodeFileData = decodeFileData; exports.BaseResource = BaseResource; exports.EXPAND_RESOURCE_NAMES_MAX_IDS = EXPAND_RESOURCE_NAMES_MAX_IDS; exports.expandResourceNames = expandResourceNames; exports.WORKFLOW_RESOURCES = WORKFLOW_RESOURCES; exports.MAX_FIELD_CATALOG_WIRE = MAX_FIELD_CATALOG_WIRE; exports.FIELD_CATALOG_HONESTY_NOTE = FIELD_CATALOG_HONESTY_NOTE; exports.fieldCatalog = fieldCatalog; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = PICKLIST_VALUE_NOT_SERVED_NOTE; exports.TICKET_LABEL_FIELDS = TICKET_LABEL_FIELDS; exports.createNamePlan = createNamePlan; exports.addNameSibling = addNameSibling; exports.addLabelSibling = addLabelSibling; exports.resolveCompositeNames = resolveCompositeNames; exports.MODEL_FIELD_SETS = MODEL_FIELD_SETS; exports.MODEL_DATE_FIELDS = MODEL_DATE_FIELDS; exports.FETCH_MANY_MAX_ITEMS = FETCH_MANY_MAX_ITEMS; exports.validateFetchManyItems = validateFetchManyItems; exports.fetchMany = fetchMany; exports.FETCH_BY_IDS_MAX_ITEMS = FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_BY_IDS_CHUNK_SIZE = FETCH_BY_IDS_CHUNK_SIZE; exports.fetchByIds = fetchByIds;