node-autotask 0.42.0 → 0.44.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 +31 -0
- package/MCP_TOOL_CATALOG.json +27 -8
- package/MCP_TOOL_MANIFEST.md +138 -137
- package/N8N_MCP_MANIFEST.json +17 -17
- package/N8N_MCP_MANIFEST.md +18 -18
- package/README.md +6 -19
- package/capabilities.json +1825 -1442
- package/dist/{base-CVx2VMSj.d.cts → base-CftidiyZ.d.cts} +2 -1
- package/dist/{base-CVx2VMSj.d.ts → base-CftidiyZ.d.ts} +2 -1
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.d.cts +2 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-HD5BRA3Z.cjs → chunk-6WLGHKIU.cjs} +286 -286
- package/dist/{chunk-TTPHVFPJ.js → chunk-7MCKJTSA.js} +3 -3
- package/dist/{chunk-5VHSLJMR.js → chunk-A6LHCJQP.js} +30 -9
- package/dist/{chunk-ZR24JGW2.js → chunk-BKTOMNT2.js} +2 -2
- package/dist/{chunk-SEFJJY4J.cjs → chunk-EMYDC5SG.cjs} +151 -120
- package/dist/{chunk-MYL34QU5.cjs → chunk-KWQSGWY5.cjs} +143 -143
- package/dist/{chunk-AETFO6BO.js → chunk-LYI5FRPX.js} +55 -24
- package/dist/{chunk-WP33PQVM.js → chunk-N6IWPGHB.js} +1824 -1441
- package/dist/{chunk-VEOSOIU4.cjs → chunk-PH3ESYAF.cjs} +1824 -1441
- package/dist/{chunk-MJTKK3QG.cjs → chunk-SN4BMQ2N.cjs} +31 -10
- package/dist/{index-Cm_Xpt7X.d.cts → index-D8FtzUGP.d.ts} +54 -41
- package/dist/{index-C3KFMnRT.d.cts → index-DgBA1JMH.d.cts} +131 -130
- package/dist/{index-C3KFMnRT.d.ts → index-DgBA1JMH.d.ts} +131 -130
- package/dist/{index-C7rMJ4IV.d.ts → index-YbEk0awP.d.cts} +54 -41
- package/dist/index.cjs +23 -23
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +5 -5
- package/dist/operations/index.cjs +337 -244
- package/dist/operations/index.d.cts +53 -45
- package/dist/operations/index.d.ts +53 -45
- package/dist/operations/index.js +121 -28
- package/dist/pool.cjs +9 -9
- package/dist/pool.d.cts +4 -3
- package/dist/pool.d.ts +4 -3
- package/dist/pool.js +5 -5
- package/dist/resources/index.cjs +5 -5
- package/dist/resources/index.d.cts +2 -2
- package/dist/resources/index.d.ts +2 -2
- package/dist/resources/index.js +4 -4
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/untrusted.cjs +2 -2
- package/dist/untrusted.d.cts +14 -5
- package/dist/untrusted.d.ts +14 -5
- package/dist/untrusted.js +1 -1
- package/docs/API.md +126 -37
- package/examples/mcp/schemas.ts +2 -0
- package/examples/mcp/tools-read.ts +3 -2
- package/package.json +17 -10
|
@@ -70,32 +70,33 @@
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
var _chunkSEFJJY4Jcjs = require('../chunk-SEFJJY4J.cjs');
|
|
74
73
|
|
|
74
|
+
var _chunkEMYDC5SGcjs = require('../chunk-EMYDC5SG.cjs');
|
|
75
75
|
|
|
76
|
-
var _chunkVEOSOIU4cjs = require('../chunk-VEOSOIU4.cjs');
|
|
77
76
|
|
|
77
|
+
var _chunkPH3ESYAFcjs = require('../chunk-PH3ESYAF.cjs');
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
|
|
80
|
+
var _chunkSN4BMQ2Ncjs = require('../chunk-SN4BMQ2N.cjs');
|
|
80
81
|
|
|
81
82
|
// src/operations/searchAcrossResources.ts
|
|
82
83
|
var DEFAULT_LIMIT = 25;
|
|
83
84
|
function resourceFor(client, key) {
|
|
84
|
-
return client[
|
|
85
|
+
return client[_chunkEMYDC5SGcjs.camelKey.call(void 0, key)];
|
|
85
86
|
}
|
|
86
87
|
async function searchAcrossResources(client, query, opts = {}) {
|
|
87
88
|
const text = query.trim();
|
|
88
89
|
if (text === "") {
|
|
89
|
-
throw new (0,
|
|
90
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("searchAcrossResources: query must be a non-empty string");
|
|
90
91
|
}
|
|
91
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
92
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkEMYDC5SGcjs.WORKFLOW_RESOURCES));
|
|
92
93
|
if (keys.length === 0) {
|
|
93
|
-
throw new (0,
|
|
94
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("searchAcrossResources: no resources requested");
|
|
94
95
|
}
|
|
95
|
-
const limit =
|
|
96
|
+
const limit = _chunkEMYDC5SGcjs.clampPageSize.call(void 0, _nullishCoalesce(opts.limit, () => ( DEFAULT_LIMIT)));
|
|
96
97
|
const totalLimit = opts.totalLimit;
|
|
97
98
|
if (totalLimit !== void 0 && !(Number.isInteger(totalLimit) && totalLimit >= 1)) {
|
|
98
|
-
throw new (0,
|
|
99
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("searchAcrossResources: totalLimit must be a positive integer");
|
|
99
100
|
}
|
|
100
101
|
const results = [];
|
|
101
102
|
const skipped = [];
|
|
@@ -126,7 +127,7 @@ async function searchAcrossResources(client, query, opts = {}) {
|
|
|
126
127
|
|
|
127
128
|
// src/operations/resolveAny.ts
|
|
128
129
|
function resourceFor2(client, key) {
|
|
129
|
-
return client[
|
|
130
|
+
return client[_chunkEMYDC5SGcjs.camelKey.call(void 0, key)];
|
|
130
131
|
}
|
|
131
132
|
var FAULT_CATEGORIES = /* @__PURE__ */ new Set(["auth", "rate_limit", "server", "network", "timeout", "policy"]);
|
|
132
133
|
function missCost(identifier) {
|
|
@@ -135,18 +136,23 @@ function missCost(identifier) {
|
|
|
135
136
|
}
|
|
136
137
|
async function resolveAny(client, identifier, opts = {}) {
|
|
137
138
|
if (typeof identifier === "number") {
|
|
138
|
-
|
|
139
|
+
_chunkEMYDC5SGcjs.parseIdentifier.call(void 0, identifier, "identifier");
|
|
139
140
|
} else if (identifier.trim() === "") {
|
|
140
|
-
throw new (0,
|
|
141
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveAny: identifier must be non-empty");
|
|
141
142
|
}
|
|
142
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
143
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkEMYDC5SGcjs.WORKFLOW_RESOURCES));
|
|
143
144
|
if (keys.length === 0) {
|
|
144
|
-
throw new (0,
|
|
145
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveAny: no resources requested");
|
|
145
146
|
}
|
|
146
147
|
const match = _nullishCoalesce(opts.match, () => ( "exact"));
|
|
147
148
|
if (match !== "exact" && match !== "auto") {
|
|
148
|
-
throw new (0,
|
|
149
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`resolveAny: match must be 'exact' or 'auto' (got ${JSON.stringify(match)})`);
|
|
150
|
+
}
|
|
151
|
+
if (opts.limit !== void 0 && (!Number.isInteger(opts.limit) || opts.limit < 1 || opts.limit > 500)) {
|
|
152
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveAny: limit must be an integer 1..500");
|
|
149
153
|
}
|
|
154
|
+
const configuredCap = Math.min(_nullishCoalesce(_optionalChain([client, 'access', _2 => _2.config, 'optionalAccess', _3 => _3.resolution, 'optionalAccess', _4 => _4.maxScanRecords]), () => ( 500)), 500);
|
|
155
|
+
const limit = Math.min(_nullishCoalesce(opts.limit, () => ( configuredCap)), configuredCap);
|
|
150
156
|
const results = [];
|
|
151
157
|
for (const key of keys) {
|
|
152
158
|
const holder = resourceFor2(client, key);
|
|
@@ -164,7 +170,7 @@ async function resolveAny(client, identifier, opts = {}) {
|
|
|
164
170
|
}
|
|
165
171
|
try {
|
|
166
172
|
const r = await holder.resolveDetailed(identifier);
|
|
167
|
-
|
|
173
|
+
const outcome = {
|
|
168
174
|
resource: key,
|
|
169
175
|
value: _nullishCoalesce(r.value, () => ( null)),
|
|
170
176
|
resolutionCost: r.resolutionCost,
|
|
@@ -172,29 +178,13 @@ async function resolveAny(client, identifier, opts = {}) {
|
|
|
172
178
|
scanTruncated: r.scanTruncated,
|
|
173
179
|
candidates: (_nullishCoalesce(r.candidates, () => ( []))).map((c) => c.id)
|
|
174
180
|
};
|
|
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
181
|
results.push(outcome);
|
|
192
182
|
} catch (err) {
|
|
193
183
|
let code;
|
|
194
184
|
let candidates = [];
|
|
195
|
-
if (err instanceof
|
|
185
|
+
if (err instanceof _chunkEMYDC5SGcjs.AutotaskConfigError) {
|
|
196
186
|
code = "CONFIG_ERROR";
|
|
197
|
-
} else if (
|
|
187
|
+
} else if (_chunkEMYDC5SGcjs.isAutotaskError.call(void 0, err)) {
|
|
198
188
|
if (FAULT_CATEGORIES.has(err.category)) throw err;
|
|
199
189
|
code = err.code;
|
|
200
190
|
if (code === "RESOLUTION_AMBIGUOUS" && err.resourceIds !== void 0) {
|
|
@@ -214,14 +204,110 @@ async function resolveAny(client, identifier, opts = {}) {
|
|
|
214
204
|
});
|
|
215
205
|
}
|
|
216
206
|
}
|
|
217
|
-
const
|
|
218
|
-
|
|
207
|
+
const cleanMiss = results.every((r) => r.value === null && r.candidates.length === 0 && !r.scanTruncated && (r.error === void 0 || r.error === "NOT_FOUND"));
|
|
208
|
+
if (match === "auto" && typeof identifier === "string" && !/^\d+$/.test(identifier.trim()) && cleanMiss) {
|
|
209
|
+
const contains = await searchAcrossResources(client, identifier, { resources: keys, limit });
|
|
210
|
+
for (const row of contains.results) {
|
|
211
|
+
const outcome = results.find((r) => r.resource === row.resource);
|
|
212
|
+
if (outcome === void 0 || row.matches.length === 0) continue;
|
|
213
|
+
const truncated = row.matches.length >= limit;
|
|
214
|
+
outcome.resolutionCost = "server-filter";
|
|
215
|
+
outcome.scanned = 0;
|
|
216
|
+
outcome.scanTruncated = truncated;
|
|
217
|
+
if (row.matches.length === 1 && !truncated) {
|
|
218
|
+
outcome.value = row.matches[0];
|
|
219
|
+
delete outcome.error;
|
|
220
|
+
} else {
|
|
221
|
+
outcome.candidates = row.matches.map((r) => r.id).filter((id) => typeof id === "number" || typeof id === "string");
|
|
222
|
+
outcome.error = truncated ? "RESOLUTION_TRUNCATED" : "RESOLUTION_AMBIGUOUS";
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { identifier, results, matches: results.filter((r) => r.value !== null).map((r) => r.resource), matched: "contains", contains };
|
|
226
|
+
}
|
|
227
|
+
return { identifier, results, matches: results.filter((r) => r.value !== null).map((r) => r.resource), matched: "exact" };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/operations/resolveStaff.ts
|
|
231
|
+
async function staffLabels(client) {
|
|
232
|
+
const out = { api: {}, labels: {}, state: "absent" };
|
|
233
|
+
try {
|
|
234
|
+
const catalog = await _chunkEMYDC5SGcjs.fieldCatalog.call(void 0, client, { resources: ["resources"], fields: ["licenseType", "userType"], labels: true });
|
|
235
|
+
const row = catalog.rows[0];
|
|
236
|
+
if (row === void 0 || row.error !== null) return { ...out, state: "error" };
|
|
237
|
+
for (const field of _nullishCoalesce(row.fields, () => ( []))) {
|
|
238
|
+
if (!_optionalChain([field, 'access', _5 => _5.picklistValues, 'optionalAccess', _6 => _6.length])) continue;
|
|
239
|
+
const labels = /* @__PURE__ */ new Map();
|
|
240
|
+
out.labels[field.name] = labels;
|
|
241
|
+
for (const value of field.picklistValues) {
|
|
242
|
+
if (typeof value.label !== "string") continue;
|
|
243
|
+
labels.set(String(value.value), value.label);
|
|
244
|
+
if (/\bapi\b/i.test(value.label)) (out.api[field.name] ??= /* @__PURE__ */ new Set()).add(String(value.value));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
out.state = Object.keys(out.api).length > 0 ? "ok" : Object.keys(out.labels).length > 0 ? "none" : "absent";
|
|
248
|
+
return out;
|
|
249
|
+
} catch (e) {
|
|
250
|
+
return { ...out, state: "error" };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function staffFilter(text, api, emailOnly) {
|
|
254
|
+
const base = [
|
|
255
|
+
{ field: "isActive", op: "eq", value: true },
|
|
256
|
+
...Object.entries(api).map(([field, values]) => ({ field, op: "notIn", value: [...values] }))
|
|
257
|
+
];
|
|
258
|
+
if (emailOnly) return [...base, { field: "email", op: "eq", value: text }];
|
|
259
|
+
const words = text.split(/\s+/);
|
|
260
|
+
const names = words.length === 1 ? [{ field: "firstName", op: "eq", value: text }, { field: "lastName", op: "eq", value: text }] : Array.from({ length: words.length - 1 }, (_, i) => ({ op: "and", items: [
|
|
261
|
+
{ field: "firstName", op: "eq", value: words.slice(0, i + 1).join(" ") },
|
|
262
|
+
{ field: "lastName", op: "eq", value: words.slice(i + 1).join(" ") }
|
|
263
|
+
] }));
|
|
264
|
+
return [...base, { op: "or", items: [{ field: "email", op: "eq", value: text }, { field: "userName", op: "eq", value: text }, ...names] }];
|
|
265
|
+
}
|
|
266
|
+
async function resolveStaff(client, identifier, opts = {}) {
|
|
267
|
+
if (!_chunkEMYDC5SGcjs.isRecord.call(void 0, opts) || ![Object.prototype, null].includes(Object.getPrototypeOf(opts))) {
|
|
268
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveStaff: opts must be a plain options object");
|
|
269
|
+
}
|
|
270
|
+
const keys = ["emailOnly", "includeApiUsers", "limit"];
|
|
271
|
+
const unknown = Object.keys(opts).filter((key) => !keys.includes(key));
|
|
272
|
+
if (unknown.length > 0) {
|
|
273
|
+
const listed = unknown.slice(0, 10).map((key) => JSON.stringify(key.length > 40 ? `${key.slice(0, 40)}\u2026` : key)).join(", ");
|
|
274
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`resolveStaff: unknown opts key(s) ${listed}${unknown.length > 10 ? ` (and ${unknown.length - 10} more)` : ""} \u2014 the bag is closed: ${keys.join(", ")}`);
|
|
275
|
+
}
|
|
276
|
+
for (const key of ["emailOnly", "includeApiUsers"]) {
|
|
277
|
+
if (opts[key] !== void 0 && typeof opts[key] !== "boolean") {
|
|
278
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`resolveStaff: ${key} must be a boolean`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const limit = opts.limit === void 0 ? 10 : opts.limit;
|
|
282
|
+
if (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1 || limit > 10) throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveStaff: limit must be an integer 1..10");
|
|
283
|
+
if (typeof identifier !== "number" && typeof identifier !== "string") throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveStaff: identifier must be a number or string");
|
|
284
|
+
const text = String(identifier).trim();
|
|
285
|
+
if (text === "") throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("resolveStaff: identifier must be non-empty");
|
|
286
|
+
if (typeof identifier === "number") _chunkEMYDC5SGcjs.parseIdentifier.call(void 0, identifier, "resolveStaff identifier");
|
|
287
|
+
const id = !opts.emailOnly && (typeof identifier === "number" || /^\d+$/.test(text)) ? _chunkEMYDC5SGcjs.parseIdentifier.call(void 0, identifier, "resolveStaff identifier") : void 0;
|
|
288
|
+
const meta = await staffLabels(client);
|
|
289
|
+
const isApi = (record) => Object.entries(meta.api).some(([field, values]) => record[field] != null && values.has(String(record[field])));
|
|
290
|
+
const match = (record) => {
|
|
291
|
+
const known = meta.state === "ok" && Object.entries(meta.labels).some(([field, labels]) => record[field] != null && labels.has(String(record[field])));
|
|
292
|
+
const label = _optionalChain([meta, 'access', _7 => _7.labels, 'access', _8 => _8.licenseType, 'optionalAccess', _9 => _9.get, 'call', _10 => _10(String(record.licenseType))]);
|
|
293
|
+
return { record, ...known ? { apiUser: isApi(record) } : {}, ...label === void 0 ? {} : { licenseTypeLabel: label } };
|
|
294
|
+
};
|
|
295
|
+
if (id !== void 0) {
|
|
296
|
+
const record = await client.resources.get(id);
|
|
297
|
+
const matches = [match(record)];
|
|
298
|
+
return { identifier, lookup: "id", matches, matchedCount: matches.length, truncated: false, metadataState: meta.state };
|
|
299
|
+
}
|
|
300
|
+
const page = await client.resources.queryBounded({ filter: staffFilter(text, opts.includeApiUsers ? {} : meta.api, opts.emailOnly === true), limit: 50 });
|
|
301
|
+
const rawRows = page.items;
|
|
302
|
+
const labelled = _chunkEMYDC5SGcjs.readNamesOpt.call(void 0, client, void 0, "resolveStaff") ? await _chunkEMYDC5SGcjs.labelRows.call(void 0, client, "resources", rawRows) : void 0;
|
|
303
|
+
const rows = (_nullishCoalesce(_optionalChain([labelled, 'optionalAccess', _11 => _11.rows]), () => ( rawRows))).filter((record) => opts.includeApiUsers || !isApi(record)).sort((a, b) => Number(isApi(a)) - Number(isApi(b)));
|
|
304
|
+
return { identifier, lookup: "text", matches: rows.slice(0, limit).map(match), matchedCount: rows.length, truncated: page.hasMore || rows.length > limit, metadataState: meta.state, ..._optionalChain([labelled, 'optionalAccess', _12 => _12.names]) === void 0 ? {} : { names: labelled.names } };
|
|
219
305
|
}
|
|
220
306
|
|
|
221
307
|
// src/operations/aggregate.ts
|
|
222
308
|
var AGGREGATE_TOP_MAX = 100;
|
|
223
309
|
var AGGREGATE_DEFAULT_TOP = 25;
|
|
224
|
-
var AGGREGATE_DEFAULT_LIMIT =
|
|
310
|
+
var AGGREGATE_DEFAULT_LIMIT = _chunkEMYDC5SGcjs.BOUNDED_QUERY_MAX_LIMIT;
|
|
225
311
|
var AGGREGATE_DATE_BUCKETS = ["month", "week", "year"];
|
|
226
312
|
var DATE_ONLY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
227
313
|
var DATETIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
@@ -278,7 +364,7 @@ function dateBucketLabel(value, bucket) {
|
|
|
278
364
|
}
|
|
279
365
|
var QUERY_RESOURCE_KEYS = (() => {
|
|
280
366
|
const s = /* @__PURE__ */ new Set();
|
|
281
|
-
for (const rec of
|
|
367
|
+
for (const rec of _chunkPH3ESYAFcjs.CAPABILITIES) if (rec.operation === "query") s.add(rec.resource);
|
|
282
368
|
return s;
|
|
283
369
|
})();
|
|
284
370
|
var AGGREGATE_OPT_KEYS = ["groupBy", "sum", "top", "limit", "names", "acknowledgeUnscoped"];
|
|
@@ -314,15 +400,15 @@ function parseFilterConditions(filter, problems) {
|
|
|
314
400
|
return [];
|
|
315
401
|
}
|
|
316
402
|
try {
|
|
317
|
-
return
|
|
403
|
+
return _chunkEMYDC5SGcjs.buildFilter.call(void 0, conds).filter;
|
|
318
404
|
} catch (err) {
|
|
319
|
-
problems.push(err instanceof
|
|
405
|
+
problems.push(err instanceof _chunkEMYDC5SGcjs.AutotaskConfigError ? err.message : `filter must be the query-bag filter (13 operators; caps 500 OR-conditions / 1 UDF / 8000 chars); ${String(err)}`);
|
|
320
406
|
return [];
|
|
321
407
|
}
|
|
322
408
|
}
|
|
323
409
|
function checkOptsBag(opts, problems) {
|
|
324
410
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
325
|
-
throw new (0,
|
|
411
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
326
412
|
`aggregate: opts must be the options object (got ${Array.isArray(opts) ? "an array" : typeof opts})`,
|
|
327
413
|
{ operation: "operations.aggregate" }
|
|
328
414
|
);
|
|
@@ -332,8 +418,8 @@ function checkOptsBag(opts, problems) {
|
|
|
332
418
|
problems.push(`unknown opts key "${key}" \u2014 the bag is closed: ${AGGREGATE_OPT_KEYS.join(", ")}`);
|
|
333
419
|
}
|
|
334
420
|
}
|
|
335
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
336
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
421
|
+
if (_optionalChain([opts, 'optionalAccess', _13 => _13.names]) !== void 0 && typeof opts.names !== "boolean") problems.push(`names must be a boolean (got ${typeof opts.names})`);
|
|
422
|
+
if (_optionalChain([opts, 'optionalAccess', _14 => _14.acknowledgeUnscoped]) !== void 0 && typeof opts.acknowledgeUnscoped !== "boolean") {
|
|
337
423
|
problems.push(`acknowledgeUnscoped must be a boolean (got ${typeof opts.acknowledgeUnscoped})`);
|
|
338
424
|
}
|
|
339
425
|
}
|
|
@@ -389,18 +475,18 @@ function parseTopAndLimit(opts, problems) {
|
|
|
389
475
|
if (!Number.isInteger(opts.limit)) {
|
|
390
476
|
problems.push(`limit must be an integer (got ${String(opts.limit)})`);
|
|
391
477
|
} else {
|
|
392
|
-
limit = Math.min(Math.max(opts.limit, 1),
|
|
478
|
+
limit = Math.min(Math.max(opts.limit, 1), _chunkEMYDC5SGcjs.BOUNDED_QUERY_MAX_LIMIT);
|
|
393
479
|
}
|
|
394
480
|
}
|
|
395
481
|
return { top, limit };
|
|
396
482
|
}
|
|
397
483
|
async function checkFieldNames(resourceKey, conditions, opts, problems) {
|
|
398
|
-
const record = resourceKey === void 0 ? void 0 :
|
|
484
|
+
const record = resourceKey === void 0 ? void 0 : _chunkPH3ESYAFcjs.CAPABILITIES.find((r) => r.resource === resourceKey && r.operation === "query");
|
|
399
485
|
if (record === void 0) return void 0;
|
|
400
486
|
const strings = (v) => Array.isArray(v) ? v.filter((f) => typeof f === "string" && f.trim() !== "") : [];
|
|
401
487
|
const groupBy = strings(opts.groupBy);
|
|
402
|
-
const found = await
|
|
403
|
-
filter:
|
|
488
|
+
const found = await _chunkEMYDC5SGcjs.findUnknownFieldNames.call(void 0, record, void 0, {
|
|
489
|
+
filter: _chunkEMYDC5SGcjs.collectFilterFieldNames.call(void 0, conditions, resourceKey, "operations.aggregate"),
|
|
404
490
|
groupBy: groupBy.map((f) => f.split("@")[0]),
|
|
405
491
|
sum: strings(opts.sum)
|
|
406
492
|
});
|
|
@@ -422,23 +508,30 @@ async function validateAggregate(operation, filter, opts) {
|
|
|
422
508
|
const resourceKey = parseOperationKey(operation, problems);
|
|
423
509
|
const conditions = parseFilterConditions(filter, problems);
|
|
424
510
|
checkOptsBag(opts, problems);
|
|
511
|
+
if (resourceKey !== void 0) {
|
|
512
|
+
opts = {
|
|
513
|
+
...opts,
|
|
514
|
+
...Array.isArray(opts.groupBy) ? { groupBy: opts.groupBy.map((f) => typeof f === "string" ? _chunkEMYDC5SGcjs.normalizeOwnField.call(void 0, resourceKey, f) : f) } : {},
|
|
515
|
+
...Array.isArray(opts.sum) ? { sum: opts.sum.map((f) => typeof f === "string" ? _chunkEMYDC5SGcjs.normalizeOwnField.call(void 0, resourceKey, f) : f) } : {}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
425
518
|
const oracles = {
|
|
426
519
|
resourceKey,
|
|
427
|
-
dateSets: resourceKey !== void 0 ?
|
|
520
|
+
dateSets: resourceKey !== void 0 ? _chunkEMYDC5SGcjs.MODEL_DATE_FIELDS[resourceKey] : void 0
|
|
428
521
|
};
|
|
429
522
|
const known = await checkFieldNames(resourceKey, conditions, opts, problems);
|
|
430
523
|
const groupBy = parseGroupBy(opts, oracles, known, problems);
|
|
431
524
|
const sum = checkSumFields("sum", opts.sum, problems);
|
|
432
525
|
const { top, limit } = parseTopAndLimit(opts, problems);
|
|
433
526
|
if (problems.length > 0) {
|
|
434
|
-
throw new (0,
|
|
527
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
435
528
|
`aggregate: ${problems.length} problem(s) found pre-request (zero wire was issued)
|
|
436
529
|
- ` + problems.join("\n- "),
|
|
437
530
|
{ operation: "operations.aggregate" }
|
|
438
531
|
);
|
|
439
532
|
}
|
|
440
533
|
if ((groupBy.length > 0 || sum.length > 0) && conditions.length === 0 && opts.acknowledgeUnscoped !== true) {
|
|
441
|
-
throw new (0,
|
|
534
|
+
throw new (0, _chunkEMYDC5SGcjs.ScopeRequiredError)(operation, { threshold: _chunkEMYDC5SGcjs.UNSCOPED_WALK_THRESHOLD }, "empty-filter");
|
|
442
535
|
}
|
|
443
536
|
return { resourceKey, conditions, groupBy, sum, top, limit };
|
|
444
537
|
}
|
|
@@ -468,9 +561,9 @@ function foldGroups(items, v) {
|
|
|
468
561
|
}
|
|
469
562
|
async function aggregate(client, operation, filter, opts = {}) {
|
|
470
563
|
const v = await validateAggregate(operation, filter, opts);
|
|
471
|
-
const holder = client[
|
|
564
|
+
const holder = client[_chunkEMYDC5SGcjs.camelKey.call(void 0, v.resourceKey)];
|
|
472
565
|
if (holder === void 0) {
|
|
473
|
-
throw new (0,
|
|
566
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`aggregate: the client exposes no accessor for resource "${v.resourceKey}"`, {
|
|
474
567
|
operation: "operations.aggregate",
|
|
475
568
|
suggestedAction: "Rebuild the client from the SDK build that ships this registry (the resource set is pinned by the plan)."
|
|
476
569
|
});
|
|
@@ -487,11 +580,11 @@ async function aggregate(client, operation, filter, opts = {}) {
|
|
|
487
580
|
const res = await holder.queryBounded({ filter: wireFilter, limit: v.limit });
|
|
488
581
|
const sorted = foldGroups(res.items, v);
|
|
489
582
|
const top = sorted.slice(0, v.top);
|
|
490
|
-
const label =
|
|
491
|
-
const labelled = !label || v.groupBy.length === 0 ? void 0 : await
|
|
583
|
+
const label = _chunkEMYDC5SGcjs.readNamesOpt.call(void 0, client, opts.names, "aggregate");
|
|
584
|
+
const labelled = !label || v.groupBy.length === 0 ? void 0 : await _chunkEMYDC5SGcjs.labelRows.call(void 0, client, v.resourceKey, top.map((g) => g.key));
|
|
492
585
|
const result = {
|
|
493
586
|
mode: v.groupBy.length > 0 ? "group" : "sum",
|
|
494
|
-
groups: top.map((g, i) => ({ key: _nullishCoalesce(_optionalChain([labelled, 'optionalAccess',
|
|
587
|
+
groups: top.map((g, i) => ({ key: _nullishCoalesce(_optionalChain([labelled, 'optionalAccess', _15 => _15.rows, 'access', _16 => _16[i]]), () => ( g.key)), count: g.count, ...g.sums !== void 0 ? { sums: g.sums } : {} })),
|
|
495
588
|
totalGroups: sorted.length,
|
|
496
589
|
groupsTruncated: sorted.length > top.length,
|
|
497
590
|
totalScanned: res.fetched,
|
|
@@ -502,7 +595,7 @@ async function aggregate(client, operation, filter, opts = {}) {
|
|
|
502
595
|
if (res.blindSurface !== void 0) result.blindSurface = res.blindSurface;
|
|
503
596
|
if (res.emptyReason !== void 0) result.emptyReason = res.emptyReason;
|
|
504
597
|
if (res.relationNote !== void 0) result.relationNote = res.relationNote;
|
|
505
|
-
if (_optionalChain([labelled, 'optionalAccess',
|
|
598
|
+
if (_optionalChain([labelled, 'optionalAccess', _17 => _17.names]) !== void 0) result.names = labelled.names;
|
|
506
599
|
return result;
|
|
507
600
|
}
|
|
508
601
|
|
|
@@ -521,12 +614,12 @@ var DEFAULT_CONTRACT_TYPE_RE = /^\s*(recurring|fixed)\b/i;
|
|
|
521
614
|
var CONTRACTS_PATH = "/V1.0/Contracts";
|
|
522
615
|
var COMPANIES_PATH = "/V1.0/Companies";
|
|
523
616
|
var BILLING_ITEMS_PATH = "/V1.0/BillingItems";
|
|
524
|
-
var LINE_TYPE_FIELDS = ["billingItemType", "timeEntryID", "expenseItemID", ...
|
|
525
|
-
var isLabour = (line) =>
|
|
617
|
+
var LINE_TYPE_FIELDS = ["billingItemType", "timeEntryID", "expenseItemID", ..._chunkEMYDC5SGcjs.CHARGE_LINE_FKS, ..._chunkEMYDC5SGcjs.SERVICE_LINE_FKS];
|
|
618
|
+
var isLabour = (line) => _chunkEMYDC5SGcjs.billingLineType.call(void 0, line) === "labour";
|
|
526
619
|
function picklistKey(c, dim, path, field, raw, missing) {
|
|
527
|
-
const id =
|
|
620
|
+
const id = _chunkEMYDC5SGcjs.num.call(void 0, raw);
|
|
528
621
|
if (id === 0) return { id: null, label: missing };
|
|
529
|
-
const label = _optionalChain([c, 'access',
|
|
622
|
+
const label = _optionalChain([c, 'access', _18 => _18.labels, 'access', _19 => _19[path], 'optionalAccess', _20 => _20.get, 'call', _21 => _21(field), 'optionalAccess', _22 => _22.get, 'call', _23 => _23(id)]);
|
|
530
623
|
if (label === void 0) {
|
|
531
624
|
c.unlabelled.add(`${dim}: ${field} value ${id} has no label on the live ${path} picklist (id-only)`);
|
|
532
625
|
return { id };
|
|
@@ -537,7 +630,7 @@ var DIMENSIONS = {
|
|
|
537
630
|
vertical: {
|
|
538
631
|
joins: { companies: ["marketSegmentID"] },
|
|
539
632
|
picklist: COMPANIES_PATH,
|
|
540
|
-
key: (c) => picklistKey(c, "vertical", COMPANIES_PATH, "marketSegmentID", _optionalChain([c, 'access',
|
|
633
|
+
key: (c) => picklistKey(c, "vertical", COMPANIES_PATH, "marketSegmentID", _optionalChain([c, 'access', _24 => _24.company, 'optionalAccess', _25 => _25["marketSegmentID"]]), "unassigned")
|
|
541
634
|
},
|
|
542
635
|
contractType: {
|
|
543
636
|
key: (c) => picklistKey(c, "contractType", CONTRACTS_PATH, "contractType", c.contract["contractType"], "none")
|
|
@@ -547,7 +640,7 @@ var DIMENSIONS = {
|
|
|
547
640
|
},
|
|
548
641
|
company: {
|
|
549
642
|
joins: { companies: ["companyName"] },
|
|
550
|
-
key: (c) => ({ id:
|
|
643
|
+
key: (c) => ({ id: _chunkEMYDC5SGcjs.num.call(void 0, c.line["companyID"]), name: String(_nullishCoalesce(_optionalChain([c, 'access', _26 => _26.company, 'optionalAccess', _27 => _27["companyName"]]), () => ( ""))) })
|
|
551
644
|
},
|
|
552
645
|
month: {
|
|
553
646
|
key: (c) => ({ id: c.invoice.month })
|
|
@@ -555,11 +648,11 @@ var DIMENSIONS = {
|
|
|
555
648
|
billingItemKind: {
|
|
556
649
|
lineFields: LINE_TYPE_FIELDS,
|
|
557
650
|
picklist: BILLING_ITEMS_PATH,
|
|
558
|
-
key: (c) =>
|
|
651
|
+
key: (c) => _chunkEMYDC5SGcjs.num.call(void 0, c.line["billingItemType"]) === 0 ? { id: _chunkEMYDC5SGcjs.billingLineType.call(void 0, c.line), label: _chunkEMYDC5SGcjs.billingLineType.call(void 0, c.line) } : picklistKey(c, "billingItemKind", BILLING_ITEMS_PATH, "billingItemType", c.line["billingItemType"], "other")
|
|
559
652
|
},
|
|
560
653
|
contract: {
|
|
561
654
|
joins: { contracts: ["contractName"] },
|
|
562
|
-
key: (c) => ({ id:
|
|
655
|
+
key: (c) => ({ id: _chunkEMYDC5SGcjs.num.call(void 0, c.line["contractID"]), name: String(_nullishCoalesce(c.contract["contractName"], () => ( ""))) })
|
|
563
656
|
},
|
|
564
657
|
// Per line (no contract-pointer fallback): association → level2 (the Line of Business, `name`) + level1 (the division).
|
|
565
658
|
lineOfBusiness: {
|
|
@@ -567,11 +660,11 @@ var DIMENSIONS = {
|
|
|
567
660
|
joins: { organizationalLevelAssociations: [], organizationalLevel1s: [], organizationalLevel2s: [] },
|
|
568
661
|
unresolved: "unresolvedAssociations",
|
|
569
662
|
key: (c) => {
|
|
570
|
-
const id =
|
|
663
|
+
const id = _chunkEMYDC5SGcjs.num.call(void 0, c.line["organizationalLevelAssociationID"]);
|
|
571
664
|
if (id === 0) return { id: null, label: "no LOB assigned" };
|
|
572
665
|
const a = c.joined.organizationalLevelAssociations.get(id);
|
|
573
|
-
const l1 = c.joined.organizationalLevel1s.get(
|
|
574
|
-
const l2 = c.joined.organizationalLevel2s.get(
|
|
666
|
+
const l1 = c.joined.organizationalLevel1s.get(_chunkEMYDC5SGcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _28 => _28["organizationalLevel1ID"]])));
|
|
667
|
+
const l2 = c.joined.organizationalLevel2s.get(_chunkEMYDC5SGcjs.num.call(void 0, _optionalChain([a, 'optionalAccess', _29 => _29["organizationalLevel2ID"]])));
|
|
575
668
|
if (l1 === void 0 || l2 === void 0) return "unresolvedAssociations";
|
|
576
669
|
return { id, name: String(_nullishCoalesce(l2["name"], () => ( ""))), division: String(_nullishCoalesce(l1["name"], () => ( ""))) };
|
|
577
670
|
}
|
|
@@ -582,9 +675,9 @@ var DIMENSIONS = {
|
|
|
582
675
|
joins: { timeEntries: [], resources: [] },
|
|
583
676
|
unresolved: "unresolvedTimeEntries",
|
|
584
677
|
key: (c) => {
|
|
585
|
-
const te =
|
|
678
|
+
const te = _chunkEMYDC5SGcjs.num.call(void 0, c.line["timeEntryID"]);
|
|
586
679
|
if (!isLabour(c.line) || te === 0) return { id: null, label: "n/a" };
|
|
587
|
-
const id =
|
|
680
|
+
const id = _chunkEMYDC5SGcjs.num.call(void 0, _optionalChain([c, 'access', _30 => _30.joined, 'access', _31 => _31.timeEntries, 'access', _32 => _32.get, 'call', _33 => _33(te), 'optionalAccess', _34 => _34["resourceID"]]));
|
|
588
681
|
const r = c.joined.resources.get(id);
|
|
589
682
|
if (r === void 0) return "unresolvedTimeEntries";
|
|
590
683
|
return { id, name: `${String(_nullishCoalesce(r["firstName"], () => ( "")))} ${String(_nullishCoalesce(r["lastName"], () => ( "")))}`.trim() };
|
|
@@ -595,58 +688,58 @@ var DIMENSIONS = {
|
|
|
595
688
|
joins: { billingCodes: [] },
|
|
596
689
|
unresolved: "unresolvedBillingCodes",
|
|
597
690
|
key: (c) => {
|
|
598
|
-
const id =
|
|
691
|
+
const id = _chunkEMYDC5SGcjs.num.call(void 0, c.line["billingCodeID"]);
|
|
599
692
|
if (id === 0) return { id: null, label: "none" };
|
|
600
693
|
const b = c.joined.billingCodes.get(id);
|
|
601
694
|
return b === void 0 ? "unresolvedBillingCodes" : { id, name: String(_nullishCoalesce(b["name"], () => ( ""))) };
|
|
602
695
|
}
|
|
603
696
|
}
|
|
604
697
|
};
|
|
605
|
-
var fk = (rows, field) => [...rows].map((r) =>
|
|
698
|
+
var fk = (rows, field) => [...rows].map((r) => _chunkEMYDC5SGcjs.num.call(void 0, r[field]));
|
|
606
699
|
var ONE_CHUNK = (idChunks) => Math.min(1, idChunks);
|
|
607
700
|
var JOINS = {
|
|
608
701
|
contracts: {
|
|
609
|
-
make: (http) => new (0,
|
|
702
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.ContractsResource)(http, PAGE),
|
|
610
703
|
fields: ["id", "contractType", "contractCategory"],
|
|
611
704
|
ids: (lines) => fk(lines, "contractID")
|
|
612
705
|
},
|
|
613
706
|
companies: {
|
|
614
|
-
make: (http) => new (0,
|
|
707
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.CompaniesResource)(http, PAGE),
|
|
615
708
|
fields: ["id"],
|
|
616
709
|
ids: (lines) => fk(lines, "companyID")
|
|
617
710
|
},
|
|
618
711
|
organizationalLevelAssociations: {
|
|
619
|
-
make: (http) => new (0,
|
|
712
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.OrganizationalLevelAssociationsResource)(http, PAGE),
|
|
620
713
|
fields: ["id", "organizationalLevel1ID", "organizationalLevel2ID"],
|
|
621
714
|
ids: (lines) => fk(lines, "organizationalLevelAssociationID")
|
|
622
715
|
},
|
|
623
716
|
organizationalLevel1s: {
|
|
624
|
-
make: (http) => new (0,
|
|
717
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.OrganizationalLevel1sResource)(http, PAGE),
|
|
625
718
|
fields: ["id", "name"],
|
|
626
719
|
ids: (_, j) => fk(j["organizationalLevelAssociations"].values(), "organizationalLevel1ID"),
|
|
627
720
|
chunks: ONE_CHUNK
|
|
628
721
|
},
|
|
629
722
|
organizationalLevel2s: {
|
|
630
|
-
make: (http) => new (0,
|
|
723
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.OrganizationalLevel2sResource)(http, PAGE),
|
|
631
724
|
fields: ["id", "name"],
|
|
632
725
|
ids: (_, j) => fk(j["organizationalLevelAssociations"].values(), "organizationalLevel2ID"),
|
|
633
726
|
chunks: ONE_CHUNK
|
|
634
727
|
},
|
|
635
728
|
timeEntries: {
|
|
636
|
-
make: (http) => new (0,
|
|
729
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.TimeEntriesResource)(http, PAGE),
|
|
637
730
|
fields: ["id", "resourceID"],
|
|
638
731
|
ids: (lines) => fk(lines.filter(isLabour), "timeEntryID"),
|
|
639
732
|
// One time entry per labour line: the line count is the upper bound (labour share unknown pre-walk).
|
|
640
733
|
chunks: (_, lines) => pages(lines)
|
|
641
734
|
},
|
|
642
735
|
resources: {
|
|
643
|
-
make: (http, client) => new (0,
|
|
736
|
+
make: (http, client) => new (0, _chunkEMYDC5SGcjs.ResourcesResource)(http, client.config, PAGE),
|
|
644
737
|
fields: ["id", "firstName", "lastName"],
|
|
645
738
|
ids: (_, j) => fk(j["timeEntries"].values(), "resourceID"),
|
|
646
739
|
chunks: ONE_CHUNK
|
|
647
740
|
},
|
|
648
741
|
billingCodes: {
|
|
649
|
-
make: (http) => new (0,
|
|
742
|
+
make: (http) => new (0, _chunkEMYDC5SGcjs.BillingCodesResource)(http, PAGE),
|
|
650
743
|
fields: ["id", "name"],
|
|
651
744
|
ids: (lines) => fk(lines, "billingCodeID")
|
|
652
745
|
}
|
|
@@ -681,7 +774,7 @@ function checkInt(name, v, def, max, problems) {
|
|
|
681
774
|
}
|
|
682
775
|
function validate(opts) {
|
|
683
776
|
if (typeof opts !== "object" || opts === null || Array.isArray(opts)) {
|
|
684
|
-
throw new (0,
|
|
777
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("revenueRollup: opts must be the options object { <scope>, dateFrom, dateTo, ... } (zero wire was issued)", { operation: OP });
|
|
685
778
|
}
|
|
686
779
|
const o = opts;
|
|
687
780
|
const problems = [];
|
|
@@ -698,12 +791,12 @@ function validate(opts) {
|
|
|
698
791
|
if (scopeKind === "tenantWide" && o.tenantWide !== true) problems.push("tenantWide must be exactly true");
|
|
699
792
|
}
|
|
700
793
|
const { dateFrom, dateTo } = o;
|
|
701
|
-
if (!
|
|
794
|
+
if (!_chunkEMYDC5SGcjs.isDateYMD.call(void 0, dateFrom) || !_chunkEMYDC5SGcjs.isDateYMD.call(void 0, dateTo)) {
|
|
702
795
|
problems.push("dateFrom and dateTo are both required as YYYY-MM-DD (the window is inclusive, whole UTC days)");
|
|
703
796
|
} else if (dateFrom > dateTo) {
|
|
704
797
|
problems.push(`dateFrom ${dateFrom} is after dateTo ${dateTo}`);
|
|
705
|
-
} else if (
|
|
706
|
-
problems.push(`the window spans ${
|
|
798
|
+
} else if (_chunkEMYDC5SGcjs.monthsInWindow.call(void 0, dateFrom, dateTo) > _chunkEMYDC5SGcjs.PROFITABILITY_MAX_WINDOW_MONTHS) {
|
|
799
|
+
problems.push(`the window spans ${_chunkEMYDC5SGcjs.monthsInWindow.call(void 0, dateFrom, dateTo)} months; the cap is ${_chunkEMYDC5SGcjs.PROFITABILITY_MAX_WINDOW_MONTHS}`);
|
|
707
800
|
}
|
|
708
801
|
let groupBy = [...DEFAULT_GROUP_BY];
|
|
709
802
|
if (o.groupBy !== void 0) {
|
|
@@ -730,7 +823,7 @@ function validate(opts) {
|
|
|
730
823
|
};
|
|
731
824
|
if (o.includeNonChargeable !== void 0 && typeof o.includeNonChargeable !== "boolean") problems.push("includeNonChargeable must be a boolean");
|
|
732
825
|
if (problems.length > 0) {
|
|
733
|
-
throw new (0,
|
|
826
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`revenueRollup: ${problems.length} problem(s) found pre-request (zero wire was issued)
|
|
734
827
|
- ${problems.join("\n- ")}`, { operation: OP });
|
|
735
828
|
}
|
|
736
829
|
return v;
|
|
@@ -748,7 +841,7 @@ function resolveSelector(name, sel, values) {
|
|
|
748
841
|
}
|
|
749
842
|
function unmatched(name, what, values) {
|
|
750
843
|
const live = [...values].map(([id, l]) => `${id} ${l}`).join("; ") || "(the picklist serves no values)";
|
|
751
|
-
return new (0,
|
|
844
|
+
return new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`revenueRollup: ${name}: ${what}. Live values (id label): ${live}`, {
|
|
752
845
|
operation: OP,
|
|
753
846
|
suggestedAction: `Pass ${name} as ids or exact labels from the live list.`
|
|
754
847
|
});
|
|
@@ -759,10 +852,10 @@ var chunk = (a) => {
|
|
|
759
852
|
for (let i = 0; i < a.length; i += PAGE) out.push(a.slice(i, i + PAGE));
|
|
760
853
|
return out;
|
|
761
854
|
};
|
|
762
|
-
var byId = (rows) => [...new Map(rows.map((r) => [
|
|
763
|
-
var cents = (v) => Math.round(
|
|
764
|
-
var revC = (line) => cents(
|
|
765
|
-
var extC = (line) => cents(
|
|
855
|
+
var byId = (rows) => [...new Map(rows.map((r) => [_chunkEMYDC5SGcjs.num.call(void 0, r["id"]), r])).values()];
|
|
856
|
+
var cents = (v) => Math.round(_chunkEMYDC5SGcjs.num.call(void 0, v) * 100);
|
|
857
|
+
var revC = (line) => cents(_chunkEMYDC5SGcjs.internalAmount.call(void 0, line, "internalCurrencyTotalAmount", "totalAmount"));
|
|
858
|
+
var extC = (line) => cents(_chunkEMYDC5SGcjs.internalAmount.call(void 0, line, "internalCurrencyExtendedPrice", "extendedPrice"));
|
|
766
859
|
var INTERNAL_FIELDS = ["internalCurrencyTotalAmount", "internalCurrencyExtendedPrice"];
|
|
767
860
|
var lacksInternal = (line) => INTERNAL_FIELDS.some((k) => !Number.isFinite(line[k]));
|
|
768
861
|
var money = (c) => c / 100;
|
|
@@ -773,7 +866,7 @@ async function collect(res, filter, includeFields) {
|
|
|
773
866
|
return out;
|
|
774
867
|
}
|
|
775
868
|
function blindCount() {
|
|
776
|
-
return new (0,
|
|
869
|
+
return new (0, _chunkEMYDC5SGcjs.AutotaskError)("revenueRollup: a gate count came back blind (unknown, not zero); the roll-up cannot be sized", {
|
|
777
870
|
code: "INVALID_RESPONSE",
|
|
778
871
|
category: "server",
|
|
779
872
|
operation: OP,
|
|
@@ -783,7 +876,7 @@ function blindCount() {
|
|
|
783
876
|
}
|
|
784
877
|
function countMismatch(what, streamed, counted, rows) {
|
|
785
878
|
const rowNote = rows !== void 0 && rows !== streamed ? ` (${rows} rows)` : "";
|
|
786
|
-
return new (0,
|
|
879
|
+
return new (0, _chunkEMYDC5SGcjs.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`, {
|
|
787
880
|
code: "INVALID_RESPONSE",
|
|
788
881
|
category: "server",
|
|
789
882
|
operation: OP,
|
|
@@ -792,7 +885,7 @@ function countMismatch(what, streamed, counted, rows) {
|
|
|
792
885
|
});
|
|
793
886
|
}
|
|
794
887
|
function budgetError(message, details, suggestedAction) {
|
|
795
|
-
return new (0,
|
|
888
|
+
return new (0, _chunkEMYDC5SGcjs.AutotaskError)(message, { code: "BUDGET_EXCEEDED", category: "policy", operation: OP, details, suggestedAction });
|
|
796
889
|
}
|
|
797
890
|
function lastMonthsFrom(dateTo, months) {
|
|
798
891
|
return new Date(Date.UTC(Number(dateTo.slice(0, 4)), Number(dateTo.slice(5, 7)) - months, 1)).toISOString().slice(0, 10);
|
|
@@ -825,7 +918,7 @@ async function revenueRollup(client, opts) {
|
|
|
825
918
|
const groupDims = v.groupBy.map((d) => DIMENSIONS[d]);
|
|
826
919
|
const paths = [.../* @__PURE__ */ new Set([CONTRACTS_PATH, ...groupDims.flatMap((d) => d.picklist ? [d.picklist] : [])])];
|
|
827
920
|
const labels = {};
|
|
828
|
-
for (const p of paths) labels[p] = await
|
|
921
|
+
for (const p of paths) labels[p] = await _chunkEMYDC5SGcjs.readPicklists.call(void 0, http, p, OP);
|
|
829
922
|
const contractLabels = labels[CONTRACTS_PATH];
|
|
830
923
|
const typeValues = _nullishCoalesce(contractLabels.get("contractType"), () => ( /* @__PURE__ */ new Map()));
|
|
831
924
|
const inTypes = v.contractTypes ? resolveSelector("contractTypes", v.contractTypes, typeValues) : new Map([...typeValues].filter(([, l]) => DEFAULT_CONTRACT_TYPE_RE.test(l)));
|
|
@@ -834,23 +927,23 @@ async function revenueRollup(client, opts) {
|
|
|
834
927
|
let scopeIds = v.scopeIds;
|
|
835
928
|
if (v.scopeKind === "ownerResourceID") {
|
|
836
929
|
const owned = /* @__PURE__ */ new Set();
|
|
837
|
-
for await (const c of new (0,
|
|
838
|
-
const id =
|
|
930
|
+
for await (const c of new (0, _chunkEMYDC5SGcjs.CompaniesResource)(http, PAGE).query({ filter: [{ field: "ownerResourceID", op: "eq", value: v.ownerResourceID }], includeFields: ["id"], maxRecords: PAGE, names: false })) {
|
|
931
|
+
const id = _chunkEMYDC5SGcjs.num.call(void 0, c.id);
|
|
839
932
|
if (id > 0) owned.add(id);
|
|
840
933
|
if (owned.size > SCOPE_IDS_MAX) break;
|
|
841
934
|
}
|
|
842
935
|
scopeIds = [...owned].sort((a, b) => a - b);
|
|
843
936
|
if (scopeIds.length === 0 || scopeIds.length > SCOPE_IDS_MAX) {
|
|
844
|
-
throw new (0,
|
|
937
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
845
938
|
`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)`,
|
|
846
939
|
{ operation: OP, suggestedAction: "Pass companyIDs explicitly, or tenantWide: true." }
|
|
847
940
|
);
|
|
848
941
|
}
|
|
849
942
|
}
|
|
850
943
|
const scopeCond = scopeIds === void 0 ? [] : [{ field: v.scopeKind === "contractIDs" ? "contractID" : "companyID", op: "in", value: scopeIds }];
|
|
851
|
-
const invoices = new (0,
|
|
852
|
-
const billingItems = new (0,
|
|
853
|
-
const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value:
|
|
944
|
+
const invoices = new (0, _chunkEMYDC5SGcjs.InvoicesResource)(http, PAGE);
|
|
945
|
+
const billingItems = new (0, _chunkEMYDC5SGcjs.BillingItemsResource)(http, PAGE);
|
|
946
|
+
const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value: _chunkEMYDC5SGcjs.dayAfter.call(void 0, v.dateTo) }];
|
|
854
947
|
const invoiceFilter = (voided2) => [...windowOn("invoiceDateTime"), { field: "isVoided", op: "eq", value: voided2 }];
|
|
855
948
|
const withVoided = v.scopeKind !== "contractIDs";
|
|
856
949
|
const voidedFilter = [...invoiceFilter(true), ...scopeIds !== void 0 && withVoided ? [{ field: "companyID", op: "in", value: scopeIds }] : []];
|
|
@@ -859,7 +952,7 @@ async function revenueRollup(client, opts) {
|
|
|
859
952
|
const uninvoicedFilter = [{ field: "invoiceID", op: "notExist" }, ...windowOn("itemDate"), ...scopeCond];
|
|
860
953
|
const nUninvoiced = v.nonChargeable ? await billingItems.count({ filter: uninvoicedFilter }) : 0;
|
|
861
954
|
if (typeof nInvoices !== "number" || typeof nLines !== "number" || typeof nUninvoiced !== "number") throw blindCount();
|
|
862
|
-
const joinsNeeded = Object.keys(JOINS).filter((j) => j === "contracts" || groupDims.some((d) => _optionalChain([d, 'access',
|
|
955
|
+
const joinsNeeded = Object.keys(JOINS).filter((j) => j === "contracts" || groupDims.some((d) => _optionalChain([d, 'access', _35 => _35.joins, 'optionalAccess', _36 => _36[j]])));
|
|
863
956
|
const chunks = pages(nInvoices);
|
|
864
957
|
const linePages = chunks + Math.max(0, pages(nLines) - 1) + chunks;
|
|
865
958
|
const uninvoicedPages = v.nonChargeable ? Math.max(1, pages(nUninvoiced)) : 0;
|
|
@@ -874,7 +967,7 @@ async function revenueRollup(client, opts) {
|
|
|
874
967
|
const invoiceRows = await collect(invoices, invoiceFilter(false), ["id", "invoiceTotal", "invoiceDateTime", "companyID"]);
|
|
875
968
|
const invoiceById = /* @__PURE__ */ new Map();
|
|
876
969
|
for (const r of invoiceRows) {
|
|
877
|
-
invoiceById.set(
|
|
970
|
+
invoiceById.set(_chunkEMYDC5SGcjs.num.call(void 0, r["id"]), { total: cents(r["invoiceTotal"]), month: String(_nullishCoalesce(r["invoiceDateTime"], () => ( ""))).slice(0, 7), companyID: _chunkEMYDC5SGcjs.num.call(void 0, r["companyID"]) });
|
|
878
971
|
}
|
|
879
972
|
if (invoiceById.size !== nInvoices) throw countMismatch("invoice", invoiceById.size, nInvoices, invoiceRows.length);
|
|
880
973
|
const voided = withVoided ? byId(await collect(invoices, voidedFilter, ["id", "invoiceTotal"])) : void 0;
|
|
@@ -888,13 +981,13 @@ async function revenueRollup(client, opts) {
|
|
|
888
981
|
if (rows.length !== n) throw countMismatch("line", rows.length, n);
|
|
889
982
|
return rows;
|
|
890
983
|
}, chunk(ids), { concurrency: CONCURRENCY })).flat();
|
|
891
|
-
const orphan = lines.find((l) => !invoiceById.has(
|
|
984
|
+
const orphan = lines.find((l) => !invoiceById.has(_chunkEMYDC5SGcjs.num.call(void 0, l["invoiceID"])));
|
|
892
985
|
if (orphan !== void 0) {
|
|
893
|
-
throw new (0,
|
|
986
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(`revenueRollup: billing line ${_chunkEMYDC5SGcjs.num.call(void 0, orphan["id"])} belongs to invoice ${_chunkEMYDC5SGcjs.num.call(void 0, orphan["invoiceID"])}, which is not among the ${invoiceById.size} streamed invoices; the fold was discarded`, {
|
|
894
987
|
code: "INVALID_RESPONSE",
|
|
895
988
|
category: "server",
|
|
896
989
|
operation: OP,
|
|
897
|
-
details: { reason: "orphan_line", lineID:
|
|
990
|
+
details: { reason: "orphan_line", lineID: _chunkEMYDC5SGcjs.num.call(void 0, orphan["id"]), invoiceID: _chunkEMYDC5SGcjs.num.call(void 0, orphan["invoiceID"]) },
|
|
898
991
|
suggestedAction: "Retry the call."
|
|
899
992
|
});
|
|
900
993
|
}
|
|
@@ -905,15 +998,15 @@ async function revenueRollup(client, opts) {
|
|
|
905
998
|
for (const j of joinsNeeded) {
|
|
906
999
|
const spec = JOINS[j];
|
|
907
1000
|
const res = spec.make(http, client);
|
|
908
|
-
const fields = [.../* @__PURE__ */ new Set([...spec.fields, ...groupDims.flatMap((d) => _nullishCoalesce(_optionalChain([d, 'access',
|
|
1001
|
+
const fields = [.../* @__PURE__ */ new Set([...spec.fields, ...groupDims.flatMap((d) => _nullishCoalesce(_optionalChain([d, 'access', _37 => _37.joins, 'optionalAccess', _38 => _38[j]]), () => ( [])))])];
|
|
909
1002
|
const want = [...new Set(spec.ids(all, joined))].filter((id) => id > 0).sort((a, b) => a - b);
|
|
910
1003
|
const rows = await client.batch((c) => collect(res, [{ field: "id", op: "in", value: c }], fields), chunk(want), { concurrency: CONCURRENCY });
|
|
911
|
-
for (const r of rows.flat()) joined[j].set(
|
|
1004
|
+
for (const r of rows.flat()) joined[j].set(_chunkEMYDC5SGcjs.num.call(void 0, r["id"]), r);
|
|
912
1005
|
}
|
|
913
1006
|
return fold(v, { invoiceById, voided, lines, uninvoiced, joined, labels, inTypes, inCategories, scopeIds, calls, estimate });
|
|
914
1007
|
}
|
|
915
1008
|
function refusal(v, estimate, fixed, scopeIds, joinCount) {
|
|
916
|
-
const months =
|
|
1009
|
+
const months = _chunkEMYDC5SGcjs.monthsInWindow.call(void 0, v.dateFrom, v.dateTo);
|
|
917
1010
|
const variable = estimate - fixed;
|
|
918
1011
|
const fitMonths = Math.floor((v.budget - fixed) * months / variable);
|
|
919
1012
|
const suggestions = [];
|
|
@@ -986,13 +1079,13 @@ function fold(v, f) {
|
|
|
986
1079
|
const contractLabels = f.labels[CONTRACTS_PATH];
|
|
987
1080
|
const bucketLabel = (field, fallback) => (t) => {
|
|
988
1081
|
const values = contractLabels.get(field);
|
|
989
|
-
const l = _optionalChain([values, 'optionalAccess',
|
|
1082
|
+
const l = _optionalChain([values, 'optionalAccess', _39 => _39.get, 'call', _40 => _40(t)]);
|
|
990
1083
|
if (l === void 0) return `${fallback} ${t}`;
|
|
991
1084
|
return [...values.values()].filter((x) => x === l).length > 1 ? `${l} (${t})` : l;
|
|
992
1085
|
};
|
|
993
1086
|
const typeLabel = bucketLabel("contractType", "type");
|
|
994
1087
|
const catLabel = bucketLabel("contractCategory", "category");
|
|
995
|
-
const needCompany = v.groupBy.some((d) => _optionalChain([DIMENSIONS, 'access',
|
|
1088
|
+
const needCompany = v.groupBy.some((d) => _optionalChain([DIMENSIONS, 'access', _41 => _41[d], 'access', _42 => _42.joins, 'optionalAccess', _43 => _43.companies]));
|
|
996
1089
|
const byLob = v.groupBy.includes("lineOfBusiness");
|
|
997
1090
|
const unlabelled = /* @__PURE__ */ new Set();
|
|
998
1091
|
const uncontracted = amt();
|
|
@@ -1009,15 +1102,15 @@ function fold(v, f) {
|
|
|
1009
1102
|
const zeroTotal = amt();
|
|
1010
1103
|
const zeroIds = /* @__PURE__ */ new Set();
|
|
1011
1104
|
const locate = (line, invoice) => {
|
|
1012
|
-
const contractID =
|
|
1105
|
+
const contractID = _chunkEMYDC5SGcjs.num.call(void 0, line["contractID"]);
|
|
1013
1106
|
if (contractID === 0) return { bucket: uncontracted, unresolved: false };
|
|
1014
1107
|
const contract = f.joined.contracts.get(contractID);
|
|
1015
1108
|
if (contract === void 0) return { bucket: unresolvedContracts, unresolved: true };
|
|
1016
|
-
const type =
|
|
1109
|
+
const type = _chunkEMYDC5SGcjs.num.call(void 0, contract["contractType"]);
|
|
1017
1110
|
if (!f.inTypes.has(type)) return { bucket: slot(otherTypes, typeLabel(type)), unresolved: false };
|
|
1018
|
-
const cat =
|
|
1111
|
+
const cat = _chunkEMYDC5SGcjs.num.call(void 0, contract["contractCategory"]);
|
|
1019
1112
|
if (f.inCategories !== void 0 && !f.inCategories.has(cat)) return { bucket: slot(otherCats, cat === 0 ? "uncategorised" : catLabel(cat)), unresolved: false };
|
|
1020
|
-
const company = f.joined.companies.get(
|
|
1113
|
+
const company = f.joined.companies.get(_chunkEMYDC5SGcjs.num.call(void 0, line["companyID"]));
|
|
1021
1114
|
if (needCompany && company === void 0) return { bucket: unresolvedCompanies, unresolved: true };
|
|
1022
1115
|
const ctx = { line, invoice, contract, company, joined: f.joined, labels: f.labels, unlabelled };
|
|
1023
1116
|
const keys = {};
|
|
@@ -1037,7 +1130,7 @@ function fold(v, f) {
|
|
|
1037
1130
|
return { cell };
|
|
1038
1131
|
};
|
|
1039
1132
|
for (const line of f.lines) {
|
|
1040
|
-
const invoiceID =
|
|
1133
|
+
const invoiceID = _chunkEMYDC5SGcjs.num.call(void 0, line["invoiceID"]);
|
|
1041
1134
|
const invoice = f.invoiceById.get(invoiceID);
|
|
1042
1135
|
lineTotals.set(invoiceID, (_nullishCoalesce(lineTotals.get(invoiceID), () => ( 0))) + cents(line["totalAmount"]));
|
|
1043
1136
|
const c = revC(line);
|
|
@@ -1058,9 +1151,9 @@ function fold(v, f) {
|
|
|
1058
1151
|
cell.creditLines += 1;
|
|
1059
1152
|
}
|
|
1060
1153
|
cell.included += extC(line) - c;
|
|
1061
|
-
cell.contracts.add(
|
|
1154
|
+
cell.contracts.add(_chunkEMYDC5SGcjs.num.call(void 0, line["contractID"]));
|
|
1062
1155
|
cell.items += 1;
|
|
1063
|
-
allContracts.add(
|
|
1156
|
+
allContracts.add(_chunkEMYDC5SGcjs.num.call(void 0, line["contractID"]));
|
|
1064
1157
|
if (byLob && cell.keys.lineOfBusiness.id === null) add(noPointer, c);
|
|
1065
1158
|
const k = v.nonChargeable ? ncClass(line) : void 0;
|
|
1066
1159
|
if (k) ncAdd(cell.nc, k, line);
|
|
@@ -1068,7 +1161,7 @@ function fold(v, f) {
|
|
|
1068
1161
|
for (const line of f.uninvoiced) {
|
|
1069
1162
|
const k = ncClass(line);
|
|
1070
1163
|
if (!k) continue;
|
|
1071
|
-
const at = locate(line, { total: 0, month: String(_nullishCoalesce(line["itemDate"], () => ( ""))).slice(0, 7), companyID:
|
|
1164
|
+
const at = locate(line, { total: 0, month: String(_nullishCoalesce(line["itemDate"], () => ( ""))).slice(0, 7), companyID: _chunkEMYDC5SGcjs.num.call(void 0, line["companyID"]) });
|
|
1072
1165
|
if ("cell" in at) ncAdd(at.cell.nc, k, line);
|
|
1073
1166
|
else if (at.unresolved) add(unresolvedNc, extC(line));
|
|
1074
1167
|
}
|
|
@@ -1178,20 +1271,20 @@ function slot(m, k) {
|
|
|
1178
1271
|
async function relationshipMap(client, resourceKey) {
|
|
1179
1272
|
void client;
|
|
1180
1273
|
if (typeof resourceKey !== "string" || resourceKey.trim() === "") {
|
|
1181
|
-
throw new (0,
|
|
1274
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1182
1275
|
`relationshipMap: resourceKey must be a non-empty plan resource key string (e.g. 'tickets'; got ${typeof resourceKey === "string" ? "a blank string" : typeof resourceKey})`,
|
|
1183
1276
|
{ suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items, ticket_notes." }
|
|
1184
1277
|
);
|
|
1185
1278
|
}
|
|
1186
1279
|
const key = resourceKey.trim();
|
|
1187
|
-
const entry =
|
|
1280
|
+
const entry = _chunkEMYDC5SGcjs.RELATIONSHIP_MAP[key];
|
|
1188
1281
|
if (entry === void 0) {
|
|
1189
|
-
throw new (0,
|
|
1190
|
-
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
1282
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(
|
|
1283
|
+
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkEMYDC5SGcjs.RELATIONSHIP_MAP).length} resources`,
|
|
1191
1284
|
{
|
|
1192
1285
|
code: "RESOURCE_UNKNOWN",
|
|
1193
1286
|
category: "validation",
|
|
1194
|
-
suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${
|
|
1287
|
+
suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${_chunkEMYDC5SGcjs.RELATIONSHIP_ZONE.label} (${_chunkEMYDC5SGcjs.RELATIONSHIP_ZONE.zone})-verified.`
|
|
1195
1288
|
}
|
|
1196
1289
|
);
|
|
1197
1290
|
}
|
|
@@ -1208,24 +1301,24 @@ var BLIND_SURFACE_KINDS = [
|
|
|
1208
1301
|
async function blindSurfaces(client, opts) {
|
|
1209
1302
|
void client;
|
|
1210
1303
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
1211
|
-
throw new (0,
|
|
1304
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("blindSurfaces: opts must be an object { resource?: string, kind?: BlindSurfaceKind }");
|
|
1212
1305
|
}
|
|
1213
|
-
const inv =
|
|
1306
|
+
const inv = _chunkEMYDC5SGcjs.BLIND_SURFACE_INVENTORY;
|
|
1214
1307
|
if (inv === null) {
|
|
1215
|
-
throw new (0,
|
|
1308
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("blindSurfaces: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
|
|
1216
1309
|
}
|
|
1217
1310
|
let surfaces = inv.surfaces;
|
|
1218
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1311
|
+
if (_optionalChain([opts, 'optionalAccess', _44 => _44.resource]) !== void 0) {
|
|
1219
1312
|
const key = typeof opts.resource === "string" ? opts.resource.trim() : "";
|
|
1220
1313
|
if (key === "") {
|
|
1221
|
-
throw new (0,
|
|
1314
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1222
1315
|
"blindSurfaces: opts.resource must be a non-empty plan resource key string (e.g. 'tickets')",
|
|
1223
1316
|
{ suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items." }
|
|
1224
1317
|
);
|
|
1225
1318
|
}
|
|
1226
1319
|
if (!inv.surfaces.some((row) => row.resource === key)) {
|
|
1227
|
-
throw new (0,
|
|
1228
|
-
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
1320
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(
|
|
1321
|
+
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkEMYDC5SGcjs.RELATIONSHIP_MAP).length} resources`,
|
|
1229
1322
|
{
|
|
1230
1323
|
code: "RESOURCE_UNKNOWN",
|
|
1231
1324
|
category: "validation",
|
|
@@ -1235,9 +1328,9 @@ async function blindSurfaces(client, opts) {
|
|
|
1235
1328
|
}
|
|
1236
1329
|
surfaces = surfaces.filter((row) => row.resource === key);
|
|
1237
1330
|
}
|
|
1238
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1331
|
+
if (_optionalChain([opts, 'optionalAccess', _45 => _45.kind]) !== void 0) {
|
|
1239
1332
|
if (!BLIND_SURFACE_KINDS.includes(opts.kind)) {
|
|
1240
|
-
throw new (0,
|
|
1333
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1241
1334
|
`blindSurfaces: unknown kind "${String(opts.kind)}" \u2014 the valid classes are: ${BLIND_SURFACE_KINDS.join(", ")}`,
|
|
1242
1335
|
{ suggestedAction: `Filter with one of: ${BLIND_SURFACE_KINDS.join(", ")} (or omit kind for the full 116-surface inventory).` }
|
|
1243
1336
|
);
|
|
@@ -1250,51 +1343,51 @@ async function blindSurfaces(client, opts) {
|
|
|
1250
1343
|
// src/operations/probeReachability.ts
|
|
1251
1344
|
async function probeReachability(client, opts) {
|
|
1252
1345
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
1253
|
-
throw new (0,
|
|
1346
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("probeReachability: opts must be an object { resources?: string[], limit?: 1|2, maxWireCalls?: number, confirmProbe?: true }");
|
|
1254
1347
|
}
|
|
1255
|
-
const defs =
|
|
1256
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1257
|
-
throw new (0,
|
|
1348
|
+
const defs = _chunkEMYDC5SGcjs.REACHABILITY_PROBE_DEFAULTS;
|
|
1349
|
+
if (_optionalChain([opts, 'optionalAccess', _46 => _46.confirmProbe]) !== true) {
|
|
1350
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1258
1351
|
"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",
|
|
1259
1352
|
{ suggestedAction: `Re-call with { confirmProbe: true } (plus resources/limit/maxWireCalls as needed). For the ZERO-wire pinned inventory use operations.blindSurfaces.` }
|
|
1260
1353
|
);
|
|
1261
1354
|
}
|
|
1262
|
-
const limit = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
1355
|
+
const limit = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _47 => _47.limit]), () => ( defs.limitDefault));
|
|
1263
1356
|
if (!Number.isInteger(limit) || limit < 1 || limit > defs.limitMax) {
|
|
1264
|
-
throw new (0,
|
|
1357
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1265
1358
|
`probeReachability: limit must be an integer 1..${defs.limitMax} (got ${String(limit)}) \u2014 the rows-per-surface bound for the discovery read`
|
|
1266
1359
|
);
|
|
1267
1360
|
}
|
|
1268
|
-
const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
1361
|
+
const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _48 => _48.maxWireCalls]), () => ( defs.defaultCap));
|
|
1269
1362
|
if (!Number.isInteger(cap) || cap < 1) {
|
|
1270
|
-
throw new (0,
|
|
1363
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`probeReachability: maxWireCalls must be a positive integer (got ${String(cap)})`);
|
|
1271
1364
|
}
|
|
1272
1365
|
if (cap > defs.hardCap) {
|
|
1273
|
-
throw new (0,
|
|
1366
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1274
1367
|
`probeReachability: maxWireCalls ${cap} exceeds the hard wire cap of ${defs.hardCap} \u2014 the sweep is refused above it (never capped silently)`,
|
|
1275
1368
|
{ suggestedAction: `Pass maxWireCalls \u2264 ${defs.hardCap} and a resources set no larger than the cap (the refused set is never truncated).` }
|
|
1276
1369
|
);
|
|
1277
1370
|
}
|
|
1278
|
-
const inv =
|
|
1371
|
+
const inv = _chunkEMYDC5SGcjs.BLIND_SURFACE_INVENTORY;
|
|
1279
1372
|
if (inv === null) {
|
|
1280
|
-
throw new (0,
|
|
1373
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("probeReachability: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
|
|
1281
1374
|
}
|
|
1282
1375
|
let targets;
|
|
1283
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1376
|
+
if (_optionalChain([opts, 'optionalAccess', _49 => _49.resources]) === void 0) {
|
|
1284
1377
|
targets = [...defs.defaultTargets];
|
|
1285
1378
|
} else {
|
|
1286
1379
|
if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
|
|
1287
|
-
throw new (0,
|
|
1380
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("probeReachability: opts.resources must be a non-empty string[] of plan resource keys (or omit it for the default non-data-full set)");
|
|
1288
1381
|
}
|
|
1289
1382
|
const seen = /* @__PURE__ */ new Set();
|
|
1290
1383
|
for (const r of opts.resources) {
|
|
1291
1384
|
if (typeof r !== "string" || r.trim() === "") {
|
|
1292
|
-
throw new (0,
|
|
1385
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`probeReachability: opts.resources must contain non-empty plan resource key strings (got ${typeof r === "string" && r.trim() === "" ? "a blank string" : typeof r})`);
|
|
1293
1386
|
}
|
|
1294
1387
|
const key = r.trim();
|
|
1295
1388
|
if (!inv.surfaces.some((row) => row.resource === key)) {
|
|
1296
1389
|
const surfaceCount = new Set(inv.surfaces.map((s) => s.resource)).size;
|
|
1297
|
-
throw new (0,
|
|
1390
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(
|
|
1298
1391
|
`probeReachability: unknown resource "${key}" \u2014 the inventory has ${surfaceCount} surfaces`,
|
|
1299
1392
|
{
|
|
1300
1393
|
code: "RESOURCE_UNKNOWN",
|
|
@@ -1308,7 +1401,7 @@ async function probeReachability(client, opts) {
|
|
|
1308
1401
|
targets = [...seen];
|
|
1309
1402
|
}
|
|
1310
1403
|
if (targets.length > cap) {
|
|
1311
|
-
throw new (0,
|
|
1404
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1312
1405
|
`probeReachability: ${targets.length} requested surface(s) exceed the wire cap of ${cap} \u2014 the sweep is refused above its cap (never truncated)`,
|
|
1313
1406
|
{ suggestedAction: `Raise maxWireCalls (\u2264 ${defs.hardCap}) to cover the set, or pass a smaller resources list.` }
|
|
1314
1407
|
);
|
|
@@ -1318,8 +1411,8 @@ async function probeReachability(client, opts) {
|
|
|
1318
1411
|
for (const resource of targets.sort()) {
|
|
1319
1412
|
const row = byResource.get(resource);
|
|
1320
1413
|
if (row === void 0) continue;
|
|
1321
|
-
const holder = client[
|
|
1322
|
-
const probeFn = _optionalChain([holder, 'optionalAccess',
|
|
1414
|
+
const holder = client[_chunkEMYDC5SGcjs.camelKey.call(void 0, resource)];
|
|
1415
|
+
const probeFn = _optionalChain([holder, 'optionalAccess', _50 => _50.queryBounded]);
|
|
1323
1416
|
if (typeof probeFn !== "function") {
|
|
1324
1417
|
results.push({
|
|
1325
1418
|
...row,
|
|
@@ -1330,14 +1423,14 @@ async function probeReachability(client, opts) {
|
|
|
1330
1423
|
}
|
|
1331
1424
|
try {
|
|
1332
1425
|
const res = await probeFn.call(holder, { limit });
|
|
1333
|
-
const items = Array.isArray(_optionalChain([res, 'optionalAccess',
|
|
1426
|
+
const items = Array.isArray(_optionalChain([res, 'optionalAccess', _51 => _51.items])) ? res.items : [];
|
|
1334
1427
|
results.push({
|
|
1335
1428
|
...row,
|
|
1336
1429
|
unfilteredRows: items.length,
|
|
1337
1430
|
probe: { ok: true, wire: 1, error: null }
|
|
1338
1431
|
});
|
|
1339
1432
|
} catch (err) {
|
|
1340
|
-
const code =
|
|
1433
|
+
const code = _chunkEMYDC5SGcjs.isAutotaskError.call(void 0, err) ? err.code : "NETWORK_ERROR";
|
|
1341
1434
|
const message = err instanceof Error ? err.message : String(err);
|
|
1342
1435
|
results.push({
|
|
1343
1436
|
...row,
|
|
@@ -1365,30 +1458,30 @@ var CREATE_BLOCKER_KINDS = [
|
|
|
1365
1458
|
async function createGuidance(client, opts) {
|
|
1366
1459
|
void client;
|
|
1367
1460
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
1368
|
-
throw new (0,
|
|
1461
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1369
1462
|
"createGuidance: opts must be an object { resources?: string[], kind?: CreateBlockerKind }"
|
|
1370
1463
|
);
|
|
1371
1464
|
}
|
|
1372
|
-
let servedRows =
|
|
1465
|
+
let servedRows = _chunkEMYDC5SGcjs.CREATE_GUIDANCE.rows.map((row) => ({
|
|
1373
1466
|
...row,
|
|
1374
1467
|
// Issue #219 N4: one precedence rule, stated on every row (live-proven >
|
|
1375
1468
|
// zone > spec). The spec set is not available here (it is a LIVE read) —
|
|
1376
1469
|
// the helper is handed the plan's two shapes and names the source.
|
|
1377
|
-
requiredFields:
|
|
1470
|
+
requiredFields: _chunkEMYDC5SGcjs.effectiveRequiredFields.call(void 0, void 0, _nullishCoalesce(_optionalChain([_chunkEMYDC5SGcjs.RELATIONSHIP_MAP, 'access', _52 => _52[row.resource], 'optionalAccess', _53 => _53.zoneFacts]), () => ( null)))
|
|
1378
1471
|
}));
|
|
1379
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1472
|
+
if (_optionalChain([opts, 'optionalAccess', _54 => _54.resources]) !== void 0) {
|
|
1380
1473
|
if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
|
|
1381
|
-
throw new (0,
|
|
1474
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("createGuidance: opts.resources must be a non-empty string[] of plan resource keys");
|
|
1382
1475
|
}
|
|
1383
1476
|
const wanted = /* @__PURE__ */ new Set();
|
|
1384
1477
|
for (const r of opts.resources) {
|
|
1385
1478
|
if (typeof r !== "string" || r.trim() === "") {
|
|
1386
|
-
throw new (0,
|
|
1479
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)("createGuidance: opts.resources must contain non-empty plan resource key strings");
|
|
1387
1480
|
}
|
|
1388
1481
|
const key = r.trim();
|
|
1389
|
-
if (!
|
|
1390
|
-
throw new (0,
|
|
1391
|
-
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${
|
|
1482
|
+
if (!_chunkEMYDC5SGcjs.CREATE_GUIDANCE.rows.some((row) => row.resource === key)) {
|
|
1483
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(
|
|
1484
|
+
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${_chunkEMYDC5SGcjs.CREATE_GUIDANCE.rows.length} create entities`,
|
|
1392
1485
|
{
|
|
1393
1486
|
code: "RESOURCE_UNKNOWN",
|
|
1394
1487
|
category: "validation",
|
|
@@ -1400,45 +1493,44 @@ async function createGuidance(client, opts) {
|
|
|
1400
1493
|
}
|
|
1401
1494
|
servedRows = servedRows.filter((row) => wanted.has(row.resource));
|
|
1402
1495
|
}
|
|
1403
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
1496
|
+
if (_optionalChain([opts, 'optionalAccess', _55 => _55.kind]) !== void 0) {
|
|
1404
1497
|
if (!CREATE_BLOCKER_KINDS.includes(opts.kind)) {
|
|
1405
|
-
throw new (0,
|
|
1498
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1406
1499
|
`createGuidance: unknown kind "${String(opts.kind)}" \u2014 the valid kinds are: ${CREATE_BLOCKER_KINDS.join(", ")}`
|
|
1407
1500
|
);
|
|
1408
1501
|
}
|
|
1409
|
-
servedRows = servedRows.filter((row) => _optionalChain([row, 'access',
|
|
1502
|
+
servedRows = servedRows.filter((row) => _optionalChain([row, 'access', _56 => _56.blocker, 'optionalAccess', _57 => _57.kind]) === opts.kind);
|
|
1410
1503
|
}
|
|
1411
1504
|
return {
|
|
1412
|
-
zone:
|
|
1413
|
-
label:
|
|
1414
|
-
verifiedAt:
|
|
1505
|
+
zone: _chunkEMYDC5SGcjs.CREATE_GUIDANCE.zone,
|
|
1506
|
+
label: _chunkEMYDC5SGcjs.CREATE_GUIDANCE.label,
|
|
1507
|
+
verifiedAt: _chunkEMYDC5SGcjs.CREATE_GUIDANCE.verifiedAt,
|
|
1415
1508
|
rows: servedRows,
|
|
1416
|
-
counts:
|
|
1509
|
+
counts: _chunkEMYDC5SGcjs.CREATE_GUIDANCE.counts
|
|
1417
1510
|
};
|
|
1418
1511
|
}
|
|
1419
1512
|
|
|
1420
1513
|
// src/operations/registryIndex.ts
|
|
1421
|
-
var OPERATION_BY_ID = new Map(
|
|
1514
|
+
var OPERATION_BY_ID = new Map(_chunkPH3ESYAFcjs.CAPABILITIES.map((r) => [r.id, r]));
|
|
1422
1515
|
|
|
1423
1516
|
// src/operations/sanitiseResult.ts
|
|
1424
1517
|
async function sanitiseResult(client, result, operation) {
|
|
1425
1518
|
void client;
|
|
1426
1519
|
if (typeof operation !== "string" || operation === "") {
|
|
1427
|
-
throw new (0,
|
|
1520
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1428
1521
|
'sanitiseResult: operation must be a non-empty registry operation key (e.g. "tickets.query")',
|
|
1429
1522
|
{ suggestedAction: "Pass the operation key the result came from \u2014 the registry id, not the resource key." }
|
|
1430
1523
|
);
|
|
1431
1524
|
}
|
|
1432
1525
|
const record = OPERATION_BY_ID.get(operation);
|
|
1433
1526
|
if (record === void 0) {
|
|
1434
|
-
throw new (0,
|
|
1527
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1435
1528
|
`sanitiseResult: unknown operation "${operation.slice(0, 60)}" \u2014 it is not in the capability registry`,
|
|
1436
1529
|
{ operation, suggestedAction: "List the registry (the ./capabilities subpath) for the exact operation key." }
|
|
1437
1530
|
);
|
|
1438
1531
|
}
|
|
1439
|
-
const fields = _optionalChain([record, 'access',
|
|
1440
|
-
|
|
1441
|
-
return _chunkMJTKK3QGcjs.deepMarkUntrusted.call(void 0, result, fields);
|
|
1532
|
+
const fields = _optionalChain([record, 'access', _58 => _58.metadata, 'optionalAccess', _59 => _59.untrustedFields]);
|
|
1533
|
+
return _chunkSN4BMQ2Ncjs.deepMarkUntrusted.call(void 0, result, Array.isArray(fields) ? fields : []);
|
|
1442
1534
|
}
|
|
1443
1535
|
|
|
1444
1536
|
// src/operations/recovery.ts
|
|
@@ -1446,7 +1538,7 @@ var RECOVERY_CONFIRM = "operations.recovery";
|
|
|
1446
1538
|
var RECOVERY_DEFAULT_LIMIT = 25;
|
|
1447
1539
|
var RECOVERY_MAX_LIMIT = 100;
|
|
1448
1540
|
function configError(message, operation, suggestedAction) {
|
|
1449
|
-
throw new (0,
|
|
1541
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(message, { operation, suggestedAction });
|
|
1450
1542
|
}
|
|
1451
1543
|
function parseMatchId(record) {
|
|
1452
1544
|
const raw = record.id;
|
|
@@ -1462,7 +1554,7 @@ function parseMatchId(record) {
|
|
|
1462
1554
|
return { id: null, unsafe: true };
|
|
1463
1555
|
}
|
|
1464
1556
|
function validateRecoveryInput(input, operation) {
|
|
1465
|
-
if (!
|
|
1557
|
+
if (!_chunkEMYDC5SGcjs.isRecord.call(void 0, input)) {
|
|
1466
1558
|
configError(
|
|
1467
1559
|
`recovery: input must be an object { resource, marker, ... } (got ${typeof input})`,
|
|
1468
1560
|
operation,
|
|
@@ -1496,10 +1588,10 @@ function validateRecoveryInput(input, operation) {
|
|
|
1496
1588
|
return { resource, marker, action };
|
|
1497
1589
|
}
|
|
1498
1590
|
function resolveRecoveryTarget(client, resource, operation) {
|
|
1499
|
-
const entry =
|
|
1591
|
+
const entry = _chunkEMYDC5SGcjs.RELATIONSHIP_MAP[resource];
|
|
1500
1592
|
if (entry === void 0) {
|
|
1501
|
-
throw new (0,
|
|
1502
|
-
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(
|
|
1593
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskError)(
|
|
1594
|
+
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(_chunkEMYDC5SGcjs.RELATIONSHIP_MAP).length} resources`,
|
|
1503
1595
|
{
|
|
1504
1596
|
code: "RESOURCE_UNKNOWN",
|
|
1505
1597
|
category: "validation",
|
|
@@ -1508,7 +1600,7 @@ function resolveRecoveryTarget(client, resource, operation) {
|
|
|
1508
1600
|
}
|
|
1509
1601
|
);
|
|
1510
1602
|
}
|
|
1511
|
-
const holder = client[
|
|
1603
|
+
const holder = client[_chunkEMYDC5SGcjs.camelKey.call(void 0, resource)];
|
|
1512
1604
|
if (!holder || typeof holder.queryBounded !== "function") {
|
|
1513
1605
|
configError(
|
|
1514
1606
|
`recovery: ${resource} exposes no bounded query surface \u2014 the marker search cannot run`,
|
|
@@ -1519,7 +1611,7 @@ function resolveRecoveryTarget(client, resource, operation) {
|
|
|
1519
1611
|
return { entry, holder };
|
|
1520
1612
|
}
|
|
1521
1613
|
function resolveMarkerField(input, resource, operation) {
|
|
1522
|
-
const field = input.field !== void 0 ? String(input.field) :
|
|
1614
|
+
const field = input.field !== void 0 ? String(input.field) : _chunkEMYDC5SGcjs.MARKER_FIELDS[resource];
|
|
1523
1615
|
if (typeof field !== "string" || field.trim() === "") {
|
|
1524
1616
|
configError(
|
|
1525
1617
|
`recovery: ${resource} has no plan markerField and no input.field was passed \u2014 the marker search needs a name-like field to filter on`,
|
|
@@ -1558,7 +1650,7 @@ function resolveExtraFilter(input, operation) {
|
|
|
1558
1650
|
);
|
|
1559
1651
|
}
|
|
1560
1652
|
for (const c of input.filter) {
|
|
1561
|
-
if (!
|
|
1653
|
+
if (!_chunkEMYDC5SGcjs.isRecord.call(void 0, c) || typeof c.op !== "string" || c.op === "and" || c.op === "or") {
|
|
1562
1654
|
configError(
|
|
1563
1655
|
"recovery: input.filter accepts only plain leaf conditions ({ field, op, value }) \u2014 no grouping",
|
|
1564
1656
|
operation,
|
|
@@ -1583,7 +1675,7 @@ function resolveLimit(input, operation) {
|
|
|
1583
1675
|
async function applyRecoveryDeletes(holder, matches, parentId, resource, operation) {
|
|
1584
1676
|
const deleteMethod = holder.delete;
|
|
1585
1677
|
if (deleteMethod === void 0) {
|
|
1586
|
-
throw new (0,
|
|
1678
|
+
throw new (0, _chunkEMYDC5SGcjs.DeleteBoundaryError)(
|
|
1587
1679
|
`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`,
|
|
1588
1680
|
{
|
|
1589
1681
|
operation,
|
|
@@ -1612,14 +1704,14 @@ async function applyRecoveryDeletes(holder, matches, parentId, resource, operati
|
|
|
1612
1704
|
verify = "still-present";
|
|
1613
1705
|
}
|
|
1614
1706
|
} catch (err) {
|
|
1615
|
-
if (err instanceof
|
|
1707
|
+
if (err instanceof _chunkEMYDC5SGcjs.NotFoundError) verify = "not-found";
|
|
1616
1708
|
else {
|
|
1617
1709
|
verify = "error";
|
|
1618
|
-
code =
|
|
1710
|
+
code = _chunkEMYDC5SGcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
|
|
1619
1711
|
}
|
|
1620
1712
|
}
|
|
1621
1713
|
} catch (err) {
|
|
1622
|
-
code =
|
|
1714
|
+
code = _chunkEMYDC5SGcjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
|
|
1623
1715
|
}
|
|
1624
1716
|
deleted.push({ id, verified: verify === "not-found", code });
|
|
1625
1717
|
}
|
|
@@ -1647,7 +1739,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
1647
1739
|
const parentId = resolveParentId(input, entry, resource, operation);
|
|
1648
1740
|
const extra = resolveExtraFilter(input, operation);
|
|
1649
1741
|
const limit = resolveLimit(input, operation);
|
|
1650
|
-
const boundaryNote =
|
|
1742
|
+
const boundaryNote = _chunkEMYDC5SGcjs.DELETE_BOUNDARY_NOTES[resource];
|
|
1651
1743
|
const boundary = {
|
|
1652
1744
|
available: boundaryNote === void 0,
|
|
1653
1745
|
reason: _nullishCoalesce(boundaryNote, () => ( null)),
|
|
@@ -1659,7 +1751,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
1659
1751
|
};
|
|
1660
1752
|
const isDelete = action === "delete";
|
|
1661
1753
|
if (isDelete && boundaryNote !== void 0) {
|
|
1662
|
-
throw new (0,
|
|
1754
|
+
throw new (0, _chunkEMYDC5SGcjs.DeleteBoundaryError)(
|
|
1663
1755
|
`recovery: the vendor defines no DELETE for ${resource} \u2014 the delete cannot be issued through the API (zero wire was issued)`,
|
|
1664
1756
|
{
|
|
1665
1757
|
operation,
|
|
@@ -1668,10 +1760,10 @@ async function recovery(client, input, opts = {}) {
|
|
|
1668
1760
|
}
|
|
1669
1761
|
);
|
|
1670
1762
|
}
|
|
1671
|
-
const dryRun = _optionalChain([opts, 'optionalAccess',
|
|
1672
|
-
const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
1763
|
+
const dryRun = _optionalChain([opts, 'optionalAccess', _60 => _60.dryRun]) !== false;
|
|
1764
|
+
const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _61 => _61.confirm]), () => ( input.confirm));
|
|
1673
1765
|
if (isDelete && !dryRun && confirm !== RECOVERY_CONFIRM) {
|
|
1674
|
-
throw new (0,
|
|
1766
|
+
throw new (0, _chunkEMYDC5SGcjs.ConfirmationRequiredError)(
|
|
1675
1767
|
`recovery: action 'delete' apply is destructive and requires its confirmation flag: pass confirm: "${RECOVERY_CONFIRM}"`,
|
|
1676
1768
|
{
|
|
1677
1769
|
operation: RECOVERY_CONFIRM,
|
|
@@ -1687,7 +1779,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
1687
1779
|
const query = await holder.queryBounded({ filter: conditions, limit });
|
|
1688
1780
|
if (query.hasMore) {
|
|
1689
1781
|
const wire = isDelete ? "DELETE wire" : "mutating wire";
|
|
1690
|
-
throw new (0,
|
|
1782
|
+
throw new (0, _chunkEMYDC5SGcjs.RecoveryTruncatedError)(
|
|
1691
1783
|
`recovery: the marker search on ${resource} TRIPPED its match cap (${limit}) \u2014 more matches exist than were returned (zero ${wire} was issued)`,
|
|
1692
1784
|
{
|
|
1693
1785
|
operation,
|
|
@@ -1716,7 +1808,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
1716
1808
|
return { ...base, simulated: true, dryRun: true };
|
|
1717
1809
|
}
|
|
1718
1810
|
if (unsafeId) {
|
|
1719
|
-
throw new (0,
|
|
1811
|
+
throw new (0, _chunkEMYDC5SGcjs.MarkerUnsafeIdError)(
|
|
1720
1812
|
`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)`,
|
|
1721
1813
|
{
|
|
1722
1814
|
operation,
|
|
@@ -1734,7 +1826,7 @@ function needsConfirmation(record) {
|
|
|
1734
1826
|
return record.effect === "destructive" || (_nullishCoalesce(record.flags, () => ( []))).includes("requiresApproval");
|
|
1735
1827
|
}
|
|
1736
1828
|
function refuse(message, operation, suggestedAction) {
|
|
1737
|
-
throw new (0,
|
|
1829
|
+
throw new (0, _chunkEMYDC5SGcjs.ConfirmationRequiredError)(message, { operation, suggestedAction });
|
|
1738
1830
|
}
|
|
1739
1831
|
var MODE_BY_EFFECT = {
|
|
1740
1832
|
read: "read",
|
|
@@ -1780,7 +1872,7 @@ function looseTypeOk(type, value) {
|
|
|
1780
1872
|
case "string[]":
|
|
1781
1873
|
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
1782
1874
|
case "object":
|
|
1783
|
-
return
|
|
1875
|
+
return _chunkEMYDC5SGcjs.isRecord.call(void 0, value);
|
|
1784
1876
|
default:
|
|
1785
1877
|
return true;
|
|
1786
1878
|
}
|
|
@@ -1794,12 +1886,12 @@ function declaredArgList(record) {
|
|
|
1794
1886
|
function resolveDispatchArgs(record, argsIn) {
|
|
1795
1887
|
const operation = record.id;
|
|
1796
1888
|
const bad = (message) => {
|
|
1797
|
-
throw new (0,
|
|
1889
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`invoke: "${operation}" ${message}`, { operation });
|
|
1798
1890
|
};
|
|
1799
1891
|
if (argsIn === void 0 || argsIn === null) return [];
|
|
1800
1892
|
if (Array.isArray(argsIn)) return argsIn;
|
|
1801
1893
|
const byName = argsIn;
|
|
1802
|
-
if (!
|
|
1894
|
+
if (!_chunkEMYDC5SGcjs.isRecord.call(void 0, byName) || ![Object.prototype, null].includes(Object.getPrototypeOf(byName))) {
|
|
1803
1895
|
return bad(`args must be a positional array or a plain object of named inputs (declared: ${declaredArgList(record)})`);
|
|
1804
1896
|
}
|
|
1805
1897
|
const schema = _nullishCoalesce(record.inputSchema, () => ( {}));
|
|
@@ -1820,7 +1912,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
1820
1912
|
const bagName = names.find((n) => schema[n].properties);
|
|
1821
1913
|
const surplus = args[names.length];
|
|
1822
1914
|
const bagHint = bagName && surplus !== null && typeof surplus === "object" && !Array.isArray(surplus) ? ` \u2014 options go inside the single ${bagName} object` : "";
|
|
1823
|
-
throw new (0,
|
|
1915
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1824
1916
|
`invoke: "${operation}" declares ${names.length} positional arg(s) (${declaredArgList(record)}) but ${args.length} were passed \u2014 extra args are refused${bagHint}`,
|
|
1825
1917
|
{
|
|
1826
1918
|
operation,
|
|
@@ -1830,7 +1922,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
1830
1922
|
}
|
|
1831
1923
|
const required = names.filter((n) => schema[n].required);
|
|
1832
1924
|
if (args.length < required.length) {
|
|
1833
|
-
throw new (0,
|
|
1925
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1834
1926
|
`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)}`,
|
|
1835
1927
|
{ operation }
|
|
1836
1928
|
);
|
|
@@ -1841,7 +1933,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
1841
1933
|
const name = names[i];
|
|
1842
1934
|
const spec = schema[name];
|
|
1843
1935
|
if (!looseTypeOk(spec.type, value)) {
|
|
1844
|
-
throw new (0,
|
|
1936
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1845
1937
|
`invoke: "${operation}" arg ${i + 1} is declared ${name}: ${spec.type} \u2014 the value has the wrong type (pass a ${spec.type} value)`,
|
|
1846
1938
|
{ operation }
|
|
1847
1939
|
);
|
|
@@ -1849,17 +1941,17 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
1849
1941
|
}
|
|
1850
1942
|
}
|
|
1851
1943
|
function foldFlattenedOpts(record, toolArgs) {
|
|
1852
|
-
if (!
|
|
1853
|
-
throw new (0,
|
|
1944
|
+
if (!_chunkEMYDC5SGcjs.isRecord.call(void 0, toolArgs)) {
|
|
1945
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(`invoke: "${record.id}" tool args must be a plain object of named inputs`, { operation: record.id });
|
|
1854
1946
|
}
|
|
1855
|
-
const bagKeys = (_nullishCoalesce(_optionalChain([record, 'access',
|
|
1947
|
+
const bagKeys = (_nullishCoalesce(_optionalChain([record, 'access', _62 => _62.inputSchema, 'optionalAccess', _63 => _63.opts, 'optionalAccess', _64 => _64.properties]), () => ( []))).map((p) => p.name);
|
|
1856
1948
|
const flat = Object.keys(toolArgs).filter((k) => bagKeys.includes(k) && toolArgs[k] !== void 0 && toolArgs[k] !== null);
|
|
1857
1949
|
const folded = { ...toolArgs };
|
|
1858
1950
|
for (const k of bagKeys) delete folded[k];
|
|
1859
1951
|
if (folded.opts === null) delete folded.opts;
|
|
1860
1952
|
if (flat.length === 0) return folded;
|
|
1861
1953
|
if (folded.opts !== void 0) {
|
|
1862
|
-
throw new (0,
|
|
1954
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1863
1955
|
`invoke: "${record.id}" was given both opts and flattened option(s) ${flat.map((k) => `"${k}"`).join(", ")} \u2014 pass one form`,
|
|
1864
1956
|
{ operation: record.id }
|
|
1865
1957
|
);
|
|
@@ -1925,12 +2017,12 @@ function validateParamsBag(record, args) {
|
|
|
1925
2017
|
if (record.inputSchemaStrict !== true) return;
|
|
1926
2018
|
const valid = PARAMS_BAG_KEYS[record.operation];
|
|
1927
2019
|
if (valid === void 0) return;
|
|
1928
|
-
const bag = _optionalChain([args, 'optionalAccess',
|
|
1929
|
-
if (bag === void 0 || bag === null || !
|
|
2020
|
+
const bag = _optionalChain([args, 'optionalAccess', _65 => _65[0]]);
|
|
2021
|
+
if (bag === void 0 || bag === null || !_chunkEMYDC5SGcjs.isRecord.call(void 0, bag)) return;
|
|
1930
2022
|
const unknown = Object.keys(bag).filter((k) => !valid.includes(k));
|
|
1931
2023
|
if (unknown.length === 0) return;
|
|
1932
2024
|
const suggestions = keySuggestions(unknown, valid);
|
|
1933
|
-
throw new (0,
|
|
2025
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1934
2026
|
`invoke: "${record.id}" params bag has unknown key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the bag is closed (valid keys: ${valid.join(", ")})`,
|
|
1935
2027
|
{
|
|
1936
2028
|
operation: record.id,
|
|
@@ -1944,7 +2036,7 @@ function validateInvokeOptions(opts, operation) {
|
|
|
1944
2036
|
const unknown = Object.keys(opts).filter((k) => !INVOKE_OPTION_KEYS.includes(k));
|
|
1945
2037
|
if (unknown.length === 0) return;
|
|
1946
2038
|
const suggestions = keySuggestions(unknown, ["dryRun", "confirm", "lastModifiedDate", "maxRetries", "fresh"]);
|
|
1947
|
-
throw new (0,
|
|
2039
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1948
2040
|
`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)`,
|
|
1949
2041
|
{
|
|
1950
2042
|
operation,
|
|
@@ -1957,7 +2049,7 @@ function unknownKeysRefusal(raw, validKeys, subject, operation) {
|
|
|
1957
2049
|
const unknown = Object.keys(raw).filter((k) => !validKeys.includes(k));
|
|
1958
2050
|
if (unknown.length === 0) return null;
|
|
1959
2051
|
const suggestions = keySuggestions(unknown, [...validKeys]);
|
|
1960
|
-
return new (0,
|
|
2052
|
+
return new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
1961
2053
|
`unknown ${subject} ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the ${subject} set is closed (valid keys: ${validKeys.join(", ")})`,
|
|
1962
2054
|
{
|
|
1963
2055
|
...operation !== void 0 ? { operation } : {},
|
|
@@ -1988,26 +2080,25 @@ function hasIdScope(filter) {
|
|
|
1988
2080
|
return op === "eq" && real(n.value) || op === "in" && list.some(real);
|
|
1989
2081
|
}
|
|
1990
2082
|
async function guardUnscopedQueryWalk(holder, operation, bag) {
|
|
1991
|
-
const filter = _optionalChain([bag, 'optionalAccess',
|
|
1992
|
-
const limit = _optionalChain([bag, 'optionalAccess',
|
|
1993
|
-
const latest = _optionalChain([bag, 'optionalAccess',
|
|
1994
|
-
const walk = typeof _optionalChain([bag, 'optionalAccess',
|
|
1995
|
-
const maxRows = typeof _optionalChain([walk, 'optionalAccess',
|
|
1996
|
-
const effectiveLimit = typeof limit === "number" ? limit :
|
|
1997
|
-
|
|
1998
|
-
if (
|
|
1999
|
-
if (walked <= _chunkSEFJJY4Jcjs.UNSCOPED_WALK_THRESHOLD || hasIdScope(filter)) return {};
|
|
2083
|
+
const filter = _optionalChain([bag, 'optionalAccess', _66 => _66["filter"]]);
|
|
2084
|
+
const limit = _optionalChain([bag, 'optionalAccess', _67 => _67["limit"]]);
|
|
2085
|
+
const latest = _optionalChain([bag, 'optionalAccess', _68 => _68["latest"]]);
|
|
2086
|
+
const walk = typeof _optionalChain([bag, 'optionalAccess', _69 => _69["walk"]]) === "object" && _optionalChain([bag, 'optionalAccess', _70 => _70["walk"]]) !== null ? _optionalChain([bag, 'optionalAccess', _71 => _71["walk"]]) : void 0;
|
|
2087
|
+
const maxRows = typeof _optionalChain([walk, 'optionalAccess', _72 => _72.maxRows]) === "number" ? walk.maxRows : void 0;
|
|
2088
|
+
const effectiveLimit = typeof limit === "number" ? limit : _chunkEMYDC5SGcjs.BOUNDED_QUERY_DEFAULT_LIMIT;
|
|
2089
|
+
const walked = _nullishCoalesce(maxRows, () => ( (typeof latest === "number" ? Math.max(effectiveLimit, latest) : effectiveLimit)));
|
|
2090
|
+
if (walked <= _chunkEMYDC5SGcjs.UNSCOPED_WALK_THRESHOLD || hasIdScope(filter)) return {};
|
|
2000
2091
|
let conditions;
|
|
2001
2092
|
try {
|
|
2002
|
-
conditions =
|
|
2003
|
-
} catch (
|
|
2093
|
+
conditions = _chunkEMYDC5SGcjs.normalizedConditions.call(void 0, filter);
|
|
2094
|
+
} catch (e2) {
|
|
2004
2095
|
return {};
|
|
2005
2096
|
}
|
|
2006
2097
|
let counted;
|
|
2007
2098
|
try {
|
|
2008
2099
|
counted = await holder.count({ filter: conditions === void 0 ? void 0 : conditions });
|
|
2009
2100
|
} catch (err) {
|
|
2010
|
-
const code = _optionalChain([err, 'optionalAccess',
|
|
2101
|
+
const code = _optionalChain([err, 'optionalAccess', _73 => _73.code]);
|
|
2011
2102
|
if (typeof code === "string" && PROPAGATE_CODES.has(code)) throw err;
|
|
2012
2103
|
const label = typeof code === "string" && /^[A-Z][A-Z_]{2,40}$/.test(code) ? ` (${code})` : "";
|
|
2013
2104
|
return { note: `scope check skipped: the pre-flight count failed${label}; this unscoped walk was not guarded.` };
|
|
@@ -2020,7 +2111,7 @@ async function guardUnscopedQueryWalk(holder, operation, bag) {
|
|
|
2020
2111
|
if (count === void 0) {
|
|
2021
2112
|
return { note: "scope check skipped: the pre-flight count was unreadable; this unscoped walk was not guarded." };
|
|
2022
2113
|
}
|
|
2023
|
-
if (count >
|
|
2114
|
+
if (count > _chunkEMYDC5SGcjs.UNSCOPED_WALK_THRESHOLD) throw new (0, _chunkEMYDC5SGcjs.ScopeRequiredError)(operation, { threshold: _chunkEMYDC5SGcjs.UNSCOPED_WALK_THRESHOLD, count });
|
|
2024
2115
|
return {};
|
|
2025
2116
|
}
|
|
2026
2117
|
|
|
@@ -2040,7 +2131,7 @@ function bufferResult(buf) {
|
|
|
2040
2131
|
function resolveRecord(operation) {
|
|
2041
2132
|
const record = OPERATION_BY_ID.get(operation);
|
|
2042
2133
|
if (record === void 0) {
|
|
2043
|
-
throw new (0,
|
|
2134
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2044
2135
|
`invoke: unknown operation "${operation}" \u2014 it is not in the capability registry`,
|
|
2045
2136
|
{ operation, suggestedAction: "List the registry (the ./capabilities subpath) for the exact operation key." }
|
|
2046
2137
|
);
|
|
@@ -2051,30 +2142,30 @@ function governPreRequest(record, operation, opts) {
|
|
|
2051
2142
|
validateInvokeOptions(opts, operation);
|
|
2052
2143
|
const mode = opts.mode;
|
|
2053
2144
|
if (mode !== void 0 && MODE_BY_EFFECT[record.effect] !== mode) {
|
|
2054
|
-
throw new (0,
|
|
2145
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(crossModeRefusal(operation, record.effect, mode), { operation });
|
|
2055
2146
|
}
|
|
2056
2147
|
if (opts.dryRun !== void 0 && typeof opts.dryRun !== "boolean") {
|
|
2057
|
-
throw new (0,
|
|
2148
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2058
2149
|
`invoke: dryRun must be a boolean (got ${typeof opts.dryRun}) \u2014 "${operation}" was not issued`,
|
|
2059
2150
|
{ operation, suggestedAction: "Pass dryRun: true (simulate) or dryRun: false (apply) as a real boolean." }
|
|
2060
2151
|
);
|
|
2061
2152
|
}
|
|
2062
2153
|
if (opts.fresh !== void 0) {
|
|
2063
2154
|
if (typeof opts.fresh !== "boolean") {
|
|
2064
|
-
throw new (0,
|
|
2155
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2065
2156
|
`invoke: fresh must be a boolean (got ${typeof opts.fresh}) \u2014 "${operation}" was not issued`,
|
|
2066
2157
|
{ operation, suggestedAction: "Pass fresh: true (bypass the read cache) or omit it." }
|
|
2067
2158
|
);
|
|
2068
2159
|
}
|
|
2069
2160
|
if (record.effect !== "read" || record.kind !== "primitive" || record.operation !== "get" || !("opts" in (_nullishCoalesce(record.inputSchema, () => ( {}))))) {
|
|
2070
|
-
throw new (0,
|
|
2161
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2071
2162
|
`invoke: fresh applies only to a single-record "<resource>.get" read \u2014 "${operation}" was not issued`,
|
|
2072
2163
|
{ operation, suggestedAction: "Drop the fresh option (only <resource>.get consults the read cache per call)." }
|
|
2073
2164
|
);
|
|
2074
2165
|
}
|
|
2075
2166
|
}
|
|
2076
2167
|
if (record.effect === "read" && opts.dryRun === true) {
|
|
2077
|
-
throw new (0,
|
|
2168
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2078
2169
|
`invoke: "${operation}" is a read \u2014 dryRun is not applicable (reads issue their request as-is)`,
|
|
2079
2170
|
{ operation }
|
|
2080
2171
|
);
|
|
@@ -2089,9 +2180,10 @@ function governPreRequest(record, operation, opts) {
|
|
|
2089
2180
|
}
|
|
2090
2181
|
function operationsHolder(client) {
|
|
2091
2182
|
return {
|
|
2183
|
+
resolveStaff: (identifier, opts) => resolveStaff(client, identifier, opts),
|
|
2092
2184
|
resolveAny: (identifier, opts) => resolveAny(client, identifier, opts),
|
|
2093
2185
|
searchAcrossResources: (query, opts) => searchAcrossResources(client, query, opts),
|
|
2094
|
-
fetchMany: (items, opts) =>
|
|
2186
|
+
fetchMany: (items, opts) => _chunkEMYDC5SGcjs.fetchMany.call(void 0, client, items, opts),
|
|
2095
2187
|
// Issue #62: the generic aggregate + the cheap count — the
|
|
2096
2188
|
// groupBy/sum-absent mode is ONE vendor /query/count (the S12-C blind
|
|
2097
2189
|
// sentinel rides through); the group/sum modes walk the named
|
|
@@ -2103,12 +2195,12 @@ function operationsHolder(client) {
|
|
|
2103
2195
|
// Issue #59 PR-B: the bulk fetch by ids — query-first chunked `id in`
|
|
2104
2196
|
// reads + the per-id `get` fallback (blind-surface-safe; per-item
|
|
2105
2197
|
// typed outcomes reuse the fetchMany shapes).
|
|
2106
|
-
fetchByIds: (items, opts) =>
|
|
2198
|
+
fetchByIds: (items, opts) => _chunkEMYDC5SGcjs.fetchByIds.call(void 0, client, items, opts),
|
|
2107
2199
|
// Issue #65: opt-in resource name expansion — per-id resources.get
|
|
2108
2200
|
// reads ONLY (never an id-in query — the resources table can be blind
|
|
2109
2201
|
// to count/query while per-id reads work); blind-marked rows for ids
|
|
2110
2202
|
// the API user cannot resolve; the read cache (default-on).
|
|
2111
|
-
expandResourceNames: (ids, opts) =>
|
|
2203
|
+
expandResourceNames: (ids, opts) => _chunkEMYDC5SGcjs.expandResourceNames.call(void 0, client, ids, opts),
|
|
2112
2204
|
relationshipMap: (resourceKey) => relationshipMap(client, resourceKey),
|
|
2113
2205
|
// Issue #11: the served blind-surface inventory (zero wire) + the
|
|
2114
2206
|
// bounded caller-opted reachability sweep (read-only, confirmProbe-
|
|
@@ -2118,7 +2210,7 @@ function operationsHolder(client) {
|
|
|
2118
2210
|
// Issue #12: the served zone-fact create-guidance catalog (zero wire).
|
|
2119
2211
|
createGuidance: (opts) => createGuidance(client, opts),
|
|
2120
2212
|
// Issue #202: ExecuteCommand deep links — pure, zero wire.
|
|
2121
|
-
uiLink: (input) =>
|
|
2213
|
+
uiLink: (input) => _chunkEMYDC5SGcjs.uiLink.call(void 0, client, input),
|
|
2122
2214
|
// Issue #287 (D8): the projection-layer untrusted-content helper — pure,
|
|
2123
2215
|
// zero wire (the registry record's metadata.untrustedFields + the deep
|
|
2124
2216
|
// walker from src/untrusted.ts; an unknown operation refuses).
|
|
@@ -2127,7 +2219,7 @@ function operationsHolder(client) {
|
|
|
2127
2219
|
// entityInformation GETs (the op's own cap refuses over-cap fan-outs
|
|
2128
2220
|
// pre-request; per-resource failures are recorded on the row and
|
|
2129
2221
|
// never abort the call).
|
|
2130
|
-
fieldCatalog: (opts) =>
|
|
2222
|
+
fieldCatalog: (opts) => _chunkEMYDC5SGcjs.fieldCatalog.call(void 0, client, opts),
|
|
2131
2223
|
// Issue #9: the one-call recovery/cleanup op — effect write in the
|
|
2132
2224
|
// registry (the governor's dry-run-first applies to it); the op's own
|
|
2133
2225
|
// confirm gate makes the destructive action deliberate (the governor
|
|
@@ -2137,15 +2229,15 @@ function operationsHolder(client) {
|
|
|
2137
2229
|
}
|
|
2138
2230
|
function resolveHolder(client, record, operation) {
|
|
2139
2231
|
const clientBag = client;
|
|
2140
|
-
let holder = clientBag[
|
|
2232
|
+
let holder = clientBag[_chunkEMYDC5SGcjs.camelKey.call(void 0, record.resource)];
|
|
2141
2233
|
if (typeof holder === "function") {
|
|
2142
|
-
holder = _nullishCoalesce(clientBag[`${
|
|
2234
|
+
holder = _nullishCoalesce(clientBag[`${_chunkEMYDC5SGcjs.camelKey.call(void 0, record.resource)}Resource`], () => ( holder));
|
|
2143
2235
|
}
|
|
2144
2236
|
if (holder === void 0 && record.resource === "operations") {
|
|
2145
2237
|
holder = operationsHolder(client);
|
|
2146
2238
|
}
|
|
2147
2239
|
if (holder === void 0) {
|
|
2148
|
-
throw new (0,
|
|
2240
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2149
2241
|
`invoke: the client exposes no accessor for resource "${record.resource}"`,
|
|
2150
2242
|
{ operation }
|
|
2151
2243
|
);
|
|
@@ -2200,7 +2292,7 @@ function validateFreshSpelling(record, args) {
|
|
|
2200
2292
|
const at = Object.keys(_nullishCoalesce(record.inputSchema, () => ( {}))).indexOf("opts");
|
|
2201
2293
|
const bag = at < 0 ? void 0 : args[at];
|
|
2202
2294
|
if (bag === void 0 || bag === null) return;
|
|
2203
|
-
throw new (0,
|
|
2295
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2204
2296
|
`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
2297
|
{
|
|
2206
2298
|
operation: record.id,
|
|
@@ -2213,7 +2305,7 @@ var PRE_REQUEST_VALIDATORS = [
|
|
|
2213
2305
|
(c) => validateDispatchArgs(c.record, c.args),
|
|
2214
2306
|
(c) => validateParamsBag(c.record, c.args),
|
|
2215
2307
|
(c) => validateFreshSpelling(c.record, c.args),
|
|
2216
|
-
(c) => c.boundedQuery || c.countedQuery ?
|
|
2308
|
+
(c) => c.boundedQuery || c.countedQuery ? _chunkEMYDC5SGcjs.validateQueryFieldNames.call(void 0, c.record, c.holder, c.args) : Promise.resolve(void 0)
|
|
2217
2309
|
];
|
|
2218
2310
|
async function runPreRequestPass(ctx) {
|
|
2219
2311
|
for (const step of PRE_REQUEST_VALIDATORS) await step(ctx);
|
|
@@ -2225,11 +2317,11 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
2225
2317
|
const countedQuery = record.kind === "primitive" && record.operation === "count";
|
|
2226
2318
|
const holder = resolveHolder(client, record, operation);
|
|
2227
2319
|
await runPreRequestPass({ record, operation, args, opts, client, holder, boundedQuery, countedQuery });
|
|
2228
|
-
const labelQuery = boundedQuery &&
|
|
2320
|
+
const labelQuery = boundedQuery && _chunkEMYDC5SGcjs.readNamesOpt.call(void 0, client, _optionalChain([args, 'access', _74 => _74[0], 'optionalAccess', _75 => _75["names"]]), `invoke: "${record.id}" params bag`);
|
|
2229
2321
|
const methodName = boundedQuery ? "queryBounded" : record.operation;
|
|
2230
2322
|
const method = holder[methodName];
|
|
2231
2323
|
if (typeof method !== "function") {
|
|
2232
|
-
throw new (0,
|
|
2324
|
+
throw new (0, _chunkEMYDC5SGcjs.AutotaskConfigError)(
|
|
2233
2325
|
`invoke: "${record.resource}.${methodName}" is not a callable method on the client`,
|
|
2234
2326
|
{ operation }
|
|
2235
2327
|
);
|
|
@@ -2238,15 +2330,15 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
2238
2330
|
const mutationOpts = buildMutationOpts(opts, isWrite);
|
|
2239
2331
|
const callArgs = buildCallArgs(record, args, mutationOpts, isWrite);
|
|
2240
2332
|
if (opts.fresh === true) appendFresh(record, callArgs);
|
|
2241
|
-
if (boundedQuery)
|
|
2333
|
+
if (boundedQuery) _chunkEMYDC5SGcjs.validateWalkBag.call(void 0, _optionalChain([args, 'access', _76 => _76[0], 'optionalAccess', _77 => _77["walk"]]), `invoke: "${record.id}"`, { operation: record.id });
|
|
2242
2334
|
let scopeNote;
|
|
2243
|
-
if (boundedQuery && _optionalChain([args, 'access',
|
|
2335
|
+
if (boundedQuery && _optionalChain([args, 'access', _78 => _78[0], 'optionalAccess', _79 => _79["acknowledgeUnscoped"]]) !== true) {
|
|
2244
2336
|
scopeNote = (await guardUnscopedQueryWalk(holder, record.id, args[0])).note;
|
|
2245
2337
|
}
|
|
2246
2338
|
const result = await method.apply(holder, callArgs);
|
|
2247
|
-
if (labelQuery && Array.isArray(_optionalChain([result, 'optionalAccess',
|
|
2339
|
+
if (labelQuery && _optionalChain([args, 'access', _80 => _80[0], 'optionalAccess', _81 => _81["walk"]]) === void 0 && Array.isArray(_optionalChain([result, 'optionalAccess', _82 => _82.items]))) {
|
|
2248
2340
|
const bounded = result;
|
|
2249
|
-
const labelled = await
|
|
2341
|
+
const labelled = await _chunkEMYDC5SGcjs.labelRows.call(void 0, client, record.resource, bounded.items);
|
|
2250
2342
|
return { ...bounded, items: labelled.rows, ...labelled.names !== void 0 ? { names: labelled.names } : {}, ...scopeNote !== void 0 ? { scopeNote } : {} };
|
|
2251
2343
|
}
|
|
2252
2344
|
const finished = Buffer.isBuffer(result) ? bufferResult(result) : result;
|
|
@@ -2316,4 +2408,5 @@ async function invokeDelete(client, operation, args = [], opts = {}) {
|
|
|
2316
2408
|
|
|
2317
2409
|
|
|
2318
2410
|
|
|
2319
|
-
|
|
2411
|
+
|
|
2412
|
+
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 = _chunkEMYDC5SGcjs.EXPAND_RESOURCE_NAMES_MAX_IDS; exports.FETCH_BY_IDS_CHUNK_SIZE = _chunkEMYDC5SGcjs.FETCH_BY_IDS_CHUNK_SIZE; exports.FETCH_BY_IDS_MAX_ITEMS = _chunkEMYDC5SGcjs.FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_MANY_MAX_ITEMS = _chunkEMYDC5SGcjs.FETCH_MANY_MAX_ITEMS; exports.FIELD_CACHE_KINDS = _chunkEMYDC5SGcjs.FIELD_CACHE_KINDS; exports.FIELD_CATALOG_HONESTY_NOTE = _chunkEMYDC5SGcjs.FIELD_CATALOG_HONESTY_NOTE; exports.INVOKE_OPTION_KEYS = INVOKE_OPTION_KEYS; exports.MAX_FIELD_CATALOG_WIRE = _chunkEMYDC5SGcjs.MAX_FIELD_CATALOG_WIRE; exports.MIN_FIELD_CATALOG_MAX_BYTES = _chunkEMYDC5SGcjs.MIN_FIELD_CATALOG_MAX_BYTES; exports.PARAMS_BAG_KEYS = PARAMS_BAG_KEYS; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = _chunkEMYDC5SGcjs.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 = _chunkEMYDC5SGcjs.UI_LINK_ENTITIES; exports.WORKFLOW_RESOURCES = _chunkEMYDC5SGcjs.WORKFLOW_RESOURCES; exports.aggregate = aggregate; exports.blindSurfaces = blindSurfaces; exports.buildUiLink = _chunkEMYDC5SGcjs.buildUiLink; exports.createGuidance = createGuidance; exports.dateBucketLabel = dateBucketLabel; exports.effectiveRequiredFields = _chunkEMYDC5SGcjs.effectiveRequiredFields; exports.expandResourceNames = _chunkEMYDC5SGcjs.expandResourceNames; exports.fetchByIds = _chunkEMYDC5SGcjs.fetchByIds; exports.fetchMany = _chunkEMYDC5SGcjs.fetchMany; exports.fieldCatalog = _chunkEMYDC5SGcjs.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.resolveStaff = resolveStaff; exports.revenueRollup = revenueRollup; exports.sanitiseResult = sanitiseResult; exports.searchAcrossResources = searchAcrossResources; exports.uiLink = _chunkEMYDC5SGcjs.uiLink; exports.unknownKeysRefusal = unknownKeysRefusal; exports.validateDispatchArgs = validateDispatchArgs; exports.validateFetchManyItems = _chunkEMYDC5SGcjs.validateFetchManyItems; exports.validateInvokeOptions = validateInvokeOptions; exports.validateParamsBag = validateParamsBag;
|