node-autotask 0.18.0 → 0.20.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 (39) hide show
  1. package/ARCHITECTURE.md +15 -8
  2. package/CHANGELOG.md +590 -0
  3. package/MCP_TOOL_CATALOG.json +6 -6
  4. package/MCP_TOOL_MANIFEST.md +128 -128
  5. package/N8N_MCP_MANIFEST.json +44 -9
  6. package/N8N_MCP_MANIFEST.md +8 -8
  7. package/README.md +8 -4
  8. package/capabilities.json +1941 -1829
  9. package/capabilities.schema.json +6 -0
  10. package/dist/capabilities.cjs +2 -2
  11. package/dist/capabilities.js +1 -1
  12. package/dist/{chunk-VV2UUW2J.js → chunk-2T77J2ZM.js} +1940 -1828
  13. package/dist/{chunk-5O5EPYBO.cjs → chunk-FLYTKJKV.cjs} +1940 -1828
  14. package/dist/{chunk-VYUZZIEE.js → chunk-GA6UCX3Z.js} +292 -58
  15. package/dist/{chunk-W2WSZOZA.js → chunk-JEJUFXHX.js} +2 -2
  16. package/dist/{chunk-WRWX6WIK.cjs → chunk-L6V66V22.cjs} +360 -126
  17. package/dist/{chunk-G564CHXM.cjs → chunk-RMLGOCGA.cjs} +135 -135
  18. package/dist/{chunk-HXOWEYV3.js → chunk-XSYJB4IW.js} +3 -3
  19. package/dist/{chunk-7I3F3AJJ.cjs → chunk-YH5CPRDN.cjs} +394 -394
  20. package/dist/{index-D7x3MkLK.d.cts → index-AN-NjLi9.d.cts} +126 -21
  21. package/dist/{index-BqPY04ZG.d.ts → index-CvLLsOCP.d.ts} +126 -21
  22. package/dist/index.cjs +24 -22
  23. package/dist/index.d.cts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +6 -4
  26. package/dist/operations/index.cjs +184 -136
  27. package/dist/operations/index.d.cts +2 -2
  28. package/dist/operations/index.d.ts +2 -2
  29. package/dist/operations/index.js +79 -31
  30. package/dist/pool.cjs +8 -8
  31. package/dist/pool.d.cts +1 -1
  32. package/dist/pool.d.ts +1 -1
  33. package/dist/pool.js +4 -4
  34. package/dist/resources/index.cjs +4 -4
  35. package/dist/resources/index.d.cts +1 -1
  36. package/dist/resources/index.d.ts +1 -1
  37. package/dist/resources/index.js +3 -3
  38. package/docs/API.md +126 -40
  39. package/package.json +2 -1
@@ -1,6 +1,6 @@
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;
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; var _class7;
2
2
 
3
- var _chunk5O5EPYBOcjs = require('./chunk-5O5EPYBO.cjs');
3
+ var _chunkFLYTKJKVcjs = require('./chunk-FLYTKJKV.cjs');
4
4
 
5
5
  // src/auth.ts
6
6
  var AUTH_HEADERS = {
@@ -1536,6 +1536,7 @@ var DEFAULT_TIMEOUT_MS = 3e4;
1536
1536
  var DEFAULT_MAX_RETRIES = 3;
1537
1537
  var DEFAULT_MAINTENANCE_MAX_WAIT_MS = 36e5;
1538
1538
  var DEFAULT_MAINTENANCE_POLL_MS = 3e4;
1539
+ var MAINTENANCE_WINDOW_MAX_MS = 4 * 36e5;
1539
1540
  var DEFAULT_MAX_CONCURRENT = 10;
1540
1541
  var DEFAULT_MAX_RESPONSE_BYTES = 64 * 1024 * 1024;
1541
1542
  var DEFAULT_MAX_SCAN_RECORDS = 500;
@@ -2073,6 +2074,88 @@ function refusedFilterShape(filter) {
2073
2074
  // src/http.ts
2074
2075
  var _async_hooks = require('async_hooks');
2075
2076
 
2077
+ // src/latest-count-cache.ts
2078
+ var LATEST_COUNT_CACHE_TTL_MS = 3e4;
2079
+ var LATEST_COUNT_CACHE_MAX_ENTRIES = 4096;
2080
+ var LatestCountCache = (_class6 = class {
2081
+ /** The TTL in ms. */
2082
+
2083
+ /** The entry bound (applies to STORED entries). */
2084
+
2085
+ __init10() {this.store = /* @__PURE__ */ new Map()}
2086
+ /** The invalidation epoch (the `ReadCache` pattern — issue #139): bumped
2087
+ * by `clear()`; capture it before a wire read and pass it to `set` so a
2088
+ * probe in flight across a write cannot re-store its stale answer. */
2089
+ __init11() {this.epochCounter = 0}
2090
+ constructor(ttlMs, maxEntries = LATEST_COUNT_CACHE_MAX_ENTRIES) {;_class6.prototype.__init10.call(this);_class6.prototype.__init11.call(this);
2091
+ if (!Number.isInteger(ttlMs) || ttlMs <= 0) {
2092
+ throw new AutotaskConfigError(`latestCountCache.ttlMs must be a positive integer (got ${String(ttlMs)})`);
2093
+ }
2094
+ if (!Number.isInteger(maxEntries) || maxEntries <= 0) {
2095
+ throw new AutotaskConfigError(`latestCountCache.maxEntries must be a positive integer (got ${String(maxEntries)})`);
2096
+ }
2097
+ this.ttlMs = ttlMs;
2098
+ this.maxEntries = maxEntries;
2099
+ }
2100
+ /** The composite key: (resource plan key, canonical filter serialisation)
2101
+ * — the `\u0000` separator is unencodable in a filter value, so no two
2102
+ * (resource, conditions) pairs collide. */
2103
+ static key(resourceKey, conditions) {
2104
+ return `${resourceKey}\0${JSON.stringify(_nullishCoalesce(conditions, () => ( [])))}`;
2105
+ }
2106
+ /** The live entry's count, or `undefined` (absent OR expired — an expired
2107
+ * entry is purged lazily on this read). */
2108
+ get(key) {
2109
+ const entry = this.store.get(key);
2110
+ if (entry === void 0) return void 0;
2111
+ if (entry.expiresAt <= Date.now()) {
2112
+ this.store.delete(key);
2113
+ return void 0;
2114
+ }
2115
+ return entry.value;
2116
+ }
2117
+ /** The invalidation epoch: bumped by `clear()`; capture it before a wire
2118
+ * read and pass it to `set` so a probe in flight across a write cannot
2119
+ * re-store its stale answer (issue #139, the `ReadCache` pattern). */
2120
+ get epoch() {
2121
+ return this.epochCounter;
2122
+ }
2123
+ /** Store a SUCCESSFUL plain-number count under `key`, live for `ttlMs`.
2124
+ * `epoch` is the invalidation epoch the caller captured BEFORE its wire
2125
+ * read: a probe that straddled a `clear()` (a write) is dropped, never
2126
+ * re-stored with its pre-write body (issue #139). Past the cap: purge
2127
+ * expired entries first, then evict the oldest-inserted (Map iteration
2128
+ * order = insertion order). */
2129
+ set(key, value, epoch = this.epochCounter) {
2130
+ if (epoch !== this.epochCounter) return;
2131
+ if (!Number.isFinite(value)) return;
2132
+ const entry = { value, expiresAt: Date.now() + this.ttlMs };
2133
+ if (!this.store.has(key) && this.store.size >= this.maxEntries) {
2134
+ for (const [k, e] of this.store) {
2135
+ if (e.expiresAt <= Date.now()) this.store.delete(k);
2136
+ }
2137
+ if (this.store.size >= this.maxEntries) {
2138
+ const oldest = this.store.keys().next();
2139
+ if (!oldest.done) this.store.delete(oldest.value);
2140
+ }
2141
+ }
2142
+ this.store.set(key, entry);
2143
+ }
2144
+ /** Drop one entry (absent = no-op). Issue #157: the stale-LOW recovery
2145
+ * deletes the cached total before its one fresh wire re-probe, so the
2146
+ * re-probe cannot be served by the entry it is meant to replace. */
2147
+ delete(key) {
2148
+ this.store.delete(key);
2149
+ }
2150
+ /** Clear every entry (a real write through the owning client — the
2151
+ * write-then-read re-fetch rule) and bump the invalidation epoch: a
2152
+ * `set` captured before this `clear` is discarded (issue #139). */
2153
+ clear() {
2154
+ this.epochCounter += 1;
2155
+ this.store.clear();
2156
+ }
2157
+ }, _class6);
2158
+
2076
2159
  // src/relationships.ts
2077
2160
  var RELATIONSHIP_ZONE = {
2078
2161
  "zone": "ww29",
@@ -8305,7 +8388,7 @@ var RELATIONSHIP_MAP = {
8305
8388
  ],
8306
8389
  "naturalKeys": {
8307
8390
  "hasSearch": true,
8308
- "searchCovers": "title only (contains); ticketNumber lookups use resolve / findByTicketNumber",
8391
+ "searchCovers": "title only (contains \u2014 the vendor's contains match is looser than a literal substring (case/token matching): a search can return MORE hits than a local title-substring check (measured 2026-10-19: 25 vs 24); a per-field contains filter in tickets.query is the precise tool); ticketNumber lookups use resolve / findByTicketNumber",
8309
8392
  "findBy": [
8310
8393
  "findByTicketNumber"
8311
8394
  ]
@@ -10252,8 +10335,8 @@ var EMPTY_REASON_STAMPS = {
10252
10335
  var POINTER_NOTES = {
10253
10336
  "ticket_history.query": `W1 (ww29 (australia-nz) live 2026-10-04; vendor contract change live-verified 2026-10-06): the vendor requires ticket_history.query to be supplied with exactly ONE ticketID-equals filter \u2014 an unfiltered call 500s by contract (10-06 text: "When querying the TicketHistory entity you are required to supply one and only one ticketID equals filter"). WITH the filter the query WORKS (live 2026-10-06: rows returned, hasMore true \u2014 a single {op:'eq', field:'ticketID', value:<id>} condition; the filter vocabulary is eq/noteq/gt/gte/lt/lte/beginsWith/endsWith/contains/exist/notExist/in/notIn/and/or). tickets.timeline / tickets.fullContext remain the convenient composites; raw history rows come from the filtered query.`,
10254
10337
  "time_entries.create": `W-A3 (ww29 (australia-nz) live 2026-10-04; drift re-verified 2026-10-06): the vendor now refuses ALL time-entry writes for this API-only user with "API-only user cannot be selected for this field" (10-04 text: "The specified AssignedResourceID and AssignedRoleID combination is not currently defined"). UNSATISFIABLE for an API-only integration user: the resources table is blind (0 rows) and the only selectable resource is the user's own API-only record, which the vendor refuses. createForResource \u2014 stage-11 PROVEN (8 live creates, 10-04) \u2014 is walled by the SAME drift (confirm-100 receipt 2026-10-06). Tenant evidence that valid pairs exist: postedWithin rows (resourceID 31131373 / 29869529 with roleID 29682834) \u2014 human resources the API user cannot select.`,
10255
- "time_entries.getPosted": `W-D3 (ww29 (australia-nz) live 2026-10-04, re-verified live 2026-10-15): this zone's TimeEntry entity exposes NO posted-state filter field \u2014 the vendor rejects postingStatus, postedDate and status with "Unable to find X in the TimeEntry Entity" (live field-existence oracle 2026-10-04: only dateWorked / resourceID / ticketID / taskID resolve as filter fields). Re-probed 2026-10-15 (ww29 re-probe campaign): time_entries.getPosted live 500, vendor body verbatim 'Unable to find postedDate in the TimeEntry Entity.' \u2014 a vendor endpoint defect on AU03, not a transient fault: posted cannot be filtered server-side on this zone \u2014 use time_entries.postedWithin (the dateWorked window, live-verified working) or read time_entries.query and derive posted-state from the fields your zone's entity exposes`,
10256
- "time_entries.getUnposted": `W-D3 (ww29 (australia-nz) live 2026-10-04, re-verified live 2026-10-15): this zone's TimeEntry entity exposes NO posted-state filter field \u2014 the vendor rejects postingStatus, postedDate and status with "Unable to find X in the TimeEntry Entity" (live field-existence oracle 2026-10-04: only dateWorked / resourceID / ticketID / taskID resolve as filter fields). Re-probed 2026-10-15 (ww29 re-probe campaign): time_entries.getUnposted live 500, vendor body verbatim 'Unable to find postedDate in the TimeEntry Entity.' \u2014 a vendor endpoint defect on AU03, not a transient fault: unposted cannot be filtered server-side on this zone \u2014 use time_entries.postedWithin (the dateWorked window, live-verified working) or read time_entries.query and derive posted-state from the fields your zone's entity exposes`,
10338
+ "time_entries.getPosted": "W-D3 (ww29 (australia-nz) live 2026-10-04, re-verified live 2026-10-15): this zone's TimeEntry entity exposes NO posted-state filter field \u2014 the vendor rejects postingStatus, postedDate and status with \"Unable to find X in the TimeEntry Entity\" (live field-existence oracle 2026-10-04: only dateWorked / resourceID / ticketID / taskID resolve as filter fields). Re-probed 2026-10-15 (ww29 re-probe campaign): time_entries.getPosted live 500, vendor body verbatim 'Unable to find postedDate in the TimeEntry Entity.' \u2014 a vendor endpoint defect on AU03, not a transient fault: posted cannot be filtered server-side on this zone \u2014 use time_entries.postedWithin (the dateWorked window, live-verified working \u2014 omit the `posted` narrowing on this zone: it sends postedDate, which the zone 500s) or read time_entries.query and derive posted-state from the fields your zone's entity exposes",
10339
+ "time_entries.getUnposted": "W-D3 (ww29 (australia-nz) live 2026-10-04, re-verified live 2026-10-15): this zone's TimeEntry entity exposes NO posted-state filter field \u2014 the vendor rejects postingStatus, postedDate and status with \"Unable to find X in the TimeEntry Entity\" (live field-existence oracle 2026-10-04: only dateWorked / resourceID / ticketID / taskID resolve as filter fields). Re-probed 2026-10-15 (ww29 re-probe campaign): time_entries.getUnposted live 500, vendor body verbatim 'Unable to find postedDate in the TimeEntry Entity.' \u2014 a vendor endpoint defect on AU03, not a transient fault: unposted cannot be filtered server-side on this zone \u2014 use time_entries.postedWithin (the dateWorked window, live-verified working \u2014 omit the `posted` narrowing on this zone: it sends postedDate, which the zone 500s) or read time_entries.query and derive posted-state from the fields your zone's entity exposes",
10257
10340
  "authenticate.get": "W2: authenticate.get is DESIGNATOR-ONLY \u2014 it returns the designator identity, not a tenant data surface; a miss/empty here is not a data-empty signal (no emptyReason is attached by design \u2014 a false reason would be worse than none)"
10258
10341
  };
10259
10342
  var BLIND_SURFACE_INVENTORY = {
@@ -14779,9 +14862,21 @@ function backoffDelay(attempt) {
14779
14862
  const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
14780
14863
  return Math.floor(exp / 2 + Math.random() * (exp / 2));
14781
14864
  }
14782
- function isMaintenancePage(err) {
14783
- const snippet = typeof _optionalChain([err, 'access', _57 => _57.details, 'optionalAccess', _58 => _58.bodySnippet]) === "string" ? err.details.bodySnippet : "";
14784
- return /maintenance|temporarily unavailable|service unavailable|outage|downtime|down for/i.test(snippet);
14865
+ var MAINTENANCE_PROBE_BYTES = 256;
14866
+ function maintenanceProbe(text) {
14867
+ return Buffer.from(text, "utf8").subarray(0, MAINTENANCE_PROBE_BYTES).toString("utf8");
14868
+ }
14869
+ function looksLikeMaintenanceText(text) {
14870
+ return /maintenance|temporarily unavailable|service unavailable|outage|downtime|down for/i.test(
14871
+ maintenanceProbe(text)
14872
+ );
14873
+ }
14874
+ function isHtmlLike(contentType, body) {
14875
+ if (contentType !== null && /text\/html|application\/xhtml/i.test(contentType)) return true;
14876
+ return body.trimStart().startsWith("<");
14877
+ }
14878
+ function maintenanceExhaustedAction(maxWaitMs, waits) {
14879
+ return `The zone stayed in a maintenance window for ${Math.round(maxWaitMs / 6e4)} min \u2014 the SDK waited and retried ${waits} time(s) and gave up. Re-run after the window (the observed median is about 2 h; the ceiling is 4 h \u2014 MAINTENANCE_WINDOW_MAX_MS), or raise maintenanceMaxWaitMs.`;
14785
14880
  }
14786
14881
  function parseRetryAfter(value) {
14787
14882
  if (value === null || value.length === 0) return void 0;
@@ -14799,7 +14894,7 @@ function isAbortLike(err) {
14799
14894
  return typeof err === "object" && err !== null && "name" in err && err.name === "AbortError";
14800
14895
  }
14801
14896
  function isJsonMediaType(header) {
14802
- 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()]), () => ( ""));
14897
+ 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()]), () => ( ""));
14803
14898
  return mediaType.startsWith("application/json") || mediaType.endsWith("+json");
14804
14899
  }
14805
14900
  function bodySnippet(text, redactPersonalData) {
@@ -14846,7 +14941,7 @@ function credentialShapeExpectation(headers, auth) {
14846
14941
  ...problem !== void 0 ? { problem } : {}
14847
14942
  };
14848
14943
  }
14849
- var HttpClient = (_class6 = class {
14944
+ var HttpClient = (_class7 = class {
14850
14945
  /**
14851
14946
  * The LIVE base URL (issue #43): the construction-time value until a zone
14852
14947
  * re-point happens, then the tenant's newly resolved zone base. Reads are
@@ -14875,6 +14970,11 @@ var HttpClient = (_class6 = class {
14875
14970
 
14876
14971
  /** Resource-name cache for `operations.expandResourceNames` (issue #80: the default instance when `resourceNameCache` is absent; undefined only when the user set `false` explicitly, issue #65). */
14877
14972
 
14973
+ /** The `latest` walk's count-probe cache (issue #127: the short-TTL
14974
+ * per-client count cache — ALWAYS on, process-internal: no config
14975
+ * surface, no served keys; the plain `count` op and `operations.aggregate`
14976
+ * bypass it by construction and promise fresh totals). */
14977
+
14878
14978
  /** Resolved update fallback gate (issue #34; OFF by default). */
14879
14979
 
14880
14980
 
@@ -14888,7 +14988,7 @@ var HttpClient = (_class6 = class {
14888
14988
  * exhaustion `suggestedAction` (stop/narrow, never "raise the limit"). */
14889
14989
 
14890
14990
  /** Request timestamps inside the trailing hour (only used when `rateLimit.perHour` is set). */
14891
- __init10() {this.hourStamps = []}
14991
+ __init12() {this.hourStamps = []}
14892
14992
  /** Tenant 429 cooldown gate store (undefined when the gate is disabled). */
14893
14993
 
14894
14994
 
@@ -14932,14 +15032,15 @@ var HttpClient = (_class6 = class {
14932
15032
  * already travels in every auth header; nothing new crosses the boundary). */
14933
15033
 
14934
15034
 
14935
- __init11() {this.inFlight = 0}
14936
- __init12() {this.waitQueue = []}
14937
- constructor(config) {;_class6.prototype.__init10.call(this);_class6.prototype.__init11.call(this);_class6.prototype.__init12.call(this);
15035
+ __init13() {this.inFlight = 0}
15036
+ __init14() {this.waitQueue = []}
15037
+ constructor(config) {;_class7.prototype.__init12.call(this);_class7.prototype.__init13.call(this);_class7.prototype.__init14.call(this);
14938
15038
  this.liveBaseUrl = config.baseUrl;
14939
15039
  this.resolution = config.resolution;
14940
15040
  this.readCache = config.readCache;
14941
15041
  this.fieldCache = config.fieldCache;
14942
15042
  this.resourceNameCache = config.resourceNameCache;
15043
+ this.latestCountCache = new LatestCountCache(LATEST_COUNT_CACHE_TTL_MS);
14943
15044
  this.update = config.update;
14944
15045
  this.zone = config.zone;
14945
15046
  this.reResolveZoneOn401 = config.reResolveZoneOn401;
@@ -14955,7 +15056,7 @@ var HttpClient = (_class6 = class {
14955
15056
  this.maintenanceMaxWaitMs = config.maintenanceMaxWaitMs;
14956
15057
  this.maintenancePollMs = config.maintenancePollMs;
14957
15058
  this.maxResponseBytes = config.maxResponseBytes;
14958
- this.perHour = _optionalChain([config, 'access', _66 => _66.rateLimit, 'optionalAccess', _67 => _67.perHour]);
15059
+ this.perHour = _optionalChain([config, 'access', _64 => _64.rateLimit, 'optionalAccess', _65 => _65.perHour]);
14959
15060
  this.tenantKey = buildTenantKey(config.userName, config.baseUrl);
14960
15061
  this.cooldownStore = config.cooldown.enabled ? _nullishCoalesce(config.cooldown.store, () => ( defaultCooldownStore())) : void 0;
14961
15062
  this.cooldownMaxMs = config.cooldown.maxMs;
@@ -15016,7 +15117,7 @@ var HttpClient = (_class6 = class {
15016
15117
  };
15017
15118
  if (next.successes >= breaker.successesToClose) {
15018
15119
  breaker.store.delete(key);
15019
- _optionalChain([this, 'access', _68 => _68.logger, 'access', _69 => _69.warn, 'optionalCall', _70 => _70(
15120
+ _optionalChain([this, 'access', _66 => _66.logger, 'access', _67 => _67.warn, 'optionalCall', _68 => _68(
15020
15121
  `[autotask] circuit breaker CLOSED for ${key} (${next.successes} probe successes)`,
15021
15122
  void 0
15022
15123
  )]);
@@ -15046,7 +15147,7 @@ var HttpClient = (_class6 = class {
15046
15147
  const failures = [...st.failures.filter((t) => t > now - breaker.failureWindowMs), now];
15047
15148
  if (failures.length >= breaker.failureThreshold) {
15048
15149
  breaker.store.set(key, { failures, openedAt: now, successes: 0, probes: 0 });
15049
- _optionalChain([this, 'access', _71 => _71.logger, 'access', _72 => _72.warn, 'optionalCall', _73 => _73(
15150
+ _optionalChain([this, 'access', _69 => _69.logger, 'access', _70 => _70.warn, 'optionalCall', _71 => _71(
15050
15151
  `[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`,
15051
15152
  correlationId
15052
15153
  )]);
@@ -15161,7 +15262,7 @@ var HttpClient = (_class6 = class {
15161
15262
  return void 0;
15162
15263
  }
15163
15264
  if (res.status < 200 || res.status >= 300) {
15164
- await _optionalChain([res, 'access', _74 => _74.body, 'optionalAccess', _75 => _75.cancel, 'call', _76 => _76(), 'access', _77 => _77.catch, 'call', _78 => _78(() => void 0)]);
15265
+ await _optionalChain([res, 'access', _72 => _72.body, 'optionalAccess', _73 => _73.cancel, 'call', _74 => _74(), 'access', _75 => _75.catch, 'call', _76 => _76(() => void 0)]);
15165
15266
  return void 0;
15166
15267
  }
15167
15268
  let text;
@@ -15197,7 +15298,7 @@ var HttpClient = (_class6 = class {
15197
15298
  this.liveBaseUrl = to;
15198
15299
  this.tenantKey = buildTenantKey(this.auth.userName, to);
15199
15300
  this.breakerKey = buildBreakerKey(to);
15200
- _optionalChain([this, 'access', _79 => _79.logger, 'access', _80 => _80.warn, 'optionalCall', _81 => _81(
15301
+ _optionalChain([this, 'access', _77 => _77.logger, 'access', _78 => _78.warn, 'optionalCall', _79 => _79(
15201
15302
  `[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`,
15202
15303
  void 0
15203
15304
  )]);
@@ -15217,6 +15318,7 @@ var HttpClient = (_class6 = class {
15217
15318
  const maintenancePollMs = _nullishCoalesce(opts.maintenancePollMs, () => ( this.maintenancePollMs));
15218
15319
  let firstMaintenanceAt;
15219
15320
  let maintenanceWaits = 0;
15321
+ let maintenanceBudgetSpent = false;
15220
15322
  const started = Date.now();
15221
15323
  let deadlineAt = started + timeoutMs;
15222
15324
  const callerSignal = _nullishCoalesce(opts.signal, () => ( ambientSignal.getStore()));
@@ -15235,7 +15337,7 @@ var HttpClient = (_class6 = class {
15235
15337
  const expectBody = _nullishCoalesce(opts.expectBody, () => ( method !== "DELETE"));
15236
15338
  const ctx = { operation: opts.operation, url, correlationId };
15237
15339
  let lastStatus;
15238
- 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);
15340
+ 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);
15239
15341
  const canWait = (delay) => delay <= MAX_RETRY_DELAY_MS && delay < deadlineAt - Date.now();
15240
15342
  const pause = async (delay) => {
15241
15343
  try {
@@ -15249,7 +15351,7 @@ var HttpClient = (_class6 = class {
15249
15351
  if (deadline2 !== void 0) {
15250
15352
  const remainingMs = deadline2 - Date.now();
15251
15353
  if (remainingMs > 0) {
15252
- if (_optionalChain([callerSignal, 'optionalAccess', _83 => _83.aborted])) throw interrupted();
15354
+ if (_optionalChain([callerSignal, 'optionalAccess', _81 => _81.aborted])) throw interrupted();
15253
15355
  const seconds = Math.ceil(remainingMs / 1e3);
15254
15356
  const err = new RateLimitError(
15255
15357
  `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.`,
@@ -15280,7 +15382,7 @@ var HttpClient = (_class6 = class {
15280
15382
  let breakerProbe = false;
15281
15383
  let breakerProbeKey;
15282
15384
  if (this.breaker !== void 0 && !opts.bypassCircuitBreaker) {
15283
- if (_optionalChain([callerSignal, 'optionalAccess', _84 => _84.aborted])) throw interrupted();
15385
+ if (_optionalChain([callerSignal, 'optionalAccess', _82 => _82.aborted])) throw interrupted();
15284
15386
  const now = Date.now();
15285
15387
  const st = this.breaker.store.get(this.breakerKey);
15286
15388
  if (st !== void 0 && st.openedAt !== null) {
@@ -15338,7 +15440,7 @@ var HttpClient = (_class6 = class {
15338
15440
  breakerProbeKey = this.breakerKey;
15339
15441
  }
15340
15442
  }
15341
- _optionalChain([this, 'access', _85 => _85.logger, 'access', _86 => _86.debug, 'optionalCall', _87 => _87(`[autotask] ${method} ${opts.path}`, correlationId)]);
15443
+ _optionalChain([this, 'access', _83 => _83.logger, 'access', _84 => _84.debug, 'optionalCall', _85 => _85(`[autotask] ${method} ${opts.path}`, correlationId)]);
15342
15444
  try {
15343
15445
  let attempt = 0;
15344
15446
  let outcome = null;
@@ -15358,7 +15460,7 @@ var HttpClient = (_class6 = class {
15358
15460
  if (signal.aborted || isAbortLike(err2)) throw interrupted();
15359
15461
  const delay = backoffDelay(attempt);
15360
15462
  if (attempt < maxRetries && retriable5xx && canWait(delay)) {
15361
- _optionalChain([this, 'access', _88 => _88.logger, 'access', _89 => _89.warn, 'optionalCall', _90 => _90(
15463
+ _optionalChain([this, 'access', _86 => _86.logger, 'access', _87 => _87.warn, 'optionalCall', _88 => _88(
15362
15464
  `[autotask] network error on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15363
15465
  correlationId
15364
15466
  )]);
@@ -15376,7 +15478,7 @@ var HttpClient = (_class6 = class {
15376
15478
  try {
15377
15479
  status = res.status;
15378
15480
  if (status >= 300 && status < 400) {
15379
- await _optionalChain([res, 'access', _91 => _91.body, 'optionalAccess', _92 => _92.cancel, 'call', _93 => _93(), 'access', _94 => _94.catch, 'call', _95 => _95(() => void 0)]);
15481
+ await _optionalChain([res, 'access', _89 => _89.body, 'optionalAccess', _90 => _90.cancel, 'call', _91 => _91(), 'access', _92 => _92.catch, 'call', _93 => _93(() => void 0)]);
15380
15482
  throw new ResponseRejectedError(
15381
15483
  `Refused to follow a ${status} redirect for ${method} ${opts.path}`,
15382
15484
  { ...ctx, code: "REDIRECT_BLOCKED", httpStatus: status, suggestedAction: "Check the configured zone/baseUrl; the API does not redirect." }
@@ -15437,14 +15539,15 @@ var HttpClient = (_class6 = class {
15437
15539
  httpStatus: status,
15438
15540
  suggestedAction: "The zone returned a non-JSON 2xx body; verify baseUrl points at the REST API."
15439
15541
  });
15440
- if (err2.code === "UNEXPECTED_CONTENT_TYPE" && maintenanceMaxWaitMs > 0 && isMaintenancePage(err2)) {
15542
+ if (err2.code === "UNEXPECTED_CONTENT_TYPE" && maintenanceMaxWaitMs > 0 && looksLikeMaintenanceText(text)) {
15441
15543
  const now = Date.now();
15442
15544
  firstMaintenanceAt ??= now;
15443
15545
  const remaining = maintenanceMaxWaitMs - (now - firstMaintenanceAt);
15444
15546
  if (remaining > 0) {
15445
15547
  const wait = Math.min(maintenancePollMs, remaining);
15548
+ if (wait >= remaining) maintenanceBudgetSpent = true;
15446
15549
  maintenanceWaits += 1;
15447
- _optionalChain([this, 'access', _96 => _96.logger, 'access', _97 => _97.warn, 'optionalCall', _98 => _98(
15550
+ _optionalChain([this, 'access', _94 => _94.logger, 'access', _95 => _95.warn, 'optionalCall', _96 => _96(
15448
15551
  `[autotask] maintenance window on ${method} ${opts.path}; waiting ${Math.round(wait / 1e3)}s (retry ${maintenanceWaits}, up to ${Math.round(maintenanceMaxWaitMs / 6e4)} min)`,
15449
15552
  correlationId
15450
15553
  )]);
@@ -15453,12 +15556,13 @@ var HttpClient = (_class6 = class {
15453
15556
  await pause(wait);
15454
15557
  continue;
15455
15558
  }
15559
+ maintenanceBudgetSpent = true;
15456
15560
  }
15457
15561
  if (err2.code === "UNEXPECTED_CONTENT_TYPE" && retriable5xx && attempt < maxRetries) {
15458
15562
  const retryAfter = parseRetryAfter(res.headers.get("Retry-After"));
15459
15563
  const delay = retryAfter !== void 0 ? retryAfter * 1e3 : backoffDelay(attempt);
15460
15564
  if (canWait(delay)) {
15461
- _optionalChain([this, 'access', _99 => _99.logger, 'access', _100 => _100.warn, 'optionalCall', _101 => _101(
15565
+ _optionalChain([this, 'access', _97 => _97.logger, 'access', _98 => _98.warn, 'optionalCall', _99 => _99(
15462
15566
  `[autotask] non-JSON 2xx on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15463
15567
  correlationId
15464
15568
  )]);
@@ -15467,17 +15571,27 @@ var HttpClient = (_class6 = class {
15467
15571
  continue;
15468
15572
  }
15469
15573
  }
15470
- if (maintenanceWaits > 0 && err2.code === "UNEXPECTED_CONTENT_TYPE") {
15574
+ const pageSnippet = typeof _optionalChain([err2, 'access', _100 => _100.details, 'optionalAccess', _101 => _101.bodySnippet]) === "string" ? err2.details.bodySnippet : "";
15575
+ if (maintenanceWaits > 0) {
15471
15576
  err2.details = {
15472
15577
  ..._nullishCoalesce(err2.details, () => ( {})),
15473
15578
  maintenance: {
15474
15579
  waits: maintenanceWaits,
15475
15580
  waitedMs: Date.now() - (_nullishCoalesce(firstMaintenanceAt, () => ( Date.now()))),
15476
15581
  maxWaitMs: maintenanceMaxWaitMs,
15477
- exhausted: true
15582
+ exhausted: maintenanceBudgetSpent
15478
15583
  }
15479
15584
  };
15480
- 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.`;
15585
+ if (maintenanceBudgetSpent) {
15586
+ err2.suggestedAction = maintenanceExhaustedAction(maintenanceMaxWaitMs, maintenanceWaits);
15587
+ }
15588
+ }
15589
+ if (err2.code === "UNEXPECTED_CONTENT_TYPE" && !looksLikeMaintenanceText(text) && isHtmlLike(res.headers.get("Content-Type"), text)) {
15590
+ err2.details = { ..._nullishCoalesce(err2.details, () => ( {})), maintenancePatternMiss: true };
15591
+ _optionalChain([this, 'access', _102 => _102.logger, 'access', _103 => _103.debug, 'optionalCall', _104 => _104(
15592
+ `[autotask] non-JSON body did not match the maintenance vocabulary on ${method} ${opts.path}: ${pageSnippet}`,
15593
+ correlationId
15594
+ )]);
15481
15595
  }
15482
15596
  attachEmptyReasonDetails(err2);
15483
15597
  throw err2;
@@ -15489,20 +15603,45 @@ var HttpClient = (_class6 = class {
15489
15603
  break;
15490
15604
  }
15491
15605
  let body;
15606
+ let nonJsonBody;
15492
15607
  if (text.length > 0) {
15493
15608
  try {
15494
15609
  body = JSON.parse(text);
15495
15610
  } catch (e13) {
15496
15611
  body = text;
15612
+ nonJsonBody = text;
15497
15613
  }
15498
15614
  }
15615
+ const nonJsonSnippet = nonJsonBody === void 0 ? void 0 : bodySnippet(nonJsonBody, this.redactPersonalData);
15616
+ const nonJsonIsMaintenance = nonJsonBody !== void 0 && looksLikeMaintenanceText(nonJsonBody);
15617
+ const nonJsonIsHtmlCandidate = nonJsonBody !== void 0 && isHtmlLike(res.headers.get("Content-Type"), nonJsonBody);
15618
+ const nonJsonMaintenanceMayWait = nonJsonIsMaintenance && retriable5xx;
15619
+ if (nonJsonBody !== void 0 && maintenanceMaxWaitMs > 0 && nonJsonMaintenanceMayWait) {
15620
+ const now = Date.now();
15621
+ firstMaintenanceAt ??= now;
15622
+ const remaining = maintenanceMaxWaitMs - (now - firstMaintenanceAt);
15623
+ if (remaining > 0) {
15624
+ const wait = Math.min(maintenancePollMs, remaining);
15625
+ if (wait >= remaining) maintenanceBudgetSpent = true;
15626
+ maintenanceWaits += 1;
15627
+ _optionalChain([this, 'access', _105 => _105.logger, 'access', _106 => _106.warn, 'optionalCall', _107 => _107(
15628
+ `[autotask] maintenance window on ${method} ${opts.path} (HTTP ${status}); waiting ${Math.round(wait / 1e3)}s (retry ${maintenanceWaits}, up to ${Math.round(maintenanceMaxWaitMs / 6e4)} min)`,
15629
+ correlationId
15630
+ )]);
15631
+ deadlineAt = Date.now() + wait + timeoutMs;
15632
+ armDeadline(deadlineAt - Date.now());
15633
+ await pause(wait);
15634
+ continue;
15635
+ }
15636
+ maintenanceBudgetSpent = true;
15637
+ }
15499
15638
  const deterministic500 = status >= 500 && isDeterministicVendor500(parseVendorErrors(body));
15500
15639
  const retryableStatus = status === 429 || status >= 500;
15501
15640
  if (retryableStatus && !deterministic500 && attempt < maxRetries && (status === 429 ? retriable : retriable5xx)) {
15502
15641
  const retryAfter = parseRetryAfter(res.headers.get("Retry-After"));
15503
15642
  const delay = retryAfter !== void 0 ? retryAfter * 1e3 : backoffDelay(attempt);
15504
15643
  if (canWait(delay)) {
15505
- _optionalChain([this, 'access', _102 => _102.logger, 'access', _103 => _103.warn, 'optionalCall', _104 => _104(
15644
+ _optionalChain([this, 'access', _108 => _108.logger, 'access', _109 => _109.warn, 'optionalCall', _110 => _110(
15506
15645
  `[autotask] ${status} on ${method} ${opts.path}; retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`,
15507
15646
  correlationId
15508
15647
  )]);
@@ -15515,7 +15654,7 @@ var HttpClient = (_class6 = class {
15515
15654
  const target = await this.discoverZoneBase(signal, ctx);
15516
15655
  const targetViolation = target === void 0 || this.hostPolicy === void 0 ? null : decideHostPolicy(target, this.hostPolicy);
15517
15656
  if (targetViolation !== null) {
15518
- _optionalChain([this, 'access', _105 => _105.logger, 'access', _106 => _106.warn, 'optionalCall', _107 => _107(
15657
+ _optionalChain([this, 'access', _111 => _111.logger, 'access', _112 => _112.warn, 'optionalCall', _113 => _113(
15519
15658
  `[autotask] zone re-point refused by hostPolicy (${targetViolation.bound}): ${targetViolation.origin} \u2014 the original 401 propagates, zero wire to the refused host`,
15520
15659
  void 0
15521
15660
  )]);
@@ -15537,6 +15676,32 @@ var HttpClient = (_class6 = class {
15537
15676
  credentialShapeExpectation(headers, this.auth)
15538
15677
  );
15539
15678
  err.correlationId = correlationId;
15679
+ if (maintenanceWaits > 0) {
15680
+ err.details = {
15681
+ ..._nullishCoalesce(err.details, () => ( {})),
15682
+ maintenance: {
15683
+ waits: maintenanceWaits,
15684
+ waitedMs: Date.now() - (_nullishCoalesce(firstMaintenanceAt, () => ( Date.now()))),
15685
+ maxWaitMs: maintenanceMaxWaitMs,
15686
+ exhausted: maintenanceBudgetSpent
15687
+ }
15688
+ };
15689
+ if (maintenanceBudgetSpent) {
15690
+ err.suggestedAction = maintenanceExhaustedAction(maintenanceMaxWaitMs, maintenanceWaits);
15691
+ }
15692
+ }
15693
+ if (nonJsonBody !== void 0) {
15694
+ if (nonJsonIsMaintenance && !retriable5xx) {
15695
+ err.details = { ..._nullishCoalesce(err.details, () => ( {})), maintenanceDetected: true };
15696
+ err.suggestedAction = `A maintenance-shaped page answered ${method} ${opts.path} (HTTP ${status}); it was NOT waited out or re-sent \u2014 a non-2xx edge page can arrive after the request was forwarded, so verify the record before re-issuing (only a GET or an explicitly idempotent-flagged call waits this window out).`;
15697
+ } else if (!nonJsonIsMaintenance && nonJsonIsHtmlCandidate) {
15698
+ err.details = { ..._nullishCoalesce(err.details, () => ( {})), maintenancePatternMiss: true };
15699
+ _optionalChain([this, 'access', _114 => _114.logger, 'access', _115 => _115.debug, 'optionalCall', _116 => _116(
15700
+ `[autotask] non-JSON body did not match the maintenance vocabulary on ${method} ${opts.path}: ${nonJsonSnippet}`,
15701
+ correlationId
15702
+ )]);
15703
+ }
15704
+ }
15540
15705
  if (status === 401 && zoneRetry !== void 0) {
15541
15706
  err.details = {
15542
15707
  ..._nullishCoalesce(err.details, () => ( {})),
@@ -15553,7 +15718,7 @@ var HttpClient = (_class6 = class {
15553
15718
  threadThreshold
15554
15719
  });
15555
15720
  this.cooldownStore.set(this.tenantKey, Date.now() + durationMs);
15556
- _optionalChain([this, 'access', _108 => _108.logger, 'access', _109 => _109.warn, 'optionalCall', _110 => _110(
15721
+ _optionalChain([this, 'access', _117 => _117.logger, 'access', _118 => _118.warn, 'optionalCall', _119 => _119(
15557
15722
  `[autotask] 429 on ${method} ${opts.path} surfaces after ${attempt + 1} attempt(s); tenant cooldown armed for ${Math.round(durationMs / 1e3)}s`,
15558
15723
  correlationId
15559
15724
  )]);
@@ -15598,7 +15763,7 @@ var HttpClient = (_class6 = class {
15598
15763
  if (this.fieldCache !== void 0 && err instanceof AutotaskError) {
15599
15764
  const op = typeof opts.operation === "string" ? opts.operation : void 0;
15600
15765
  const verb = op !== void 0 ? op.slice(op.lastIndexOf(".") + 1) : "";
15601
- const drift = _optionalChain([err, 'access', _111 => _111.details, 'optionalAccess', _112 => _112.deterministic]) === true || err.code === "INVALID_RESPONSE" && META_TRIO_VERBS.has(verb);
15766
+ const drift = _optionalChain([err, 'access', _120 => _120.details, 'optionalAccess', _121 => _121.deterministic]) === true || err.code === "INVALID_RESPONSE" && META_TRIO_VERBS.has(verb);
15602
15767
  if (drift && op !== void 0) {
15603
15768
  const dot = op.indexOf(".");
15604
15769
  if (dot > 0) this.fieldCache.invalidate(op.slice(0, dot));
@@ -15608,7 +15773,8 @@ var HttpClient = (_class6 = class {
15608
15773
  } finally {
15609
15774
  clearTimeout(deadlineTimer);
15610
15775
  if (!(method === "GET" || opts.idempotent === true)) {
15611
- _optionalChain([this, 'access', _113 => _113.readCache, 'optionalAccess', _114 => _114.clear, 'call', _115 => _115()]);
15776
+ _optionalChain([this, 'access', _122 => _122.readCache, 'optionalAccess', _123 => _123.clear, 'call', _124 => _124()]);
15777
+ this.latestCountCache.clear();
15612
15778
  const nameOp = typeof opts.operation === "string" ? opts.operation : void 0;
15613
15779
  const nameDot = nameOp !== void 0 ? nameOp.indexOf(".") : -1;
15614
15780
  if (this.resourceNameCache !== void 0 && nameOp !== void 0 && nameDot > 0 && nameOp.slice(0, nameDot) === "resources") {
@@ -15618,7 +15784,7 @@ var HttpClient = (_class6 = class {
15618
15784
  }
15619
15785
  throw new AutotaskError("unreachable: the request loop ended without an outcome");
15620
15786
  }
15621
- }, _class6);
15787
+ }, _class7);
15622
15788
  var INVALID_SHAPE_ACTION = "Report the unexpected response shape; verify baseUrl points at the REST API.";
15623
15789
  var META_TRIO_VERBS = /* @__PURE__ */ new Set(["getEntityInfo", "getFieldInfo", "getUdfInfo"]);
15624
15790
  function attachEmptyReasonDetails(err) {
@@ -15628,7 +15794,7 @@ function attachEmptyReasonDetails(err) {
15628
15794
  const resource = err.operation.slice(0, dot);
15629
15795
  const op = err.operation.slice(dot + 1);
15630
15796
  const surface = err.operation;
15631
- const stamp = _optionalChain([EMPTY_REASON_STAMPS, 'access', _116 => _116[resource], 'optionalAccess', _117 => _117[op]]);
15797
+ const stamp = _optionalChain([EMPTY_REASON_STAMPS, 'access', _125 => _125[resource], 'optionalAccess', _126 => _126[op]]);
15632
15798
  const pointer = POINTER_NOTES[surface];
15633
15799
  const isGetMiss = err instanceof NotFoundError && op === "get";
15634
15800
  if (stamp === void 0 && pointer === void 0 && !isGetMiss) return;
@@ -15918,7 +16084,7 @@ async function expandResourceNames(client, ids, opts = {}) {
15918
16084
  continue;
15919
16085
  }
15920
16086
  }
15921
- const epoch = _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _118 => _118.epoch]), () => ( 0));
16087
+ const epoch = _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _127 => _127.epoch]), () => ( 0));
15922
16088
  const work = (async () => {
15923
16089
  try {
15924
16090
  const record = await holder.get(id, { fresh });
@@ -16005,7 +16171,7 @@ function capabilitySets() {
16005
16171
  const fieldOps = /* @__PURE__ */ new Map();
16006
16172
  const udfOps = /* @__PURE__ */ new Map();
16007
16173
  const resources = /* @__PURE__ */ new Set();
16008
- for (const rec of _chunk5O5EPYBOcjs.CAPABILITIES) {
16174
+ for (const rec of _chunkFLYTKJKVcjs.CAPABILITIES) {
16009
16175
  if (rec.resource === "operations") continue;
16010
16176
  resources.add(rec.resource);
16011
16177
  if (rec.operation === "getFieldInfo") fieldOps.set(rec.resource, rec);
@@ -16038,7 +16204,7 @@ async function fieldCatalog(client, opts) {
16038
16204
  }
16039
16205
  }
16040
16206
  const { fieldOps, udfOps, resources: allResources } = capabilitySets();
16041
- const includeRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _119 => _119.include]), () => ( ["fields"]));
16207
+ const includeRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _128 => _128.include]), () => ( ["fields"]));
16042
16208
  if (!Array.isArray(includeRaw) || includeRaw.length === 0) {
16043
16209
  throw new AutotaskConfigError("fieldCatalog: opts.include must be a non-empty array of (info|fields|udf)");
16044
16210
  }
@@ -16052,7 +16218,7 @@ async function fieldCatalog(client, opts) {
16052
16218
  }
16053
16219
  if (!include.includes(kind)) include.push(kind);
16054
16220
  }
16055
- const resourcesRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _120 => _120.resources]), () => ( WORKFLOW_RESOURCES));
16221
+ const resourcesRaw = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _129 => _129.resources]), () => ( WORKFLOW_RESOURCES));
16056
16222
  if (!Array.isArray(resourcesRaw) || resourcesRaw.length === 0) {
16057
16223
  throw new AutotaskConfigError("fieldCatalog: opts.resources must be a non-empty array of plan resource keys");
16058
16224
  }
@@ -16084,7 +16250,7 @@ async function fieldCatalog(client, opts) {
16084
16250
  if (!targets.includes(key)) targets.push(key);
16085
16251
  }
16086
16252
  let fieldsFilter;
16087
- const fieldsRaw = _optionalChain([opts, 'optionalAccess', _121 => _121.fields]);
16253
+ const fieldsRaw = _optionalChain([opts, 'optionalAccess', _130 => _130.fields]);
16088
16254
  if (fieldsRaw !== void 0) {
16089
16255
  if (!Array.isArray(fieldsRaw) || fieldsRaw.length === 0) {
16090
16256
  throw new AutotaskConfigError("fieldCatalog: opts.fields must be a non-empty array of vendor field name strings");
@@ -16106,7 +16272,7 @@ async function fieldCatalog(client, opts) {
16106
16272
  `fieldCatalog: opts.labels must be a boolean (got ${typeof opts.labels})`
16107
16273
  );
16108
16274
  }
16109
- const labels = _optionalChain([opts, 'optionalAccess', _122 => _122.labels]) === true;
16275
+ const labels = _optionalChain([opts, 'optionalAccess', _131 => _131.labels]) === true;
16110
16276
  const cost = targets.length * include.length;
16111
16277
  if (cost > MAX_FIELD_CATALOG_WIRE) {
16112
16278
  throw new AutotaskConfigError(
@@ -16115,7 +16281,7 @@ async function fieldCatalog(client, opts) {
16115
16281
  );
16116
16282
  }
16117
16283
  const cache = client.http.fieldCache;
16118
- const fresh = _optionalChain([opts, 'optionalAccess', _123 => _123.fresh]) === true;
16284
+ const fresh = _optionalChain([opts, 'optionalAccess', _132 => _132.fresh]) === true;
16119
16285
  const zone = _nullishCoalesce(client.config.zone, () => ( "unknown"));
16120
16286
  const rows = [];
16121
16287
  let wireUsed = 0;
@@ -16139,11 +16305,11 @@ async function fieldCatalog(client, opts) {
16139
16305
  error: null
16140
16306
  };
16141
16307
  const fetches = {
16142
- 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" })))),
16143
- 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" })))),
16144
- 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" }))))
16308
+ info: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _133 => _133.getEntityInfo, 'optionalCall', _134 => _134()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getEntityInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16309
+ fields: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _135 => _135.getFieldInfo, 'optionalCall', _136 => _136()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getFieldInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" })))),
16310
+ udf: () => _nullishCoalesce(_optionalChain([holder, 'optionalAccess', _137 => _137.getUdfInfo, 'optionalCall', _138 => _138()]), () => ( Promise.reject(new AutotaskError(`fieldCatalog: the client exposes no getUdfInfo read for "${resource}"`, { code: "INVALID_RESPONSE", category: "server" }))))
16145
16311
  };
16146
- if (fresh) _optionalChain([cache, 'optionalAccess', _130 => _130.invalidate, 'call', _131 => _131(resource)]);
16312
+ if (fresh) _optionalChain([cache, 'optionalAccess', _139 => _139.invalidate, 'call', _140 => _140(resource)]);
16147
16313
  let allCached = true;
16148
16314
  const ages = [];
16149
16315
  for (const kind of include) {
@@ -16196,7 +16362,7 @@ async function fieldCatalog(client, opts) {
16196
16362
  label: zone,
16197
16363
  cached: cache !== void 0,
16198
16364
  labels,
16199
- ttlMs: _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _132 => _132.ttlMs]), () => ( null)),
16365
+ ttlMs: _nullishCoalesce(_optionalChain([cache, 'optionalAccess', _141 => _141.ttlMs]), () => ( null)),
16200
16366
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
16201
16367
  rows,
16202
16368
  wireUsed,
@@ -16361,7 +16527,7 @@ async function resolveCompositeNames(http, plan, opts = {}) {
16361
16527
  } else {
16362
16528
  for (const f of plan.labelFields) {
16363
16529
  const frow = row.fields.find((x) => x.name === f);
16364
- picklists[f] = _optionalChain([frow, 'optionalAccess', _133 => _133.picklistValues]);
16530
+ picklists[f] = _optionalChain([frow, 'optionalAccess', _142 => _142.picklistValues]);
16365
16531
  }
16366
16532
  }
16367
16533
  } catch (err) {
@@ -16372,8 +16538,8 @@ async function resolveCompositeNames(http, plan, opts = {}) {
16372
16538
  }
16373
16539
  return {
16374
16540
  section,
16375
- resourceName: (id) => _nullishCoalesce(_optionalChain([section, 'access', _134 => _134.rows, 'access', _135 => _135[`resource:${id}`], 'optionalAccess', _136 => _136.name]), () => ( null)),
16376
- recordName: (table, id) => _nullishCoalesce(_optionalChain([section, 'access', _137 => _137.rows, 'access', _138 => _138[`${table}:${id}`], 'optionalAccess', _139 => _139.name]), () => ( null)),
16541
+ resourceName: (id) => _nullishCoalesce(_optionalChain([section, 'access', _143 => _143.rows, 'access', _144 => _144[`resource:${id}`], 'optionalAccess', _145 => _145.name]), () => ( null)),
16542
+ recordName: (table, id) => _nullishCoalesce(_optionalChain([section, 'access', _146 => _146.rows, 'access', _147 => _147[`${table}:${id}`], 'optionalAccess', _148 => _148.name]), () => ( null)),
16377
16543
  labelFor: (field, value) => {
16378
16544
  if (value === null || value === void 0) return null;
16379
16545
  const values = picklists[field];
@@ -16644,8 +16810,8 @@ function validateFetchManyItems(items, cap, opName = "fetchMany", capRef = `FETC
16644
16810
  problems.push(`${at}.fields: must be an array of exact vendor field names (discover them via operations.fieldCatalog)`);
16645
16811
  continue;
16646
16812
  }
16647
- if (_optionalChain([validation, 'optionalAccess', _140 => _140.fieldCheck]) !== false) {
16648
- const authoritative = _nullishCoalesce(_optionalChain([validation, 'optionalAccess', _141 => _141.fieldSetsByResource, 'optionalAccess', _142 => _142.get, 'call', _143 => _143(resourceKey)]), () => ( fields));
16813
+ if (_optionalChain([validation, 'optionalAccess', _149 => _149.fieldCheck]) !== false) {
16814
+ const authoritative = _nullishCoalesce(_optionalChain([validation, 'optionalAccess', _150 => _150.fieldSetsByResource, 'optionalAccess', _151 => _151.get, 'call', _152 => _152(resourceKey)]), () => ( fields));
16649
16815
  for (const f of item.fields) {
16650
16816
  if (!authoritative.includes(f)) {
16651
16817
  problems.push(
@@ -16749,7 +16915,7 @@ function project2(value, fields) {
16749
16915
  return out;
16750
16916
  }
16751
16917
  function resourcePathOf(key, holder) {
16752
- const path = _optionalChain([holder, 'optionalAccess', _144 => _144.resourcePath]);
16918
+ const path = _optionalChain([holder, 'optionalAccess', _153 => _153.resourcePath]);
16753
16919
  if (typeof path !== "string" || path === "") {
16754
16920
  throw new AutotaskConfigError(`fetchByIds: the client exposes no ${key} resource path (registry drift)`, {
16755
16921
  suggestedAction: "Rebuild the client from the SDK build that ships this registry (the resource set is pinned by the plan)."
@@ -16921,7 +17087,7 @@ function blindEmptyReason(stamp) {
16921
17087
  };
16922
17088
  }
16923
17089
  function attachUpdateTargetMissReason(err, key) {
16924
- const pinned = _optionalChain([EMPTY_REASON_STAMPS, 'access', _145 => _145[key], 'optionalAccess', _146 => _146.update]);
17090
+ const pinned = _optionalChain([EMPTY_REASON_STAMPS, 'access', _154 => _154[key], 'optionalAccess', _155 => _155.update]);
16925
17091
  if (pinned === void 0) return;
16926
17092
  err.details = { ..._nullishCoalesce(err.details, () => ( {})), emptyReason: pinned };
16927
17093
  }
@@ -17102,7 +17268,7 @@ var BaseResource = class {
17102
17268
  return (page, pageSize) => this.fetchPage(p, page, pageSize, state);
17103
17269
  }
17104
17270
  walkPageSize(params) {
17105
- return clampPageSize(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _147 => _147.maxRecords]), () => ( this.defaultPageSize)));
17271
+ return clampPageSize(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _156 => _156.maxRecords]), () => ( this.defaultPageSize)));
17106
17272
  }
17107
17273
  /** Stream items across pages (the resource `query` surface). */
17108
17274
  queryItems(params) {
@@ -17114,7 +17280,7 @@ var BaseResource = class {
17114
17280
  }
17115
17281
  /** Collect every item across all pages (the resource `queryAll` surface; 1000-page guarded). */
17116
17282
  async queryAllItems(params) {
17117
- return collectAll(this.pageFetcher(params), { pageSize: this.walkPageSize(params), maxRecords: _optionalChain([params, 'optionalAccess', _148 => _148.maxTotalRecords]) });
17283
+ return collectAll(this.pageFetcher(params), { pageSize: this.walkPageSize(params), maxRecords: _optionalChain([params, 'optionalAccess', _157 => _157.maxTotalRecords]) });
17118
17284
  }
17119
17285
  /**
17120
17286
  * `queryBounded` — server-side pagination (the MCP query surface): ONE call
@@ -17151,19 +17317,19 @@ var BaseResource = class {
17151
17317
  "queryBounded: params must be an object { filter?, limit?, latest?, includeFields? } \u2014 a bare conditions array is not accepted (wrap it: { filter: [...] })"
17152
17318
  );
17153
17319
  }
17154
- const limit = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _149 => _149.limit]), () => ( BOUNDED_QUERY_DEFAULT_LIMIT));
17320
+ const limit = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _158 => _158.limit]), () => ( BOUNDED_QUERY_DEFAULT_LIMIT));
17155
17321
  if (!Number.isInteger(limit) || limit < 1 || limit > BOUNDED_QUERY_MAX_LIMIT) {
17156
17322
  throw new AutotaskConfigError(
17157
17323
  `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`
17158
17324
  );
17159
17325
  }
17160
- const noteChars = _optionalChain([params, 'optionalAccess', _150 => _150.noteChars]);
17326
+ const noteChars = _optionalChain([params, 'optionalAccess', _159 => _159.noteChars]);
17161
17327
  if (noteChars !== void 0 && (!Number.isInteger(noteChars) || noteChars < 1)) {
17162
17328
  throw new AutotaskConfigError(
17163
17329
  `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)`
17164
17330
  );
17165
17331
  }
17166
- const walkParams = _optionalChain([params, 'optionalAccess', _151 => _151.fieldsPreset]) !== void 0 ? { ...params, includeFields: resolveFieldsPreset(params.fieldsPreset, this.config.key, params.includeFields) } : _nullishCoalesce(params, () => ( {}));
17332
+ const walkParams = _optionalChain([params, 'optionalAccess', _160 => _160.fieldsPreset]) !== void 0 ? { ...params, includeFields: resolveFieldsPreset(params.fieldsPreset, this.config.key, params.includeFields) } : _nullishCoalesce(params, () => ( {}));
17167
17333
  const latest = walkParams.latest;
17168
17334
  if (latest !== void 0) {
17169
17335
  if (!Number.isInteger(latest) || latest < 1 || latest > BOUNDED_QUERY_MAX_LIMIT) {
@@ -17171,7 +17337,7 @@ var BaseResource = class {
17171
17337
  `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`
17172
17338
  );
17173
17339
  }
17174
- if (_optionalChain([params, 'optionalAccess', _152 => _152.limit]) !== void 0 && limit < latest) {
17340
+ if (_optionalChain([params, 'optionalAccess', _161 => _161.limit]) !== void 0 && limit < latest) {
17175
17341
  throw new AutotaskConfigError(
17176
17342
  `queryBounded: limit (${String(limit)}) must be >= latest (${String(latest)}) \u2014 latest governs the returned count and limit is the walk window`
17177
17343
  );
@@ -17253,8 +17419,8 @@ var BaseResource = class {
17253
17419
  * speculation). */
17254
17420
  stampEmptyQueryResult(result, params) {
17255
17421
  if (result.items.length !== 0) return;
17256
- result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _153 => _153[this.config.key], 'optionalAccess', _154 => _154.query]), _optionalChain([params, 'optionalAccess', _155 => _155.filter]));
17257
- 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;
17422
+ result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _162 => _162[this.config.key], 'optionalAccess', _163 => _163.query]), _optionalChain([params, 'optionalAccess', _164 => _164.filter]));
17423
+ const pinnedReason = normalizedConditions(_optionalChain([params, 'optionalAccess', _165 => _165.filter])) === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _166 => _166[this.config.key], 'optionalAccess', _167 => _167.query]) : void 0;
17258
17424
  if (result.blindSurface !== void 0 || pinnedReason !== void 0) {
17259
17425
  result.emptyReason = result.blindSurface !== void 0 ? blindEmptyReason(result.blindSurface) : pinnedReason;
17260
17426
  }
@@ -17268,17 +17434,56 @@ var BaseResource = class {
17268
17434
  const bigB = typeof b === "number" ? BigInt(String(b)) : BigInt(b);
17269
17435
  return bigA < bigB ? -1 : bigA > bigB ? 1 : 0;
17270
17436
  }
17437
+ /** Issue #127: the `latest` walk's count probes through the per-client
17438
+ * short-TTL count cache (`LatestCountCache` — fixed 30 s TTL, the
17439
+ * memory guard; cleared on every real write through this client, the
17440
+ * write-then-read re-fetch rule). Only a SUCCESSFUL plain-number vendor
17441
+ * count answer is stored: the blind-surface / pinned-empty sentinels are
17442
+ * RECORDS and pass through un-stored (the plan-pinned stamps stay fresh
17443
+ * and re-derive on every call), and an error rejects before any store.
17444
+ * The key is (resource plan key, canonical filter serialisation — the
17445
+ * normalised conditions' JSON): the initial `count(F)` probe and every
17446
+ * `id gt T` threshold probe are separate entries, and a re-asked
17447
+ * "top N" within the TTL makes ZERO extra count calls (its probes all
17448
+ * hit — the bracket/search sequence is deterministic given the counts).
17449
+ * Issue #157: two corrections to the snapshot trade. (1) A total of 0 is
17450
+ * NEVER stored — a 0 is rare and cheap to re-probe, and a cached 0 fed
17451
+ * the false-empty branch (a repeat after an out-of-band insert returned
17452
+ * no rows without walking). (2) `fresh: true` DELETES the entry before
17453
+ * the wire read and re-stores the fresh answer — the ONE re-probe the
17454
+ * stale-LOW recovery in `latestWalk` is allowed. Counts are snapshots,
17455
+ * not contracts: the truncation guard covers the growth-of-total
17456
+ * direction; a stale-LOW total within the TTL is resolved by that one
17457
+ * fresh re-probe (never by the guard alone). The plain `count` op and
17458
+ * `operations.aggregate` call `countGlobal` directly and promise fresh
17459
+ * totals — this wrapper is used ONLY on the latest-walk probe path.
17460
+ */
17461
+ async latestProbeCount(filter, opts = {}) {
17462
+ const cache = this.http.latestCountCache;
17463
+ const key = LatestCountCache.key(this.config.key, normalizedConditions(filter));
17464
+ if (opts.fresh === true) {
17465
+ cache.delete(key);
17466
+ } else {
17467
+ const hit = cache.get(key);
17468
+ if (hit !== void 0) return { value: hit, cached: true };
17469
+ }
17470
+ const epoch = cache.epoch;
17471
+ const res = await this.countGlobal({ filter });
17472
+ const value = res;
17473
+ if (typeof value === "number" && value !== 0) cache.set(key, value, epoch);
17474
+ return { value, cached: false };
17475
+ }
17271
17476
  /** Issue #59: one `latest` threshold count probe — a ROWLESS
17272
17477
  * `count(F ∧ id gt T)` call (the vendor caps — ≤500 OR-conditions,
17273
17478
  * 8000 chars serialised — leave a single `gt` condition room on any
17274
- * filter). The `BlindCountResult` sentinel (a record, not a number —
17479
+ * filter). Issue #127: it rides the per-client short-TTL count cache — the same (resource, conditions) probe within the 30 s window is reused (zero vendor calls); a sentinel answer is never cached. The `BlindCountResult` sentinel (a record, not a number —
17275
17480
  * the declared `number` return is the documented under-type) unwraps to
17276
17481
  * its `count` value (always 0): at or above the max matching id the
17277
17482
  * count is 0, which is exactly the bracket-termination signal. */
17278
17483
  async countAboveId(baseConds, t) {
17279
17484
  const value = t <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(t) : t.toString();
17280
- const res = await this.countGlobal({ filter: [...baseConds, { op: "gt", field: "id", value }] });
17281
- return typeof res === "object" && res !== null && "count" in res ? res.count : res;
17485
+ const probed = await this.latestProbeCount([...baseConds, { op: "gt", field: "id", value }]);
17486
+ return typeof probed.value === "object" && probed.value !== null && "count" in probed.value ? probed.value.count : probed.value;
17282
17487
  }
17283
17488
  /**
17284
17489
  * Issue #59: the `latest: N` mechanism — the N highest-`id` rows,
@@ -17296,8 +17501,11 @@ var BaseResource = class {
17296
17501
  * 1 + ceil(C/500) <= 6, independent of table size. A truncated walk
17297
17502
  * (the vendor's rows disagree with its own count) is
17298
17503
  * LATEST_WINDOW_INCOMPLETE — the top-N of a truncated set is
17299
- * unprovable. Sort id-descending; return the top N (a set of
17300
- * C < N returns itself).
17504
+ * unprovable — EXCEPT issue #157: when `C` came from the CACHE, the
17505
+ * total is re-probed ONCE fresh (the stale-LOW recovery: a larger
17506
+ * fresh total continues the walk against it; the refusal stands only
17507
+ * when the fresh probe confirms the cached value). Sort
17508
+ * id-descending; return the top N (a set of C < N returns itself).
17301
17509
  * - `C > 2500` → THRESHOLD mode: find the smallest id threshold `T`
17302
17510
  * with `count(F ∧ id gt T) <= N` by exponential bracketing
17303
17511
  * (T = 1, 2, 4, …) + binary search — each probe ONE rowless count
@@ -17324,13 +17532,25 @@ var BaseResource = class {
17324
17532
  * answer.
17325
17533
  * `includeFields` always carries `id` (the P1 id-append,
17326
17534
  * `buildQueryRequest`), which `latest` sorts on. Pure read; no mutation
17327
- * paths involved.
17535
+ * paths involved. Issue #127: every count probe of this walk (the
17536
+ * initial `count(F)` + the `id gt T` threshold probes) rides the
17537
+ * per-client short-TTL count cache (30 s; a real write through this
17538
+ * client clears it) — a re-asked "top N" within the window reuses the
17539
+ * probes (zero extra vendor count calls); sentinel answers are never
17540
+ * cached (the plan-pinned stamps stay fresh), and a 0 total is never
17541
+ * cached either (issue #157: a 0 is cheap to re-probe and a cached 0
17542
+ * would shadow an out-of-band insert). The stale-LOW direction is closed
17543
+ * by the ONE fresh re-probe above; the stale-HIGH direction is safe by
17544
+ * construction (threshold mode re-probes fresh `id gt T` counts and
17545
+ * full-set mode ends when the cursor exhausts). The plain `count` op and
17546
+ * `operations.aggregate` bypass the cache by construction and promise
17547
+ * fresh totals.
17328
17548
  */
17329
17549
  async latestWalk(params, limit, latest) {
17330
17550
  const baseConds = _nullishCoalesce(normalizedConditions(params.filter), () => ( []));
17331
- const probe = await this.countGlobal(params);
17332
- if (typeof probe === "object" && probe !== null) {
17333
- const rec = probe;
17551
+ const probe = await this.latestProbeCount(params.filter);
17552
+ if (typeof probe.value === "object" && probe.value !== null) {
17553
+ const rec = probe.value;
17334
17554
  if (rec.blindSurface !== void 0) {
17335
17555
  return this.latestBlindWalk(params, limit, latest);
17336
17556
  }
@@ -17338,47 +17558,60 @@ var BaseResource = class {
17338
17558
  this.stampEmptyQueryResult(result, params);
17339
17559
  return result;
17340
17560
  }
17341
- const total = probe;
17342
- if (total === 0) {
17343
- const result = { items: [], fetched: 0, hasMore: false, pagesWalked: 0 };
17344
- this.stampEmptyQueryResult(result, params);
17345
- return result;
17346
- }
17347
- if (total <= BOUNDED_QUERY_MAX_LIMIT) {
17348
- const { items: items2, pages: pages2, guard: guard2, sliced: sliced2, cursor: cursor2 } = await this.walkBounded(params, total);
17349
- if (this.walkTruncated(total, { itemsLength: items2.length, guard: guard2, sliced: sliced2, cursor: cursor2 })) {
17350
- throw this.latestWindowIncompleteError(total);
17561
+ let total = probe.value;
17562
+ let cacheSourced = probe.cached;
17563
+ let reProbed = false;
17564
+ for (; ; ) {
17565
+ if (total === 0) {
17566
+ const result = { items: [], fetched: 0, hasMore: false, pagesWalked: 0 };
17567
+ this.stampEmptyQueryResult(result, params);
17568
+ return result;
17351
17569
  }
17352
- return this.finishLatest(items2, latest, pages2);
17353
- }
17354
- let probes = 1;
17355
- const spend = () => {
17356
- probes += 1;
17357
- if (probes > LATEST_MAX_COUNT_PROBES) throw this.latestThresholdUnresolvedError();
17358
- };
17359
- let lo = 0n;
17360
- let hi = 0n;
17361
- for (let t = 1n; ; t = t << 1n) {
17362
- spend();
17363
- if (await this.countAboveId(baseConds, t) <= latest) {
17364
- hi = t;
17365
- break;
17570
+ if (total <= BOUNDED_QUERY_MAX_LIMIT) {
17571
+ const { items: items2, pages: pages2, guard: guard2, sliced: sliced2, cursor: cursor2 } = await this.walkBounded(params, total);
17572
+ if (this.walkTruncated(total, { itemsLength: items2.length, guard: guard2, sliced: sliced2, cursor: cursor2 })) {
17573
+ if (cacheSourced && !reProbed) {
17574
+ reProbed = true;
17575
+ const fresh = await this.latestProbeCount(params.filter, { fresh: true });
17576
+ if (typeof fresh.value === "number" && fresh.value > total) {
17577
+ total = fresh.value;
17578
+ cacheSourced = false;
17579
+ continue;
17580
+ }
17581
+ }
17582
+ throw this.latestWindowIncompleteError(total);
17583
+ }
17584
+ return this.finishLatest(items2, latest, pages2);
17366
17585
  }
17367
- lo = t;
17368
- }
17369
- while (hi - lo > 1n) {
17370
- const mid = lo + hi >> 1n;
17371
- spend();
17372
- if (await this.countAboveId(baseConds, mid) <= latest) hi = mid;
17373
- else lo = mid;
17374
- }
17375
- const windowValue = hi <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(hi) : hi.toString();
17376
- const window = [...baseConds, { op: "gte", field: "id", value: windowValue }];
17377
- const { items, pages, guard, sliced, cursor } = await this.walkBounded({ ...params, filter: window }, latest + 1);
17378
- if (this.walkTruncated(latest + 1, { itemsLength: items.length, guard, sliced, cursor })) {
17379
- throw this.latestWindowIncompleteError(latest + 1);
17586
+ let probes = reProbed ? 2 : 1;
17587
+ const spend = () => {
17588
+ probes += 1;
17589
+ if (probes > LATEST_MAX_COUNT_PROBES) throw this.latestThresholdUnresolvedError();
17590
+ };
17591
+ let lo = 0n;
17592
+ let hi = 0n;
17593
+ for (let t = 1n; ; t = t << 1n) {
17594
+ spend();
17595
+ if (await this.countAboveId(baseConds, t) <= latest) {
17596
+ hi = t;
17597
+ break;
17598
+ }
17599
+ lo = t;
17600
+ }
17601
+ while (hi - lo > 1n) {
17602
+ const mid = lo + hi >> 1n;
17603
+ spend();
17604
+ if (await this.countAboveId(baseConds, mid) <= latest) hi = mid;
17605
+ else lo = mid;
17606
+ }
17607
+ const windowValue = hi <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(hi) : hi.toString();
17608
+ const window = [...baseConds, { op: "gte", field: "id", value: windowValue }];
17609
+ const { items, pages, guard, sliced, cursor } = await this.walkBounded({ ...params, filter: window }, latest + 1);
17610
+ if (this.walkTruncated(latest + 1, { itemsLength: items.length, guard, sliced, cursor })) {
17611
+ throw this.latestWindowIncompleteError(latest + 1);
17612
+ }
17613
+ return this.finishLatest(items, latest, pages);
17380
17614
  }
17381
- return this.finishLatest(items, latest, pages);
17382
17615
  }
17383
17616
  /** The shared `latest` completion: the (provably complete or
17384
17617
  * stamp-scoped) set sorted id-descending, top N taken. `hasMore: false`
@@ -17405,7 +17638,7 @@ var BaseResource = class {
17405
17638
  if (result.items.length === 0) {
17406
17639
  this.stampEmptyQueryResult(result, params);
17407
17640
  } else {
17408
- result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _159 => _159[this.config.key], 'optionalAccess', _160 => _160.query]), params.filter);
17641
+ result.blindSurface = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _168 => _168[this.config.key], 'optionalAccess', _169 => _169.query]), params.filter);
17409
17642
  }
17410
17643
  return result;
17411
17644
  }
@@ -17444,7 +17677,7 @@ var BaseResource = class {
17444
17677
  * or, on a plan-pinned blind surface, the `{ count: 0, blindSurface }`
17445
17678
  * typed sentinel (S12-C T10; see `BlindCountResult`). */
17446
17679
  async countGlobal(params) {
17447
- const conditions = normalizedConditions(_optionalChain([params, 'optionalAccess', _161 => _161.filter]));
17680
+ const conditions = normalizedConditions(_optionalChain([params, 'optionalAccess', _170 => _170.filter]));
17448
17681
  const body = {};
17449
17682
  body.filter = conditions === void 0 ? [] : buildFilter(conditions).filter;
17450
17683
  const res = await this.http.request({
@@ -17455,9 +17688,9 @@ var BaseResource = class {
17455
17688
  idempotent: true
17456
17689
  });
17457
17690
  const count = unwrapQueryCount(res, `${this.config.key}.count`);
17458
- const stamp = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _162 => _162[this.config.key], 'optionalAccess', _163 => _163.count]), _optionalChain([params, 'optionalAccess', _164 => _164.filter]));
17691
+ const stamp = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _171 => _171[this.config.key], 'optionalAccess', _172 => _172.count]), _optionalChain([params, 'optionalAccess', _173 => _173.filter]));
17459
17692
  if (count === 0) {
17460
- const pinnedReason = conditions === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _165 => _165[this.config.key], 'optionalAccess', _166 => _166.count]) : void 0;
17693
+ const pinnedReason = conditions === void 0 ? _optionalChain([EMPTY_REASON_STAMPS, 'access', _174 => _174[this.config.key], 'optionalAccess', _175 => _175.count]) : void 0;
17461
17694
  if (stamp !== void 0 || pinnedReason !== void 0) {
17462
17695
  return {
17463
17696
  count,
@@ -17488,9 +17721,9 @@ var BaseResource = class {
17488
17721
  const hit = cache.get(path);
17489
17722
  if (hit !== void 0) return hit;
17490
17723
  }
17491
- const epoch = _optionalChain([cache, 'optionalAccess', _167 => _167.epoch]);
17724
+ const epoch = _optionalChain([cache, 'optionalAccess', _176 => _176.epoch]);
17492
17725
  const res = await this.http.request({ method: "GET", path, operation });
17493
- _optionalChain([cache, 'optionalAccess', _168 => _168.set, 'call', _169 => _169(path, res, resource, epoch)]);
17726
+ _optionalChain([cache, 'optionalAccess', _177 => _177.set, 'call', _178 => _178(path, res, resource, epoch)]);
17494
17727
  return res;
17495
17728
  }
17496
17729
  /**
@@ -17529,7 +17762,7 @@ var BaseResource = class {
17529
17762
  return value;
17530
17763
  });
17531
17764
  work.catch((err) => {
17532
- if (err instanceof AutotaskError && (err.code === "INVALID_RESPONSE" || _optionalChain([err, 'access', _170 => _170.details, 'optionalAccess', _171 => _171.deterministic]) === true)) {
17765
+ if (err instanceof AutotaskError && (err.code === "INVALID_RESPONSE" || _optionalChain([err, 'access', _179 => _179.details, 'optionalAccess', _180 => _180.deterministic]) === true)) {
17533
17766
  cache.invalidate(key);
17534
17767
  }
17535
17768
  });
@@ -17559,7 +17792,7 @@ var BaseResource = class {
17559
17792
  path: `${this.resourcePath}/${numeric}`,
17560
17793
  operation: `${this.config.key}.get`,
17561
17794
  skipResponseRedaction: true,
17562
- maxRetries: _optionalChain([readOpts, 'optionalAccess', _172 => _172.maxRetries])
17795
+ maxRetries: _optionalChain([readOpts, 'optionalAccess', _181 => _181.maxRetries])
17563
17796
  });
17564
17797
  return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17565
17798
  }
@@ -17578,7 +17811,7 @@ var BaseResource = class {
17578
17811
  path: this.scopedItemPath(parentId, numeric),
17579
17812
  operation: `${this.config.key}.get`,
17580
17813
  skipResponseRedaction: true,
17581
- maxRetries: _optionalChain([readOpts, 'optionalAccess', _173 => _173.maxRetries])
17814
+ maxRetries: _optionalChain([readOpts, 'optionalAccess', _182 => _182.maxRetries])
17582
17815
  });
17583
17816
  return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17584
17817
  }
@@ -18237,7 +18470,7 @@ var BaseResource = class {
18237
18470
  current = parentId === void 0 ? await this.getGlobal(id, true) : this.config.attachmentGet ? await this.getScopedModel(parentId, id, true) : await this.getScopedRaw(parentId, id, true);
18238
18471
  } catch (err) {
18239
18472
  if (err instanceof NotFoundError) {
18240
- const updateReason = _optionalChain([EMPTY_REASON_STAMPS, 'access', _174 => _174[this.config.key], 'optionalAccess', _175 => _175.update]);
18473
+ const updateReason = _optionalChain([EMPTY_REASON_STAMPS, 'access', _183 => _183[this.config.key], 'optionalAccess', _184 => _184.update]);
18241
18474
  checks.push({
18242
18475
  name: "current-record-exists",
18243
18476
  ok: false,
@@ -18395,12 +18628,12 @@ var BaseResource = class {
18395
18628
  return null;
18396
18629
  }
18397
18630
  }
18398
- const epoch = _optionalChain([cache, 'optionalAccess', _176 => _176.epoch]);
18631
+ const epoch = _optionalChain([cache, 'optionalAccess', _185 => _185.epoch]);
18399
18632
  try {
18400
18633
  return await this.fetchRecordRaw(entityPath, referenceId);
18401
18634
  } catch (err) {
18402
18635
  if (err instanceof NotFoundError) {
18403
- _optionalChain([cache, 'optionalAccess', _177 => _177.set, 'call', _178 => _178(absentKey, CONTEXT_ABSENT_MARKER, RESOURCE_KEY_BY_PATH[entityPath], epoch)]);
18636
+ _optionalChain([cache, 'optionalAccess', _186 => _186.set, 'call', _187 => _187(absentKey, CONTEXT_ABSENT_MARKER, RESOURCE_KEY_BY_PATH[entityPath], epoch)]);
18404
18637
  return null;
18405
18638
  }
18406
18639
  throw err;
@@ -18517,7 +18750,7 @@ var BaseResource = class {
18517
18750
  missDetail(operator, fields) {
18518
18751
  const key = this.config.key;
18519
18752
  const probe = fields.map((field) => ({ field, op: operator, value: "" }));
18520
- const blind = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _179 => _179[key], 'optionalAccess', _180 => _180.query]), probe);
18753
+ const blind = blindStampFor(_optionalChain([BLIND_SURFACE_STAMPS, 'access', _188 => _188[key], 'optionalAccess', _189 => _189.query]), probe);
18521
18754
  const next = [];
18522
18755
  if (blind !== void 0) {
18523
18756
  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.`);
@@ -18793,4 +19026,5 @@ var BaseResource = class {
18793
19026
 
18794
19027
 
18795
19028
 
18796
- 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.buildQueryBody = buildQueryBody; 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;
19029
+
19030
+ 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.MAINTENANCE_WINDOW_MAX_MS = MAINTENANCE_WINDOW_MAX_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.buildQueryBody = buildQueryBody; 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;