node-autotask 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/MCP_TOOL_CATALOG.json +2 -2
  2. package/MCP_TOOL_MANIFEST.md +4 -4
  3. package/N8N_MCP_MANIFEST.json +2 -2
  4. package/N8N_MCP_MANIFEST.md +3 -3
  5. package/capabilities.json +1259 -1259
  6. package/dist/capabilities.cjs +2 -3
  7. package/dist/capabilities.js +1 -2
  8. package/dist/{chunk-UYJ5V262.js → chunk-3VB6N44U.js} +32 -182
  9. package/dist/{chunk-BZPFDRAE.js → chunk-6KFP5HV3.js} +1258 -1259
  10. package/dist/chunk-DMMMWO6A.js +0 -0
  11. package/dist/chunk-FLB2X6O5.cjs +1 -0
  12. package/dist/{chunk-UDWV4VVD.js → chunk-HWC2WPX2.js} +214 -20
  13. package/dist/chunk-IDPB4N2Q.cjs +1 -0
  14. package/dist/{chunk-QJU2N32V.js → chunk-NVJ2PTN3.js} +2 -3
  15. package/dist/{chunk-53MC2QRQ.cjs → chunk-QUM74WLQ.cjs} +135 -136
  16. package/dist/{chunk-OYHKIYVR.cjs → chunk-S7VMY5KN.cjs} +422 -572
  17. package/dist/chunk-UPQIUWOS.js +0 -0
  18. package/dist/{chunk-LTKMTXUR.cjs → chunk-WTVD2JZN.cjs} +1258 -1259
  19. package/dist/{chunk-RWLPTU67.cjs → chunk-WTVLHMZA.cjs} +235 -41
  20. package/dist/{index-ZknpNhtc.d.ts → index-BOyh7S65.d.cts} +8 -8
  21. package/dist/{index-CfU1JDgS.d.cts → index-DGgMD8aq.d.ts} +8 -8
  22. package/dist/{index-O2zzIMcQ.d.cts → index-cQ6CRexR.d.cts} +3 -1
  23. package/dist/{index-O2zzIMcQ.d.ts → index-cQ6CRexR.d.ts} +3 -1
  24. package/dist/index.cjs +21 -22
  25. package/dist/index.d.cts +4 -4
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +6 -7
  28. package/dist/operations/index.cjs +133 -129
  29. package/dist/operations/index.d.cts +8 -3
  30. package/dist/operations/index.d.ts +8 -3
  31. package/dist/operations/index.js +9 -5
  32. package/dist/pool.cjs +36 -12
  33. package/dist/pool.d.cts +2 -2
  34. package/dist/pool.d.ts +2 -2
  35. package/dist/pool.js +31 -7
  36. package/dist/resources/index.cjs +5 -6
  37. package/dist/resources/index.d.cts +2 -2
  38. package/dist/resources/index.d.ts +2 -2
  39. package/dist/resources/index.js +4 -5
  40. package/dist/types/index.cjs +1 -2
  41. package/dist/types/index.d.cts +1 -1
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/types/index.js +1 -2
  44. package/dist/untrusted.cjs +0 -1
  45. package/dist/untrusted.js +0 -1
  46. package/docs/API.md +12 -6
  47. package/package.json +1 -1
  48. package/dist/capabilities.cjs.map +0 -1
  49. package/dist/capabilities.js.map +0 -1
  50. package/dist/chunk-53MC2QRQ.cjs.map +0 -1
  51. package/dist/chunk-BZPFDRAE.js.map +0 -1
  52. package/dist/chunk-CXM35TEC.cjs +0 -1
  53. package/dist/chunk-CXM35TEC.cjs.map +0 -1
  54. package/dist/chunk-GIVD2CQ3.js +0 -1
  55. package/dist/chunk-GIVD2CQ3.js.map +0 -1
  56. package/dist/chunk-LTKMTXUR.cjs.map +0 -1
  57. package/dist/chunk-MHBMSBTA.js +0 -1
  58. package/dist/chunk-MHBMSBTA.js.map +0 -1
  59. package/dist/chunk-NZUFSSIZ.cjs +0 -1
  60. package/dist/chunk-NZUFSSIZ.cjs.map +0 -1
  61. package/dist/chunk-OYHKIYVR.cjs.map +0 -1
  62. package/dist/chunk-QJU2N32V.js.map +0 -1
  63. package/dist/chunk-RWLPTU67.cjs.map +0 -1
  64. package/dist/chunk-UDWV4VVD.js.map +0 -1
  65. package/dist/chunk-UYJ5V262.js.map +0 -1
  66. package/dist/index.cjs.map +0 -1
  67. package/dist/index.js.map +0 -1
  68. package/dist/operations/index.cjs.map +0 -1
  69. package/dist/operations/index.js.map +0 -1
  70. package/dist/pool.cjs.map +0 -1
  71. package/dist/pool.js.map +0 -1
  72. package/dist/resources/index.cjs.map +0 -1
  73. package/dist/resources/index.js.map +0 -1
  74. package/dist/types/index.cjs.map +0 -1
  75. package/dist/types/index.js.map +0 -1
  76. package/dist/untrusted.cjs.map +0 -1
  77. package/dist/untrusted.js.map +0 -1
@@ -2,10 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkLTKMTXURcjs = require('./chunk-LTKMTXUR.cjs');
5
+ var _chunkWTVD2JZNcjs = require('./chunk-WTVD2JZN.cjs');
6
6
 
7
7
 
8
8
 
9
9
 
10
- exports.CAPABILITIES = _chunkLTKMTXURcjs.CAPABILITIES; exports.CAPABILITY_GROUPS = _chunkLTKMTXURcjs.CAPABILITY_GROUPS; exports.CAPABILITY_PLAN_HASHES = _chunkLTKMTXURcjs.CAPABILITY_PLAN_HASHES;
11
- //# sourceMappingURL=capabilities.cjs.map
10
+ exports.CAPABILITIES = _chunkWTVD2JZNcjs.CAPABILITIES; exports.CAPABILITY_GROUPS = _chunkWTVD2JZNcjs.CAPABILITY_GROUPS; exports.CAPABILITY_PLAN_HASHES = _chunkWTVD2JZNcjs.CAPABILITY_PLAN_HASHES;
@@ -2,10 +2,9 @@ import {
2
2
  CAPABILITIES,
3
3
  CAPABILITY_GROUPS,
4
4
  CAPABILITY_PLAN_HASHES
5
- } from "./chunk-BZPFDRAE.js";
5
+ } from "./chunk-6KFP5HV3.js";
6
6
  export {
7
7
  CAPABILITIES,
8
8
  CAPABILITY_GROUPS,
9
9
  CAPABILITY_PLAN_HASHES
10
10
  };
11
- //# sourceMappingURL=capabilities.js.map
@@ -4,34 +4,36 @@ import {
4
4
  BLIND_SURFACE_STAMPS,
5
5
  BaseResource,
6
6
  ConflictError,
7
- FIELD_CATALOG_HONESTY_NOTE,
8
7
  NotFoundError,
9
8
  RELATIONSHIP_MAP,
10
9
  ResolutionError,
11
10
  StaleObjectError,
11
+ TICKET_LABEL_FIELDS,
12
12
  UNTRUSTED_FIELDS_BY_RESOURCE,
13
+ addLabelSibling,
14
+ addNameSibling,
13
15
  blindStampFor,
14
16
  buildDryRunResult,
15
17
  buildFilter,
16
18
  clampPageSize,
19
+ createNamePlan,
17
20
  cursorToPath,
18
21
  decodeFileData,
19
- expandResourceNames,
20
- fieldCatalog,
21
22
  formatVendorDetail,
22
23
  isAutotaskError,
23
24
  mergePartialBody,
24
25
  parseIdentifier,
25
26
  parseVendorErrors,
27
+ resolveCompositeNames,
26
28
  resolveFieldsPreset,
27
29
  truncateNoteChars,
28
30
  unwrapItem,
29
31
  unwrapItems,
30
32
  unwrapOperation
31
- } from "./chunk-UDWV4VVD.js";
33
+ } from "./chunk-HWC2WPX2.js";
32
34
  import {
33
35
  CAPABILITIES
34
- } from "./chunk-BZPFDRAE.js";
36
+ } from "./chunk-6KFP5HV3.js";
35
37
 
36
38
  // src/resources/appointments.ts
37
39
  var AppointmentsResource = class extends BaseResource {
@@ -820,181 +822,6 @@ var ClassificationIconsResource = class extends BaseResource {
820
822
  }
821
823
  };
822
824
 
823
- // src/operations/compositeNames.ts
824
- var DEFAULT_MAX_NAME_READS = 20;
825
- var TICKET_LABEL_FIELDS = ["status", "priority", "ticketType", "issueType", "subIssueType", "source", "queueID"];
826
- function isVendorId(value) {
827
- if (typeof value === "number") return Number.isSafeInteger(value) && value >= 0;
828
- if (typeof value === "string") return /^\d+$/.test(value);
829
- return false;
830
- }
831
- function createNamePlan(labelFields = []) {
832
- const resourceIds = [];
833
- const resSeen = /* @__PURE__ */ new Set();
834
- const recordFks = [];
835
- const fkSeen = /* @__PURE__ */ new Set();
836
- return {
837
- plan: () => ({ resourceIds, recordFks, labelFields }),
838
- addResource: (value) => {
839
- if (!isVendorId(value)) return;
840
- const k = String(value);
841
- if (!resSeen.has(k)) {
842
- resSeen.add(k);
843
- resourceIds.push(value);
844
- }
845
- },
846
- addFk: (table, value) => {
847
- if (!isVendorId(value)) return;
848
- const k = `${table}:${String(value)}`;
849
- if (!fkSeen.has(k)) {
850
- fkSeen.add(k);
851
- recordFks.push({ table, id: value });
852
- }
853
- }
854
- };
855
- }
856
- function addNameSibling(row, field, resolve) {
857
- const value = row[field];
858
- if (value === void 0) return;
859
- row[`${field}Name`] = isVendorId(value) ? resolve(value) : null;
860
- }
861
- function addLabelSibling(row, field, names) {
862
- const value = row[field];
863
- if (value === void 0) return;
864
- row[`${field}Label`] = names.labelFor(field, value);
865
- }
866
- var FK_TABLE_PATH = {
867
- role: "/V1.0/Roles",
868
- billingCode: "/V1.0/BillingCodes",
869
- contract: "/V1.0/Contracts"
870
- };
871
- var FK_NAME_FIELD = {
872
- role: "name",
873
- billingCode: "name",
874
- contract: "contractName"
875
- };
876
- function fkName(record, table) {
877
- const value = record[FK_NAME_FIELD[table]];
878
- return typeof value === "string" && value.trim() !== "" ? value : null;
879
- }
880
- function faultRow(err) {
881
- const e = err;
882
- return e.httpStatus !== void 0 ? { code: e.code, message: e.message, httpStatus: e.httpStatus } : { code: e.code, message: e.message };
883
- }
884
- async function resolveCompositeNames(http, plan, opts = {}) {
885
- if (opts.maxNameReads !== void 0 && (!Number.isInteger(opts.maxNameReads) || opts.maxNameReads < 1)) {
886
- throw new AutotaskConfigError(`composite names: maxNameReads must be an integer >= 1 (got ${String(opts.maxNameReads)})`);
887
- }
888
- const budget = Math.min(DEFAULT_MAX_NAME_READS, opts.maxNameReads ?? DEFAULT_MAX_NAME_READS);
889
- const client = http.client;
890
- if (client === void 0) {
891
- throw new AutotaskConfigError("composite names: the transport is not wired to an AutotaskClient (the composite must run through the client)");
892
- }
893
- const readCache = http.readCache;
894
- const nameCache = http.resourceNameCache;
895
- const section = { truncated: false, rows: {}, reasons: {} };
896
- let remaining = budget;
897
- const coldResource = [];
898
- for (const id of plan.resourceIds) {
899
- if (nameCache !== void 0 && nameCache.get(id) !== void 0) continue;
900
- if (readCache !== void 0 && readCache.get(`/V1.0/Resources/${id}`) !== void 0) continue;
901
- coldResource.push(id);
902
- }
903
- const withinBudget = coldResource.slice(0, remaining);
904
- const overBudgetResource = coldResource.slice(remaining);
905
- remaining -= withinBudget.length;
906
- for (const id of overBudgetResource) {
907
- section.rows[`resource:${id}`] = { name: null, blind: false, capped: true };
908
- section.truncated = true;
909
- }
910
- const overSet = new Set(overBudgetResource.map((id) => String(id)));
911
- const opIds = plan.resourceIds.filter((id) => !overSet.has(String(id)));
912
- if (opIds.length > 0) {
913
- let pass = opIds;
914
- if (pass.length > 500) {
915
- for (const id of pass.slice(500)) {
916
- section.rows[`resource:${id}`] = { name: null, blind: false, capped: true };
917
- section.truncated = true;
918
- }
919
- pass = pass.slice(0, 500);
920
- }
921
- const res = await expandResourceNames(client, pass);
922
- for (const r of res.results) {
923
- const row = { name: r.name, blind: r.blind, capped: false };
924
- if (r.error !== void 0) row.error = faultRow(r.error);
925
- section.rows[`resource:${r.id}`] = row;
926
- }
927
- }
928
- const holders = {
929
- role: client.roles,
930
- billingCode: client.billingCodes,
931
- contract: client.contracts
932
- };
933
- for (const fk of plan.recordFks) {
934
- const key = `${fk.table}:${fk.id}`;
935
- const cold = readCache === void 0 || readCache.get(`${FK_TABLE_PATH[fk.table]}/${fk.id}`) === void 0;
936
- if (cold) {
937
- if (remaining < 1) {
938
- section.rows[key] = { name: null, blind: false, capped: true };
939
- section.truncated = true;
940
- continue;
941
- }
942
- remaining -= 1;
943
- }
944
- try {
945
- const record = await holders[fk.table].get(fk.id);
946
- section.rows[key] = { name: fkName(record, fk.table), blind: false, capped: false };
947
- } catch (err) {
948
- if (err instanceof NotFoundError) {
949
- section.rows[key] = { name: null, blind: true, capped: false };
950
- } else if (isAutotaskError(err) && err.code !== "ABORTED") {
951
- section.rows[key] = { name: null, blind: false, capped: false, error: faultRow(err) };
952
- } else {
953
- throw err;
954
- }
955
- }
956
- }
957
- const picklists = {};
958
- if (plan.labelFields.length > 0) {
959
- let usable = true;
960
- try {
961
- const catalog = await fieldCatalog(client, { resources: ["tickets"], labels: true, fields: [...plan.labelFields] });
962
- const row = catalog.rows.find((r) => r.resource === "tickets");
963
- if (row === void 0 || row.error !== null || row.fields === void 0) {
964
- usable = false;
965
- } else {
966
- for (const f of plan.labelFields) {
967
- const frow = row.fields.find((x) => x.name === f);
968
- picklists[f] = frow?.picklistValues;
969
- }
970
- }
971
- } catch (err) {
972
- if (isAutotaskError(err) && err.code !== "ABORTED") usable = false;
973
- else throw err;
974
- }
975
- if (!usable) for (const f of plan.labelFields) section.reasons[f] = FIELD_CATALOG_HONESTY_NOTE;
976
- }
977
- return {
978
- section,
979
- resourceName: (id) => section.rows[`resource:${id}`]?.name ?? null,
980
- recordName: (table, id) => section.rows[`${table}:${id}`]?.name ?? null,
981
- labelFor: (field, value) => {
982
- if (value === null || value === void 0) return null;
983
- const values = picklists[field];
984
- if (values === void 0) {
985
- section.reasons[field] = FIELD_CATALOG_HONESTY_NOTE;
986
- return null;
987
- }
988
- const hit = values.find((v) => String(v.value) === String(value));
989
- if (hit === void 0) {
990
- section.reasons[field] = FIELD_CATALOG_HONESTY_NOTE;
991
- return null;
992
- }
993
- return typeof hit.label === "string" ? hit.label : null;
994
- }
995
- };
996
- }
997
-
998
825
  // src/resources/special/companies.ts
999
826
  var DEFAULT_LIMIT2 = 25;
1000
827
  var MAX_LIMIT2 = 500;
@@ -1092,6 +919,22 @@ async function familyChildPage(http, parentID) {
1092
919
  const { items, pageDetails } = unwrapItems(res, "companies.search");
1093
920
  return { rows: items, hasNext: pageDetails.nextPageUrl !== null };
1094
921
  }
922
+ function assertSearchWithDetailOpts(opts) {
923
+ if (opts === void 0) return;
924
+ if (typeof opts !== "object" || opts === null || Array.isArray(opts)) {
925
+ throw new AutotaskConfigError("companies.searchWithDetail: opts must be an object { limit?: number }", {
926
+ operation: "companies.searchWithDetail"
927
+ });
928
+ }
929
+ for (const key of Object.keys(opts)) {
930
+ if (key !== "limit") {
931
+ throw new AutotaskConfigError(
932
+ `companies.searchWithDetail: unknown opts key "${key}" \u2014 the bag is closed: limit (includeFamily is a companies.search option)`,
933
+ { operation: "companies.searchWithDetail" }
934
+ );
935
+ }
936
+ }
937
+ }
1095
938
  async function searchWithFamily(_resource, query, opts = {}, http) {
1096
939
  if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
1097
940
  throw new AutotaskConfigError("companies.search: opts must be an object { limit?: number, includeFamily?: boolean }");
@@ -1640,7 +1483,8 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
1640
1483
  capped: false,
1641
1484
  hasMore: false,
1642
1485
  status: "skipped",
1643
- note: "skipped: the company (set) has no tickets or tasks in the returned join set \u2014 no tasks/tickets to join against is NOT evidence of no time entries (zero wire)"
1486
+ // joinNotes ride the skipped part too: an empty join set from a PARTIAL read (e.g. a full projects page) is not a true zero
1487
+ note: ["skipped: the company (set) has no tickets or tasks in the returned join set \u2014 no tasks/tickets to join against is NOT evidence of no time entries (zero wire)", ...joinNotes].join(" | ")
1644
1488
  };
1645
1489
  } else {
1646
1490
  const timeConditions = taskCap.ids.length > 0 && ticketCap.ids.length > 0 ? [{ op: "or", items: [{ field: "taskID", op: "in", value: taskCap.ids }, { field: "ticketID", op: "in", value: ticketCap.ids }] }] : taskCap.ids.length > 0 ? [{ field: "taskID", op: "in", value: taskCap.ids }] : [{ field: "ticketID", op: "in", value: ticketCap.ids }];
@@ -1833,6 +1677,13 @@ var CompaniesResource = class extends BaseResource {
1833
1677
  async search(query, opts) {
1834
1678
  return searchWithFamily(this, query, opts, this.http);
1835
1679
  }
1680
+ /** `search` with an empty result explained. Same closed opts discipline as `search`: only `limit` is
1681
+ * accepted here (an unknown key is refused pre-request, zero wire — never silently dropped); the
1682
+ * family block is a `search`-only option. */
1683
+ async searchWithDetail(query, opts = {}) {
1684
+ assertSearchWithDetailOpts(opts);
1685
+ return super.searchWithDetail(query, opts);
1686
+ }
1836
1687
  /** Get the Company with its primary context records in one call (each part a single-record
1837
1688
  * fetch; no sub-lists; absent/dangling references come back null). */
1838
1689
  async getContext(id) {
@@ -11082,4 +10933,3 @@ export {
11082
10933
  VersionResource,
11083
10934
  ZoneInformationResource
11084
10935
  };
11085
- //# sourceMappingURL=chunk-UYJ5V262.js.map