node-autotask 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/MCP_TOOL_CATALOG.json +6 -6
- package/MCP_TOOL_MANIFEST.md +127 -127
- package/N8N_MCP_MANIFEST.json +44 -9
- package/N8N_MCP_MANIFEST.md +8 -8
- package/capabilities.json +1938 -1826
- package/capabilities.schema.json +6 -0
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-NDK7WYWA.js → chunk-2T77J2ZM.js} +1937 -1825
- package/dist/{chunk-JM52ZU7T.cjs → chunk-FLYTKJKV.cjs} +1937 -1825
- package/dist/{chunk-LB2X4X4B.js → chunk-GA6UCX3Z.js} +207 -51
- package/dist/{chunk-4YKV7ORF.js → chunk-JEJUFXHX.js} +2 -2
- package/dist/{chunk-QDYSHAU6.cjs → chunk-L6V66V22.cjs} +215 -59
- package/dist/{chunk-TIM75K3G.cjs → chunk-RMLGOCGA.cjs} +135 -135
- package/dist/{chunk-D5RAQ4DE.js → chunk-XSYJB4IW.js} +3 -3
- package/dist/{chunk-7RDR5DSI.cjs → chunk-YH5CPRDN.cjs} +394 -394
- package/dist/{index-aZ3tCh1h.d.cts → index-AN-NjLi9.d.cts} +100 -9
- package/dist/{index-DLugNSr7.d.ts → index-CvLLsOCP.d.ts} +100 -9
- package/dist/index.cjs +22 -22
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/operations/index.cjs +184 -136
- package/dist/operations/index.d.cts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +79 -31
- package/dist/pool.cjs +8 -8
- package/dist/pool.d.cts +1 -1
- package/dist/pool.d.ts +1 -1
- package/dist/pool.js +4 -4
- package/dist/resources/index.cjs +4 -4
- package/dist/resources/index.d.cts +1 -1
- package/dist/resources/index.d.ts +1 -1
- package/dist/resources/index.js +3 -3
- package/docs/API.md +78 -22
- package/package.json +1 -1
|
@@ -36,26 +36,27 @@
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
var _chunkQDYSHAU6cjs = require('../chunk-QDYSHAU6.cjs');
|
|
40
39
|
|
|
40
|
+
var _chunkL6V66V22cjs = require('../chunk-L6V66V22.cjs');
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
var _chunkFLYTKJKVcjs = require('../chunk-FLYTKJKV.cjs');
|
|
43
44
|
|
|
44
45
|
// src/operations/searchAcrossResources.ts
|
|
45
46
|
var DEFAULT_LIMIT = 25;
|
|
46
47
|
function resourceFor(client, key) {
|
|
47
|
-
return client[
|
|
48
|
+
return client[_chunkL6V66V22cjs.camelKey.call(void 0, key)];
|
|
48
49
|
}
|
|
49
50
|
async function searchAcrossResources(client, query, opts = {}) {
|
|
50
51
|
const text = query.trim();
|
|
51
52
|
if (text === "") {
|
|
52
|
-
throw new (0,
|
|
53
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("searchAcrossResources: query must be a non-empty string");
|
|
53
54
|
}
|
|
54
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
55
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkL6V66V22cjs.WORKFLOW_RESOURCES));
|
|
55
56
|
if (keys.length === 0) {
|
|
56
|
-
throw new (0,
|
|
57
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("searchAcrossResources: no resources requested");
|
|
57
58
|
}
|
|
58
|
-
const limit =
|
|
59
|
+
const limit = _chunkL6V66V22cjs.clampPageSize.call(void 0, _nullishCoalesce(opts.limit, () => ( DEFAULT_LIMIT)));
|
|
59
60
|
const results = [];
|
|
60
61
|
const skipped = [];
|
|
61
62
|
for (const key of keys) {
|
|
@@ -73,7 +74,7 @@ async function searchAcrossResources(client, query, opts = {}) {
|
|
|
73
74
|
|
|
74
75
|
// src/operations/resolveAny.ts
|
|
75
76
|
function resourceFor2(client, key) {
|
|
76
|
-
return client[
|
|
77
|
+
return client[_chunkL6V66V22cjs.camelKey.call(void 0, key)];
|
|
77
78
|
}
|
|
78
79
|
var FAULT_CATEGORIES = /* @__PURE__ */ new Set(["auth", "rate_limit", "server", "network", "timeout", "policy"]);
|
|
79
80
|
function missCost(identifier) {
|
|
@@ -82,13 +83,13 @@ function missCost(identifier) {
|
|
|
82
83
|
}
|
|
83
84
|
async function resolveAny(client, identifier, opts = {}) {
|
|
84
85
|
if (typeof identifier === "number") {
|
|
85
|
-
|
|
86
|
+
_chunkL6V66V22cjs.parseIdentifier.call(void 0, identifier, "identifier");
|
|
86
87
|
} else if (identifier.trim() === "") {
|
|
87
|
-
throw new (0,
|
|
88
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("resolveAny: identifier must be non-empty");
|
|
88
89
|
}
|
|
89
|
-
const keys = _nullishCoalesce(opts.resources, () => (
|
|
90
|
+
const keys = _nullishCoalesce(opts.resources, () => ( _chunkL6V66V22cjs.WORKFLOW_RESOURCES));
|
|
90
91
|
if (keys.length === 0) {
|
|
91
|
-
throw new (0,
|
|
92
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("resolveAny: no resources requested");
|
|
92
93
|
}
|
|
93
94
|
const results = [];
|
|
94
95
|
for (const key of keys) {
|
|
@@ -118,9 +119,9 @@ async function resolveAny(client, identifier, opts = {}) {
|
|
|
118
119
|
} catch (err) {
|
|
119
120
|
let code;
|
|
120
121
|
let candidates = [];
|
|
121
|
-
if (err instanceof
|
|
122
|
+
if (err instanceof _chunkL6V66V22cjs.AutotaskConfigError) {
|
|
122
123
|
code = "CONFIG_ERROR";
|
|
123
|
-
} else if (
|
|
124
|
+
} else if (_chunkL6V66V22cjs.isAutotaskError.call(void 0, err)) {
|
|
124
125
|
if (FAULT_CATEGORIES.has(err.category)) throw err;
|
|
125
126
|
code = err.code;
|
|
126
127
|
if (code === "RESOLUTION_AMBIGUOUS" && err.resourceIds !== void 0) {
|
|
@@ -147,7 +148,7 @@ async function resolveAny(client, identifier, opts = {}) {
|
|
|
147
148
|
// src/operations/aggregate.ts
|
|
148
149
|
var AGGREGATE_TOP_MAX = 100;
|
|
149
150
|
var AGGREGATE_DEFAULT_TOP = 25;
|
|
150
|
-
var AGGREGATE_DEFAULT_LIMIT =
|
|
151
|
+
var AGGREGATE_DEFAULT_LIMIT = _chunkL6V66V22cjs.BOUNDED_QUERY_MAX_LIMIT;
|
|
151
152
|
var AGGREGATE_DATE_BUCKETS = ["month", "week", "year"];
|
|
152
153
|
var DATE_ONLY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
153
154
|
var DATETIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
@@ -204,7 +205,7 @@ function dateBucketLabel(value, bucket) {
|
|
|
204
205
|
}
|
|
205
206
|
var QUERY_RESOURCE_KEYS = (() => {
|
|
206
207
|
const s = /* @__PURE__ */ new Set();
|
|
207
|
-
for (const rec of
|
|
208
|
+
for (const rec of _chunkFLYTKJKVcjs.CAPABILITIES) if (rec.operation === "query") s.add(rec.resource);
|
|
208
209
|
return s;
|
|
209
210
|
})();
|
|
210
211
|
var AGGREGATE_OPT_KEYS = ["groupBy", "sum", "top", "limit"];
|
|
@@ -239,14 +240,14 @@ function validateAggregate(operation, filter, opts) {
|
|
|
239
240
|
conditions = [];
|
|
240
241
|
} else {
|
|
241
242
|
try {
|
|
242
|
-
conditions =
|
|
243
|
+
conditions = _chunkL6V66V22cjs.buildFilter.call(void 0, conds).filter;
|
|
243
244
|
} catch (err) {
|
|
244
|
-
problems.push(err instanceof
|
|
245
|
+
problems.push(err instanceof _chunkL6V66V22cjs.AutotaskConfigError ? err.message : `filter must be the query-bag filter (13 operators; caps 500 OR-conditions / 1 UDF / 8000 chars); ${String(err)}`);
|
|
245
246
|
}
|
|
246
247
|
}
|
|
247
248
|
}
|
|
248
249
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
249
|
-
throw new (0,
|
|
250
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
250
251
|
`aggregate: opts must be the options object (got ${Array.isArray(opts) ? "an array" : typeof opts})`,
|
|
251
252
|
{ operation: "operations.aggregate" }
|
|
252
253
|
);
|
|
@@ -256,8 +257,8 @@ function validateAggregate(operation, filter, opts) {
|
|
|
256
257
|
problems.push(`unknown opts key "${key}" \u2014 the bag is closed: ${AGGREGATE_OPT_KEYS.join(", ")}`);
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
|
-
const fieldSets = resourceKey !== void 0 ?
|
|
260
|
-
const dateSets = resourceKey !== void 0 ?
|
|
260
|
+
const fieldSets = resourceKey !== void 0 ? _chunkL6V66V22cjs.MODEL_FIELD_SETS[resourceKey] : void 0;
|
|
261
|
+
const dateSets = resourceKey !== void 0 ? _chunkL6V66V22cjs.MODEL_DATE_FIELDS[resourceKey] : void 0;
|
|
261
262
|
const checkFields = (name, fields) => {
|
|
262
263
|
if (fields === void 0) return [];
|
|
263
264
|
if (!Array.isArray(fields) || fields.length === 0 || fields.some((f) => typeof f !== "string" || f.trim() === "")) {
|
|
@@ -321,11 +322,11 @@ function validateAggregate(operation, filter, opts) {
|
|
|
321
322
|
if (!Number.isInteger(opts.limit)) {
|
|
322
323
|
problems.push(`limit must be an integer (got ${String(opts.limit)})`);
|
|
323
324
|
} else {
|
|
324
|
-
limit = Math.min(Math.max(opts.limit, 1),
|
|
325
|
+
limit = Math.min(Math.max(opts.limit, 1), _chunkL6V66V22cjs.BOUNDED_QUERY_MAX_LIMIT);
|
|
325
326
|
}
|
|
326
327
|
}
|
|
327
328
|
if (problems.length > 0) {
|
|
328
|
-
throw new (0,
|
|
329
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
329
330
|
`aggregate: ${problems.length} problem(s) found pre-request (zero wire was issued)
|
|
330
331
|
- ` + problems.join("\n- "),
|
|
331
332
|
{ operation: "operations.aggregate" }
|
|
@@ -335,9 +336,9 @@ function validateAggregate(operation, filter, opts) {
|
|
|
335
336
|
}
|
|
336
337
|
async function aggregate(client, operation, filter, opts = {}) {
|
|
337
338
|
const v = validateAggregate(operation, filter, opts);
|
|
338
|
-
const holder = client[
|
|
339
|
+
const holder = client[_chunkL6V66V22cjs.camelKey.call(void 0, v.resourceKey)];
|
|
339
340
|
if (holder === void 0) {
|
|
340
|
-
throw new (0,
|
|
341
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(`aggregate: the client exposes no accessor for resource "${v.resourceKey}"`, {
|
|
341
342
|
operation: "operations.aggregate",
|
|
342
343
|
suggestedAction: "Rebuild the client from the SDK build that ships this registry (the resource set is pinned by the plan)."
|
|
343
344
|
});
|
|
@@ -392,20 +393,20 @@ async function aggregate(client, operation, filter, opts = {}) {
|
|
|
392
393
|
async function relationshipMap(client, resourceKey) {
|
|
393
394
|
void client;
|
|
394
395
|
if (typeof resourceKey !== "string" || resourceKey.trim() === "") {
|
|
395
|
-
throw new (0,
|
|
396
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
396
397
|
`relationshipMap: resourceKey must be a non-empty plan resource key string (e.g. 'tickets'; got ${typeof resourceKey === "string" ? "a blank string" : typeof resourceKey})`,
|
|
397
398
|
{ suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items, ticket_notes." }
|
|
398
399
|
);
|
|
399
400
|
}
|
|
400
401
|
const key = resourceKey.trim();
|
|
401
|
-
const entry =
|
|
402
|
+
const entry = _chunkL6V66V22cjs.RELATIONSHIP_MAP[key];
|
|
402
403
|
if (entry === void 0) {
|
|
403
|
-
throw new (0,
|
|
404
|
-
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
404
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskError)(
|
|
405
|
+
`relationshipMap: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkL6V66V22cjs.RELATIONSHIP_MAP).length} resources`,
|
|
405
406
|
{
|
|
406
407
|
code: "RESOURCE_UNKNOWN",
|
|
407
408
|
category: "validation",
|
|
408
|
-
suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${
|
|
409
|
+
suggestedAction: `Pass the exact plan resource key (snake_case) from autotask_catalog (e.g. tickets, companies, configuration_items). Zone facts served are ${_chunkL6V66V22cjs.RELATIONSHIP_ZONE.label} (${_chunkL6V66V22cjs.RELATIONSHIP_ZONE.zone})-verified.`
|
|
409
410
|
}
|
|
410
411
|
);
|
|
411
412
|
}
|
|
@@ -422,24 +423,24 @@ var BLIND_SURFACE_KINDS = [
|
|
|
422
423
|
async function blindSurfaces(client, opts) {
|
|
423
424
|
void client;
|
|
424
425
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
425
|
-
throw new (0,
|
|
426
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("blindSurfaces: opts must be an object { resource?: string, kind?: BlindSurfaceKind }");
|
|
426
427
|
}
|
|
427
|
-
const inv =
|
|
428
|
+
const inv = _chunkL6V66V22cjs.BLIND_SURFACE_INVENTORY;
|
|
428
429
|
if (inv === null) {
|
|
429
|
-
throw new (0,
|
|
430
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("blindSurfaces: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
|
|
430
431
|
}
|
|
431
432
|
let surfaces = inv.surfaces;
|
|
432
433
|
if (_optionalChain([opts, 'optionalAccess', _ => _.resource]) !== void 0) {
|
|
433
434
|
const key = typeof opts.resource === "string" ? opts.resource.trim() : "";
|
|
434
435
|
if (key === "") {
|
|
435
|
-
throw new (0,
|
|
436
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
436
437
|
"blindSurfaces: opts.resource must be a non-empty plan resource key string (e.g. 'tickets')",
|
|
437
438
|
{ suggestedAction: "Pass the exact plan resource key (snake_case) from autotask_catalog \u2014 e.g. tickets, companies, configuration_items." }
|
|
438
439
|
);
|
|
439
440
|
}
|
|
440
441
|
if (!inv.surfaces.some((row) => row.resource === key)) {
|
|
441
|
-
throw new (0,
|
|
442
|
-
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(
|
|
442
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskError)(
|
|
443
|
+
`blindSurfaces: unknown resource "${key}" \u2014 the plan has ${Object.keys(_chunkL6V66V22cjs.RELATIONSHIP_MAP).length} resources`,
|
|
443
444
|
{
|
|
444
445
|
code: "RESOURCE_UNKNOWN",
|
|
445
446
|
category: "validation",
|
|
@@ -451,7 +452,7 @@ async function blindSurfaces(client, opts) {
|
|
|
451
452
|
}
|
|
452
453
|
if (_optionalChain([opts, 'optionalAccess', _2 => _2.kind]) !== void 0) {
|
|
453
454
|
if (!BLIND_SURFACE_KINDS.includes(opts.kind)) {
|
|
454
|
-
throw new (0,
|
|
455
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
455
456
|
`blindSurfaces: unknown kind "${String(opts.kind)}" \u2014 the valid classes are: ${BLIND_SURFACE_KINDS.join(", ")}`,
|
|
456
457
|
{ suggestedAction: `Filter with one of: ${BLIND_SURFACE_KINDS.join(", ")} (or omit kind for the full 116-surface inventory).` }
|
|
457
458
|
);
|
|
@@ -464,51 +465,51 @@ async function blindSurfaces(client, opts) {
|
|
|
464
465
|
// src/operations/probeReachability.ts
|
|
465
466
|
async function probeReachability(client, opts) {
|
|
466
467
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
467
|
-
throw new (0,
|
|
468
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("probeReachability: opts must be an object { resources?: string[], limit?: 1|2, maxWireCalls?: number, confirmProbe?: true }");
|
|
468
469
|
}
|
|
469
|
-
const defs =
|
|
470
|
+
const defs = _chunkL6V66V22cjs.REACHABILITY_PROBE_DEFAULTS;
|
|
470
471
|
if (_optionalChain([opts, 'optionalAccess', _3 => _3.confirmProbe]) !== true) {
|
|
471
|
-
throw new (0,
|
|
472
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
472
473
|
"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",
|
|
473
474
|
{ suggestedAction: `Re-call with { confirmProbe: true } (plus resources/limit/maxWireCalls as needed). For the ZERO-wire pinned inventory use operations.blindSurfaces.` }
|
|
474
475
|
);
|
|
475
476
|
}
|
|
476
477
|
const limit = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _4 => _4.limit]), () => ( defs.limitDefault));
|
|
477
478
|
if (!Number.isInteger(limit) || limit < 1 || limit > defs.limitMax) {
|
|
478
|
-
throw new (0,
|
|
479
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
479
480
|
`probeReachability: limit must be an integer 1..${defs.limitMax} (got ${String(limit)}) \u2014 the rows-per-surface bound for the discovery read`
|
|
480
481
|
);
|
|
481
482
|
}
|
|
482
483
|
const cap = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _5 => _5.maxWireCalls]), () => ( defs.defaultCap));
|
|
483
484
|
if (!Number.isInteger(cap) || cap < 1) {
|
|
484
|
-
throw new (0,
|
|
485
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(`probeReachability: maxWireCalls must be a positive integer (got ${String(cap)})`);
|
|
485
486
|
}
|
|
486
487
|
if (cap > defs.hardCap) {
|
|
487
|
-
throw new (0,
|
|
488
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
488
489
|
`probeReachability: maxWireCalls ${cap} exceeds the hard wire cap of ${defs.hardCap} \u2014 the sweep is refused above it (never capped silently)`,
|
|
489
490
|
{ suggestedAction: `Pass maxWireCalls \u2264 ${defs.hardCap} and a resources set no larger than the cap (the refused set is never truncated).` }
|
|
490
491
|
);
|
|
491
492
|
}
|
|
492
|
-
const inv =
|
|
493
|
+
const inv = _chunkL6V66V22cjs.BLIND_SURFACE_INVENTORY;
|
|
493
494
|
if (inv === null) {
|
|
494
|
-
throw new (0,
|
|
495
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("probeReachability: the reachability inventory is absent from the generated artifact \u2014 re-run the build");
|
|
495
496
|
}
|
|
496
497
|
let targets;
|
|
497
498
|
if (_optionalChain([opts, 'optionalAccess', _6 => _6.resources]) === void 0) {
|
|
498
499
|
targets = [...defs.defaultTargets];
|
|
499
500
|
} else {
|
|
500
501
|
if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
|
|
501
|
-
throw new (0,
|
|
502
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("probeReachability: opts.resources must be a non-empty string[] of plan resource keys (or omit it for the default non-data-full set)");
|
|
502
503
|
}
|
|
503
504
|
const seen = /* @__PURE__ */ new Set();
|
|
504
505
|
for (const r of opts.resources) {
|
|
505
506
|
if (typeof r !== "string" || r.trim() === "") {
|
|
506
|
-
throw new (0,
|
|
507
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(`probeReachability: opts.resources must contain non-empty plan resource key strings (got ${typeof r === "string" && r.trim() === "" ? "a blank string" : typeof r})`);
|
|
507
508
|
}
|
|
508
509
|
const key = r.trim();
|
|
509
510
|
if (!inv.surfaces.some((row) => row.resource === key)) {
|
|
510
511
|
const surfaceCount = new Set(inv.surfaces.map((s) => s.resource)).size;
|
|
511
|
-
throw new (0,
|
|
512
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskError)(
|
|
512
513
|
`probeReachability: unknown resource "${key}" \u2014 the inventory has ${surfaceCount} surfaces`,
|
|
513
514
|
{
|
|
514
515
|
code: "RESOURCE_UNKNOWN",
|
|
@@ -522,7 +523,7 @@ async function probeReachability(client, opts) {
|
|
|
522
523
|
targets = [...seen];
|
|
523
524
|
}
|
|
524
525
|
if (targets.length > cap) {
|
|
525
|
-
throw new (0,
|
|
526
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
526
527
|
`probeReachability: ${targets.length} requested surface(s) exceed the wire cap of ${cap} \u2014 the sweep is refused above its cap (never truncated)`,
|
|
527
528
|
{ suggestedAction: `Raise maxWireCalls (\u2264 ${defs.hardCap}) to cover the set, or pass a smaller resources list.` }
|
|
528
529
|
);
|
|
@@ -532,7 +533,7 @@ async function probeReachability(client, opts) {
|
|
|
532
533
|
for (const resource of targets.sort()) {
|
|
533
534
|
const row = byResource.get(resource);
|
|
534
535
|
if (row === void 0) continue;
|
|
535
|
-
const holder = client[
|
|
536
|
+
const holder = client[_chunkL6V66V22cjs.camelKey.call(void 0, resource)];
|
|
536
537
|
const probeFn = _optionalChain([holder, 'optionalAccess', _7 => _7.queryBounded]);
|
|
537
538
|
if (typeof probeFn !== "function") {
|
|
538
539
|
results.push({
|
|
@@ -551,7 +552,7 @@ async function probeReachability(client, opts) {
|
|
|
551
552
|
probe: { ok: true, wire: 1, error: null }
|
|
552
553
|
});
|
|
553
554
|
} catch (err) {
|
|
554
|
-
const code =
|
|
555
|
+
const code = _chunkL6V66V22cjs.isAutotaskError.call(void 0, err) ? err.code : "NETWORK_ERROR";
|
|
555
556
|
const message = err instanceof Error ? err.message : String(err);
|
|
556
557
|
results.push({
|
|
557
558
|
...row,
|
|
@@ -579,24 +580,24 @@ var CREATE_BLOCKER_KINDS = [
|
|
|
579
580
|
async function createGuidance(client, opts) {
|
|
580
581
|
void client;
|
|
581
582
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
582
|
-
throw new (0,
|
|
583
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
583
584
|
"createGuidance: opts must be an object { resources?: string[], kind?: CreateBlockerKind }"
|
|
584
585
|
);
|
|
585
586
|
}
|
|
586
|
-
let rows =
|
|
587
|
+
let rows = _chunkL6V66V22cjs.CREATE_GUIDANCE.rows;
|
|
587
588
|
if (_optionalChain([opts, 'optionalAccess', _9 => _9.resources]) !== void 0) {
|
|
588
589
|
if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
|
|
589
|
-
throw new (0,
|
|
590
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("createGuidance: opts.resources must be a non-empty string[] of plan resource keys");
|
|
590
591
|
}
|
|
591
592
|
const wanted = /* @__PURE__ */ new Set();
|
|
592
593
|
for (const r of opts.resources) {
|
|
593
594
|
if (typeof r !== "string" || r.trim() === "") {
|
|
594
|
-
throw new (0,
|
|
595
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)("createGuidance: opts.resources must contain non-empty plan resource key strings");
|
|
595
596
|
}
|
|
596
597
|
const key = r.trim();
|
|
597
|
-
if (!
|
|
598
|
-
throw new (0,
|
|
599
|
-
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${
|
|
598
|
+
if (!_chunkL6V66V22cjs.CREATE_GUIDANCE.rows.some((row) => row.resource === key)) {
|
|
599
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskError)(
|
|
600
|
+
`createGuidance: unknown resource "${key}" \u2014 the catalog has ${_chunkL6V66V22cjs.CREATE_GUIDANCE.rows.length} create entities`,
|
|
600
601
|
{
|
|
601
602
|
code: "RESOURCE_UNKNOWN",
|
|
602
603
|
category: "validation",
|
|
@@ -610,18 +611,18 @@ async function createGuidance(client, opts) {
|
|
|
610
611
|
}
|
|
611
612
|
if (_optionalChain([opts, 'optionalAccess', _10 => _10.kind]) !== void 0) {
|
|
612
613
|
if (!CREATE_BLOCKER_KINDS.includes(opts.kind)) {
|
|
613
|
-
throw new (0,
|
|
614
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
614
615
|
`createGuidance: unknown kind "${String(opts.kind)}" \u2014 the valid kinds are: ${CREATE_BLOCKER_KINDS.join(", ")}`
|
|
615
616
|
);
|
|
616
617
|
}
|
|
617
618
|
rows = rows.filter((row) => _optionalChain([row, 'access', _11 => _11.blocker, 'optionalAccess', _12 => _12.kind]) === opts.kind);
|
|
618
619
|
}
|
|
619
620
|
return {
|
|
620
|
-
zone:
|
|
621
|
-
label:
|
|
622
|
-
verifiedAt:
|
|
621
|
+
zone: _chunkL6V66V22cjs.CREATE_GUIDANCE.zone,
|
|
622
|
+
label: _chunkL6V66V22cjs.CREATE_GUIDANCE.label,
|
|
623
|
+
verifiedAt: _chunkL6V66V22cjs.CREATE_GUIDANCE.verifiedAt,
|
|
623
624
|
rows,
|
|
624
|
-
counts:
|
|
625
|
+
counts: _chunkL6V66V22cjs.CREATE_GUIDANCE.counts
|
|
625
626
|
};
|
|
626
627
|
}
|
|
627
628
|
|
|
@@ -630,7 +631,7 @@ var RECOVERY_CONFIRM = "operations.recovery";
|
|
|
630
631
|
var RECOVERY_DEFAULT_LIMIT = 25;
|
|
631
632
|
var RECOVERY_MAX_LIMIT = 100;
|
|
632
633
|
function configError(message, operation, suggestedAction) {
|
|
633
|
-
throw new (0,
|
|
634
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(message, { operation, suggestedAction });
|
|
634
635
|
}
|
|
635
636
|
function parseMatchId(record) {
|
|
636
637
|
const raw = record.id;
|
|
@@ -647,7 +648,7 @@ function parseMatchId(record) {
|
|
|
647
648
|
}
|
|
648
649
|
async function recovery(client, input, opts = {}) {
|
|
649
650
|
const operation = RECOVERY_CONFIRM;
|
|
650
|
-
if (!
|
|
651
|
+
if (!_chunkL6V66V22cjs.isRecord.call(void 0, input)) {
|
|
651
652
|
configError(
|
|
652
653
|
`recovery: input must be an object { resource, marker, ... } (got ${typeof input})`,
|
|
653
654
|
operation,
|
|
@@ -678,10 +679,10 @@ async function recovery(client, input, opts = {}) {
|
|
|
678
679
|
"Pass action: 'delete' for the destructive path (dry-run-first; the apply requires the confirm string)."
|
|
679
680
|
);
|
|
680
681
|
}
|
|
681
|
-
const entry =
|
|
682
|
+
const entry = _chunkL6V66V22cjs.RELATIONSHIP_MAP[resource];
|
|
682
683
|
if (entry === void 0) {
|
|
683
|
-
throw new (0,
|
|
684
|
-
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(
|
|
684
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskError)(
|
|
685
|
+
`recovery: unknown resource "${resource}" \u2014 the plan has ${Object.keys(_chunkL6V66V22cjs.RELATIONSHIP_MAP).length} resources`,
|
|
685
686
|
{
|
|
686
687
|
code: "RESOURCE_UNKNOWN",
|
|
687
688
|
category: "validation",
|
|
@@ -690,7 +691,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
690
691
|
}
|
|
691
692
|
);
|
|
692
693
|
}
|
|
693
|
-
const holder = client[
|
|
694
|
+
const holder = client[_chunkL6V66V22cjs.camelKey.call(void 0, resource)];
|
|
694
695
|
if (!holder || typeof holder.queryBounded !== "function") {
|
|
695
696
|
configError(
|
|
696
697
|
`recovery: ${resource} exposes no bounded query surface \u2014 the marker search cannot run`,
|
|
@@ -698,7 +699,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
698
699
|
"Use a resource with a query surface, or address the record by id directly (get/fetchMany)."
|
|
699
700
|
);
|
|
700
701
|
}
|
|
701
|
-
const field = input.field !== void 0 ? String(input.field) :
|
|
702
|
+
const field = input.field !== void 0 ? String(input.field) : _chunkL6V66V22cjs.MARKER_FIELDS[resource];
|
|
702
703
|
if (typeof field !== "string" || field.trim() === "") {
|
|
703
704
|
configError(
|
|
704
705
|
`recovery: ${resource} has no plan markerField and no input.field was passed \u2014 the marker search needs a name-like field to filter on`,
|
|
@@ -734,7 +735,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
734
735
|
);
|
|
735
736
|
}
|
|
736
737
|
for (const c of input.filter) {
|
|
737
|
-
if (!
|
|
738
|
+
if (!_chunkL6V66V22cjs.isRecord.call(void 0, c) || typeof c.op !== "string" || c.op === "and" || c.op === "or") {
|
|
738
739
|
configError(
|
|
739
740
|
"recovery: input.filter accepts only plain leaf conditions ({ field, op, value }) \u2014 no grouping",
|
|
740
741
|
operation,
|
|
@@ -755,7 +756,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
755
756
|
}
|
|
756
757
|
limit = input.limit;
|
|
757
758
|
}
|
|
758
|
-
const boundaryNote =
|
|
759
|
+
const boundaryNote = _chunkL6V66V22cjs.DELETE_BOUNDARY_NOTES[resource];
|
|
759
760
|
const boundary = {
|
|
760
761
|
available: boundaryNote === void 0,
|
|
761
762
|
reason: _nullishCoalesce(boundaryNote, () => ( null)),
|
|
@@ -767,7 +768,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
767
768
|
};
|
|
768
769
|
const isDelete = action === "delete";
|
|
769
770
|
if (isDelete && boundaryNote !== void 0) {
|
|
770
|
-
throw new (0,
|
|
771
|
+
throw new (0, _chunkL6V66V22cjs.DeleteBoundaryError)(
|
|
771
772
|
`recovery: the vendor defines no DELETE for ${resource} \u2014 the delete cannot be issued through the API (zero wire was issued)`,
|
|
772
773
|
{
|
|
773
774
|
operation,
|
|
@@ -779,7 +780,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
779
780
|
const dryRun = _optionalChain([opts, 'optionalAccess', _13 => _13.dryRun]) !== false;
|
|
780
781
|
const confirm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _14 => _14.confirm]), () => ( input.confirm));
|
|
781
782
|
if (isDelete && !dryRun && confirm !== RECOVERY_CONFIRM) {
|
|
782
|
-
throw new (0,
|
|
783
|
+
throw new (0, _chunkL6V66V22cjs.ConfirmationRequiredError)(
|
|
783
784
|
`recovery: action 'delete' apply is destructive and requires its confirmation flag: pass confirm: "${RECOVERY_CONFIRM}"`,
|
|
784
785
|
{
|
|
785
786
|
operation: RECOVERY_CONFIRM,
|
|
@@ -795,7 +796,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
795
796
|
const query = await holder.queryBounded({ filter: conditions, limit });
|
|
796
797
|
if (query.hasMore) {
|
|
797
798
|
const wire = isDelete ? "DELETE wire" : "mutating wire";
|
|
798
|
-
throw new (0,
|
|
799
|
+
throw new (0, _chunkL6V66V22cjs.RecoveryTruncatedError)(
|
|
799
800
|
`recovery: the marker search on ${resource} TRIPPED its match cap (${limit}) \u2014 more matches exist than were returned (zero ${wire} was issued)`,
|
|
800
801
|
{
|
|
801
802
|
operation,
|
|
@@ -834,7 +835,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
834
835
|
return { ...base, simulated: true, dryRun: true };
|
|
835
836
|
}
|
|
836
837
|
if (unsafeId) {
|
|
837
|
-
throw new (0,
|
|
838
|
+
throw new (0, _chunkL6V66V22cjs.MarkerUnsafeIdError)(
|
|
838
839
|
`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)`,
|
|
839
840
|
{
|
|
840
841
|
operation,
|
|
@@ -845,7 +846,7 @@ async function recovery(client, input, opts = {}) {
|
|
|
845
846
|
}
|
|
846
847
|
const deleteMethod = holder.delete;
|
|
847
848
|
if (deleteMethod === void 0) {
|
|
848
|
-
throw new (0,
|
|
849
|
+
throw new (0, _chunkL6V66V22cjs.DeleteBoundaryError)(
|
|
849
850
|
`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`,
|
|
850
851
|
{
|
|
851
852
|
operation,
|
|
@@ -874,14 +875,14 @@ async function recovery(client, input, opts = {}) {
|
|
|
874
875
|
verify = "still-present";
|
|
875
876
|
}
|
|
876
877
|
} catch (err) {
|
|
877
|
-
if (err instanceof
|
|
878
|
+
if (err instanceof _chunkL6V66V22cjs.NotFoundError) verify = "not-found";
|
|
878
879
|
else {
|
|
879
880
|
verify = "error";
|
|
880
|
-
code =
|
|
881
|
+
code = _chunkL6V66V22cjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
|
|
881
882
|
}
|
|
882
883
|
}
|
|
883
884
|
} catch (err) {
|
|
884
|
-
code =
|
|
885
|
+
code = _chunkL6V66V22cjs.isAutotaskError.call(void 0, err) ? err.code : "SERVER_ERROR";
|
|
885
886
|
}
|
|
886
887
|
deleted.push({ id, verified: verify === "not-found", code });
|
|
887
888
|
}
|
|
@@ -889,13 +890,13 @@ async function recovery(client, input, opts = {}) {
|
|
|
889
890
|
}
|
|
890
891
|
|
|
891
892
|
// src/operations/invoke.ts
|
|
892
|
-
var RECORDS =
|
|
893
|
+
var RECORDS = _chunkFLYTKJKVcjs.CAPABILITIES;
|
|
893
894
|
var byId = new Map(RECORDS.map((r) => [r.id, r]));
|
|
894
895
|
function needsConfirmation(record) {
|
|
895
896
|
return record.effect === "destructive" || (_nullishCoalesce(record.flags, () => ( []))).includes("requiresApproval");
|
|
896
897
|
}
|
|
897
898
|
function refuse(message, operation, suggestedAction) {
|
|
898
|
-
throw new (0,
|
|
899
|
+
throw new (0, _chunkL6V66V22cjs.ConfirmationRequiredError)(message, { operation, suggestedAction });
|
|
899
900
|
}
|
|
900
901
|
var MODE_BY_EFFECT = {
|
|
901
902
|
read: "read",
|
|
@@ -939,7 +940,7 @@ function looseTypeOk(type, value) {
|
|
|
939
940
|
case "string[]":
|
|
940
941
|
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
941
942
|
case "object":
|
|
942
|
-
return
|
|
943
|
+
return _chunkL6V66V22cjs.isRecord.call(void 0, value);
|
|
943
944
|
default:
|
|
944
945
|
return true;
|
|
945
946
|
}
|
|
@@ -956,7 +957,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
956
957
|
const schema = _nullishCoalesce(record.inputSchema, () => ( {}));
|
|
957
958
|
const names = Object.keys(schema);
|
|
958
959
|
if (args.length > names.length) {
|
|
959
|
-
throw new (0,
|
|
960
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
960
961
|
`invoke: "${operation}" declares ${names.length} positional arg(s) (${declaredArgList(record)}) but ${args.length} were passed \u2014 extra args are refused, not dropped (v0.2.0 silently dropped them)`,
|
|
961
962
|
{
|
|
962
963
|
operation,
|
|
@@ -966,7 +967,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
966
967
|
}
|
|
967
968
|
const required = names.filter((n) => schema[n].required);
|
|
968
969
|
if (args.length < required.length) {
|
|
969
|
-
throw new (0,
|
|
970
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
970
971
|
`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)}`,
|
|
971
972
|
{ operation }
|
|
972
973
|
);
|
|
@@ -977,7 +978,7 @@ function validateDispatchArgs(record, argsIn) {
|
|
|
977
978
|
const name = names[i];
|
|
978
979
|
const spec = schema[name];
|
|
979
980
|
if (!looseTypeOk(spec.type, value)) {
|
|
980
|
-
throw new (0,
|
|
981
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
981
982
|
`invoke: "${operation}" arg ${i + 1} is declared ${name}: ${spec.type} \u2014 the value has the wrong type (pass a ${spec.type} value)`,
|
|
982
983
|
{ operation }
|
|
983
984
|
);
|
|
@@ -992,7 +993,10 @@ var PARAMS_BAG_KEYS = {
|
|
|
992
993
|
// cannot silently open the bag (the keys are the vendor `QueryParams` set
|
|
993
994
|
// the raw method accepts).
|
|
994
995
|
queryAll: ["filter", "maxRecords", "includeFields", "maxTotalRecords", "via"],
|
|
995
|
-
|
|
996
|
+
// issue #145: the count bag carries the fieldCheck opt-out — the #140
|
|
997
|
+
// refusal's advised remedy (before, the closed bag refused the very key it
|
|
998
|
+
// advised, and the remedy looped into a second CONFIG_ERROR).
|
|
999
|
+
count: ["filter", "fieldCheck"]
|
|
996
1000
|
};
|
|
997
1001
|
var BAG_KEY_SYNONYMS = {
|
|
998
1002
|
filters: "filter",
|
|
@@ -1034,11 +1038,11 @@ function validateParamsBag(record, args) {
|
|
|
1034
1038
|
const valid = PARAMS_BAG_KEYS[record.operation];
|
|
1035
1039
|
if (valid === void 0) return;
|
|
1036
1040
|
const bag = _optionalChain([args, 'optionalAccess', _15 => _15[0]]);
|
|
1037
|
-
if (bag === void 0 || bag === null || !
|
|
1041
|
+
if (bag === void 0 || bag === null || !_chunkL6V66V22cjs.isRecord.call(void 0, bag)) return;
|
|
1038
1042
|
const unknown = Object.keys(bag).filter((k) => !valid.includes(k));
|
|
1039
1043
|
if (unknown.length === 0) return;
|
|
1040
1044
|
const suggestions = unknown.map((k) => [k, suggestForKey(k, valid)]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
|
|
1041
|
-
throw new (0,
|
|
1045
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1042
1046
|
`invoke: "${record.id}" params bag has unknown key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the bag is closed (valid keys: ${valid.join(", ")})`,
|
|
1043
1047
|
{
|
|
1044
1048
|
operation: record.id,
|
|
@@ -1051,62 +1055,105 @@ async function liveFieldNames(holder) {
|
|
|
1051
1055
|
if (typeof reader !== "function") return null;
|
|
1052
1056
|
try {
|
|
1053
1057
|
const rows = await reader.call(holder);
|
|
1058
|
+
if (!Array.isArray(rows)) return null;
|
|
1054
1059
|
const names = [];
|
|
1055
1060
|
for (const row of rows) {
|
|
1056
1061
|
if (typeof row.name === "string") names.push(row.name);
|
|
1057
1062
|
}
|
|
1058
1063
|
return names.length > 0 ? names : null;
|
|
1059
1064
|
} catch (err) {
|
|
1060
|
-
if (!
|
|
1065
|
+
if (!_chunkL6V66V22cjs.isAutotaskError.call(void 0, err) || err.code === "ABORTED") throw err;
|
|
1061
1066
|
return null;
|
|
1062
1067
|
}
|
|
1063
1068
|
}
|
|
1064
1069
|
var UNKNOWN_NAME_LIST_CAP = 20;
|
|
1065
1070
|
var UNKNOWN_NAME_DISPLAY_CHARS = 80;
|
|
1066
|
-
|
|
1071
|
+
function formatUnknownNameList(names) {
|
|
1072
|
+
const listed = names.slice(0, UNKNOWN_NAME_LIST_CAP).map((n) => `"${n.length > UNKNOWN_NAME_DISPLAY_CHARS ? `${n.slice(0, UNKNOWN_NAME_DISPLAY_CHARS)}\u2026` : n}"`).join(", ");
|
|
1073
|
+
const more = names.length > UNKNOWN_NAME_LIST_CAP ? ` (and ${names.length - UNKNOWN_NAME_LIST_CAP} more)` : "";
|
|
1074
|
+
return `${listed}${more}`;
|
|
1075
|
+
}
|
|
1076
|
+
function collectFilterFieldNames(conditions) {
|
|
1077
|
+
const out = [];
|
|
1078
|
+
const walk = (conds) => {
|
|
1079
|
+
for (const cond of conds) {
|
|
1080
|
+
if (!_chunkL6V66V22cjs.isRecord.call(void 0, cond)) continue;
|
|
1081
|
+
if (cond.op === "and" || cond.op === "or") {
|
|
1082
|
+
if (Array.isArray(cond.items)) walk(cond.items);
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
if (cond.udf === true) continue;
|
|
1086
|
+
if (typeof cond.field === "string" && cond.field.length > 0) out.push(cond.field);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
walk(conditions);
|
|
1090
|
+
return out;
|
|
1091
|
+
}
|
|
1092
|
+
async function validateQueryFieldNames(record, holder, args) {
|
|
1067
1093
|
const bag = args[0];
|
|
1068
|
-
if (!
|
|
1094
|
+
if (!_chunkL6V66V22cjs.isRecord.call(void 0, bag)) return;
|
|
1069
1095
|
const fieldCheck = bag["fieldCheck"];
|
|
1070
1096
|
if (fieldCheck !== void 0 && typeof fieldCheck !== "boolean") {
|
|
1071
|
-
throw new (0,
|
|
1097
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1072
1098
|
`invoke: "${record.id}" params bag fieldCheck must be a boolean (got ${typeof fieldCheck}) \u2014 the request was not issued`,
|
|
1073
|
-
{ operation: record.id, suggestedAction: "Pass fieldCheck: true (default) or fieldCheck: false (disable the includeFields
|
|
1099
|
+
{ operation: record.id, suggestedAction: "Pass fieldCheck: true (default) or fieldCheck: false (disable the field-name checks \u2014 includeFields AND filter condition names)." }
|
|
1074
1100
|
);
|
|
1075
1101
|
}
|
|
1076
1102
|
const includeFields = bag["includeFields"];
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1103
|
+
let includeNames;
|
|
1104
|
+
if (includeFields !== void 0) {
|
|
1105
|
+
let shapeOk = Array.isArray(includeFields);
|
|
1106
|
+
const names = [];
|
|
1107
|
+
if (shapeOk) {
|
|
1108
|
+
for (const entry of includeFields) {
|
|
1109
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
1110
|
+
shapeOk = false;
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
names.push(entry);
|
|
1085
1114
|
}
|
|
1086
|
-
names.push(entry);
|
|
1087
1115
|
}
|
|
1116
|
+
if (!shapeOk) {
|
|
1117
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1118
|
+
`invoke: "${record.id}" params bag includeFields must be an array of non-empty field-name strings \u2014 the request was not issued`,
|
|
1119
|
+
{
|
|
1120
|
+
operation: record.id,
|
|
1121
|
+
suggestedAction: 'Pass includeFields as an array of exact vendor field names, e.g. ["id", "title"]; the live set is in operations.fieldCatalog.'
|
|
1122
|
+
}
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1125
|
+
includeNames = names;
|
|
1088
1126
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
operation: record.id,
|
|
1094
|
-
suggestedAction: 'Pass includeFields as an array of exact vendor field names, e.g. ["id", "title"]; the live set is in operations.fieldCatalog.'
|
|
1095
|
-
}
|
|
1096
|
-
);
|
|
1127
|
+
let filterNames;
|
|
1128
|
+
if (bag["filter"] !== void 0) {
|
|
1129
|
+
const conditions = _chunkL6V66V22cjs.normalizedConditions.call(void 0, bag["filter"]);
|
|
1130
|
+
filterNames = collectFilterFieldNames(_nullishCoalesce(conditions, () => ( [])));
|
|
1097
1131
|
}
|
|
1098
|
-
if (names.length === 0) return;
|
|
1099
1132
|
if (fieldCheck === false) return;
|
|
1133
|
+
const hasInclude = includeNames !== void 0 && includeNames.length > 0;
|
|
1134
|
+
const hasFilter = filterNames !== void 0 && filterNames.length > 0;
|
|
1135
|
+
if (!hasInclude && !hasFilter) return;
|
|
1100
1136
|
const live = await liveFieldNames(holder);
|
|
1101
|
-
|
|
1137
|
+
let known;
|
|
1138
|
+
let liveOnlyExempt = [];
|
|
1139
|
+
if (live !== null) {
|
|
1140
|
+
known = live;
|
|
1141
|
+
} else {
|
|
1142
|
+
const vendored = _chunkL6V66V22cjs.MODEL_FIELD_SETS[record.resource];
|
|
1143
|
+
liveOnlyExempt = Array.isArray(_optionalChain([record, 'access', _16 => _16.metadata, 'optionalAccess', _17 => _17.liveOnlyFields])) ? record.metadata.liveOnlyFields : [];
|
|
1144
|
+
known = vendored === void 0 ? void 0 : [...vendored, ...liveOnlyExempt];
|
|
1145
|
+
}
|
|
1102
1146
|
if (known === void 0) return;
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1109
|
-
|
|
1147
|
+
const authority = live !== null ? "the tenant's live entity field metadata" : liveOnlyExempt.length > 0 ? "the vendored spec (src/field-sets.ts) + the plan-pinned live-only fields (exempt from the vendored refusal)" : "the vendored spec (src/field-sets.ts)";
|
|
1148
|
+
const unknownInclude = hasInclude ? includeNames.filter((name) => !known.includes(name)) : [];
|
|
1149
|
+
const unknownFilter = hasFilter ? [...new Set(filterNames.filter((name) => !known.includes(name)))] : [];
|
|
1150
|
+
if (unknownInclude.length === 0 && unknownFilter.length === 0) return;
|
|
1151
|
+
const parts = [];
|
|
1152
|
+
if (unknownInclude.length > 0) parts.push(`includeFields has unknown field name(s) ${formatUnknownNameList(unknownInclude)}`);
|
|
1153
|
+
if (unknownFilter.length > 0) parts.push(`filter condition(s) carry unknown field name(s) ${formatUnknownNameList(unknownFilter)}`);
|
|
1154
|
+
const wireClause = record.operation === "count" ? "the count request was not issued" : "the query POST was not issued";
|
|
1155
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1156
|
+
`invoke: "${record.id}" ${parts.join("; ")} against ${authority} \u2014 ${wireClause}`,
|
|
1110
1157
|
{
|
|
1111
1158
|
operation: record.id,
|
|
1112
1159
|
suggestedAction: `Use exact vendor field names (operations.fieldCatalog lists the live set for the entity); pass fieldCheck: false to disable this name check. The authority here was ${authority}.`
|
|
@@ -1119,7 +1166,7 @@ function validateInvokeOptions(opts, operation) {
|
|
|
1119
1166
|
const unknown = Object.keys(opts).filter((k) => !INVOKE_OPTION_KEYS.includes(k));
|
|
1120
1167
|
if (unknown.length === 0) return;
|
|
1121
1168
|
const suggestions = unknown.map((k) => [k, suggestForKey(k, ["dryRun", "confirm", "lastModifiedDate", "maxRetries"])]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
|
|
1122
|
-
throw new (0,
|
|
1169
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1123
1170
|
`invoke: "${operation}" has unknown option key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the options set is closed (valid: dryRun, confirm, lastModifiedDate, maxRetries; "mode" is internal to the mode wrappers)`,
|
|
1124
1171
|
{
|
|
1125
1172
|
operation,
|
|
@@ -1132,7 +1179,7 @@ function unknownKeysRefusal(raw, validKeys, subject, operation) {
|
|
|
1132
1179
|
const unknown = Object.keys(raw).filter((k) => !validKeys.includes(k));
|
|
1133
1180
|
if (unknown.length === 0) return null;
|
|
1134
1181
|
const suggestions = unknown.map((k) => [k, suggestForKey(k, [...validKeys])]).filter((pair) => pair[1] !== null).map(([k, s]) => `"${k}" \u2192 "${s}"`);
|
|
1135
|
-
return new (0,
|
|
1182
|
+
return new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1136
1183
|
`unknown ${subject} ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the ${subject} set is closed (valid keys: ${validKeys.join(", ")})`,
|
|
1137
1184
|
{
|
|
1138
1185
|
...operation !== void 0 ? { operation } : {},
|
|
@@ -1144,7 +1191,7 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1144
1191
|
const args = _nullishCoalesce(argsIn, () => ( []));
|
|
1145
1192
|
const record = byId.get(operation);
|
|
1146
1193
|
if (record === void 0) {
|
|
1147
|
-
throw new (0,
|
|
1194
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1148
1195
|
`invoke: unknown operation "${operation}" \u2014 it is not in the capability registry`,
|
|
1149
1196
|
{ operation, suggestedAction: "List the registry (the ./capabilities subpath) for the exact operation key." }
|
|
1150
1197
|
);
|
|
@@ -1152,17 +1199,17 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1152
1199
|
validateInvokeOptions(opts, operation);
|
|
1153
1200
|
const mode = opts.mode;
|
|
1154
1201
|
if (mode !== void 0 && MODE_BY_EFFECT[record.effect] !== mode) {
|
|
1155
|
-
throw new (0,
|
|
1202
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(crossModeRefusal(operation, record.effect, mode), { operation });
|
|
1156
1203
|
}
|
|
1157
1204
|
if (opts.dryRun !== void 0 && typeof opts.dryRun !== "boolean") {
|
|
1158
|
-
throw new (0,
|
|
1205
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1159
1206
|
`invoke: dryRun must be a boolean (got ${typeof opts.dryRun}) \u2014 "${operation}" was not issued`,
|
|
1160
1207
|
{ operation, suggestedAction: "Pass dryRun: true (simulate) or dryRun: false (apply) as a real boolean." }
|
|
1161
1208
|
);
|
|
1162
1209
|
}
|
|
1163
1210
|
const isWrite = record.effect !== "read";
|
|
1164
1211
|
if (!isWrite && opts.dryRun === true) {
|
|
1165
|
-
throw new (0,
|
|
1212
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1166
1213
|
`invoke: "${operation}" is a read \u2014 dryRun is not applicable (reads issue their request as-is)`,
|
|
1167
1214
|
{ operation }
|
|
1168
1215
|
);
|
|
@@ -1177,15 +1224,16 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1177
1224
|
validateDispatchArgs(record, args);
|
|
1178
1225
|
validateParamsBag(record, args);
|
|
1179
1226
|
const boundedQuery = record.kind === "primitive" && record.operation === "query";
|
|
1180
|
-
|
|
1227
|
+
const countedQuery = record.kind === "primitive" && record.operation === "count";
|
|
1228
|
+
let holder = client[_chunkL6V66V22cjs.camelKey.call(void 0, record.resource)];
|
|
1181
1229
|
if (typeof holder === "function") {
|
|
1182
|
-
holder = _nullishCoalesce(client[`${
|
|
1230
|
+
holder = _nullishCoalesce(client[`${_chunkL6V66V22cjs.camelKey.call(void 0, record.resource)}Resource`], () => ( holder));
|
|
1183
1231
|
}
|
|
1184
1232
|
if (holder === void 0 && record.resource === "operations") {
|
|
1185
1233
|
holder = {
|
|
1186
1234
|
resolveAny: (identifier, opts2) => resolveAny(client, identifier, opts2),
|
|
1187
1235
|
searchAcrossResources: (query, opts2) => searchAcrossResources(client, query, opts2),
|
|
1188
|
-
fetchMany: (items, opts2) =>
|
|
1236
|
+
fetchMany: (items, opts2) => _chunkL6V66V22cjs.fetchMany.call(void 0, client, items, opts2),
|
|
1189
1237
|
// Issue #62: the generic aggregate + the cheap count — the
|
|
1190
1238
|
// groupBy/sum-absent mode is ONE vendor /query/count (the S12-C blind
|
|
1191
1239
|
// sentinel rides through); the group/sum modes walk the named
|
|
@@ -1195,12 +1243,12 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1195
1243
|
// Issue #59 PR-B: the bulk fetch by ids — query-first chunked `id in`
|
|
1196
1244
|
// reads + the per-id `get` fallback (blind-surface-safe; per-item
|
|
1197
1245
|
// typed outcomes reuse the fetchMany shapes).
|
|
1198
|
-
fetchByIds: (items, opts2) =>
|
|
1246
|
+
fetchByIds: (items, opts2) => _chunkL6V66V22cjs.fetchByIds.call(void 0, client, items, opts2),
|
|
1199
1247
|
// Issue #65: opt-in resource name expansion — per-id resources.get
|
|
1200
1248
|
// reads ONLY (never an id-in query — the resources table can be blind
|
|
1201
1249
|
// to count/query while per-id reads work); blind-marked rows for ids
|
|
1202
1250
|
// the API user cannot resolve; the name cache (default-on).
|
|
1203
|
-
expandResourceNames: (ids, opts2) =>
|
|
1251
|
+
expandResourceNames: (ids, opts2) => _chunkL6V66V22cjs.expandResourceNames.call(void 0, client, ids, opts2),
|
|
1204
1252
|
relationshipMap: (resourceKey) => relationshipMap(client, resourceKey),
|
|
1205
1253
|
// Issue #11: the served blind-surface inventory (zero wire) + the
|
|
1206
1254
|
// bounded caller-opted reachability sweep (read-only, confirmProbe-
|
|
@@ -1213,7 +1261,7 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1213
1261
|
// entityInformation GETs (the op's own cap refuses over-cap fan-outs
|
|
1214
1262
|
// pre-request; per-resource failures are recorded on the row and
|
|
1215
1263
|
// never abort the call).
|
|
1216
|
-
fieldCatalog: (opts2) =>
|
|
1264
|
+
fieldCatalog: (opts2) => _chunkL6V66V22cjs.fieldCatalog.call(void 0, client, opts2),
|
|
1217
1265
|
// Issue #9: the one-call recovery/cleanup op — effect write in the
|
|
1218
1266
|
// registry (the governor's dry-run-first applies to it); the op's own
|
|
1219
1267
|
// confirm gate makes the destructive action deliberate (the governor
|
|
@@ -1222,16 +1270,16 @@ async function invokeMode(client, operation, argsIn = [], opts = {}) {
|
|
|
1222
1270
|
};
|
|
1223
1271
|
}
|
|
1224
1272
|
if (holder === void 0) {
|
|
1225
|
-
throw new (0,
|
|
1273
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1226
1274
|
`invoke: the client exposes no accessor for resource "${record.resource}"`,
|
|
1227
1275
|
{ operation }
|
|
1228
1276
|
);
|
|
1229
1277
|
}
|
|
1230
|
-
if (boundedQuery) await
|
|
1278
|
+
if (boundedQuery || countedQuery) await validateQueryFieldNames(record, holder, args);
|
|
1231
1279
|
const methodName = boundedQuery ? "queryBounded" : record.operation;
|
|
1232
1280
|
const method = holder[methodName];
|
|
1233
1281
|
if (typeof method !== "function") {
|
|
1234
|
-
throw new (0,
|
|
1282
|
+
throw new (0, _chunkL6V66V22cjs.AutotaskConfigError)(
|
|
1235
1283
|
`invoke: "${record.resource}.${methodName}" is not a callable method on the client`,
|
|
1236
1284
|
{ operation }
|
|
1237
1285
|
);
|
|
@@ -1338,4 +1386,4 @@ async function invokeDelete(client, operation, args = [], opts = {}) {
|
|
|
1338
1386
|
|
|
1339
1387
|
|
|
1340
1388
|
|
|
1341
|
-
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 =
|
|
1389
|
+
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 = _chunkL6V66V22cjs.EXPAND_RESOURCE_NAMES_MAX_IDS; exports.FETCH_BY_IDS_CHUNK_SIZE = _chunkL6V66V22cjs.FETCH_BY_IDS_CHUNK_SIZE; exports.FETCH_BY_IDS_MAX_ITEMS = _chunkL6V66V22cjs.FETCH_BY_IDS_MAX_ITEMS; exports.FETCH_MANY_MAX_ITEMS = _chunkL6V66V22cjs.FETCH_MANY_MAX_ITEMS; exports.FIELD_CACHE_KINDS = _chunkL6V66V22cjs.FIELD_CACHE_KINDS; exports.FIELD_CATALOG_HONESTY_NOTE = _chunkL6V66V22cjs.FIELD_CATALOG_HONESTY_NOTE; exports.INVOKE_OPTION_KEYS = INVOKE_OPTION_KEYS; exports.MAX_FIELD_CATALOG_WIRE = _chunkL6V66V22cjs.MAX_FIELD_CATALOG_WIRE; exports.PARAMS_BAG_KEYS = PARAMS_BAG_KEYS; exports.PICKLIST_VALUE_NOT_SERVED_NOTE = _chunkL6V66V22cjs.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.WORKFLOW_RESOURCES = _chunkL6V66V22cjs.WORKFLOW_RESOURCES; exports.aggregate = aggregate; exports.blindSurfaces = blindSurfaces; exports.createGuidance = createGuidance; exports.dateBucketLabel = dateBucketLabel; exports.expandResourceNames = _chunkL6V66V22cjs.expandResourceNames; exports.fetchByIds = _chunkL6V66V22cjs.fetchByIds; exports.fetchMany = _chunkL6V66V22cjs.fetchMany; exports.fieldCatalog = _chunkL6V66V22cjs.fieldCatalog; 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.searchAcrossResources = searchAcrossResources; exports.unknownKeysRefusal = unknownKeysRefusal; exports.validateDispatchArgs = validateDispatchArgs; exports.validateFetchManyItems = _chunkL6V66V22cjs.validateFetchManyItems; exports.validateInvokeOptions = validateInvokeOptions; exports.validateParamsBag = validateParamsBag;
|