node-autotask 0.41.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/MCP_TOOL_CATALOG.json +152 -132
- package/MCP_TOOL_MANIFEST.md +16 -15
- package/N8N_MCP_MANIFEST.json +3 -3
- package/N8N_MCP_MANIFEST.md +4 -4
- package/README.md +4 -5
- package/capabilities.json +3919 -3195
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-P5655PGY.js → chunk-4EFXIE53.js} +2 -2
- package/dist/{chunk-MJ6J74F3.cjs → chunk-5BDUMDAQ.cjs} +3918 -3194
- package/dist/{chunk-ZVSSAULC.js → chunk-JY2BWYXY.js} +3918 -3194
- package/dist/{chunk-TCND5PFF.js → chunk-KTEDPS4X.js} +3 -3
- package/dist/{chunk-LR6FDJI3.js → chunk-Q23JULNN.js} +2736 -2749
- package/dist/{chunk-YAHFPOQF.cjs → chunk-SK3GYRNA.cjs} +143 -143
- package/dist/{chunk-DXEBPK55.cjs → chunk-TH7B5H4P.cjs} +286 -286
- package/dist/{chunk-DKAD7MOV.cjs → chunk-VFLAMMIJ.cjs} +2768 -2781
- package/dist/index-C3KFMnRT.d.cts +6860 -0
- package/dist/index-C3KFMnRT.d.ts +6860 -0
- package/dist/{index-CqO1HNHl.d.ts → index-C7rMJ4IV.d.ts} +132 -7184
- package/dist/{index-CqO1HNHl.d.cts → index-Cm_Xpt7X.d.cts} +132 -7184
- package/dist/index.cjs +23 -25
- package/dist/index.d.cts +58 -34
- package/dist/index.d.ts +58 -34
- package/dist/index.js +9 -11
- package/dist/operations/index.cjs +363 -242
- package/dist/operations/index.d.cts +281 -25
- package/dist/operations/index.d.ts +281 -25
- package/dist/operations/index.js +178 -57
- package/dist/pool.cjs +8 -8
- package/dist/pool.d.cts +2 -1
- package/dist/pool.d.ts +2 -1
- package/dist/pool.js +4 -4
- package/dist/resources/index.cjs +4 -4
- package/dist/resources/index.d.cts +2 -1
- package/dist/resources/index.d.ts +2 -1
- package/dist/resources/index.js +3 -3
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/docs/API.md +95 -120
- package/docs/LIVE-TESTING.md +9 -5
- package/docs/RELEASING.md +121 -0
- package/package.json +10 -3
|
@@ -69,30 +69,33 @@
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
var _chunkDKAD7MOVcjs = require('../chunk-DKAD7MOV.cjs');
|
|
73
72
|
|
|
73
|
+
var _chunkVFLAMMIJcjs = require('../chunk-VFLAMMIJ.cjs');
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
require('../chunk-
|
|
75
|
+
|
|
76
|
+
var _chunk5BDUMDAQcjs = require('../chunk-5BDUMDAQ.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[
|
|
84
|
+
return client[_chunkVFLAMMIJcjs.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,
|
|
89
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("searchAcrossResources: query must be a non-empty string");
|
|
87
90
|
}
|
|
88
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
91
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkVFLAMMIJcjs.WORKFLOW_RESOURCES));
|
|
89
92
|
if (keys.length === 0) {
|
|
90
|
-
throw new (0,
|
|
93
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("searchAcrossResources: no resources requested");
|
|
91
94
|
}
|
|
92
|
-
const limit =
|
|
95
|
+
const limit = _chunkVFLAMMIJcjs.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,
|
|
98
|
+
throw new (0, _chunkVFLAMMIJcjs.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[
|
|
129
|
+
return client[_chunkVFLAMMIJcjs.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
|
-
|
|
138
|
+
_chunkVFLAMMIJcjs.parseIdentifier.call(void 0, identifier, "identifier");
|
|
136
139
|
} else if (identifier.trim() === "") {
|
|
137
|
-
throw new (0,
|
|
140
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("resolveAny: identifier must be non-empty");
|
|
138
141
|
}
|
|
139
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
142
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkVFLAMMIJcjs.WORKFLOW_RESOURCES));
|
|
140
143
|
if (keys.length === 0) {
|
|
141
|
-
throw new (0,
|
|
144
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("resolveAny: no resources requested");
|
|
145
|
+
}
|
|
146
|
+
const match = _nullishCoalesce(opts.match, () => ( "exact"));
|
|
147
|
+
if (match !== "exact" && match !== "auto") {
|
|
148
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
-
|
|
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
|
|
195
|
+
if (err instanceof _chunkVFLAMMIJcjs.AutotaskConfigError) {
|
|
172
196
|
code = "CONFIG_ERROR";
|
|
173
|
-
} else if (
|
|
197
|
+
} else if (_chunkVFLAMMIJcjs.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 =
|
|
224
|
+
var AGGREGATE_DEFAULT_LIMIT = _chunkVFLAMMIJcjs.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
|
|
281
|
+
for (const rec of _chunk5BDUMDAQcjs.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
|
|
317
|
+
return _chunkVFLAMMIJcjs.buildFilter.call(void 0, conds).filter;
|
|
294
318
|
} catch (err) {
|
|
295
|
-
problems.push(err instanceof
|
|
319
|
+
problems.push(err instanceof _chunkVFLAMMIJcjs.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,
|
|
325
|
+
throw new (0, _chunkVFLAMMIJcjs.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),
|
|
392
|
+
limit = Math.min(Math.max(opts.limit, 1), _chunkVFLAMMIJcjs.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 :
|
|
398
|
+
const record = resourceKey === void 0 ? void 0 : _chunk5BDUMDAQcjs.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
|
|
376
|
-
filter:
|
|
402
|
+
const found = await _chunkVFLAMMIJcjs.findUnknownFieldNames.call(void 0, record, void 0, {
|
|
403
|
+
filter: _chunkVFLAMMIJcjs.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 ?
|
|
427
|
+
dateSets: resourceKey !== void 0 ? _chunkVFLAMMIJcjs.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,
|
|
434
|
+
throw new (0, _chunkVFLAMMIJcjs.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, _chunkVFLAMMIJcjs.ScopeRequiredError)(operation, { threshold: _chunkVFLAMMIJcjs.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[
|
|
471
|
+
const holder = client[_chunkVFLAMMIJcjs.camelKey.call(void 0, v.resourceKey)];
|
|
442
472
|
if (holder === void 0) {
|
|
443
|
-
throw new (0,
|
|
473
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
|
490
|
+
const label = _chunkVFLAMMIJcjs.readNamesOpt.call(void 0, client, opts.names, "aggregate");
|
|
491
|
+
const labelled = !label || v.groupBy.length === 0 ? void 0 : await _chunkVFLAMMIJcjs.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',
|
|
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',
|
|
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", ...
|
|
492
|
-
var isLabour = (line) =>
|
|
524
|
+
var LINE_TYPE_FIELDS = ["billingItemType", "timeEntryID", "expenseItemID", ..._chunkVFLAMMIJcjs.CHARGE_LINE_FKS, ..._chunkVFLAMMIJcjs.SERVICE_LINE_FKS];
|
|
525
|
+
var isLabour = (line) => _chunkVFLAMMIJcjs.billingLineType.call(void 0, line) === "labour";
|
|
493
526
|
function picklistKey(c, dim, path, field, raw, missing) {
|
|
494
|
-
const id =
|
|
527
|
+
const id = _chunkVFLAMMIJcjs.num.call(void 0, raw);
|
|
495
528
|
if (id === 0) return { id: null, label: missing };
|
|
496
|
-
const label = _optionalChain([c, 'access',
|
|
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',
|
|
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:
|
|
550
|
+
key: (c) => ({ id: _chunkVFLAMMIJcjs.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) =>
|
|
558
|
+
key: (c) => _chunkVFLAMMIJcjs.num.call(void 0, c.line["billingItemType"]) === 0 ? { id: _chunkVFLAMMIJcjs.billingLineType.call(void 0, c.line), label: _chunkVFLAMMIJcjs.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:
|
|
562
|
+
key: (c) => ({ id: _chunkVFLAMMIJcjs.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 =
|
|
570
|
+
const id = _chunkVFLAMMIJcjs.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(
|
|
541
|
-
const l2 = c.joined.organizationalLevel2s.get(
|
|
573
|
+
const l1 = c.joined.organizationalLevel1s.get(_chunkVFLAMMIJcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _17 => _17["organizationalLevel1ID"]])));
|
|
574
|
+
const l2 = c.joined.organizationalLevel2s.get(_chunkVFLAMMIJcjs.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 =
|
|
585
|
+
const te = _chunkVFLAMMIJcjs.num.call(void 0, c.line["timeEntryID"]);
|
|
553
586
|
if (!isLabour(c.line) || te === 0) return { id: null, label: "n/a" };
|
|
554
|
-
const id =
|
|
587
|
+
const id = _chunkVFLAMMIJcjs.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 =
|
|
598
|
+
const id = _chunkVFLAMMIJcjs.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) =>
|
|
605
|
+
var fk = (rows, field) => [...rows].map((r) => _chunkVFLAMMIJcjs.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,
|
|
609
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
614
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.CompaniesResource)(http, PAGE),
|
|
582
615
|
fields: ["id"],
|
|
583
616
|
ids: (lines) => fk(lines, "companyID")
|
|
584
617
|
},
|
|
585
618
|
organizationalLevelAssociations: {
|
|
586
|
-
make: (http) => new (0,
|
|
619
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
624
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
630
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
636
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
643
|
+
make: (http, client) => new (0, _chunkVFLAMMIJcjs.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,
|
|
649
|
+
make: (http) => new (0, _chunkVFLAMMIJcjs.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,
|
|
684
|
+
throw new (0, _chunkVFLAMMIJcjs.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 (!
|
|
701
|
+
if (!_chunkVFLAMMIJcjs.isDateYMD.call(void 0, dateFrom) || !_chunkVFLAMMIJcjs.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 (
|
|
673
|
-
problems.push(`the window spans ${
|
|
705
|
+
} else if (_chunkVFLAMMIJcjs.monthsInWindow.call(void 0, dateFrom, dateTo) > _chunkVFLAMMIJcjs.PROFITABILITY_MAX_WINDOW_MONTHS) {
|
|
706
|
+
problems.push(`the window spans ${_chunkVFLAMMIJcjs.monthsInWindow.call(void 0, dateFrom, dateTo)} months; the cap is ${_chunkVFLAMMIJcjs.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,
|
|
733
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
751
|
+
return new (0, _chunkVFLAMMIJcjs.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) => [
|
|
730
|
-
var cents = (v) => Math.round(
|
|
731
|
-
var revC = (line) => cents(
|
|
732
|
-
var extC = (line) => cents(
|
|
762
|
+
var byId = (rows) => [...new Map(rows.map((r) => [_chunkVFLAMMIJcjs.num.call(void 0, r["id"]), r])).values()];
|
|
763
|
+
var cents = (v) => Math.round(_chunkVFLAMMIJcjs.num.call(void 0, v) * 100);
|
|
764
|
+
var revC = (line) => cents(_chunkVFLAMMIJcjs.internalAmount.call(void 0, line, "internalCurrencyTotalAmount", "totalAmount"));
|
|
765
|
+
var extC = (line) => cents(_chunkVFLAMMIJcjs.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,
|
|
776
|
+
return new (0, _chunkVFLAMMIJcjs.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,
|
|
786
|
+
return new (0, _chunkVFLAMMIJcjs.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,
|
|
795
|
+
return new (0, _chunkVFLAMMIJcjs.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
|
|
828
|
+
for (const p of paths) labels[p] = await _chunkVFLAMMIJcjs.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,
|
|
805
|
-
const id =
|
|
837
|
+
for await (const c of new (0, _chunkVFLAMMIJcjs.CompaniesResource)(http, PAGE).query({ filter: [{ field: "ownerResourceID", op: "eq", value: v.ownerResourceID }], includeFields: ["id"], maxRecords: PAGE, names: false })) {
|
|
838
|
+
const id = _chunkVFLAMMIJcjs.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,
|
|
844
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
819
|
-
const billingItems = new (0,
|
|
820
|
-
const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value:
|
|
851
|
+
const invoices = new (0, _chunkVFLAMMIJcjs.InvoicesResource)(http, PAGE);
|
|
852
|
+
const billingItems = new (0, _chunkVFLAMMIJcjs.BillingItemsResource)(http, PAGE);
|
|
853
|
+
const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value: _chunkVFLAMMIJcjs.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',
|
|
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(
|
|
877
|
+
invoiceById.set(_chunkVFLAMMIJcjs.num.call(void 0, r["id"]), { total: cents(r["invoiceTotal"]), month: String(_nullishCoalesce(r["invoiceDateTime"], () => ( ""))).slice(0, 7), companyID: _chunkVFLAMMIJcjs.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(
|
|
891
|
+
const orphan = lines.find((l) => !invoiceById.has(_chunkVFLAMMIJcjs.num.call(void 0, l["invoiceID"])));
|
|
859
892
|
if (orphan !== void 0) {
|
|
860
|
-
throw new (0,
|
|
893
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskError)(`revenueRollup: billing line ${_chunkVFLAMMIJcjs.num.call(void 0, orphan["id"])} belongs to invoice ${_chunkVFLAMMIJcjs.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:
|
|
897
|
+
details: { reason: "orphan_line", lineID: _chunkVFLAMMIJcjs.num.call(void 0, orphan["id"]), invoiceID: _chunkVFLAMMIJcjs.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',
|
|
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(
|
|
911
|
+
for (const r of rows.flat()) joined[j].set(_chunkVFLAMMIJcjs.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 =
|
|
916
|
+
const months = _chunkVFLAMMIJcjs.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',
|
|
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',
|
|
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 =
|
|
1012
|
+
const contractID = _chunkVFLAMMIJcjs.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 =
|
|
1016
|
+
const type = _chunkVFLAMMIJcjs.num.call(void 0, contract["contractType"]);
|
|
984
1017
|
if (!f.inTypes.has(type)) return { bucket: slot(otherTypes, typeLabel(type)), unresolved: false };
|
|
985
|
-
const cat =
|
|
1018
|
+
const cat = _chunkVFLAMMIJcjs.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(
|
|
1020
|
+
const company = f.joined.companies.get(_chunkVFLAMMIJcjs.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 =
|
|
1040
|
+
const invoiceID = _chunkVFLAMMIJcjs.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(
|
|
1061
|
+
cell.contracts.add(_chunkVFLAMMIJcjs.num.call(void 0, line["contractID"]));
|
|
1029
1062
|
cell.items += 1;
|
|
1030
|
-
allContracts.add(
|
|
1063
|
+
allContracts.add(_chunkVFLAMMIJcjs.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:
|
|
1071
|
+
const at = locate(line, { total: 0, month: String(_nullishCoalesce(line["itemDate"], () => ( ""))).slice(0, 7), companyID: _chunkVFLAMMIJcjs.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,
|
|
1181
|
+
throw new (0, _chunkVFLAMMIJcjs.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 =
|
|
1187
|
+
const entry = _chunkVFLAMMIJcjs.RELATIONSHIP_MAP[key];
|
|
1155
1188
|
if (entry === void 0) {
|
|
1156
|
-
throw new (0,
|
|
1157
|
-
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
1189
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskError)(
|
|
1190
|
+
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkVFLAMMIJcjs.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 ${
|
|
1194
|
+
suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${_chunkVFLAMMIJcjs.RELATIONSHIP_ZONE.label} (${_chunkVFLAMMIJcjs.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,
|
|
1211
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("blindSurfaces: opts must be an object { resource?: string, kind?: BlindSurfaceKind }");
|
|
1179
1212
|
}
|
|
1180
|
-
const inv =
|
|
1213
|
+
const inv = _chunkVFLAMMIJcjs.BLIND_SURFACE_INVENTORY;
|
|
1181
1214
|
if (inv === null) {
|
|
1182
|
-
throw new (0,
|
|
1215
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
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,
|
|
1221
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1195
|
-
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
1227
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskError)(
|
|
1228
|
+
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkVFLAMMIJcjs.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',
|
|
1238
|
+
if (_optionalChain([opts, 'optionalAccess', _34 => _34.kind]) !== void 0) {
|
|
1206
1239
|
if (!BLIND_SURFACE_KINDS.includes(opts.kind)) {
|
|
1207
|
-
throw new (0,
|
|
1240
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1253
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("probeReachability: opts must be an object { resources?: string[], limit?: 1|2, maxWireCalls?: number, confirmProbe?: true }");
|
|
1221
1254
|
}
|
|
1222
|
-
const defs =
|
|
1223
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1224
|
-
throw new (0,
|
|
1255
|
+
const defs = _chunkVFLAMMIJcjs.REACHABILITY_PROBE_DEFAULTS;
|
|
1256
|
+
if (_optionalChain([opts, 'optionalAccess', _35 => _35.confirmProbe]) !== true) {
|
|
1257
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
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,
|
|
1264
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
1268
|
+
const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _37 => _37.maxWireCalls]), () => ( defs.defaultCap));
|
|
1236
1269
|
if (!Number.isInteger(cap) || cap < 1) {
|
|
1237
|
-
throw new (0,
|
|
1270
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)(`probeReachability: maxWireCalls must be a positive integer (got ${String(cap)})`);
|
|
1238
1271
|
}
|
|
1239
1272
|
if (cap > defs.hardCap) {
|
|
1240
|
-
throw new (0,
|
|
1273
|
+
throw new (0, _chunkVFLAMMIJcjs.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 =
|
|
1278
|
+
const inv = _chunkVFLAMMIJcjs.BLIND_SURFACE_INVENTORY;
|
|
1246
1279
|
if (inv === null) {
|
|
1247
|
-
throw new (0,
|
|
1280
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
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,
|
|
1287
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1292
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1297
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1311
|
+
throw new (0, _chunkVFLAMMIJcjs.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[
|
|
1289
|
-
const probeFn = _optionalChain([holder, 'optionalAccess',
|
|
1321
|
+
const holder = client[_chunkVFLAMMIJcjs.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',
|
|
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 =
|
|
1340
|
+
const code = _chunkVFLAMMIJcjs.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,
|
|
1368
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)(
|
|
1336
1369
|
"createGuidance: opts must be an object { resources?: string[], kind?: CreateBlockerKind }"
|
|
1337
1370
|
);
|
|
1338
1371
|
}
|
|
1339
|
-
let servedRows =
|
|
1372
|
+
let servedRows = _chunkVFLAMMIJcjs.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:
|
|
1377
|
+
requiredFields: _chunkVFLAMMIJcjs.effectiveRequiredFields.call(void 0, void 0, _nullishCoalesce(_optionalChain([_chunkVFLAMMIJcjs.RELATIONSHIP_MAP, 'access', _41 => _41[row.resource], 'optionalAccess', _42 => _42.zoneFacts]), () => ( null)))
|
|
1345
1378
|
}));
|
|
1346
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
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,
|
|
1381
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1386
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)("createGuidance: opts.resources must contain non-empty plan resource key strings");
|
|
1354
1387
|
}
|
|
1355
1388
|
const key = r.trim();
|
|
1356
|
-
if (!
|
|
1357
|
-
throw new (0,
|
|
1358
|
-
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${
|
|
1389
|
+
if (!_chunkVFLAMMIJcjs.CREATE_GUIDANCE.rows.some((row) => row.resource === key)) {
|
|
1390
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskError)(
|
|
1391
|
+
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${_chunkVFLAMMIJcjs.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',
|
|
1403
|
+
if (_optionalChain([opts, 'optionalAccess', _44 => _44.kind]) !== void 0) {
|
|
1371
1404
|
if (!CREATE_BLOCKER_KINDS.includes(opts.kind)) {
|
|
1372
|
-
throw new (0,
|
|
1405
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
1409
|
+
servedRows = servedRows.filter((row) => _optionalChain([row, 'access', _45 => _45.blocker, 'optionalAccess', _46 => _46.kind]) === opts.kind);
|
|
1377
1410
|
}
|
|
1378
1411
|
return {
|
|
1379
|
-
zone:
|
|
1380
|
-
label:
|
|
1381
|
-
verifiedAt:
|
|
1412
|
+
zone: _chunkVFLAMMIJcjs.CREATE_GUIDANCE.zone,
|
|
1413
|
+
label: _chunkVFLAMMIJcjs.CREATE_GUIDANCE.label,
|
|
1414
|
+
verifiedAt: _chunkVFLAMMIJcjs.CREATE_GUIDANCE.verifiedAt,
|
|
1382
1415
|
rows: servedRows,
|
|
1383
|
-
counts:
|
|
1416
|
+
counts: _chunkVFLAMMIJcjs.CREATE_GUIDANCE.counts
|
|
1384
1417
|
};
|
|
1385
1418
|
}
|
|
1386
1419
|
|
|
1420
|
+
// src/operations/registryIndex.ts
|
|
1421
|
+
var OPERATION_BY_ID = new Map(_chunk5BDUMDAQcjs.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, _chunkVFLAMMIJcjs.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, _chunkVFLAMMIJcjs.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,
|
|
1449
|
+
throw new (0, _chunkVFLAMMIJcjs.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 (!
|
|
1465
|
+
if (!_chunkVFLAMMIJcjs.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 =
|
|
1499
|
+
const entry = _chunkVFLAMMIJcjs.RELATIONSHIP_MAP[resource];
|
|
1443
1500
|
if (entry === void 0) {
|
|
1444
|
-
throw new (0,
|
|
1445
|
-
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(
|
|
1501
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskError)(
|
|
1502
|
+
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(_chunkVFLAMMIJcjs.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[
|
|
1511
|
+
const holder = client[_chunkVFLAMMIJcjs.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) :
|
|
1522
|
+
const field = input.field !== void 0 ? String(input.field) : _chunkVFLAMMIJcjs.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 (!
|
|
1561
|
+
if (!_chunkVFLAMMIJcjs.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,
|
|
1586
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
|
1615
|
+
if (err instanceof _chunkVFLAMMIJcjs.NotFoundError) verify = "not-found";
|
|
1559
1616
|
else {
|
|
1560
1617
|
verify = "error";
|
|
1561
|
-
code =
|
|
1618
|
+
code = _chunkVFLAMMIJcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
|
|
1562
1619
|
}
|
|
1563
1620
|
}
|
|
1564
1621
|
} catch (err) {
|
|
1565
|
-
code =
|
|
1622
|
+
code = _chunkVFLAMMIJcjs.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 =
|
|
1650
|
+
const boundaryNote = _chunkVFLAMMIJcjs.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,
|
|
1662
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
1615
|
-
const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
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,
|
|
1674
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1690
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1719
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1737
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
|
1783
|
+
return _chunkVFLAMMIJcjs.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,
|
|
1797
|
+
throw new (0, _chunkVFLAMMIJcjs.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 (!
|
|
1802
|
+
if (!_chunkVFLAMMIJcjs.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,
|
|
1823
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1833
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
1844
|
+
throw new (0, _chunkVFLAMMIJcjs.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 (!
|
|
1796
|
-
throw new (0,
|
|
1852
|
+
if (!_chunkVFLAMMIJcjs.isRecord.call(void 0, toolArgs)) {
|
|
1853
|
+
throw new (0, _chunkVFLAMMIJcjs.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',
|
|
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,
|
|
1862
|
+
throw new (0, _chunkVFLAMMIJcjs.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", "
|
|
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',
|
|
1867
|
-
if (bag === void 0 || bag === null || !
|
|
1928
|
+
const bag = _optionalChain([args, 'optionalAccess', _54 => _54[0]]);
|
|
1929
|
+
if (bag === void 0 || bag === null || !_chunkVFLAMMIJcjs.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
|
|
1871
|
-
throw new (0,
|
|
1932
|
+
const suggestions = keySuggestions(unknown, valid);
|
|
1933
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
|
1904
|
-
throw new (0,
|
|
1946
|
+
const suggestions = keySuggestions(unknown, ["dryRun", "confirm", "lastModifiedDate", "maxRetries", "fresh"]);
|
|
1947
|
+
throw new (0, _chunkVFLAMMIJcjs.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
|
|
1917
|
-
return new (0,
|
|
1959
|
+
const suggestions = keySuggestions(unknown, [...validKeys]);
|
|
1960
|
+
return new (0, _chunkVFLAMMIJcjs.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/
|
|
1927
|
-
var
|
|
1928
|
-
|
|
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 : _chunkVFLAMMIJcjs.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 <= _chunkVFLAMMIJcjs.UNSCOPED_WALK_THRESHOLD || hasIdScope(filter)) return {};
|
|
2000
|
+
let conditions;
|
|
2001
|
+
try {
|
|
2002
|
+
conditions = _chunkVFLAMMIJcjs.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 > _chunkVFLAMMIJcjs.UNSCOPED_WALK_THRESHOLD) throw new (0, _chunkVFLAMMIJcjs.ScopeRequiredError)(operation, { threshold: _chunkVFLAMMIJcjs.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 =
|
|
2041
|
+
const record = OPERATION_BY_ID.get(operation);
|
|
1945
2042
|
if (record === void 0) {
|
|
1946
|
-
throw new (0,
|
|
2043
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
2054
|
+
throw new (0, _chunkVFLAMMIJcjs.AutotaskConfigError)(crossModeRefusal(operation, record.effect, mode), { operation });
|
|
1958
2055
|
}
|
|
1959
2056
|
if (opts.dryRun !== void 0 && typeof opts.dryRun !== "boolean") {
|
|
1960
|
-
throw new (0,
|
|
2057
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
2064
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
2070
|
+
throw new (0, _chunkVFLAMMIJcjs.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,
|
|
2077
|
+
throw new (0, _chunkVFLAMMIJcjs.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) =>
|
|
2094
|
+
fetchMany: (items, opts) => _chunkVFLAMMIJcjs.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) =>
|
|
2106
|
+
fetchByIds: (items, opts) => _chunkVFLAMMIJcjs.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) =>
|
|
2111
|
+
expandResourceNames: (ids, opts) => _chunkVFLAMMIJcjs.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) =>
|
|
2121
|
+
uiLink: (input) => _chunkVFLAMMIJcjs.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) =>
|
|
2130
|
+
fieldCatalog: (opts) => _chunkVFLAMMIJcjs.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[
|
|
2140
|
+
let holder = clientBag[_chunkVFLAMMIJcjs.camelKey.call(void 0, record.resource)];
|
|
2040
2141
|
if (typeof holder === "function") {
|
|
2041
|
-
holder = _nullishCoalesce(clientBag[`${
|
|
2142
|
+
holder = _nullishCoalesce(clientBag[`${_chunkVFLAMMIJcjs.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,
|
|
2148
|
+
throw new (0, _chunkVFLAMMIJcjs.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, _chunkVFLAMMIJcjs.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 ? _chunkVFLAMMIJcjs.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
|
-
|
|
2108
|
-
const labelQuery = boundedQuery &&
|
|
2227
|
+
await runPreRequestPass({ record, operation, args, opts, client, holder, boundedQuery, countedQuery });
|
|
2228
|
+
const labelQuery = boundedQuery && _chunkVFLAMMIJcjs.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,
|
|
2232
|
+
throw new (0, _chunkVFLAMMIJcjs.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) _chunkVFLAMMIJcjs.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',
|
|
2247
|
+
if (labelQuery && Array.isArray(_optionalChain([result, 'optionalAccess', _69 => _69.items]))) {
|
|
2123
2248
|
const bounded = result;
|
|
2124
|
-
const labelled = await
|
|
2125
|
-
return { ...bounded, items: labelled.rows, ...labelled.names !== void 0 ? { names: labelled.names } : {} };
|
|
2249
|
+
const labelled = await _chunkVFLAMMIJcjs.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
|
-
|
|
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 = _chunkVFLAMMIJcjs.EXPAND_RESOURCE_NAMES_MAX_IDS; exports.FETCH_BY_IDS_CHUNK_SIZE = _chunkVFLAMMIJcjs.FETCH_BY_IDS_CHUNK_SIZE; exports.FETCH_BY_IDS_MAX_ITEMS = _chunkVFLAMMIJcjs.FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_MANY_MAX_ITEMS = _chunkVFLAMMIJcjs.FETCH_MANY_MAX_ITEMS; exports.FIELD_CACHE_KINDS = _chunkVFLAMMIJcjs.FIELD_CACHE_KINDS; exports.FIELD_CATALOG_HONESTY_NOTE = _chunkVFLAMMIJcjs.FIELD_CATALOG_HONESTY_NOTE; exports.INVOKE_OPTION_KEYS = INVOKE_OPTION_KEYS; exports.MAX_FIELD_CATALOG_WIRE = _chunkVFLAMMIJcjs.MAX_FIELD_CATALOG_WIRE; exports.MIN_FIELD_CATALOG_MAX_BYTES = _chunkVFLAMMIJcjs.MIN_FIELD_CATALOG_MAX_BYTES; exports.PARAMS_BAG_KEYS = PARAMS_BAG_KEYS; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = _chunkVFLAMMIJcjs.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 = _chunkVFLAMMIJcjs.UI_LINK_ENTITIES; exports.WORKFLOW_RESOURCES = _chunkVFLAMMIJcjs.WORKFLOW_RESOURCES; exports.aggregate = aggregate; exports.blindSurfaces = blindSurfaces; exports.buildUiLink = _chunkVFLAMMIJcjs.buildUiLink; exports.createGuidance = createGuidance; exports.dateBucketLabel = dateBucketLabel; exports.effectiveRequiredFields = _chunkVFLAMMIJcjs.effectiveRequiredFields; exports.expandResourceNames = _chunkVFLAMMIJcjs.expandResourceNames; exports.fetchByIds = _chunkVFLAMMIJcjs.fetchByIds; exports.fetchMany = _chunkVFLAMMIJcjs.fetchMany; exports.fieldCatalog = _chunkVFLAMMIJcjs.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 = _chunkVFLAMMIJcjs.uiLink; exports.unknownKeysRefusal = unknownKeysRefusal; exports.validateDispatchArgs = validateDispatchArgs; exports.validateFetchManyItems = _chunkVFLAMMIJcjs.validateFetchManyItems; exports.validateInvokeOptions = validateInvokeOptions; exports.validateParamsBag = validateParamsBag;
|