node-autotask 0.41.0 → 0.42.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 (43) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/MCP_TOOL_CATALOG.json +152 -132
  3. package/MCP_TOOL_MANIFEST.md +16 -15
  4. package/N8N_MCP_MANIFEST.json +3 -3
  5. package/N8N_MCP_MANIFEST.md +4 -4
  6. package/README.md +4 -5
  7. package/capabilities.json +3909 -3185
  8. package/dist/capabilities.cjs +2 -2
  9. package/dist/capabilities.js +1 -1
  10. package/dist/{chunk-LR6FDJI3.js → chunk-AETFO6BO.js} +2736 -2749
  11. package/dist/{chunk-DXEBPK55.cjs → chunk-HD5BRA3Z.cjs} +285 -285
  12. package/dist/{chunk-YAHFPOQF.cjs → chunk-MYL34QU5.cjs} +143 -143
  13. package/dist/{chunk-DKAD7MOV.cjs → chunk-SEFJJY4J.cjs} +2768 -2781
  14. package/dist/{chunk-TCND5PFF.js → chunk-TTPHVFPJ.js} +2 -2
  15. package/dist/{chunk-MJ6J74F3.cjs → chunk-VEOSOIU4.cjs} +3908 -3184
  16. package/dist/{chunk-ZVSSAULC.js → chunk-WP33PQVM.js} +3908 -3184
  17. package/dist/{chunk-P5655PGY.js → chunk-ZR24JGW2.js} +2 -2
  18. package/dist/index-C3KFMnRT.d.cts +6860 -0
  19. package/dist/index-C3KFMnRT.d.ts +6860 -0
  20. package/dist/{index-CqO1HNHl.d.ts → index-C7rMJ4IV.d.ts} +132 -7184
  21. package/dist/{index-CqO1HNHl.d.cts → index-Cm_Xpt7X.d.cts} +132 -7184
  22. package/dist/index.cjs +23 -25
  23. package/dist/index.d.cts +58 -34
  24. package/dist/index.d.ts +58 -34
  25. package/dist/index.js +9 -11
  26. package/dist/operations/index.cjs +363 -242
  27. package/dist/operations/index.d.cts +281 -25
  28. package/dist/operations/index.d.ts +281 -25
  29. package/dist/operations/index.js +178 -57
  30. package/dist/pool.cjs +8 -8
  31. package/dist/pool.d.cts +2 -1
  32. package/dist/pool.d.ts +2 -1
  33. package/dist/pool.js +4 -4
  34. package/dist/resources/index.cjs +4 -4
  35. package/dist/resources/index.d.cts +2 -1
  36. package/dist/resources/index.d.ts +2 -1
  37. package/dist/resources/index.js +3 -3
  38. package/dist/types/index.d.cts +1 -1
  39. package/dist/types/index.d.ts +1 -1
  40. package/docs/API.md +95 -120
  41. package/docs/LIVE-TESTING.md +9 -5
  42. package/docs/RELEASING.md +121 -0
  43. package/package.json +3 -2
@@ -69,30 +69,33 @@
69
69
 
70
70
 
71
71
 
72
- var _chunkDKAD7MOVcjs = require('../chunk-DKAD7MOV.cjs');
73
72
 
73
+ var _chunkSEFJJY4Jcjs = require('../chunk-SEFJJY4J.cjs');
74
74
 
75
- var _chunkMJ6J74F3cjs = require('../chunk-MJ6J74F3.cjs');
76
- require('../chunk-MJTKK3QG.cjs');
75
+
76
+ var _chunkVEOSOIU4cjs = require('../chunk-VEOSOIU4.cjs');
77
+
78
+
79
+ var _chunkMJTKK3QGcjs = require('../chunk-MJTKK3QG.cjs');
77
80
 
78
81
  // src/operations/searchAcrossResources.ts
79
82
  var DEFAULT_LIMIT = 25;
80
83
  function resourceFor(client, key) {
81
- return client[_chunkDKAD7MOVcjs.camelKey.call(void 0, key)];
84
+ return client[_chunkSEFJJY4Jcjs.camelKey.call(void 0, key)];
82
85
  }
83
86
  async function searchAcrossResources(client, query, opts = {}) {
84
87
  const text = query.trim();
85
88
  if (text === "") {
86
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("searchAcrossResources: query must be a non-empty string");
89
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("searchAcrossResources: query must be a non-empty string");
87
90
  }
88
- const keys = _nullishCoalesce(opts.resources, () => ( _chunkDKAD7MOVcjs.WORKFLOW_RESOURCES));
91
+ const keys = _nullishCoalesce(opts.resources, () => ( _chunkSEFJJY4Jcjs.WORKFLOW_RESOURCES));
89
92
  if (keys.length === 0) {
90
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("searchAcrossResources: no resources requested");
93
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("searchAcrossResources: no resources requested");
91
94
  }
92
- const limit = _chunkDKAD7MOVcjs.clampPageSize.call(void 0, _nullishCoalesce(opts.limit, () => ( DEFAULT_LIMIT)));
95
+ const limit = _chunkSEFJJY4Jcjs.clampPageSize.call(void 0, _nullishCoalesce(opts.limit, () => ( DEFAULT_LIMIT)));
93
96
  const totalLimit = opts.totalLimit;
94
97
  if (totalLimit !== void 0 && !(Number.isInteger(totalLimit) && totalLimit >= 1)) {
95
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("searchAcrossResources: totalLimit must be a positive integer");
98
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("searchAcrossResources: totalLimit must be a positive integer");
96
99
  }
97
100
  const results = [];
98
101
  const skipped = [];
@@ -123,7 +126,7 @@ async function searchAcrossResources(client, query, opts = {}) {
123
126
 
124
127
  // src/operations/resolveAny.ts
125
128
  function resourceFor2(client, key) {
126
- return client[_chunkDKAD7MOVcjs.camelKey.call(void 0, key)];
129
+ return client[_chunkSEFJJY4Jcjs.camelKey.call(void 0, key)];
127
130
  }
128
131
  var FAULT_CATEGORIES = /* @__PURE__ */ new Set(["auth", "rate_limit", "server", "network", "timeout", "policy"]);
129
132
  function missCost(identifier) {
@@ -132,13 +135,17 @@ function missCost(identifier) {
132
135
  }
133
136
  async function resolveAny(client, identifier, opts = {}) {
134
137
  if (typeof identifier === "number") {
135
- _chunkDKAD7MOVcjs.parseIdentifier.call(void 0, identifier, "identifier");
138
+ _chunkSEFJJY4Jcjs.parseIdentifier.call(void 0, identifier, "identifier");
136
139
  } else if (identifier.trim() === "") {
137
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("resolveAny: identifier must be non-empty");
140
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("resolveAny: identifier must be non-empty");
138
141
  }
139
- const keys = _nullishCoalesce(opts.resources, () => ( _chunkDKAD7MOVcjs.WORKFLOW_RESOURCES));
142
+ const keys = _nullishCoalesce(opts.resources, () => ( _chunkSEFJJY4Jcjs.WORKFLOW_RESOURCES));
140
143
  if (keys.length === 0) {
141
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("resolveAny: no resources requested");
144
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("resolveAny: no resources requested");
145
+ }
146
+ const match = _nullishCoalesce(opts.match, () => ( "exact"));
147
+ if (match !== "exact" && match !== "auto") {
148
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`resolveAny: match must be 'exact' or 'auto' (got ${JSON.stringify(match)})`);
142
149
  }
143
150
  const results = [];
144
151
  for (const key of keys) {
@@ -157,20 +164,37 @@ async function resolveAny(client, identifier, opts = {}) {
157
164
  }
158
165
  try {
159
166
  const r = await holder.resolveDetailed(identifier);
160
- results.push({
167
+ let outcome = {
161
168
  resource: key,
162
169
  value: _nullishCoalesce(r.value, () => ( null)),
163
170
  resolutionCost: r.resolutionCost,
164
171
  scanned: r.scanned,
165
172
  scanTruncated: r.scanTruncated,
166
173
  candidates: (_nullishCoalesce(r.candidates, () => ( []))).map((c) => c.id)
167
- });
174
+ };
175
+ if (match === "auto" && outcome.value === null && typeof identifier === "string") {
176
+ const hits = await holder.resolveContainsMatches(identifier);
177
+ if (hits.length === 1) {
178
+ outcome = { resource: key, value: hits[0], resolutionCost: "server-filter", scanned: 0, scanTruncated: false, candidates: [] };
179
+ } else if (hits.length > 1) {
180
+ outcome = {
181
+ resource: key,
182
+ value: null,
183
+ resolutionCost: "server-filter",
184
+ scanned: 0,
185
+ scanTruncated: false,
186
+ candidates: hits.map((h) => h.id).filter((id) => typeof id === "number"),
187
+ error: "RESOLUTION_AMBIGUOUS"
188
+ };
189
+ }
190
+ }
191
+ results.push(outcome);
168
192
  } catch (err) {
169
193
  let code;
170
194
  let candidates = [];
171
- if (err instanceof _chunkDKAD7MOVcjs.AutotaskConfigError) {
195
+ if (err instanceof _chunkSEFJJY4Jcjs.AutotaskConfigError) {
172
196
  code = "CONFIG_ERROR";
173
- } else if (_chunkDKAD7MOVcjs.isAutotaskError.call(void 0, err)) {
197
+ } else if (_chunkSEFJJY4Jcjs.isAutotaskError.call(void 0, err)) {
174
198
  if (FAULT_CATEGORIES.has(err.category)) throw err;
175
199
  code = err.code;
176
200
  if (code === "RESOLUTION_AMBIGUOUS" && err.resourceIds !== void 0) {
@@ -197,7 +221,7 @@ async function resolveAny(client, identifier, opts = {}) {
197
221
  // src/operations/aggregate.ts
198
222
  var AGGREGATE_TOP_MAX = 100;
199
223
  var AGGREGATE_DEFAULT_TOP = 25;
200
- var AGGREGATE_DEFAULT_LIMIT = _chunkDKAD7MOVcjs.BOUNDED_QUERY_MAX_LIMIT;
224
+ var AGGREGATE_DEFAULT_LIMIT = _chunkSEFJJY4Jcjs.BOUNDED_QUERY_MAX_LIMIT;
201
225
  var AGGREGATE_DATE_BUCKETS = ["month", "week", "year"];
202
226
  var DATE_ONLY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
203
227
  var DATETIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?(Z|[+-]\d{2}:?\d{2})?$/;
@@ -254,10 +278,10 @@ function dateBucketLabel(value, bucket) {
254
278
  }
255
279
  var QUERY_RESOURCE_KEYS = (() => {
256
280
  const s = /* @__PURE__ */ new Set();
257
- for (const rec of _chunkMJ6J74F3cjs.CAPABILITIES) if (rec.operation === "query") s.add(rec.resource);
281
+ for (const rec of _chunkVEOSOIU4cjs.CAPABILITIES) if (rec.operation === "query") s.add(rec.resource);
258
282
  return s;
259
283
  })();
260
- var AGGREGATE_OPT_KEYS = ["groupBy", "sum", "top", "limit", "names"];
284
+ var AGGREGATE_OPT_KEYS = ["groupBy", "sum", "top", "limit", "names", "acknowledgeUnscoped"];
261
285
  var OP_RE = /^([a-z0-9_]+)\.query$/;
262
286
  function num2(v) {
263
287
  return typeof v === "number" && Number.isFinite(v) ? v : 0;
@@ -290,15 +314,15 @@ function parseFilterConditions(filter, problems) {
290
314
  return [];
291
315
  }
292
316
  try {
293
- return _chunkDKAD7MOVcjs.buildFilter.call(void 0, conds).filter;
317
+ return _chunkSEFJJY4Jcjs.buildFilter.call(void 0, conds).filter;
294
318
  } catch (err) {
295
- problems.push(err instanceof _chunkDKAD7MOVcjs.AutotaskConfigError ? err.message : `filter must be the query-bag filter (13 operators; caps 500 OR-conditions / 1 UDF / 8000 chars); ${String(err)}`);
319
+ problems.push(err instanceof _chunkSEFJJY4Jcjs.AutotaskConfigError ? err.message : `filter must be the query-bag filter (13 operators; caps 500 OR-conditions / 1 UDF / 8000 chars); ${String(err)}`);
296
320
  return [];
297
321
  }
298
322
  }
299
323
  function checkOptsBag(opts, problems) {
300
324
  if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
301
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
325
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
302
326
  `aggregate: opts must be the options object (got ${Array.isArray(opts) ? "an array" : typeof opts})`,
303
327
  { operation: "operations.aggregate" }
304
328
  );
@@ -309,6 +333,9 @@ function checkOptsBag(opts, problems) {
309
333
  }
310
334
  }
311
335
  if (_optionalChain([opts, 'optionalAccess', _2 => _2.names]) !== void 0 && typeof opts.names !== "boolean") problems.push(`names must be a boolean (got ${typeof opts.names})`);
336
+ if (_optionalChain([opts, 'optionalAccess', _3 => _3.acknowledgeUnscoped]) !== void 0 && typeof opts.acknowledgeUnscoped !== "boolean") {
337
+ problems.push(`acknowledgeUnscoped must be a boolean (got ${typeof opts.acknowledgeUnscoped})`);
338
+ }
312
339
  }
313
340
  function checkSumFields(name, fields, problems) {
314
341
  if (fields === void 0) return [];
@@ -362,18 +389,18 @@ function parseTopAndLimit(opts, problems) {
362
389
  if (!Number.isInteger(opts.limit)) {
363
390
  problems.push(`limit must be an integer (got ${String(opts.limit)})`);
364
391
  } else {
365
- limit = Math.min(Math.max(opts.limit, 1), _chunkDKAD7MOVcjs.BOUNDED_QUERY_MAX_LIMIT);
392
+ limit = Math.min(Math.max(opts.limit, 1), _chunkSEFJJY4Jcjs.BOUNDED_QUERY_MAX_LIMIT);
366
393
  }
367
394
  }
368
395
  return { top, limit };
369
396
  }
370
397
  async function checkFieldNames(resourceKey, conditions, opts, problems) {
371
- const record = resourceKey === void 0 ? void 0 : _chunkMJ6J74F3cjs.CAPABILITIES.find((r) => r.resource === resourceKey && r.operation === "query");
398
+ const record = resourceKey === void 0 ? void 0 : _chunkVEOSOIU4cjs.CAPABILITIES.find((r) => r.resource === resourceKey && r.operation === "query");
372
399
  if (record === void 0) return void 0;
373
400
  const strings = (v) => Array.isArray(v) ? v.filter((f) => typeof f === "string" && f.trim() !== "") : [];
374
401
  const groupBy = strings(opts.groupBy);
375
- const found = await _chunkDKAD7MOVcjs.findUnknownFieldNames.call(void 0, record, void 0, {
376
- filter: _chunkDKAD7MOVcjs.collectFilterFieldNames.call(void 0, conditions),
402
+ const found = await _chunkSEFJJY4Jcjs.findUnknownFieldNames.call(void 0, record, void 0, {
403
+ filter: _chunkSEFJJY4Jcjs.collectFilterFieldNames.call(void 0, conditions, resourceKey),
377
404
  groupBy: groupBy.map((f) => f.split("@")[0]),
378
405
  sum: strings(opts.sum)
379
406
  });
@@ -397,19 +424,22 @@ async function validateAggregate(operation, filter, opts) {
397
424
  checkOptsBag(opts, problems);
398
425
  const oracles = {
399
426
  resourceKey,
400
- dateSets: resourceKey !== void 0 ? _chunkDKAD7MOVcjs.MODEL_DATE_FIELDS[resourceKey] : void 0
427
+ dateSets: resourceKey !== void 0 ? _chunkSEFJJY4Jcjs.MODEL_DATE_FIELDS[resourceKey] : void 0
401
428
  };
402
429
  const known = await checkFieldNames(resourceKey, conditions, opts, problems);
403
430
  const groupBy = parseGroupBy(opts, oracles, known, problems);
404
431
  const sum = checkSumFields("sum", opts.sum, problems);
405
432
  const { top, limit } = parseTopAndLimit(opts, problems);
406
433
  if (problems.length > 0) {
407
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
434
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
408
435
  `aggregate: ${problems.length} problem(s) found pre-request (zero wire was issued)
409
436
  - ` + problems.join("\n- "),
410
437
  { operation: "operations.aggregate" }
411
438
  );
412
439
  }
440
+ if ((groupBy.length > 0 || sum.length > 0) && conditions.length === 0 && opts.acknowledgeUnscoped !== true) {
441
+ throw new (0, _chunkSEFJJY4Jcjs.ScopeRequiredError)(operation, { threshold: _chunkSEFJJY4Jcjs.UNSCOPED_WALK_THRESHOLD }, "empty-filter");
442
+ }
413
443
  return { resourceKey, conditions, groupBy, sum, top, limit };
414
444
  }
415
445
  function foldGroups(items, v) {
@@ -438,9 +468,9 @@ function foldGroups(items, v) {
438
468
  }
439
469
  async function aggregate(client, operation, filter, opts = {}) {
440
470
  const v = await validateAggregate(operation, filter, opts);
441
- const holder = client[_chunkDKAD7MOVcjs.camelKey.call(void 0, v.resourceKey)];
471
+ const holder = client[_chunkSEFJJY4Jcjs.camelKey.call(void 0, v.resourceKey)];
442
472
  if (holder === void 0) {
443
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`aggregate: the client exposes no accessor for resource "${v.resourceKey}"`, {
473
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`aggregate: the client exposes no accessor for resource "${v.resourceKey}"`, {
444
474
  operation: "operations.aggregate",
445
475
  suggestedAction: "Rebuild the client from the SDK build that ships this registry (the resource set is pinned by the plan)."
446
476
  });
@@ -449,7 +479,7 @@ async function aggregate(client, operation, filter, opts = {}) {
449
479
  if (v.groupBy.length === 0 && v.sum.length === 0) {
450
480
  const raw = await holder.count({ filter: wireFilter });
451
481
  const sentinel = typeof raw === "object" && raw !== null && "count" in raw ? raw : { count: raw };
452
- const result2 = { mode: "count", count: sentinel.count, blind: sentinel.blindSurface !== void 0 };
482
+ const result2 = { mode: "count", count: sentinel.count, blind: sentinel.blindSurface !== void 0, truncated: false };
453
483
  if (sentinel.blindSurface !== void 0) result2.blindSurface = sentinel.blindSurface;
454
484
  if (sentinel.emptyReason !== void 0) result2.emptyReason = sentinel.emptyReason;
455
485
  return result2;
@@ -457,19 +487,22 @@ async function aggregate(client, operation, filter, opts = {}) {
457
487
  const res = await holder.queryBounded({ filter: wireFilter, limit: v.limit });
458
488
  const sorted = foldGroups(res.items, v);
459
489
  const top = sorted.slice(0, v.top);
460
- const labelled = opts.names === false || v.groupBy.length === 0 ? void 0 : await _chunkDKAD7MOVcjs.labelRows.call(void 0, client, v.resourceKey, top.map((g) => g.key));
490
+ const label = _chunkSEFJJY4Jcjs.readNamesOpt.call(void 0, client, opts.names, "aggregate");
491
+ const labelled = !label || v.groupBy.length === 0 ? void 0 : await _chunkSEFJJY4Jcjs.labelRows.call(void 0, client, v.resourceKey, top.map((g) => g.key));
461
492
  const result = {
462
493
  mode: v.groupBy.length > 0 ? "group" : "sum",
463
- groups: top.map((g, i) => ({ key: _nullishCoalesce(_optionalChain([labelled, 'optionalAccess', _3 => _3.rows, 'access', _4 => _4[i]]), () => ( g.key)), count: g.count, ...g.sums !== void 0 ? { sums: g.sums } : {} })),
494
+ groups: top.map((g, i) => ({ key: _nullishCoalesce(_optionalChain([labelled, 'optionalAccess', _4 => _4.rows, 'access', _5 => _5[i]]), () => ( g.key)), count: g.count, ...g.sums !== void 0 ? { sums: g.sums } : {} })),
464
495
  totalGroups: sorted.length,
465
496
  groupsTruncated: sorted.length > top.length,
466
497
  totalScanned: res.fetched,
467
- hasMore: res.hasMore
498
+ hasMore: res.hasMore,
499
+ truncated: res.hasMore
500
+ // issue #287 (D6): the walk hit its limit — groups may be incomplete
468
501
  };
469
502
  if (res.blindSurface !== void 0) result.blindSurface = res.blindSurface;
470
503
  if (res.emptyReason !== void 0) result.emptyReason = res.emptyReason;
471
504
  if (res.relationNote !== void 0) result.relationNote = res.relationNote;
472
- if (_optionalChain([labelled, 'optionalAccess', _5 => _5.names]) !== void 0) result.names = labelled.names;
505
+ if (_optionalChain([labelled, 'optionalAccess', _6 => _6.names]) !== void 0) result.names = labelled.names;
473
506
  return result;
474
507
  }
475
508
 
@@ -488,12 +521,12 @@ var DEFAULT_CONTRACT_TYPE_RE = /^\s*(recurring|fixed)\b/i;
488
521
  var CONTRACTS_PATH = "/V1.0/Contracts";
489
522
  var COMPANIES_PATH = "/V1.0/Companies";
490
523
  var BILLING_ITEMS_PATH = "/V1.0/BillingItems";
491
- var LINE_TYPE_FIELDS = ["billingItemType", "timeEntryID", "expenseItemID", ..._chunkDKAD7MOVcjs.CHARGE_LINE_FKS, ..._chunkDKAD7MOVcjs.SERVICE_LINE_FKS];
492
- var isLabour = (line) => _chunkDKAD7MOVcjs.billingLineType.call(void 0, line) === "labour";
524
+ var LINE_TYPE_FIELDS = ["billingItemType", "timeEntryID", "expenseItemID", ..._chunkSEFJJY4Jcjs.CHARGE_LINE_FKS, ..._chunkSEFJJY4Jcjs.SERVICE_LINE_FKS];
525
+ var isLabour = (line) => _chunkSEFJJY4Jcjs.billingLineType.call(void 0, line) === "labour";
493
526
  function picklistKey(c, dim, path, field, raw, missing) {
494
- const id = _chunkDKAD7MOVcjs.num.call(void 0, raw);
527
+ const id = _chunkSEFJJY4Jcjs.num.call(void 0, raw);
495
528
  if (id === 0) return { id: null, label: missing };
496
- const label = _optionalChain([c, 'access', _6 => _6.labels, 'access', _7 => _7[path], 'optionalAccess', _8 => _8.get, 'call', _9 => _9(field), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(id)]);
529
+ const label = _optionalChain([c, 'access', _7 => _7.labels, 'access', _8 => _8[path], 'optionalAccess', _9 => _9.get, 'call', _10 => _10(field), 'optionalAccess', _11 => _11.get, 'call', _12 => _12(id)]);
497
530
  if (label === void 0) {
498
531
  c.unlabelled.add(`${dim}: ${field} value ${id} has no label on the live ${path} picklist (id-only)`);
499
532
  return { id };
@@ -504,7 +537,7 @@ var DIMENSIONS = {
504
537
  vertical: {
505
538
  joins: { companies: ["marketSegmentID"] },
506
539
  picklist: COMPANIES_PATH,
507
- key: (c) => picklistKey(c, "vertical", COMPANIES_PATH, "marketSegmentID", _optionalChain([c, 'access', _12 => _12.company, 'optionalAccess', _13 => _13["marketSegmentID"]]), "unassigned")
540
+ key: (c) => picklistKey(c, "vertical", COMPANIES_PATH, "marketSegmentID", _optionalChain([c, 'access', _13 => _13.company, 'optionalAccess', _14 => _14["marketSegmentID"]]), "unassigned")
508
541
  },
509
542
  contractType: {
510
543
  key: (c) => picklistKey(c, "contractType", CONTRACTS_PATH, "contractType", c.contract["contractType"], "none")
@@ -514,7 +547,7 @@ var DIMENSIONS = {
514
547
  },
515
548
  company: {
516
549
  joins: { companies: ["companyName"] },
517
- key: (c) => ({ id: _chunkDKAD7MOVcjs.num.call(void 0, c.line["companyID"]), name: String(_nullishCoalesce(_optionalChain([c, 'access', _14 => _14.company, 'optionalAccess', _15 => _15["companyName"]]), () => ( ""))) })
550
+ key: (c) => ({ id: _chunkSEFJJY4Jcjs.num.call(void 0, c.line["companyID"]), name: String(_nullishCoalesce(_optionalChain([c, 'access', _15 => _15.company, 'optionalAccess', _16 => _16["companyName"]]), () => ( ""))) })
518
551
  },
519
552
  month: {
520
553
  key: (c) => ({ id: c.invoice.month })
@@ -522,11 +555,11 @@ var DIMENSIONS = {
522
555
  billingItemKind: {
523
556
  lineFields: LINE_TYPE_FIELDS,
524
557
  picklist: BILLING_ITEMS_PATH,
525
- key: (c) => _chunkDKAD7MOVcjs.num.call(void 0, c.line["billingItemType"]) === 0 ? { id: _chunkDKAD7MOVcjs.billingLineType.call(void 0, c.line), label: _chunkDKAD7MOVcjs.billingLineType.call(void 0, c.line) } : picklistKey(c, "billingItemKind", BILLING_ITEMS_PATH, "billingItemType", c.line["billingItemType"], "other")
558
+ key: (c) => _chunkSEFJJY4Jcjs.num.call(void 0, c.line["billingItemType"]) === 0 ? { id: _chunkSEFJJY4Jcjs.billingLineType.call(void 0, c.line), label: _chunkSEFJJY4Jcjs.billingLineType.call(void 0, c.line) } : picklistKey(c, "billingItemKind", BILLING_ITEMS_PATH, "billingItemType", c.line["billingItemType"], "other")
526
559
  },
527
560
  contract: {
528
561
  joins: { contracts: ["contractName"] },
529
- key: (c) => ({ id: _chunkDKAD7MOVcjs.num.call(void 0, c.line["contractID"]), name: String(_nullishCoalesce(c.contract["contractName"], () => ( ""))) })
562
+ key: (c) => ({ id: _chunkSEFJJY4Jcjs.num.call(void 0, c.line["contractID"]), name: String(_nullishCoalesce(c.contract["contractName"], () => ( ""))) })
530
563
  },
531
564
  // Per line (no contract-pointer fallback): association → level2 (the Line of Business, `name`) + level1 (the division).
532
565
  lineOfBusiness: {
@@ -534,11 +567,11 @@ var DIMENSIONS = {
534
567
  joins: { organizationalLevelAssociations: [], organizationalLevel1s: [], organizationalLevel2s: [] },
535
568
  unresolved: "unresolvedAssociations",
536
569
  key: (c) => {
537
- const id = _chunkDKAD7MOVcjs.num.call(void 0, c.line["organizationalLevelAssociationID"]);
570
+ const id = _chunkSEFJJY4Jcjs.num.call(void 0, c.line["organizationalLevelAssociationID"]);
538
571
  if (id === 0) return { id: null, label: "no LOB assigned" };
539
572
  const a = c.joined.organizationalLevelAssociations.get(id);
540
- const l1 = c.joined.organizationalLevel1s.get(_chunkDKAD7MOVcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _16 => _16["organizationalLevel1ID"]])));
541
- const l2 = c.joined.organizationalLevel2s.get(_chunkDKAD7MOVcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _17 => _17["organizationalLevel2ID"]])));
573
+ const l1 = c.joined.organizationalLevel1s.get(_chunkSEFJJY4Jcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _17 => _17["organizationalLevel1ID"]])));
574
+ const l2 = c.joined.organizationalLevel2s.get(_chunkSEFJJY4Jcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _18 => _18["organizationalLevel2ID"]])));
542
575
  if (l1 === void 0 || l2 === void 0) return "unresolvedAssociations";
543
576
  return { id, name: String(_nullishCoalesce(l2["name"], () => ( ""))), division: String(_nullishCoalesce(l1["name"], () => ( ""))) };
544
577
  }
@@ -549,9 +582,9 @@ var DIMENSIONS = {
549
582
  joins: { timeEntries: [], resources: [] },
550
583
  unresolved: "unresolvedTimeEntries",
551
584
  key: (c) => {
552
- const te = _chunkDKAD7MOVcjs.num.call(void 0, c.line["timeEntryID"]);
585
+ const te = _chunkSEFJJY4Jcjs.num.call(void 0, c.line["timeEntryID"]);
553
586
  if (!isLabour(c.line) || te === 0) return { id: null, label: "n/a" };
554
- const id = _chunkDKAD7MOVcjs.num.call(void 0, _optionalChain([c, 'access', _18 => _18.joined, 'access', _19 => _19.timeEntries, 'access', _20 => _20.get, 'call', _21 => _21(te), 'optionalAccess', _22 => _22["resourceID"]]));
587
+ const id = _chunkSEFJJY4Jcjs.num.call(void 0, _optionalChain([c, 'access', _19 => _19.joined, 'access', _20 => _20.timeEntries, 'access', _21 => _21.get, 'call', _22 => _22(te), 'optionalAccess', _23 => _23["resourceID"]]));
555
588
  const r = c.joined.resources.get(id);
556
589
  if (r === void 0) return "unresolvedTimeEntries";
557
590
  return { id, name: `${String(_nullishCoalesce(r["firstName"], () => ( "")))} ${String(_nullishCoalesce(r["lastName"], () => ( "")))}`.trim() };
@@ -562,58 +595,58 @@ var DIMENSIONS = {
562
595
  joins: { billingCodes: [] },
563
596
  unresolved: "unresolvedBillingCodes",
564
597
  key: (c) => {
565
- const id = _chunkDKAD7MOVcjs.num.call(void 0, c.line["billingCodeID"]);
598
+ const id = _chunkSEFJJY4Jcjs.num.call(void 0, c.line["billingCodeID"]);
566
599
  if (id === 0) return { id: null, label: "none" };
567
600
  const b = c.joined.billingCodes.get(id);
568
601
  return b === void 0 ? "unresolvedBillingCodes" : { id, name: String(_nullishCoalesce(b["name"], () => ( ""))) };
569
602
  }
570
603
  }
571
604
  };
572
- var fk = (rows, field) => [...rows].map((r) => _chunkDKAD7MOVcjs.num.call(void 0, r[field]));
605
+ var fk = (rows, field) => [...rows].map((r) => _chunkSEFJJY4Jcjs.num.call(void 0, r[field]));
573
606
  var ONE_CHUNK = (idChunks) => Math.min(1, idChunks);
574
607
  var JOINS = {
575
608
  contracts: {
576
- make: (http) => new (0, _chunkDKAD7MOVcjs.ContractsResource)(http, PAGE),
609
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.ContractsResource)(http, PAGE),
577
610
  fields: ["id", "contractType", "contractCategory"],
578
611
  ids: (lines) => fk(lines, "contractID")
579
612
  },
580
613
  companies: {
581
- make: (http) => new (0, _chunkDKAD7MOVcjs.CompaniesResource)(http, PAGE),
614
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.CompaniesResource)(http, PAGE),
582
615
  fields: ["id"],
583
616
  ids: (lines) => fk(lines, "companyID")
584
617
  },
585
618
  organizationalLevelAssociations: {
586
- make: (http) => new (0, _chunkDKAD7MOVcjs.OrganizationalLevelAssociationsResource)(http, PAGE),
619
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.OrganizationalLevelAssociationsResource)(http, PAGE),
587
620
  fields: ["id", "organizationalLevel1ID", "organizationalLevel2ID"],
588
621
  ids: (lines) => fk(lines, "organizationalLevelAssociationID")
589
622
  },
590
623
  organizationalLevel1s: {
591
- make: (http) => new (0, _chunkDKAD7MOVcjs.OrganizationalLevel1sResource)(http, PAGE),
624
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.OrganizationalLevel1sResource)(http, PAGE),
592
625
  fields: ["id", "name"],
593
626
  ids: (_, j) => fk(j["organizationalLevelAssociations"].values(), "organizationalLevel1ID"),
594
627
  chunks: ONE_CHUNK
595
628
  },
596
629
  organizationalLevel2s: {
597
- make: (http) => new (0, _chunkDKAD7MOVcjs.OrganizationalLevel2sResource)(http, PAGE),
630
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.OrganizationalLevel2sResource)(http, PAGE),
598
631
  fields: ["id", "name"],
599
632
  ids: (_, j) => fk(j["organizationalLevelAssociations"].values(), "organizationalLevel2ID"),
600
633
  chunks: ONE_CHUNK
601
634
  },
602
635
  timeEntries: {
603
- make: (http) => new (0, _chunkDKAD7MOVcjs.TimeEntriesResource)(http, PAGE),
636
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.TimeEntriesResource)(http, PAGE),
604
637
  fields: ["id", "resourceID"],
605
638
  ids: (lines) => fk(lines.filter(isLabour), "timeEntryID"),
606
639
  // One time entry per labour line: the line count is the upper bound (labour share unknown pre-walk).
607
640
  chunks: (_, lines) => pages(lines)
608
641
  },
609
642
  resources: {
610
- make: (http, client) => new (0, _chunkDKAD7MOVcjs.ResourcesResource)(http, client.config, PAGE),
643
+ make: (http, client) => new (0, _chunkSEFJJY4Jcjs.ResourcesResource)(http, client.config, PAGE),
611
644
  fields: ["id", "firstName", "lastName"],
612
645
  ids: (_, j) => fk(j["timeEntries"].values(), "resourceID"),
613
646
  chunks: ONE_CHUNK
614
647
  },
615
648
  billingCodes: {
616
- make: (http) => new (0, _chunkDKAD7MOVcjs.BillingCodesResource)(http, PAGE),
649
+ make: (http) => new (0, _chunkSEFJJY4Jcjs.BillingCodesResource)(http, PAGE),
617
650
  fields: ["id", "name"],
618
651
  ids: (lines) => fk(lines, "billingCodeID")
619
652
  }
@@ -648,7 +681,7 @@ function checkInt(name, v, def, max, problems) {
648
681
  }
649
682
  function validate(opts) {
650
683
  if (typeof opts !== "object" || opts === null || Array.isArray(opts)) {
651
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("revenueRollup: opts must be the options object { <scope>, dateFrom, dateTo, ... } (zero wire was issued)", { operation: OP });
684
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("revenueRollup: opts must be the options object { <scope>, dateFrom, dateTo, ... } (zero wire was issued)", { operation: OP });
652
685
  }
653
686
  const o = opts;
654
687
  const problems = [];
@@ -665,12 +698,12 @@ function validate(opts) {
665
698
  if (scopeKind === "tenantWide" && o.tenantWide !== true) problems.push("tenantWide must be exactly true");
666
699
  }
667
700
  const { dateFrom, dateTo } = o;
668
- if (!_chunkDKAD7MOVcjs.isDateYMD.call(void 0, dateFrom) || !_chunkDKAD7MOVcjs.isDateYMD.call(void 0, dateTo)) {
701
+ if (!_chunkSEFJJY4Jcjs.isDateYMD.call(void 0, dateFrom) || !_chunkSEFJJY4Jcjs.isDateYMD.call(void 0, dateTo)) {
669
702
  problems.push("dateFrom and dateTo are both required as YYYY-MM-DD (the window is inclusive, whole UTC days)");
670
703
  } else if (dateFrom > dateTo) {
671
704
  problems.push(`dateFrom ${dateFrom} is after dateTo ${dateTo}`);
672
- } else if (_chunkDKAD7MOVcjs.monthsInWindow.call(void 0, dateFrom, dateTo) > _chunkDKAD7MOVcjs.PROFITABILITY_MAX_WINDOW_MONTHS) {
673
- problems.push(`the window spans ${_chunkDKAD7MOVcjs.monthsInWindow.call(void 0, dateFrom, dateTo)} months; the cap is ${_chunkDKAD7MOVcjs.PROFITABILITY_MAX_WINDOW_MONTHS}`);
705
+ } else if (_chunkSEFJJY4Jcjs.monthsInWindow.call(void 0, dateFrom, dateTo) > _chunkSEFJJY4Jcjs.PROFITABILITY_MAX_WINDOW_MONTHS) {
706
+ problems.push(`the window spans ${_chunkSEFJJY4Jcjs.monthsInWindow.call(void 0, dateFrom, dateTo)} months; the cap is ${_chunkSEFJJY4Jcjs.PROFITABILITY_MAX_WINDOW_MONTHS}`);
674
707
  }
675
708
  let groupBy = [...DEFAULT_GROUP_BY];
676
709
  if (o.groupBy !== void 0) {
@@ -697,7 +730,7 @@ function validate(opts) {
697
730
  };
698
731
  if (o.includeNonChargeable !== void 0 && typeof o.includeNonChargeable !== "boolean") problems.push("includeNonChargeable must be a boolean");
699
732
  if (problems.length > 0) {
700
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`revenueRollup: ${problems.length} problem(s) found pre-request (zero wire was issued)
733
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`revenueRollup: ${problems.length} problem(s) found pre-request (zero wire was issued)
701
734
  - ${problems.join("\n- ")}`, { operation: OP });
702
735
  }
703
736
  return v;
@@ -715,7 +748,7 @@ function resolveSelector(name, sel, values) {
715
748
  }
716
749
  function unmatched(name, what, values) {
717
750
  const live = [...values].map(([id, l]) => `${id} ${l}`).join("; ") || "(the picklist serves no values)";
718
- return new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`revenueRollup: ${name}: ${what}. Live values (id label): ${live}`, {
751
+ return new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`revenueRollup: ${name}: ${what}. Live values (id label): ${live}`, {
719
752
  operation: OP,
720
753
  suggestedAction: `Pass ${name} as ids or exact labels from the live list.`
721
754
  });
@@ -726,10 +759,10 @@ var chunk = (a) => {
726
759
  for (let i = 0; i < a.length; i += PAGE) out.push(a.slice(i, i + PAGE));
727
760
  return out;
728
761
  };
729
- var byId = (rows) => [...new Map(rows.map((r) => [_chunkDKAD7MOVcjs.num.call(void 0, r["id"]), r])).values()];
730
- var cents = (v) => Math.round(_chunkDKAD7MOVcjs.num.call(void 0, v) * 100);
731
- var revC = (line) => cents(_chunkDKAD7MOVcjs.internalAmount.call(void 0, line, "internalCurrencyTotalAmount", "totalAmount"));
732
- var extC = (line) => cents(_chunkDKAD7MOVcjs.internalAmount.call(void 0, line, "internalCurrencyExtendedPrice", "extendedPrice"));
762
+ var byId = (rows) => [...new Map(rows.map((r) => [_chunkSEFJJY4Jcjs.num.call(void 0, r["id"]), r])).values()];
763
+ var cents = (v) => Math.round(_chunkSEFJJY4Jcjs.num.call(void 0, v) * 100);
764
+ var revC = (line) => cents(_chunkSEFJJY4Jcjs.internalAmount.call(void 0, line, "internalCurrencyTotalAmount", "totalAmount"));
765
+ var extC = (line) => cents(_chunkSEFJJY4Jcjs.internalAmount.call(void 0, line, "internalCurrencyExtendedPrice", "extendedPrice"));
733
766
  var INTERNAL_FIELDS = ["internalCurrencyTotalAmount", "internalCurrencyExtendedPrice"];
734
767
  var lacksInternal = (line) => INTERNAL_FIELDS.some((k) => !Number.isFinite(line[k]));
735
768
  var money = (c) => c / 100;
@@ -740,7 +773,7 @@ async function collect(res, filter, includeFields) {
740
773
  return out;
741
774
  }
742
775
  function blindCount() {
743
- return new (0, _chunkDKAD7MOVcjs.AutotaskError)("revenueRollup: a gate count came back blind (unknown, not zero); the roll-up cannot be sized", {
776
+ return new (0, _chunkSEFJJY4Jcjs.AutotaskError)("revenueRollup: a gate count came back blind (unknown, not zero); the roll-up cannot be sized", {
744
777
  code: "INVALID_RESPONSE",
745
778
  category: "server",
746
779
  operation: OP,
@@ -750,7 +783,7 @@ function blindCount() {
750
783
  }
751
784
  function countMismatch(what, streamed, counted, rows) {
752
785
  const rowNote = rows !== void 0 && rows !== streamed ? ` (${rows} rows)` : "";
753
- return new (0, _chunkDKAD7MOVcjs.AutotaskError)(`revenueRollup: the ${what} stream returned ${streamed} distinct ids${rowNote} but the gate count was ${counted} (the data changed mid-walk or a page dropped rows); the fold was discarded`, {
786
+ return new (0, _chunkSEFJJY4Jcjs.AutotaskError)(`revenueRollup: the ${what} stream returned ${streamed} distinct ids${rowNote} but the gate count was ${counted} (the data changed mid-walk or a page dropped rows); the fold was discarded`, {
754
787
  code: "INVALID_RESPONSE",
755
788
  category: "server",
756
789
  operation: OP,
@@ -759,7 +792,7 @@ function countMismatch(what, streamed, counted, rows) {
759
792
  });
760
793
  }
761
794
  function budgetError(message, details, suggestedAction) {
762
- return new (0, _chunkDKAD7MOVcjs.AutotaskError)(message, { code: "BUDGET_EXCEEDED", category: "policy", operation: OP, details, suggestedAction });
795
+ return new (0, _chunkSEFJJY4Jcjs.AutotaskError)(message, { code: "BUDGET_EXCEEDED", category: "policy", operation: OP, details, suggestedAction });
763
796
  }
764
797
  function lastMonthsFrom(dateTo, months) {
765
798
  return new Date(Date.UTC(Number(dateTo.slice(0, 4)), Number(dateTo.slice(5, 7)) - months, 1)).toISOString().slice(0, 10);
@@ -792,7 +825,7 @@ async function revenueRollup(client, opts) {
792
825
  const groupDims = v.groupBy.map((d) => DIMENSIONS[d]);
793
826
  const paths = [.../* @__PURE__ */ new Set([CONTRACTS_PATH, ...groupDims.flatMap((d) => d.picklist ? [d.picklist] : [])])];
794
827
  const labels = {};
795
- for (const p of paths) labels[p] = await _chunkDKAD7MOVcjs.readPicklists.call(void 0, http, p, OP);
828
+ for (const p of paths) labels[p] = await _chunkSEFJJY4Jcjs.readPicklists.call(void 0, http, p, OP);
796
829
  const contractLabels = labels[CONTRACTS_PATH];
797
830
  const typeValues = _nullishCoalesce(contractLabels.get("contractType"), () => ( /* @__PURE__ */ new Map()));
798
831
  const inTypes = v.contractTypes ? resolveSelector("contractTypes", v.contractTypes, typeValues) : new Map([...typeValues].filter(([, l]) => DEFAULT_CONTRACT_TYPE_RE.test(l)));
@@ -801,23 +834,23 @@ async function revenueRollup(client, opts) {
801
834
  let scopeIds = v.scopeIds;
802
835
  if (v.scopeKind === "ownerResourceID") {
803
836
  const owned = /* @__PURE__ */ new Set();
804
- for await (const c of new (0, _chunkDKAD7MOVcjs.CompaniesResource)(http, PAGE).query({ filter: [{ field: "ownerResourceID", op: "eq", value: v.ownerResourceID }], includeFields: ["id"], maxRecords: PAGE, names: false })) {
805
- const id = _chunkDKAD7MOVcjs.num.call(void 0, c.id);
837
+ for await (const c of new (0, _chunkSEFJJY4Jcjs.CompaniesResource)(http, PAGE).query({ filter: [{ field: "ownerResourceID", op: "eq", value: v.ownerResourceID }], includeFields: ["id"], maxRecords: PAGE, names: false })) {
838
+ const id = _chunkSEFJJY4Jcjs.num.call(void 0, c.id);
806
839
  if (id > 0) owned.add(id);
807
840
  if (owned.size > SCOPE_IDS_MAX) break;
808
841
  }
809
842
  scopeIds = [...owned].sort((a, b) => a - b);
810
843
  if (scopeIds.length === 0 || scopeIds.length > SCOPE_IDS_MAX) {
811
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
844
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
812
845
  `revenueRollup: ownerResourceID ${v.ownerResourceID} resolves to ${scopeIds.length > SCOPE_IDS_MAX ? `more than ${SCOPE_IDS_MAX}` : 0} companies (companies.query; 1..${SCOPE_IDS_MAX} supported)`,
813
846
  { operation: OP, suggestedAction: "Pass companyIDs explicitly, or tenantWide: true." }
814
847
  );
815
848
  }
816
849
  }
817
850
  const scopeCond = scopeIds === void 0 ? [] : [{ field: v.scopeKind === "contractIDs" ? "contractID" : "companyID", op: "in", value: scopeIds }];
818
- const invoices = new (0, _chunkDKAD7MOVcjs.InvoicesResource)(http, PAGE);
819
- const billingItems = new (0, _chunkDKAD7MOVcjs.BillingItemsResource)(http, PAGE);
820
- const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value: _chunkDKAD7MOVcjs.dayAfter.call(void 0, v.dateTo) }];
851
+ const invoices = new (0, _chunkSEFJJY4Jcjs.InvoicesResource)(http, PAGE);
852
+ const billingItems = new (0, _chunkSEFJJY4Jcjs.BillingItemsResource)(http, PAGE);
853
+ const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value: _chunkSEFJJY4Jcjs.dayAfter.call(void 0, v.dateTo) }];
821
854
  const invoiceFilter = (voided2) => [...windowOn("invoiceDateTime"), { field: "isVoided", op: "eq", value: voided2 }];
822
855
  const withVoided = v.scopeKind !== "contractIDs";
823
856
  const voidedFilter = [...invoiceFilter(true), ...scopeIds !== void 0 && withVoided ? [{ field: "companyID", op: "in", value: scopeIds }] : []];
@@ -826,7 +859,7 @@ async function revenueRollup(client, opts) {
826
859
  const uninvoicedFilter = [{ field: "invoiceID", op: "notExist" }, ...windowOn("itemDate"), ...scopeCond];
827
860
  const nUninvoiced = v.nonChargeable ? await billingItems.count({ filter: uninvoicedFilter }) : 0;
828
861
  if (typeof nInvoices !== "number" || typeof nLines !== "number" || typeof nUninvoiced !== "number") throw blindCount();
829
- const joinsNeeded = Object.keys(JOINS).filter((j) => j === "contracts" || groupDims.some((d) => _optionalChain([d, 'access', _23 => _23.joins, 'optionalAccess', _24 => _24[j]])));
862
+ const joinsNeeded = Object.keys(JOINS).filter((j) => j === "contracts" || groupDims.some((d) => _optionalChain([d, 'access', _24 => _24.joins, 'optionalAccess', _25 => _25[j]])));
830
863
  const chunks = pages(nInvoices);
831
864
  const linePages = chunks + Math.max(0, pages(nLines) - 1) + chunks;
832
865
  const uninvoicedPages = v.nonChargeable ? Math.max(1, pages(nUninvoiced)) : 0;
@@ -841,7 +874,7 @@ async function revenueRollup(client, opts) {
841
874
  const invoiceRows = await collect(invoices, invoiceFilter(false), ["id", "invoiceTotal", "invoiceDateTime", "companyID"]);
842
875
  const invoiceById = /* @__PURE__ */ new Map();
843
876
  for (const r of invoiceRows) {
844
- invoiceById.set(_chunkDKAD7MOVcjs.num.call(void 0, r["id"]), { total: cents(r["invoiceTotal"]), month: String(_nullishCoalesce(r["invoiceDateTime"], () => ( ""))).slice(0, 7), companyID: _chunkDKAD7MOVcjs.num.call(void 0, r["companyID"]) });
877
+ invoiceById.set(_chunkSEFJJY4Jcjs.num.call(void 0, r["id"]), { total: cents(r["invoiceTotal"]), month: String(_nullishCoalesce(r["invoiceDateTime"], () => ( ""))).slice(0, 7), companyID: _chunkSEFJJY4Jcjs.num.call(void 0, r["companyID"]) });
845
878
  }
846
879
  if (invoiceById.size !== nInvoices) throw countMismatch("invoice", invoiceById.size, nInvoices, invoiceRows.length);
847
880
  const voided = withVoided ? byId(await collect(invoices, voidedFilter, ["id", "invoiceTotal"])) : void 0;
@@ -855,13 +888,13 @@ async function revenueRollup(client, opts) {
855
888
  if (rows.length !== n) throw countMismatch("line", rows.length, n);
856
889
  return rows;
857
890
  }, chunk(ids), { concurrency: CONCURRENCY })).flat();
858
- const orphan = lines.find((l) => !invoiceById.has(_chunkDKAD7MOVcjs.num.call(void 0, l["invoiceID"])));
891
+ const orphan = lines.find((l) => !invoiceById.has(_chunkSEFJJY4Jcjs.num.call(void 0, l["invoiceID"])));
859
892
  if (orphan !== void 0) {
860
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(`revenueRollup: billing line ${_chunkDKAD7MOVcjs.num.call(void 0, orphan["id"])} belongs to invoice ${_chunkDKAD7MOVcjs.num.call(void 0, orphan["invoiceID"])}, which is not among the ${invoiceById.size} streamed invoices; the fold was discarded`, {
893
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(`revenueRollup: billing line ${_chunkSEFJJY4Jcjs.num.call(void 0, orphan["id"])} belongs to invoice ${_chunkSEFJJY4Jcjs.num.call(void 0, orphan["invoiceID"])}, which is not among the ${invoiceById.size} streamed invoices; the fold was discarded`, {
861
894
  code: "INVALID_RESPONSE",
862
895
  category: "server",
863
896
  operation: OP,
864
- details: { reason: "orphan_line", lineID: _chunkDKAD7MOVcjs.num.call(void 0, orphan["id"]), invoiceID: _chunkDKAD7MOVcjs.num.call(void 0, orphan["invoiceID"]) },
897
+ details: { reason: "orphan_line", lineID: _chunkSEFJJY4Jcjs.num.call(void 0, orphan["id"]), invoiceID: _chunkSEFJJY4Jcjs.num.call(void 0, orphan["invoiceID"]) },
865
898
  suggestedAction: "Retry the call."
866
899
  });
867
900
  }
@@ -872,15 +905,15 @@ async function revenueRollup(client, opts) {
872
905
  for (const j of joinsNeeded) {
873
906
  const spec = JOINS[j];
874
907
  const res = spec.make(http, client);
875
- const fields = [.../* @__PURE__ */ new Set([...spec.fields, ...groupDims.flatMap((d) => _nullishCoalesce(_optionalChain([d, 'access', _25 => _25.joins, 'optionalAccess', _26 => _26[j]]), () => ( [])))])];
908
+ const fields = [.../* @__PURE__ */ new Set([...spec.fields, ...groupDims.flatMap((d) => _nullishCoalesce(_optionalChain([d, 'access', _26 => _26.joins, 'optionalAccess', _27 => _27[j]]), () => ( [])))])];
876
909
  const want = [...new Set(spec.ids(all, joined))].filter((id) => id > 0).sort((a, b) => a - b);
877
910
  const rows = await client.batch((c) => collect(res, [{ field: "id", op: "in", value: c }], fields), chunk(want), { concurrency: CONCURRENCY });
878
- for (const r of rows.flat()) joined[j].set(_chunkDKAD7MOVcjs.num.call(void 0, r["id"]), r);
911
+ for (const r of rows.flat()) joined[j].set(_chunkSEFJJY4Jcjs.num.call(void 0, r["id"]), r);
879
912
  }
880
913
  return fold(v, { invoiceById, voided, lines, uninvoiced, joined, labels, inTypes, inCategories, scopeIds, calls, estimate });
881
914
  }
882
915
  function refusal(v, estimate, fixed, scopeIds, joinCount) {
883
- const months = _chunkDKAD7MOVcjs.monthsInWindow.call(void 0, v.dateFrom, v.dateTo);
916
+ const months = _chunkSEFJJY4Jcjs.monthsInWindow.call(void 0, v.dateFrom, v.dateTo);
884
917
  const variable = estimate - fixed;
885
918
  const fitMonths = Math.floor((v.budget - fixed) * months / variable);
886
919
  const suggestions = [];
@@ -953,13 +986,13 @@ function fold(v, f) {
953
986
  const contractLabels = f.labels[CONTRACTS_PATH];
954
987
  const bucketLabel = (field, fallback) => (t) => {
955
988
  const values = contractLabels.get(field);
956
- const l = _optionalChain([values, 'optionalAccess', _27 => _27.get, 'call', _28 => _28(t)]);
989
+ const l = _optionalChain([values, 'optionalAccess', _28 => _28.get, 'call', _29 => _29(t)]);
957
990
  if (l === void 0) return `${fallback} ${t}`;
958
991
  return [...values.values()].filter((x) => x === l).length > 1 ? `${l} (${t})` : l;
959
992
  };
960
993
  const typeLabel = bucketLabel("contractType", "type");
961
994
  const catLabel = bucketLabel("contractCategory", "category");
962
- const needCompany = v.groupBy.some((d) => _optionalChain([DIMENSIONS, 'access', _29 => _29[d], 'access', _30 => _30.joins, 'optionalAccess', _31 => _31.companies]));
995
+ const needCompany = v.groupBy.some((d) => _optionalChain([DIMENSIONS, 'access', _30 => _30[d], 'access', _31 => _31.joins, 'optionalAccess', _32 => _32.companies]));
963
996
  const byLob = v.groupBy.includes("lineOfBusiness");
964
997
  const unlabelled = /* @__PURE__ */ new Set();
965
998
  const uncontracted = amt();
@@ -976,15 +1009,15 @@ function fold(v, f) {
976
1009
  const zeroTotal = amt();
977
1010
  const zeroIds = /* @__PURE__ */ new Set();
978
1011
  const locate = (line, invoice) => {
979
- const contractID = _chunkDKAD7MOVcjs.num.call(void 0, line["contractID"]);
1012
+ const contractID = _chunkSEFJJY4Jcjs.num.call(void 0, line["contractID"]);
980
1013
  if (contractID === 0) return { bucket: uncontracted, unresolved: false };
981
1014
  const contract = f.joined.contracts.get(contractID);
982
1015
  if (contract === void 0) return { bucket: unresolvedContracts, unresolved: true };
983
- const type = _chunkDKAD7MOVcjs.num.call(void 0, contract["contractType"]);
1016
+ const type = _chunkSEFJJY4Jcjs.num.call(void 0, contract["contractType"]);
984
1017
  if (!f.inTypes.has(type)) return { bucket: slot(otherTypes, typeLabel(type)), unresolved: false };
985
- const cat = _chunkDKAD7MOVcjs.num.call(void 0, contract["contractCategory"]);
1018
+ const cat = _chunkSEFJJY4Jcjs.num.call(void 0, contract["contractCategory"]);
986
1019
  if (f.inCategories !== void 0 && !f.inCategories.has(cat)) return { bucket: slot(otherCats, cat === 0 ? "uncategorised" : catLabel(cat)), unresolved: false };
987
- const company = f.joined.companies.get(_chunkDKAD7MOVcjs.num.call(void 0, line["companyID"]));
1020
+ const company = f.joined.companies.get(_chunkSEFJJY4Jcjs.num.call(void 0, line["companyID"]));
988
1021
  if (needCompany && company === void 0) return { bucket: unresolvedCompanies, unresolved: true };
989
1022
  const ctx = { line, invoice, contract, company, joined: f.joined, labels: f.labels, unlabelled };
990
1023
  const keys = {};
@@ -1004,7 +1037,7 @@ function fold(v, f) {
1004
1037
  return { cell };
1005
1038
  };
1006
1039
  for (const line of f.lines) {
1007
- const invoiceID = _chunkDKAD7MOVcjs.num.call(void 0, line["invoiceID"]);
1040
+ const invoiceID = _chunkSEFJJY4Jcjs.num.call(void 0, line["invoiceID"]);
1008
1041
  const invoice = f.invoiceById.get(invoiceID);
1009
1042
  lineTotals.set(invoiceID, (_nullishCoalesce(lineTotals.get(invoiceID), () => ( 0))) + cents(line["totalAmount"]));
1010
1043
  const c = revC(line);
@@ -1025,9 +1058,9 @@ function fold(v, f) {
1025
1058
  cell.creditLines += 1;
1026
1059
  }
1027
1060
  cell.included += extC(line) - c;
1028
- cell.contracts.add(_chunkDKAD7MOVcjs.num.call(void 0, line["contractID"]));
1061
+ cell.contracts.add(_chunkSEFJJY4Jcjs.num.call(void 0, line["contractID"]));
1029
1062
  cell.items += 1;
1030
- allContracts.add(_chunkDKAD7MOVcjs.num.call(void 0, line["contractID"]));
1063
+ allContracts.add(_chunkSEFJJY4Jcjs.num.call(void 0, line["contractID"]));
1031
1064
  if (byLob && cell.keys.lineOfBusiness.id === null) add(noPointer, c);
1032
1065
  const k = v.nonChargeable ? ncClass(line) : void 0;
1033
1066
  if (k) ncAdd(cell.nc, k, line);
@@ -1035,7 +1068,7 @@ function fold(v, f) {
1035
1068
  for (const line of f.uninvoiced) {
1036
1069
  const k = ncClass(line);
1037
1070
  if (!k) continue;
1038
- const at = locate(line, { total: 0, month: String(_nullishCoalesce(line["itemDate"], () => ( ""))).slice(0, 7), companyID: _chunkDKAD7MOVcjs.num.call(void 0, line["companyID"]) });
1071
+ const at = locate(line, { total: 0, month: String(_nullishCoalesce(line["itemDate"], () => ( ""))).slice(0, 7), companyID: _chunkSEFJJY4Jcjs.num.call(void 0, line["companyID"]) });
1039
1072
  if ("cell" in at) ncAdd(at.cell.nc, k, line);
1040
1073
  else if (at.unresolved) add(unresolvedNc, extC(line));
1041
1074
  }
@@ -1145,20 +1178,20 @@ function slot(m, k) {
1145
1178
  async function relationshipMap(client, resourceKey) {
1146
1179
  void client;
1147
1180
  if (typeof resourceKey !== "string" || resourceKey.trim() === "") {
1148
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1181
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1149
1182
  `relationshipMap: resourceKey must be a non-empty plan resource key string (e.g. 'tickets'; got ${typeof resourceKey === "string" ? "a blank string" : typeof resourceKey})`,
1150
1183
  { suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items, ticket_notes." }
1151
1184
  );
1152
1185
  }
1153
1186
  const key = resourceKey.trim();
1154
- const entry = _chunkDKAD7MOVcjs.RELATIONSHIP_MAP[key];
1187
+ const entry = _chunkSEFJJY4Jcjs.RELATIONSHIP_MAP[key];
1155
1188
  if (entry === void 0) {
1156
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(
1157
- `relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkDKAD7MOVcjs.RELATIONSHIP_MAP).length} resources`,
1189
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(
1190
+ `relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkSEFJJY4Jcjs.RELATIONSHIP_MAP).length} resources`,
1158
1191
  {
1159
1192
  code: "RESOURCE_UNKNOWN",
1160
1193
  category: "validation",
1161
- suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${_chunkDKAD7MOVcjs.RELATIONSHIP_ZONE.label} (${_chunkDKAD7MOVcjs.RELATIONSHIP_ZONE.zone})-verified.`
1194
+ suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${_chunkSEFJJY4Jcjs.RELATIONSHIP_ZONE.label} (${_chunkSEFJJY4Jcjs.RELATIONSHIP_ZONE.zone})-verified.`
1162
1195
  }
1163
1196
  );
1164
1197
  }
@@ -1175,24 +1208,24 @@ var BLIND_SURFACE_KINDS = [
1175
1208
  async function blindSurfaces(client, opts) {
1176
1209
  void client;
1177
1210
  if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
1178
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("blindSurfaces: opts must be an object { resource?: string, kind?: BlindSurfaceKind }");
1211
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("blindSurfaces: opts must be an object { resource?: string, kind?: BlindSurfaceKind }");
1179
1212
  }
1180
- const inv = _chunkDKAD7MOVcjs.BLIND_SURFACE_INVENTORY;
1213
+ const inv = _chunkSEFJJY4Jcjs.BLIND_SURFACE_INVENTORY;
1181
1214
  if (inv === null) {
1182
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("blindSurfaces: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
1215
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("blindSurfaces: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
1183
1216
  }
1184
1217
  let surfaces = inv.surfaces;
1185
- if (_optionalChain([opts, 'optionalAccess', _32 => _32.resource]) !== void 0) {
1218
+ if (_optionalChain([opts, 'optionalAccess', _33 => _33.resource]) !== void 0) {
1186
1219
  const key = typeof opts.resource === "string" ? opts.resource.trim() : "";
1187
1220
  if (key === "") {
1188
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1221
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1189
1222
  "blindSurfaces: opts.resource must be a non-empty plan resource key string (e.g. 'tickets')",
1190
1223
  { suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items." }
1191
1224
  );
1192
1225
  }
1193
1226
  if (!inv.surfaces.some((row) => row.resource === key)) {
1194
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(
1195
- `blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkDKAD7MOVcjs.RELATIONSHIP_MAP).length} resources`,
1227
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(
1228
+ `blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkSEFJJY4Jcjs.RELATIONSHIP_MAP).length} resources`,
1196
1229
  {
1197
1230
  code: "RESOURCE_UNKNOWN",
1198
1231
  category: "validation",
@@ -1202,9 +1235,9 @@ async function blindSurfaces(client, opts) {
1202
1235
  }
1203
1236
  surfaces = surfaces.filter((row) => row.resource === key);
1204
1237
  }
1205
- if (_optionalChain([opts, 'optionalAccess', _33 => _33.kind]) !== void 0) {
1238
+ if (_optionalChain([opts, 'optionalAccess', _34 => _34.kind]) !== void 0) {
1206
1239
  if (!BLIND_SURFACE_KINDS.includes(opts.kind)) {
1207
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1240
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1208
1241
  `blindSurfaces: unknown kind "${String(opts.kind)}" \u2014 the valid classes are: ${BLIND_SURFACE_KINDS.join(", ")}`,
1209
1242
  { suggestedAction: `Filter with one of: ${BLIND_SURFACE_KINDS.join(", ")} (or omit kind for the full 116-surface inventory).` }
1210
1243
  );
@@ -1217,51 +1250,51 @@ async function blindSurfaces(client, opts) {
1217
1250
  // src/operations/probeReachability.ts
1218
1251
  async function probeReachability(client, opts) {
1219
1252
  if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
1220
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("probeReachability: opts must be an object { resources?: string[], limit?: 1|2, maxWireCalls?: number, confirmProbe?: true }");
1253
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("probeReachability: opts must be an object { resources?: string[], limit?: 1|2, maxWireCalls?: number, confirmProbe?: true }");
1221
1254
  }
1222
- const defs = _chunkDKAD7MOVcjs.REACHABILITY_PROBE_DEFAULTS;
1223
- if (_optionalChain([opts, 'optionalAccess', _34 => _34.confirmProbe]) !== true) {
1224
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1255
+ const defs = _chunkSEFJJY4Jcjs.REACHABILITY_PROBE_DEFAULTS;
1256
+ if (_optionalChain([opts, 'optionalAccess', _35 => _35.confirmProbe]) !== true) {
1257
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1225
1258
  "probeReachability: confirmProbe: true is required \u2014 the op deliberately fans out read wire across the tenant (one bounded query per surface); pass confirmProbe: true to run it",
1226
1259
  { suggestedAction: `Re-call with { confirmProbe: true } (plus resources/limit/maxWireCalls as needed). For the ZERO-wire pinned inventory use operations.blindSurfaces.` }
1227
1260
  );
1228
1261
  }
1229
- const limit = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _35 => _35.limit]), () => ( defs.limitDefault));
1262
+ const limit = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _36 => _36.limit]), () => ( defs.limitDefault));
1230
1263
  if (!Number.isInteger(limit) || limit < 1 || limit > defs.limitMax) {
1231
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1264
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1232
1265
  `probeReachability: limit must be an integer 1..${defs.limitMax} (got ${String(limit)}) \u2014 the rows-per-surface bound for the discovery read`
1233
1266
  );
1234
1267
  }
1235
- const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _36 => _36.maxWireCalls]), () => ( defs.defaultCap));
1268
+ const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _37 => _37.maxWireCalls]), () => ( defs.defaultCap));
1236
1269
  if (!Number.isInteger(cap) || cap < 1) {
1237
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`probeReachability: maxWireCalls must be a positive integer (got ${String(cap)})`);
1270
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`probeReachability: maxWireCalls must be a positive integer (got ${String(cap)})`);
1238
1271
  }
1239
1272
  if (cap > defs.hardCap) {
1240
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1273
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1241
1274
  `probeReachability: maxWireCalls ${cap} exceeds the hard wire cap of ${defs.hardCap} \u2014 the sweep is refused above it (never capped silently)`,
1242
1275
  { suggestedAction: `Pass maxWireCalls \u2264 ${defs.hardCap} and a resources set no larger than the cap (the refused set is never truncated).` }
1243
1276
  );
1244
1277
  }
1245
- const inv = _chunkDKAD7MOVcjs.BLIND_SURFACE_INVENTORY;
1278
+ const inv = _chunkSEFJJY4Jcjs.BLIND_SURFACE_INVENTORY;
1246
1279
  if (inv === null) {
1247
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("probeReachability: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
1280
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("probeReachability: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
1248
1281
  }
1249
1282
  let targets;
1250
- if (_optionalChain([opts, 'optionalAccess', _37 => _37.resources]) === void 0) {
1283
+ if (_optionalChain([opts, 'optionalAccess', _38 => _38.resources]) === void 0) {
1251
1284
  targets = [...defs.defaultTargets];
1252
1285
  } else {
1253
1286
  if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
1254
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("probeReachability: opts.resources must be a non-empty string[] of plan resource keys (or omit it for the default non-data-full set)");
1287
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("probeReachability: opts.resources must be a non-empty string[] of plan resource keys (or omit it for the default non-data-full set)");
1255
1288
  }
1256
1289
  const seen = /* @__PURE__ */ new Set();
1257
1290
  for (const r of opts.resources) {
1258
1291
  if (typeof r !== "string" || r.trim() === "") {
1259
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`probeReachability: opts.resources must contain non-empty plan resource key strings (got ${typeof r === "string" && r.trim() === "" ? "a blank string" : typeof r})`);
1292
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`probeReachability: opts.resources must contain non-empty plan resource key strings (got ${typeof r === "string" && r.trim() === "" ? "a blank string" : typeof r})`);
1260
1293
  }
1261
1294
  const key = r.trim();
1262
1295
  if (!inv.surfaces.some((row) => row.resource === key)) {
1263
1296
  const surfaceCount = new Set(inv.surfaces.map((s) => s.resource)).size;
1264
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(
1297
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(
1265
1298
  `probeReachability: unknown resource "${key}" \u2014 the inventory has ${surfaceCount} surfaces`,
1266
1299
  {
1267
1300
  code: "RESOURCE_UNKNOWN",
@@ -1275,7 +1308,7 @@ async function probeReachability(client, opts) {
1275
1308
  targets = [...seen];
1276
1309
  }
1277
1310
  if (targets.length > cap) {
1278
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1311
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1279
1312
  `probeReachability: ${targets.length} requested surface(s) exceed the wire cap of ${cap} \u2014 the sweep is refused above its cap (never truncated)`,
1280
1313
  { suggestedAction: `Raise maxWireCalls (\u2264 ${defs.hardCap}) to cover the set, or pass a smaller resources list.` }
1281
1314
  );
@@ -1285,8 +1318,8 @@ async function probeReachability(client, opts) {
1285
1318
  for (const resource of targets.sort()) {
1286
1319
  const row = byResource.get(resource);
1287
1320
  if (row === void 0) continue;
1288
- const holder = client[_chunkDKAD7MOVcjs.camelKey.call(void 0, resource)];
1289
- const probeFn = _optionalChain([holder, 'optionalAccess', _38 => _38.queryBounded]);
1321
+ const holder = client[_chunkSEFJJY4Jcjs.camelKey.call(void 0, resource)];
1322
+ const probeFn = _optionalChain([holder, 'optionalAccess', _39 => _39.queryBounded]);
1290
1323
  if (typeof probeFn !== "function") {
1291
1324
  results.push({
1292
1325
  ...row,
@@ -1297,14 +1330,14 @@ async function probeReachability(client, opts) {
1297
1330
  }
1298
1331
  try {
1299
1332
  const res = await probeFn.call(holder, { limit });
1300
- const items = Array.isArray(_optionalChain([res, 'optionalAccess', _39 => _39.items])) ? res.items : [];
1333
+ const items = Array.isArray(_optionalChain([res, 'optionalAccess', _40 => _40.items])) ? res.items : [];
1301
1334
  results.push({
1302
1335
  ...row,
1303
1336
  unfilteredRows: items.length,
1304
1337
  probe: { ok: true, wire: 1, error: null }
1305
1338
  });
1306
1339
  } catch (err) {
1307
- const code = _chunkDKAD7MOVcjs.isAutotaskError.call(void 0, err) ? err.code : "NETWORK_ERROR";
1340
+ const code = _chunkSEFJJY4Jcjs.isAutotaskError.call(void 0, err) ? err.code : "NETWORK_ERROR";
1308
1341
  const message = err instanceof Error ? err.message : String(err);
1309
1342
  results.push({
1310
1343
  ...row,
@@ -1332,30 +1365,30 @@ var CREATE_BLOCKER_KINDS = [
1332
1365
  async function createGuidance(client, opts) {
1333
1366
  void client;
1334
1367
  if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
1335
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1368
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1336
1369
  "createGuidance: opts must be an object { resources?: string[], kind?: CreateBlockerKind }"
1337
1370
  );
1338
1371
  }
1339
- let servedRows = _chunkDKAD7MOVcjs.CREATE_GUIDANCE.rows.map((row) => ({
1372
+ let servedRows = _chunkSEFJJY4Jcjs.CREATE_GUIDANCE.rows.map((row) => ({
1340
1373
  ...row,
1341
1374
  // Issue #219 N4: one precedence rule, stated on every row (live-proven >
1342
1375
  // zone > spec). The spec set is not available here (it is a LIVE read) —
1343
1376
  // the helper is handed the plan's two shapes and names the source.
1344
- requiredFields: _chunkDKAD7MOVcjs.effectiveRequiredFields.call(void 0, void 0, _nullishCoalesce(_optionalChain([_chunkDKAD7MOVcjs.RELATIONSHIP_MAP, 'access', _40 => _40[row.resource], 'optionalAccess', _41 => _41.zoneFacts]), () => ( null)))
1377
+ requiredFields: _chunkSEFJJY4Jcjs.effectiveRequiredFields.call(void 0, void 0, _nullishCoalesce(_optionalChain([_chunkSEFJJY4Jcjs.RELATIONSHIP_MAP, 'access', _41 => _41[row.resource], 'optionalAccess', _42 => _42.zoneFacts]), () => ( null)))
1345
1378
  }));
1346
- if (_optionalChain([opts, 'optionalAccess', _42 => _42.resources]) !== void 0) {
1379
+ if (_optionalChain([opts, 'optionalAccess', _43 => _43.resources]) !== void 0) {
1347
1380
  if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
1348
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("createGuidance: opts.resources must be a non-empty string[] of plan resource keys");
1381
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("createGuidance: opts.resources must be a non-empty string[] of plan resource keys");
1349
1382
  }
1350
1383
  const wanted = /* @__PURE__ */ new Set();
1351
1384
  for (const r of opts.resources) {
1352
1385
  if (typeof r !== "string" || r.trim() === "") {
1353
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)("createGuidance: opts.resources must contain non-empty plan resource key strings");
1386
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)("createGuidance: opts.resources must contain non-empty plan resource key strings");
1354
1387
  }
1355
1388
  const key = r.trim();
1356
- if (!_chunkDKAD7MOVcjs.CREATE_GUIDANCE.rows.some((row) => row.resource === key)) {
1357
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(
1358
- `createGuidance: unknown resource "${key}" \u2014 the catalog has ${_chunkDKAD7MOVcjs.CREATE_GUIDANCE.rows.length} create entities`,
1389
+ if (!_chunkSEFJJY4Jcjs.CREATE_GUIDANCE.rows.some((row) => row.resource === key)) {
1390
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(
1391
+ `createGuidance: unknown resource "${key}" \u2014 the catalog has ${_chunkSEFJJY4Jcjs.CREATE_GUIDANCE.rows.length} create entities`,
1359
1392
  {
1360
1393
  code: "RESOURCE_UNKNOWN",
1361
1394
  category: "validation",
@@ -1367,29 +1400,53 @@ async function createGuidance(client, opts) {
1367
1400
  }
1368
1401
  servedRows = servedRows.filter((row) => wanted.has(row.resource));
1369
1402
  }
1370
- if (_optionalChain([opts, 'optionalAccess', _43 => _43.kind]) !== void 0) {
1403
+ if (_optionalChain([opts, 'optionalAccess', _44 => _44.kind]) !== void 0) {
1371
1404
  if (!CREATE_BLOCKER_KINDS.includes(opts.kind)) {
1372
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1405
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1373
1406
  `createGuidance: unknown kind "${String(opts.kind)}" \u2014 the valid kinds are: ${CREATE_BLOCKER_KINDS.join(", ")}`
1374
1407
  );
1375
1408
  }
1376
- servedRows = servedRows.filter((row) => _optionalChain([row, 'access', _44 => _44.blocker, 'optionalAccess', _45 => _45.kind]) === opts.kind);
1409
+ servedRows = servedRows.filter((row) => _optionalChain([row, 'access', _45 => _45.blocker, 'optionalAccess', _46 => _46.kind]) === opts.kind);
1377
1410
  }
1378
1411
  return {
1379
- zone: _chunkDKAD7MOVcjs.CREATE_GUIDANCE.zone,
1380
- label: _chunkDKAD7MOVcjs.CREATE_GUIDANCE.label,
1381
- verifiedAt: _chunkDKAD7MOVcjs.CREATE_GUIDANCE.verifiedAt,
1412
+ zone: _chunkSEFJJY4Jcjs.CREATE_GUIDANCE.zone,
1413
+ label: _chunkSEFJJY4Jcjs.CREATE_GUIDANCE.label,
1414
+ verifiedAt: _chunkSEFJJY4Jcjs.CREATE_GUIDANCE.verifiedAt,
1382
1415
  rows: servedRows,
1383
- counts: _chunkDKAD7MOVcjs.CREATE_GUIDANCE.counts
1416
+ counts: _chunkSEFJJY4Jcjs.CREATE_GUIDANCE.counts
1384
1417
  };
1385
1418
  }
1386
1419
 
1420
+ // src/operations/registryIndex.ts
1421
+ var OPERATION_BY_ID = new Map(_chunkVEOSOIU4cjs.CAPABILITIES.map((r) => [r.id, r]));
1422
+
1423
+ // src/operations/sanitiseResult.ts
1424
+ async function sanitiseResult(client, result, operation) {
1425
+ void client;
1426
+ if (typeof operation !== "string" || operation === "") {
1427
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1428
+ 'sanitiseResult: operation must be a non-empty registry operation key (e.g. "tickets.query")',
1429
+ { suggestedAction: "Pass the operation key the result came from \u2014 the registry id, not the resource key." }
1430
+ );
1431
+ }
1432
+ const record = OPERATION_BY_ID.get(operation);
1433
+ if (record === void 0) {
1434
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1435
+ `sanitiseResult: unknown operation "${operation.slice(0, 60)}" \u2014 it is not in the capability registry`,
1436
+ { operation, suggestedAction: "List the registry (the ./capabilities subpath) for the exact operation key." }
1437
+ );
1438
+ }
1439
+ const fields = _optionalChain([record, 'access', _47 => _47.metadata, 'optionalAccess', _48 => _48.untrustedFields]);
1440
+ if (!Array.isArray(fields) || fields.length === 0) return result;
1441
+ return _chunkMJTKK3QGcjs.deepMarkUntrusted.call(void 0, result, fields);
1442
+ }
1443
+
1387
1444
  // src/operations/recovery.ts
1388
1445
  var RECOVERY_CONFIRM = "operations.recovery";
1389
1446
  var RECOVERY_DEFAULT_LIMIT = 25;
1390
1447
  var RECOVERY_MAX_LIMIT = 100;
1391
1448
  function configError(message, operation, suggestedAction) {
1392
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(message, { operation, suggestedAction });
1449
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(message, { operation, suggestedAction });
1393
1450
  }
1394
1451
  function parseMatchId(record) {
1395
1452
  const raw = record.id;
@@ -1405,7 +1462,7 @@ function parseMatchId(record) {
1405
1462
  return { id: null, unsafe: true };
1406
1463
  }
1407
1464
  function validateRecoveryInput(input, operation) {
1408
- if (!_chunkDKAD7MOVcjs.isRecord.call(void 0, input)) {
1465
+ if (!_chunkSEFJJY4Jcjs.isRecord.call(void 0, input)) {
1409
1466
  configError(
1410
1467
  `recovery: input must be an object { resource, marker, ... } (got ${typeof input})`,
1411
1468
  operation,
@@ -1439,10 +1496,10 @@ function validateRecoveryInput(input, operation) {
1439
1496
  return { resource, marker, action };
1440
1497
  }
1441
1498
  function resolveRecoveryTarget(client, resource, operation) {
1442
- const entry = _chunkDKAD7MOVcjs.RELATIONSHIP_MAP[resource];
1499
+ const entry = _chunkSEFJJY4Jcjs.RELATIONSHIP_MAP[resource];
1443
1500
  if (entry === void 0) {
1444
- throw new (0, _chunkDKAD7MOVcjs.AutotaskError)(
1445
- `recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(_chunkDKAD7MOVcjs.RELATIONSHIP_MAP).length} resources`,
1501
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskError)(
1502
+ `recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(_chunkSEFJJY4Jcjs.RELATIONSHIP_MAP).length} resources`,
1446
1503
  {
1447
1504
  code: "RESOURCE_UNKNOWN",
1448
1505
  category: "validation",
@@ -1451,7 +1508,7 @@ function resolveRecoveryTarget(client, resource, operation) {
1451
1508
  }
1452
1509
  );
1453
1510
  }
1454
- const holder = client[_chunkDKAD7MOVcjs.camelKey.call(void 0, resource)];
1511
+ const holder = client[_chunkSEFJJY4Jcjs.camelKey.call(void 0, resource)];
1455
1512
  if (!holder || typeof holder.queryBounded !== "function") {
1456
1513
  configError(
1457
1514
  `recovery: ${resource} exposes no bounded query surface \u2014 the marker search cannot run`,
@@ -1462,7 +1519,7 @@ function resolveRecoveryTarget(client, resource, operation) {
1462
1519
  return { entry, holder };
1463
1520
  }
1464
1521
  function resolveMarkerField(input, resource, operation) {
1465
- const field = input.field !== void 0 ? String(input.field) : _chunkDKAD7MOVcjs.MARKER_FIELDS[resource];
1522
+ const field = input.field !== void 0 ? String(input.field) : _chunkSEFJJY4Jcjs.MARKER_FIELDS[resource];
1466
1523
  if (typeof field !== "string" || field.trim() === "") {
1467
1524
  configError(
1468
1525
  `recovery: ${resource} has no plan markerField and no input.field was passed \u2014 the marker search needs a name-like field to filter on`,
@@ -1501,7 +1558,7 @@ function resolveExtraFilter(input, operation) {
1501
1558
  );
1502
1559
  }
1503
1560
  for (const c of input.filter) {
1504
- if (!_chunkDKAD7MOVcjs.isRecord.call(void 0, c) || typeof c.op !== "string" || c.op === "and" || c.op === "or") {
1561
+ if (!_chunkSEFJJY4Jcjs.isRecord.call(void 0, c) || typeof c.op !== "string" || c.op === "and" || c.op === "or") {
1505
1562
  configError(
1506
1563
  "recovery: input.filter accepts only plain leaf conditions ({ field, op, value }) \u2014 no grouping",
1507
1564
  operation,
@@ -1526,7 +1583,7 @@ function resolveLimit(input, operation) {
1526
1583
  async function applyRecoveryDeletes(holder, matches, parentId, resource, operation) {
1527
1584
  const deleteMethod = holder.delete;
1528
1585
  if (deleteMethod === void 0) {
1529
- throw new (0, _chunkDKAD7MOVcjs.DeleteBoundaryError)(
1586
+ throw new (0, _chunkSEFJJY4Jcjs.DeleteBoundaryError)(
1530
1587
  `recovery: ${resource} has no delete method on the client \u2014 the boundary is marked available in the plan but the typed delete surface is missing`,
1531
1588
  {
1532
1589
  operation,
@@ -1555,14 +1612,14 @@ async function applyRecoveryDeletes(holder, matches, parentId, resource, operati
1555
1612
  verify = "still-present";
1556
1613
  }
1557
1614
  } catch (err) {
1558
- if (err instanceof _chunkDKAD7MOVcjs.NotFoundError) verify = "not-found";
1615
+ if (err instanceof _chunkSEFJJY4Jcjs.NotFoundError) verify = "not-found";
1559
1616
  else {
1560
1617
  verify = "error";
1561
- code = _chunkDKAD7MOVcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
1618
+ code = _chunkSEFJJY4Jcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
1562
1619
  }
1563
1620
  }
1564
1621
  } catch (err) {
1565
- code = _chunkDKAD7MOVcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
1622
+ code = _chunkSEFJJY4Jcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
1566
1623
  }
1567
1624
  deleted.push({ id, verified: verify === "not-found", code });
1568
1625
  }
@@ -1590,7 +1647,7 @@ async function recovery(client, input, opts = {}) {
1590
1647
  const parentId = resolveParentId(input, entry, resource, operation);
1591
1648
  const extra = resolveExtraFilter(input, operation);
1592
1649
  const limit = resolveLimit(input, operation);
1593
- const boundaryNote = _chunkDKAD7MOVcjs.DELETE_BOUNDARY_NOTES[resource];
1650
+ const boundaryNote = _chunkSEFJJY4Jcjs.DELETE_BOUNDARY_NOTES[resource];
1594
1651
  const boundary = {
1595
1652
  available: boundaryNote === void 0,
1596
1653
  reason: _nullishCoalesce(boundaryNote, () => ( null)),
@@ -1602,7 +1659,7 @@ async function recovery(client, input, opts = {}) {
1602
1659
  };
1603
1660
  const isDelete = action === "delete";
1604
1661
  if (isDelete && boundaryNote !== void 0) {
1605
- throw new (0, _chunkDKAD7MOVcjs.DeleteBoundaryError)(
1662
+ throw new (0, _chunkSEFJJY4Jcjs.DeleteBoundaryError)(
1606
1663
  `recovery: the vendor defines no DELETE for ${resource} \u2014 the delete cannot be issued through the API (zero wire was issued)`,
1607
1664
  {
1608
1665
  operation,
@@ -1611,10 +1668,10 @@ async function recovery(client, input, opts = {}) {
1611
1668
  }
1612
1669
  );
1613
1670
  }
1614
- const dryRun = _optionalChain([opts, 'optionalAccess', _46 => _46.dryRun]) !== false;
1615
- const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _47 => _47.confirm]), () => ( input.confirm));
1671
+ const dryRun = _optionalChain([opts, 'optionalAccess', _49 => _49.dryRun]) !== false;
1672
+ const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _50 => _50.confirm]), () => ( input.confirm));
1616
1673
  if (isDelete && !dryRun && confirm !== RECOVERY_CONFIRM) {
1617
- throw new (0, _chunkDKAD7MOVcjs.ConfirmationRequiredError)(
1674
+ throw new (0, _chunkSEFJJY4Jcjs.ConfirmationRequiredError)(
1618
1675
  `recovery: action 'delete' apply is destructive and requires its confirmation flag: pass confirm: "${RECOVERY_CONFIRM}"`,
1619
1676
  {
1620
1677
  operation: RECOVERY_CONFIRM,
@@ -1630,7 +1687,7 @@ async function recovery(client, input, opts = {}) {
1630
1687
  const query = await holder.queryBounded({ filter: conditions, limit });
1631
1688
  if (query.hasMore) {
1632
1689
  const wire = isDelete ? "DELETE wire" : "mutating wire";
1633
- throw new (0, _chunkDKAD7MOVcjs.RecoveryTruncatedError)(
1690
+ throw new (0, _chunkSEFJJY4Jcjs.RecoveryTruncatedError)(
1634
1691
  `recovery: the marker search on ${resource} TRIPPED its match cap (${limit}) \u2014 more matches exist than were returned (zero ${wire} was issued)`,
1635
1692
  {
1636
1693
  operation,
@@ -1659,7 +1716,7 @@ async function recovery(client, input, opts = {}) {
1659
1716
  return { ...base, simulated: true, dryRun: true };
1660
1717
  }
1661
1718
  if (unsafeId) {
1662
- throw new (0, _chunkDKAD7MOVcjs.MarkerUnsafeIdError)(
1719
+ throw new (0, _chunkSEFJJY4Jcjs.MarkerUnsafeIdError)(
1663
1720
  `recovery: ${unsafeIds.length} of ${matches.length} match(es) on ${resource} have ids beyond Number.MAX_SAFE_INTEGER \u2014 they CANNOT be addressed through the SDK's typed delete surface (zero DELETE wire was issued)`,
1664
1721
  {
1665
1722
  operation,
@@ -1677,7 +1734,7 @@ function needsConfirmation(record) {
1677
1734
  return record.effect === "destructive" || (_nullishCoalesce(record.flags, () => ( []))).includes("requiresApproval");
1678
1735
  }
1679
1736
  function refuse(message, operation, suggestedAction) {
1680
- throw new (0, _chunkDKAD7MOVcjs.ConfirmationRequiredError)(message, { operation, suggestedAction });
1737
+ throw new (0, _chunkSEFJJY4Jcjs.ConfirmationRequiredError)(message, { operation, suggestedAction });
1681
1738
  }
1682
1739
  var MODE_BY_EFFECT = {
1683
1740
  read: "read",
@@ -1723,7 +1780,7 @@ function looseTypeOk(type, value) {
1723
1780
  case "string[]":
1724
1781
  return Array.isArray(value) && value.every((v) => typeof v === "string");
1725
1782
  case "object":
1726
- return _chunkDKAD7MOVcjs.isRecord.call(void 0, value);
1783
+ return _chunkSEFJJY4Jcjs.isRecord.call(void 0, value);
1727
1784
  default:
1728
1785
  return true;
1729
1786
  }
@@ -1737,12 +1794,12 @@ function declaredArgList(record) {
1737
1794
  function resolveDispatchArgs(record, argsIn) {
1738
1795
  const operation = record.id;
1739
1796
  const bad = (message) => {
1740
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`invoke: "${operation}" ${message}`, { operation });
1797
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`invoke: "${operation}" ${message}`, { operation });
1741
1798
  };
1742
1799
  if (argsIn === void 0 || argsIn === null) return [];
1743
1800
  if (Array.isArray(argsIn)) return argsIn;
1744
1801
  const byName = argsIn;
1745
- if (!_chunkDKAD7MOVcjs.isRecord.call(void 0, byName) || ![Object.prototype, null].includes(Object.getPrototypeOf(byName))) {
1802
+ if (!_chunkSEFJJY4Jcjs.isRecord.call(void 0, byName) || ![Object.prototype, null].includes(Object.getPrototypeOf(byName))) {
1746
1803
  return bad(`args must be a positional array or a plain object of named inputs (declared: ${declaredArgList(record)})`);
1747
1804
  }
1748
1805
  const schema = _nullishCoalesce(record.inputSchema, () => ( {}));
@@ -1763,7 +1820,7 @@ function validateDispatchArgs(record, argsIn) {
1763
1820
  const bagName = names.find((n) => schema[n].properties);
1764
1821
  const surplus = args[names.length];
1765
1822
  const bagHint = bagName && surplus !== null && typeof surplus === "object" && !Array.isArray(surplus) ? ` \u2014 options go inside the single ${bagName} object` : "";
1766
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1823
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1767
1824
  `invoke: "${operation}" declares ${names.length} positional arg(s) (${declaredArgList(record)}) but ${args.length} were passed \u2014 extra args are refused${bagHint}`,
1768
1825
  {
1769
1826
  operation,
@@ -1773,7 +1830,7 @@ function validateDispatchArgs(record, argsIn) {
1773
1830
  }
1774
1831
  const required = names.filter((n) => schema[n].required);
1775
1832
  if (args.length < required.length) {
1776
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1833
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1777
1834
  `invoke: "${operation}" requires ${required.length} positional arg(s) (${required.map((n) => `${n}: ${schema[n].type}`).join(", ")}) but only ${args.length} were passed \u2014 declared args: ${declaredArgList(record)}`,
1778
1835
  { operation }
1779
1836
  );
@@ -1784,7 +1841,7 @@ function validateDispatchArgs(record, argsIn) {
1784
1841
  const name = names[i];
1785
1842
  const spec = schema[name];
1786
1843
  if (!looseTypeOk(spec.type, value)) {
1787
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1844
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1788
1845
  `invoke: "${operation}" arg ${i + 1} is declared ${name}: ${spec.type} \u2014 the value has the wrong type (pass a ${spec.type} value)`,
1789
1846
  { operation }
1790
1847
  );
@@ -1792,17 +1849,17 @@ function validateDispatchArgs(record, argsIn) {
1792
1849
  }
1793
1850
  }
1794
1851
  function foldFlattenedOpts(record, toolArgs) {
1795
- if (!_chunkDKAD7MOVcjs.isRecord.call(void 0, toolArgs)) {
1796
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(`invoke: "${record.id}" tool args must be a plain object of named inputs`, { operation: record.id });
1852
+ if (!_chunkSEFJJY4Jcjs.isRecord.call(void 0, toolArgs)) {
1853
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(`invoke: "${record.id}" tool args must be a plain object of named inputs`, { operation: record.id });
1797
1854
  }
1798
- const bagKeys = (_nullishCoalesce(_optionalChain([record, 'access', _48 => _48.inputSchema, 'optionalAccess', _49 => _49.opts, 'optionalAccess', _50 => _50.properties]), () => ( []))).map((p) => p.name);
1855
+ const bagKeys = (_nullishCoalesce(_optionalChain([record, 'access', _51 => _51.inputSchema, 'optionalAccess', _52 => _52.opts, 'optionalAccess', _53 => _53.properties]), () => ( []))).map((p) => p.name);
1799
1856
  const flat = Object.keys(toolArgs).filter((k) => bagKeys.includes(k) && toolArgs[k] !== void 0 && toolArgs[k] !== null);
1800
1857
  const folded = { ...toolArgs };
1801
1858
  for (const k of bagKeys) delete folded[k];
1802
1859
  if (folded.opts === null) delete folded.opts;
1803
1860
  if (flat.length === 0) return folded;
1804
1861
  if (folded.opts !== void 0) {
1805
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1862
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1806
1863
  `invoke: "${record.id}" was given both opts and flattened option(s) ${flat.map((k) => `"${k}"`).join(", ")} \u2014 pass one form`,
1807
1864
  { operation: record.id }
1808
1865
  );
@@ -1812,7 +1869,7 @@ function foldFlattenedOpts(record, toolArgs) {
1812
1869
 
1813
1870
  // src/operations/invoke/inputSets.ts
1814
1871
  var PARAMS_BAG_KEYS = {
1815
- query: ["filter", "limit", "includeFields", "via", "latest", "noteChars", "fieldsPreset", "fieldCheck", "names"],
1872
+ query: ["filter", "limit", "includeFields", "via", "latest", "noteChars", "fieldCheck", "names", "acknowledgeUnscoped", "walk"],
1816
1873
  // No registry row DECLARES `queryAll` today (a plan decision: the raw walk is
1817
1874
  // called directly), so this entry never fires. It is KEPT so that a future
1818
1875
  // `queryAll` row — which `invoke` WOULD dispatch via holder[operation] —
@@ -1832,7 +1889,9 @@ var BAG_KEY_SYNONYMS = {
1832
1889
  page: "limit",
1833
1890
  pageSize: "limit",
1834
1891
  cursor: "limit",
1835
- maxrecords: "maxRecords"
1892
+ maxrecords: "maxRecords",
1893
+ fieldsPreset: "includeFields"
1894
+ // issue #287: the preset was removed — the refusal points at the explicit includeFields
1836
1895
  };
1837
1896
  function levenshtein(a, b) {
1838
1897
  if (a === b) return 0;
@@ -1859,16 +1918,19 @@ function suggestForKey(key, valid) {
1859
1918
  if (best !== null && best.dist <= 3) return best.key;
1860
1919
  return null;
1861
1920
  }
1921
+ function keySuggestions(unknown, valid) {
1922
+ return unknown.map((k) => [k, suggestForKey(k, valid)]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
1923
+ }
1862
1924
  function validateParamsBag(record, args) {
1863
1925
  if (record.inputSchemaStrict !== true) return;
1864
1926
  const valid = PARAMS_BAG_KEYS[record.operation];
1865
1927
  if (valid === void 0) return;
1866
- const bag = _optionalChain([args, 'optionalAccess', _51 => _51[0]]);
1867
- if (bag === void 0 || bag === null || !_chunkDKAD7MOVcjs.isRecord.call(void 0, bag)) return;
1928
+ const bag = _optionalChain([args, 'optionalAccess', _54 => _54[0]]);
1929
+ if (bag === void 0 || bag === null || !_chunkSEFJJY4Jcjs.isRecord.call(void 0, bag)) return;
1868
1930
  const unknown = Object.keys(bag).filter((k) => !valid.includes(k));
1869
1931
  if (unknown.length === 0) return;
1870
- const suggestions = unknown.map((k) => [k, suggestForKey(k, valid)]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
1871
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1932
+ const suggestions = keySuggestions(unknown, valid);
1933
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1872
1934
  `invoke: "${record.id}" params bag has unknown key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the bag is closed (valid keys: ${valid.join(", ")})`,
1873
1935
  {
1874
1936
  operation: record.id,
@@ -1876,32 +1938,13 @@ function validateParamsBag(record, args) {
1876
1938
  }
1877
1939
  );
1878
1940
  }
1879
- function validateGetBag(record, args) {
1880
- if (record.kind !== "primitive" || record.operation !== "get") return;
1881
- const at = Object.keys(_nullishCoalesce(record.inputSchema, () => ( {}))).indexOf("opts");
1882
- const bag = at < 0 ? void 0 : _optionalChain([args, 'optionalAccess', _52 => _52[at]]);
1883
- if (bag === void 0 || bag === null || !_chunkDKAD7MOVcjs.isRecord.call(void 0, bag)) return;
1884
- const unknown = Object.keys(bag).filter((k) => k !== "fresh");
1885
- if (unknown.length > 0) {
1886
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1887
- `invoke: "${record.id}" opts bag has unknown key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the bag is closed (valid keys: fresh)`,
1888
- { operation: record.id, suggestedAction: "Pass only { fresh?: boolean }." }
1889
- );
1890
- }
1891
- if (bag.fresh !== void 0 && typeof bag.fresh !== "boolean") {
1892
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1893
- `invoke: fresh must be a boolean (got ${typeof bag.fresh}) \u2014 "${record.id}" was not issued`,
1894
- { operation: record.id, suggestedAction: "Pass fresh: true (bypass the read cache) or omit it." }
1895
- );
1896
- }
1897
- }
1898
1941
  var INVOKE_OPTION_KEYS = ["dryRun", "confirm", "lastModifiedDate", "maxRetries", "fresh", "mode"];
1899
1942
  function validateInvokeOptions(opts, operation) {
1900
1943
  if (opts === void 0 || opts === null) return;
1901
1944
  const unknown = Object.keys(opts).filter((k) => !INVOKE_OPTION_KEYS.includes(k));
1902
1945
  if (unknown.length === 0) return;
1903
- const suggestions = unknown.map((k) => [k, suggestForKey(k, ["dryRun", "confirm", "lastModifiedDate", "maxRetries", "fresh"])]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
1904
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1946
+ const suggestions = keySuggestions(unknown, ["dryRun", "confirm", "lastModifiedDate", "maxRetries", "fresh"]);
1947
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1905
1948
  `invoke: "${operation}" has unknown option key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the options set is closed (valid: dryRun, confirm, lastModifiedDate, maxRetries, fresh; "mode" is internal to the mode wrappers)`,
1906
1949
  {
1907
1950
  operation,
@@ -1913,8 +1956,8 @@ function unknownKeysRefusal(raw, validKeys, subject, operation) {
1913
1956
  if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return null;
1914
1957
  const unknown = Object.keys(raw).filter((k) => !validKeys.includes(k));
1915
1958
  if (unknown.length === 0) return null;
1916
- const suggestions = unknown.map((k) => [k, suggestForKey(k, [...validKeys])]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
1917
- return new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
1959
+ const suggestions = keySuggestions(unknown, [...validKeys]);
1960
+ return new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1918
1961
  `unknown ${subject} ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the ${subject} set is closed (valid keys: ${validKeys.join(", ")})`,
1919
1962
  {
1920
1963
  ...operation !== void 0 ? { operation } : {},
@@ -1923,9 +1966,63 @@ function unknownKeysRefusal(raw, validKeys, subject, operation) {
1923
1966
  );
1924
1967
  }
1925
1968
 
1926
- // src/operations/invoke/registry.ts
1927
- var RECORDS = _chunkMJ6J74F3cjs.CAPABILITIES;
1928
- var byId2 = new Map(RECORDS.map((r) => [r.id, r]));
1969
+ // src/operations/scopeGuard.ts
1970
+ var PROPAGATE_CODES = /* @__PURE__ */ new Set([
1971
+ "ABORTED",
1972
+ "UNAUTHORIZED",
1973
+ "FORBIDDEN",
1974
+ "HOST_POLICY_DENIED",
1975
+ "RATE_LIMITED",
1976
+ "RATE_LIMITED_COOLDOWN"
1977
+ ]);
1978
+ function hasIdScope(filter) {
1979
+ if (Array.isArray(filter)) return filter.some(hasIdScope);
1980
+ if (filter === null || typeof filter !== "object") return false;
1981
+ const n = filter;
1982
+ const op = typeof n.op === "string" ? n.op.toLowerCase() : "";
1983
+ if (Array.isArray(n.items)) return op === "and" && n.items.some(hasIdScope);
1984
+ if (Array.isArray(n.filter)) return hasIdScope(n.filter);
1985
+ if (typeof n.field !== "string" || !(n.field === "id" || /ID$/.test(n.field))) return false;
1986
+ const real = (v) => v !== void 0 && v !== null && v !== "";
1987
+ const list = Array.isArray(n.value) ? n.value : typeof n.value === "string" ? n.value.split(",").map((t) => t.trim()) : [];
1988
+ return op === "eq" && real(n.value) || op === "in" && list.some(real);
1989
+ }
1990
+ async function guardUnscopedQueryWalk(holder, operation, bag) {
1991
+ const filter = _optionalChain([bag, 'optionalAccess', _55 => _55["filter"]]);
1992
+ const limit = _optionalChain([bag, 'optionalAccess', _56 => _56["limit"]]);
1993
+ const latest = _optionalChain([bag, 'optionalAccess', _57 => _57["latest"]]);
1994
+ const walk = typeof _optionalChain([bag, 'optionalAccess', _58 => _58["walk"]]) === "object" && _optionalChain([bag, 'optionalAccess', _59 => _59["walk"]]) !== null ? _optionalChain([bag, 'optionalAccess', _60 => _60["walk"]]) : void 0;
1995
+ const maxRows = typeof _optionalChain([walk, 'optionalAccess', _61 => _61.maxRows]) === "number" ? walk.maxRows : void 0;
1996
+ const effectiveLimit = typeof limit === "number" ? limit : _chunkSEFJJY4Jcjs.BOUNDED_QUERY_DEFAULT_LIMIT;
1997
+ let walked = typeof latest === "number" ? Math.max(effectiveLimit, latest) : effectiveLimit;
1998
+ if (maxRows !== void 0) walked = Math.min(walked, maxRows);
1999
+ if (walked <= _chunkSEFJJY4Jcjs.UNSCOPED_WALK_THRESHOLD || hasIdScope(filter)) return {};
2000
+ let conditions;
2001
+ try {
2002
+ conditions = _chunkSEFJJY4Jcjs.normalizedConditions.call(void 0, filter);
2003
+ } catch (e) {
2004
+ return {};
2005
+ }
2006
+ let counted;
2007
+ try {
2008
+ counted = await holder.count({ filter: conditions === void 0 ? void 0 : conditions });
2009
+ } catch (err) {
2010
+ const code = _optionalChain([err, 'optionalAccess', _62 => _62.code]);
2011
+ if (typeof code === "string" && PROPAGATE_CODES.has(code)) throw err;
2012
+ const label = typeof code === "string" && /^[A-Z][A-Z_]{2,40}$/.test(code) ? ` (${code})` : "";
2013
+ return { note: `scope check skipped: the pre-flight count failed${label}; this unscoped walk was not guarded.` };
2014
+ }
2015
+ const sentinel = typeof counted === "object" && counted !== null && "count" in counted ? counted : { count: counted };
2016
+ if (sentinel.blindSurface !== void 0) {
2017
+ return { note: "scope check skipped: the count surface is blind (a 0 is not a true zero); this unscoped walk was not guarded." };
2018
+ }
2019
+ const count = typeof sentinel.count === "number" && Number.isFinite(sentinel.count) && sentinel.count >= 0 ? sentinel.count : void 0;
2020
+ if (count === void 0) {
2021
+ return { note: "scope check skipped: the pre-flight count was unreadable; this unscoped walk was not guarded." };
2022
+ }
2023
+ if (count > _chunkSEFJJY4Jcjs.UNSCOPED_WALK_THRESHOLD) throw new (0, _chunkSEFJJY4Jcjs.ScopeRequiredError)(operation, { threshold: _chunkSEFJJY4Jcjs.UNSCOPED_WALK_THRESHOLD, count });
2024
+ return {};
2025
+ }
1929
2026
 
1930
2027
  // src/operations/invoke/dispatch.ts
1931
2028
  var INVOKE_MAX_INLINE_BYTES = 1024 * 1024;
@@ -1941,9 +2038,9 @@ function bufferResult(buf) {
1941
2038
  };
1942
2039
  }
1943
2040
  function resolveRecord(operation) {
1944
- const record = byId2.get(operation);
2041
+ const record = OPERATION_BY_ID.get(operation);
1945
2042
  if (record === void 0) {
1946
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2043
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1947
2044
  `invoke: unknown operation "${operation}" \u2014 it is not in the capability registry`,
1948
2045
  { operation, suggestedAction: "List the registry (the ./capabilities subpath) for the exact operation key." }
1949
2046
  );
@@ -1954,30 +2051,30 @@ function governPreRequest(record, operation, opts) {
1954
2051
  validateInvokeOptions(opts, operation);
1955
2052
  const mode = opts.mode;
1956
2053
  if (mode !== void 0 && MODE_BY_EFFECT[record.effect] !== mode) {
1957
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(crossModeRefusal(operation, record.effect, mode), { operation });
2054
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(crossModeRefusal(operation, record.effect, mode), { operation });
1958
2055
  }
1959
2056
  if (opts.dryRun !== void 0 && typeof opts.dryRun !== "boolean") {
1960
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2057
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1961
2058
  `invoke: dryRun must be a boolean (got ${typeof opts.dryRun}) \u2014 "${operation}" was not issued`,
1962
2059
  { operation, suggestedAction: "Pass dryRun: true (simulate) or dryRun: false (apply) as a real boolean." }
1963
2060
  );
1964
2061
  }
1965
2062
  if (opts.fresh !== void 0) {
1966
2063
  if (typeof opts.fresh !== "boolean") {
1967
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2064
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1968
2065
  `invoke: fresh must be a boolean (got ${typeof opts.fresh}) \u2014 "${operation}" was not issued`,
1969
2066
  { operation, suggestedAction: "Pass fresh: true (bypass the read cache) or omit it." }
1970
2067
  );
1971
2068
  }
1972
2069
  if (record.effect !== "read" || record.kind !== "primitive" || record.operation !== "get" || !("opts" in (_nullishCoalesce(record.inputSchema, () => ( {}))))) {
1973
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2070
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1974
2071
  `invoke: fresh applies only to a single-record "<resource>.get" read \u2014 "${operation}" was not issued`,
1975
2072
  { operation, suggestedAction: "Drop the fresh option (only <resource>.get consults the read cache per call)." }
1976
2073
  );
1977
2074
  }
1978
2075
  }
1979
2076
  if (record.effect === "read" && opts.dryRun === true) {
1980
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2077
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
1981
2078
  `invoke: "${operation}" is a read \u2014 dryRun is not applicable (reads issue their request as-is)`,
1982
2079
  { operation }
1983
2080
  );
@@ -1994,7 +2091,7 @@ function operationsHolder(client) {
1994
2091
  return {
1995
2092
  resolveAny: (identifier, opts) => resolveAny(client, identifier, opts),
1996
2093
  searchAcrossResources: (query, opts) => searchAcrossResources(client, query, opts),
1997
- fetchMany: (items, opts) => _chunkDKAD7MOVcjs.fetchMany.call(void 0, client, items, opts),
2094
+ fetchMany: (items, opts) => _chunkSEFJJY4Jcjs.fetchMany.call(void 0, client, items, opts),
1998
2095
  // Issue #62: the generic aggregate + the cheap count — the
1999
2096
  // groupBy/sum-absent mode is ONE vendor /query/count (the S12-C blind
2000
2097
  // sentinel rides through); the group/sum modes walk the named
@@ -2006,12 +2103,12 @@ function operationsHolder(client) {
2006
2103
  // Issue #59 PR-B: the bulk fetch by ids — query-first chunked `id in`
2007
2104
  // reads + the per-id `get` fallback (blind-surface-safe; per-item
2008
2105
  // typed outcomes reuse the fetchMany shapes).
2009
- fetchByIds: (items, opts) => _chunkDKAD7MOVcjs.fetchByIds.call(void 0, client, items, opts),
2106
+ fetchByIds: (items, opts) => _chunkSEFJJY4Jcjs.fetchByIds.call(void 0, client, items, opts),
2010
2107
  // Issue #65: opt-in resource name expansion — per-id resources.get
2011
2108
  // reads ONLY (never an id-in query — the resources table can be blind
2012
2109
  // to count/query while per-id reads work); blind-marked rows for ids
2013
2110
  // the API user cannot resolve; the read cache (default-on).
2014
- expandResourceNames: (ids, opts) => _chunkDKAD7MOVcjs.expandResourceNames.call(void 0, client, ids, opts),
2111
+ expandResourceNames: (ids, opts) => _chunkSEFJJY4Jcjs.expandResourceNames.call(void 0, client, ids, opts),
2015
2112
  relationshipMap: (resourceKey) => relationshipMap(client, resourceKey),
2016
2113
  // Issue #11: the served blind-surface inventory (zero wire) + the
2017
2114
  // bounded caller-opted reachability sweep (read-only, confirmProbe-
@@ -2021,12 +2118,16 @@ function operationsHolder(client) {
2021
2118
  // Issue #12: the served zone-fact create-guidance catalog (zero wire).
2022
2119
  createGuidance: (opts) => createGuidance(client, opts),
2023
2120
  // Issue #202: ExecuteCommand deep links — pure, zero wire.
2024
- uiLink: (input) => _chunkDKAD7MOVcjs.uiLink.call(void 0, client, input),
2121
+ uiLink: (input) => _chunkSEFJJY4Jcjs.uiLink.call(void 0, client, input),
2122
+ // Issue #287 (D8): the projection-layer untrusted-content helper — pure,
2123
+ // zero wire (the registry record's metadata.untrustedFields + the deep
2124
+ // walker from src/untrusted.ts; an unknown operation refuses).
2125
+ sanitiseResult: (result, operation) => sanitiseResult(client, result, operation),
2025
2126
  // Issue #31: the opt-in live field-metadata channel — N bounded
2026
2127
  // entityInformation GETs (the op's own cap refuses over-cap fan-outs
2027
2128
  // pre-request; per-resource failures are recorded on the row and
2028
2129
  // never abort the call).
2029
- fieldCatalog: (opts) => _chunkDKAD7MOVcjs.fieldCatalog.call(void 0, client, opts),
2130
+ fieldCatalog: (opts) => _chunkSEFJJY4Jcjs.fieldCatalog.call(void 0, client, opts),
2030
2131
  // Issue #9: the one-call recovery/cleanup op — effect write in the
2031
2132
  // registry (the governor's dry-run-first applies to it); the op's own
2032
2133
  // confirm gate makes the destructive action deliberate (the governor
@@ -2036,15 +2137,15 @@ function operationsHolder(client) {
2036
2137
  }
2037
2138
  function resolveHolder(client, record, operation) {
2038
2139
  const clientBag = client;
2039
- let holder = clientBag[_chunkDKAD7MOVcjs.camelKey.call(void 0, record.resource)];
2140
+ let holder = clientBag[_chunkSEFJJY4Jcjs.camelKey.call(void 0, record.resource)];
2040
2141
  if (typeof holder === "function") {
2041
- holder = _nullishCoalesce(clientBag[`${_chunkDKAD7MOVcjs.camelKey.call(void 0, record.resource)}Resource`], () => ( holder));
2142
+ holder = _nullishCoalesce(clientBag[`${_chunkSEFJJY4Jcjs.camelKey.call(void 0, record.resource)}Resource`], () => ( holder));
2042
2143
  }
2043
2144
  if (holder === void 0 && record.resource === "operations") {
2044
2145
  holder = operationsHolder(client);
2045
2146
  }
2046
2147
  if (holder === void 0) {
2047
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2148
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
2048
2149
  `invoke: the client exposes no accessor for resource "${record.resource}"`,
2049
2150
  { operation }
2050
2151
  );
@@ -2094,22 +2195,41 @@ function appendFresh(record, callArgs) {
2094
2195
  callArgs[at] = { fresh: true };
2095
2196
  return callArgs;
2096
2197
  }
2198
+ function validateFreshSpelling(record, args) {
2199
+ if (record.kind !== "primitive" || record.operation !== "get") return;
2200
+ const at = Object.keys(_nullishCoalesce(record.inputSchema, () => ( {}))).indexOf("opts");
2201
+ const bag = at < 0 ? void 0 : args[at];
2202
+ if (bag === void 0 || bag === null) return;
2203
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
2204
+ `invoke: "${record.id}" takes no positional options bag \u2014 the fresh spelling is the fresh invoke option (pass { fresh: true } in the invoke options, not as a method argument)`,
2205
+ {
2206
+ operation: record.id,
2207
+ suggestedAction: 'Pass fresh: true as an invoke option: invoke(client, "<resource>.get", [id], { fresh: true }). The typed client.<resource>.get(id, { fresh: true }) method keeps its own bag.'
2208
+ }
2209
+ );
2210
+ }
2211
+ var PRE_REQUEST_VALIDATORS = [
2212
+ (c) => governPreRequest(c.record, c.operation, c.opts),
2213
+ (c) => validateDispatchArgs(c.record, c.args),
2214
+ (c) => validateParamsBag(c.record, c.args),
2215
+ (c) => validateFreshSpelling(c.record, c.args),
2216
+ (c) => c.boundedQuery || c.countedQuery ? _chunkSEFJJY4Jcjs.validateQueryFieldNames.call(void 0, c.record, c.holder, c.args) : Promise.resolve(void 0)
2217
+ ];
2218
+ async function runPreRequestPass(ctx) {
2219
+ for (const step of PRE_REQUEST_VALIDATORS) await step(ctx);
2220
+ }
2097
2221
  async function invokeMode(client, operation, argsIn = [], opts = {}) {
2098
2222
  const record = resolveRecord(operation);
2099
- governPreRequest(record, operation, opts);
2100
2223
  const args = resolveDispatchArgs(record, argsIn);
2101
- validateDispatchArgs(record, args);
2102
- validateParamsBag(record, args);
2103
- validateGetBag(record, args);
2104
2224
  const boundedQuery = record.kind === "primitive" && record.operation === "query";
2105
2225
  const countedQuery = record.kind === "primitive" && record.operation === "count";
2106
2226
  const holder = resolveHolder(client, record, operation);
2107
- if (boundedQuery || countedQuery) await _chunkDKAD7MOVcjs.validateQueryFieldNames.call(void 0, record, holder, args);
2108
- const labelQuery = boundedQuery && _chunkDKAD7MOVcjs.readNamesOpt.call(void 0, _optionalChain([args, 'access', _53 => _53[0], 'optionalAccess', _54 => _54["names"]]), `invoke: "${record.id}" params bag`);
2227
+ await runPreRequestPass({ record, operation, args, opts, client, holder, boundedQuery, countedQuery });
2228
+ const labelQuery = boundedQuery && _chunkSEFJJY4Jcjs.readNamesOpt.call(void 0, client, _optionalChain([args, 'access', _63 => _63[0], 'optionalAccess', _64 => _64["names"]]), `invoke: "${record.id}" params bag`);
2109
2229
  const methodName = boundedQuery ? "queryBounded" : record.operation;
2110
2230
  const method = holder[methodName];
2111
2231
  if (typeof method !== "function") {
2112
- throw new (0, _chunkDKAD7MOVcjs.AutotaskConfigError)(
2232
+ throw new (0, _chunkSEFJJY4Jcjs.AutotaskConfigError)(
2113
2233
  `invoke: "${record.resource}.${methodName}" is not a callable method on the client`,
2114
2234
  { operation }
2115
2235
  );
@@ -2118,16 +2238,20 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
2118
2238
  const mutationOpts = buildMutationOpts(opts, isWrite);
2119
2239
  const callArgs = buildCallArgs(record, args, mutationOpts, isWrite);
2120
2240
  if (opts.fresh === true) appendFresh(record, callArgs);
2241
+ if (boundedQuery) _chunkSEFJJY4Jcjs.validateWalkBag.call(void 0, _optionalChain([args, 'access', _65 => _65[0], 'optionalAccess', _66 => _66["walk"]]), `invoke: "${record.id}"`, { operation: record.id });
2242
+ let scopeNote;
2243
+ if (boundedQuery && _optionalChain([args, 'access', _67 => _67[0], 'optionalAccess', _68 => _68["acknowledgeUnscoped"]]) !== true) {
2244
+ scopeNote = (await guardUnscopedQueryWalk(holder, record.id, args[0])).note;
2245
+ }
2121
2246
  const result = await method.apply(holder, callArgs);
2122
- if (labelQuery && Array.isArray(_optionalChain([result, 'optionalAccess', _55 => _55.items]))) {
2247
+ if (labelQuery && Array.isArray(_optionalChain([result, 'optionalAccess', _69 => _69.items]))) {
2123
2248
  const bounded = result;
2124
- const labelled = await _chunkDKAD7MOVcjs.labelRows.call(void 0, client, record.resource, bounded.items);
2125
- return { ...bounded, items: labelled.rows, ...labelled.names !== void 0 ? { names: labelled.names } : {} };
2249
+ const labelled = await _chunkSEFJJY4Jcjs.labelRows.call(void 0, client, record.resource, bounded.items);
2250
+ return { ...bounded, items: labelled.rows, ...labelled.names !== void 0 ? { names: labelled.names } : {}, ...scopeNote !== void 0 ? { scopeNote } : {} };
2126
2251
  }
2127
- return Buffer.isBuffer(result) ? bufferResult(result) : result;
2252
+ const finished = Buffer.isBuffer(result) ? bufferResult(result) : result;
2253
+ return scopeNote !== void 0 && finished !== null && typeof finished === "object" ? { ...finished, scopeNote } : finished;
2128
2254
  }
2129
-
2130
- // src/operations/invoke/wrappers.ts
2131
2255
  async function invoke(client, operation, args = [], opts = {}) {
2132
2256
  return invokeMode(client, operation, args, { ...opts, mode: void 0 });
2133
2257
  }
@@ -2192,7 +2316,4 @@ async function invokeDelete(client, operation, args = [], opts = {}) {
2192
2316
 
2193
2317
 
2194
2318
 
2195
-
2196
-
2197
-
2198
- exports.AGGREGATE_DATE_BUCKETS = AGGREGATE_DATE_BUCKETS; exports.AGGREGATE_DEFAULT_LIMIT = AGGREGATE_DEFAULT_LIMIT; exports.AGGREGATE_DEFAULT_TOP = AGGREGATE_DEFAULT_TOP; exports.AGGREGATE_TOP_MAX = AGGREGATE_TOP_MAX; exports.BLIND_SURFACE_KINDS = BLIND_SURFACE_KINDS; exports.CREATE_BLOCKER_KINDS = CREATE_BLOCKER_KINDS; exports.ENTITY_TYPE_TO_RESOURCE = _chunkDKAD7MOVcjs.ENTITY_TYPE_TO_RESOURCE; exports.EXPAND_RESOURCE_NAMES_MAX_IDS = _chunkDKAD7MOVcjs.EXPAND_RESOURCE_NAMES_MAX_IDS; exports.FETCH_BY_IDS_CHUNK_SIZE = _chunkDKAD7MOVcjs.FETCH_BY_IDS_CHUNK_SIZE; exports.FETCH_BY_IDS_MAX_ITEMS = _chunkDKAD7MOVcjs.FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_MANY_MAX_ITEMS = _chunkDKAD7MOVcjs.FETCH_MANY_MAX_ITEMS; exports.FIELD_CACHE_KINDS = _chunkDKAD7MOVcjs.FIELD_CACHE_KINDS; exports.FIELD_CATALOG_HONESTY_NOTE = _chunkDKAD7MOVcjs.FIELD_CATALOG_HONESTY_NOTE; exports.INVOKE_OPTION_KEYS = INVOKE_OPTION_KEYS; exports.MAX_FIELD_CATALOG_WIRE = _chunkDKAD7MOVcjs.MAX_FIELD_CATALOG_WIRE; exports.MIN_FIELD_CATALOG_MAX_BYTES = _chunkDKAD7MOVcjs.MIN_FIELD_CATALOG_MAX_BYTES; exports.PARAMS_BAG_KEYS = PARAMS_BAG_KEYS; exports.PICKLIST_CATALOG_UNAVAILABLE_NOTE = _chunkDKAD7MOVcjs.PICKLIST_CATALOG_UNAVAILABLE_NOTE; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = _chunkDKAD7MOVcjs.PICKLIST_VALUE_NOT_SERVED_NOTE; exports.RECOVERY_CONFIRM = RECOVERY_CONFIRM; exports.RECOVERY_DEFAULT_LIMIT = RECOVERY_DEFAULT_LIMIT; exports.RECOVERY_MAX_LIMIT = RECOVERY_MAX_LIMIT; exports.UI_LINK_ENTITIES = _chunkDKAD7MOVcjs.UI_LINK_ENTITIES; exports.WORKFLOW_RESOURCES = _chunkDKAD7MOVcjs.WORKFLOW_RESOURCES; exports.aggregate = aggregate; exports.blindSurfaces = blindSurfaces; exports.buildUiLink = _chunkDKAD7MOVcjs.buildUiLink; exports.createGuidance = createGuidance; exports.dateBucketLabel = dateBucketLabel; exports.effectiveRequiredFields = _chunkDKAD7MOVcjs.effectiveRequiredFields; exports.expandResourceNames = _chunkDKAD7MOVcjs.expandResourceNames; exports.fetchByIds = _chunkDKAD7MOVcjs.fetchByIds; exports.fetchMany = _chunkDKAD7MOVcjs.fetchMany; exports.fieldCatalog = _chunkDKAD7MOVcjs.fieldCatalog; exports.foldFlattenedOpts = foldFlattenedOpts; exports.invoke = invoke; exports.invokeDelete = invokeDelete; exports.invokeRead = invokeRead; exports.invokeWrite = invokeWrite; exports.isEnumerableResource = _chunkDKAD7MOVcjs.isEnumerableResource; exports.needsConfirmation = needsConfirmation; exports.probeReachability = probeReachability; exports.recovery = recovery; exports.relationshipMap = relationshipMap; exports.resolveAny = resolveAny; exports.resourceForEntityType = _chunkDKAD7MOVcjs.resourceForEntityType; exports.revenueRollup = revenueRollup; exports.searchAcrossResources = searchAcrossResources; exports.uiLink = _chunkDKAD7MOVcjs.uiLink; exports.unknownKeysRefusal = unknownKeysRefusal; exports.validateDispatchArgs = validateDispatchArgs; exports.validateFetchManyItems = _chunkDKAD7MOVcjs.validateFetchManyItems; exports.validateInvokeOptions = validateInvokeOptions; exports.validateParamsBag = validateParamsBag;
2319
+ exports.AGGREGATE_DATE_BUCKETS = AGGREGATE_DATE_BUCKETS; exports.AGGREGATE_DEFAULT_LIMIT = AGGREGATE_DEFAULT_LIMIT; exports.AGGREGATE_DEFAULT_TOP = AGGREGATE_DEFAULT_TOP; exports.AGGREGATE_TOP_MAX = AGGREGATE_TOP_MAX; exports.BLIND_SURFACE_KINDS = BLIND_SURFACE_KINDS; exports.CREATE_BLOCKER_KINDS = CREATE_BLOCKER_KINDS; exports.EXPAND_RESOURCE_NAMES_MAX_IDS = _chunkSEFJJY4Jcjs.EXPAND_RESOURCE_NAMES_MAX_IDS; exports.FETCH_BY_IDS_CHUNK_SIZE = _chunkSEFJJY4Jcjs.FETCH_BY_IDS_CHUNK_SIZE; exports.FETCH_BY_IDS_MAX_ITEMS = _chunkSEFJJY4Jcjs.FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_MANY_MAX_ITEMS = _chunkSEFJJY4Jcjs.FETCH_MANY_MAX_ITEMS; exports.FIELD_CACHE_KINDS = _chunkSEFJJY4Jcjs.FIELD_CACHE_KINDS; exports.FIELD_CATALOG_HONESTY_NOTE = _chunkSEFJJY4Jcjs.FIELD_CATALOG_HONESTY_NOTE; exports.INVOKE_OPTION_KEYS = INVOKE_OPTION_KEYS; exports.MAX_FIELD_CATALOG_WIRE = _chunkSEFJJY4Jcjs.MAX_FIELD_CATALOG_WIRE; exports.MIN_FIELD_CATALOG_MAX_BYTES = _chunkSEFJJY4Jcjs.MIN_FIELD_CATALOG_MAX_BYTES; exports.PARAMS_BAG_KEYS = PARAMS_BAG_KEYS; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = _chunkSEFJJY4Jcjs.PICKLIST_VALUE_NOT_SERVED_NOTE; exports.RECOVERY_CONFIRM = RECOVERY_CONFIRM; exports.RECOVERY_DEFAULT_LIMIT = RECOVERY_DEFAULT_LIMIT; exports.RECOVERY_MAX_LIMIT = RECOVERY_MAX_LIMIT; exports.UI_LINK_ENTITIES = _chunkSEFJJY4Jcjs.UI_LINK_ENTITIES; exports.WORKFLOW_RESOURCES = _chunkSEFJJY4Jcjs.WORKFLOW_RESOURCES; exports.aggregate = aggregate; exports.blindSurfaces = blindSurfaces; exports.buildUiLink = _chunkSEFJJY4Jcjs.buildUiLink; exports.createGuidance = createGuidance; exports.dateBucketLabel = dateBucketLabel; exports.effectiveRequiredFields = _chunkSEFJJY4Jcjs.effectiveRequiredFields; exports.expandResourceNames = _chunkSEFJJY4Jcjs.expandResourceNames; exports.fetchByIds = _chunkSEFJJY4Jcjs.fetchByIds; exports.fetchMany = _chunkSEFJJY4Jcjs.fetchMany; exports.fieldCatalog = _chunkSEFJJY4Jcjs.fieldCatalog; exports.foldFlattenedOpts = foldFlattenedOpts; exports.invoke = invoke; exports.invokeDelete = invokeDelete; exports.invokeRead = invokeRead; exports.invokeWrite = invokeWrite; exports.needsConfirmation = needsConfirmation; exports.probeReachability = probeReachability; exports.recovery = recovery; exports.relationshipMap = relationshipMap; exports.resolveAny = resolveAny; exports.revenueRollup = revenueRollup; exports.sanitiseResult = sanitiseResult; exports.searchAcrossResources = searchAcrossResources; exports.uiLink = _chunkSEFJJY4Jcjs.uiLink; exports.unknownKeysRefusal = unknownKeysRefusal; exports.validateDispatchArgs = validateDispatchArgs; exports.validateFetchManyItems = _chunkSEFJJY4Jcjs.validateFetchManyItems; exports.validateInvokeOptions = validateInvokeOptions; exports.validateParamsBag = validateParamsBag;