node-autotask 0.26.0 → 0.27.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 +47 -0
- package/MCP_TOOL_CATALOG.json +921 -30
- package/MCP_TOOL_MANIFEST.md +69 -16
- package/N8N_MCP_MANIFEST.json +39 -8
- package/N8N_MCP_MANIFEST.md +9 -8
- package/README.md +11 -9
- package/capabilities.json +13316 -7733
- package/capabilities.schema.json +125 -0
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-SSUECUVN.js → chunk-42ZUISDH.js} +947 -128
- package/dist/{chunk-WM6E5O55.cjs → chunk-5CC7LGNM.cjs} +13315 -7732
- package/dist/{chunk-SG4LIVMG.cjs → chunk-5GGCSRT4.cjs} +848 -439
- package/dist/{chunk-QXWIQ67O.js → chunk-F7FVOXPQ.js} +13315 -7732
- package/dist/{chunk-7DOSJS6S.js → chunk-GURC52J7.js} +23 -2
- package/dist/{chunk-5OGJTS2E.cjs → chunk-UHTZLUDE.cjs} +157 -136
- package/dist/{chunk-VVQ6NJYZ.js → chunk-ZGTFVZL5.js} +433 -24
- package/dist/{chunk-HQGE4WAV.cjs → chunk-ZJ4ONAQF.cjs} +1054 -235
- package/dist/{index-CKYr0unq.d.cts → index-BIWy9m-a.d.ts} +379 -49
- package/dist/{index-C8QH3BkP.d.ts → index-D4XYtn4s.d.cts} +379 -49
- package/dist/{index-1zBdJIEy.d.cts → index-DQ9NgraW.d.cts} +281 -1
- package/dist/{index-1zBdJIEy.d.ts → index-DQ9NgraW.d.ts} +281 -1
- package/dist/index.cjs +44 -24
- package/dist/index.d.cts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +26 -6
- package/dist/operations/index.cjs +147 -120
- package/dist/operations/index.d.cts +136 -7
- package/dist/operations/index.d.ts +136 -7
- package/dist/operations/index.js +33 -6
- package/dist/pool.cjs +42 -9
- package/dist/pool.d.cts +14 -3
- package/dist/pool.d.ts +14 -3
- package/dist/pool.js +38 -5
- package/dist/resources/index.cjs +19 -5
- package/dist/resources/index.d.cts +2 -2
- package/dist/resources/index.d.ts +2 -2
- package/dist/resources/index.js +18 -4
- package/dist/types/index.cjs +1 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/docs/API.md +207 -9
- package/examples/mcp/schemas.ts +16 -7
- package/package.json +1 -1
- /package/dist/{chunk-S643FDOR.cjs → chunk-IXF7AKOJ.cjs} +0 -0
- /package/dist/{chunk-2TWKEB2L.js → chunk-RMG55JTF.js} +0 -0
- /package/dist/{chunk-W3K5BEVY.cjs → chunk-SDYRQFGL.cjs} +0 -0
- /package/dist/{chunk-EBCHCNPK.js → chunk-WLTLB2ND.js} +0 -0
|
@@ -38,10 +38,10 @@ import {
|
|
|
38
38
|
unwrapItem,
|
|
39
39
|
unwrapItems,
|
|
40
40
|
unwrapOperation
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-42ZUISDH.js";
|
|
42
42
|
import {
|
|
43
43
|
CAPABILITIES
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-F7FVOXPQ.js";
|
|
45
45
|
|
|
46
46
|
// src/resources/appointments.ts
|
|
47
47
|
var AppointmentsResource = class extends BaseResource {
|
|
@@ -172,6 +172,42 @@ var BillingCodesResource = class extends BaseResource {
|
|
|
172
172
|
}
|
|
173
173
|
};
|
|
174
174
|
|
|
175
|
+
// src/resources/billing_item_approval_levels.ts
|
|
176
|
+
var BillingItemApprovalLevelsResource = class extends BaseResource {
|
|
177
|
+
constructor(http, pageSize) {
|
|
178
|
+
super(http, {
|
|
179
|
+
key: "billing_item_approval_levels",
|
|
180
|
+
resourcePath: "/V1.0/BillingItemApprovalLevels",
|
|
181
|
+
deletable: false,
|
|
182
|
+
udfCapable: false
|
|
183
|
+
}, pageSize);
|
|
184
|
+
}
|
|
185
|
+
/** Query BillingItemApprovalLevel records with the G3 filter surface (server-side JSON filter). */
|
|
186
|
+
query(params) {
|
|
187
|
+
return this.queryItems(params);
|
|
188
|
+
}
|
|
189
|
+
/** Get every BillingItemApprovalLevel record (the MCP-preferred read; 1000-page guarded). */
|
|
190
|
+
async queryAll(params) {
|
|
191
|
+
return this.queryAllItems(params);
|
|
192
|
+
}
|
|
193
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
194
|
+
async count(params) {
|
|
195
|
+
return this.countGlobal(params);
|
|
196
|
+
}
|
|
197
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
198
|
+
async get(id) {
|
|
199
|
+
return this.getGlobal(id);
|
|
200
|
+
}
|
|
201
|
+
/** Create a record (OperationResultModel → { id}). `dryRun: true` returns the
|
|
202
|
+
* pinned envelope (section 19.3) and never issues the create. A 2xx that is not the
|
|
203
|
+
* specced envelope runs the plan-pinned marker recovery (issue #13 — one bounded read;
|
|
204
|
+
* `recoverIdFromMarker: false` restores the pre-recovery behaviour). */
|
|
205
|
+
async create(data, opts = {}) {
|
|
206
|
+
if (opts.dryRun === true) return this.runCreateDryRun(data);
|
|
207
|
+
return this.createGlobal(data, opts);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
175
211
|
// src/resources/special/dateWindow.ts
|
|
176
212
|
var DAY_MS = 864e5;
|
|
177
213
|
var DEFAULT_LIMIT = 500;
|
|
@@ -5184,7 +5220,7 @@ function appendWiresNote(wires, note) {
|
|
|
5184
5220
|
wires.note = (wires.note ? wires.note + " | " : "") + note;
|
|
5185
5221
|
}
|
|
5186
5222
|
function makeFetchCtx(rawHttp, v, contractId, budget) {
|
|
5187
|
-
const
|
|
5223
|
+
const OP7 = PROFITABILITY_OP;
|
|
5188
5224
|
const id = parseIdentifier(contractId, "contractId");
|
|
5189
5225
|
const idNum = typeof id === "number" ? id : Number(id);
|
|
5190
5226
|
const wires = { issued: 0, requests: 0, budget };
|
|
@@ -5196,19 +5232,19 @@ function makeFetchCtx(rawHttp, v, contractId, budget) {
|
|
|
5196
5232
|
} };
|
|
5197
5233
|
const readPart = (path, conditions, fields) => {
|
|
5198
5234
|
wires.issued += 1;
|
|
5199
|
-
return degradable(() => boundedPart(http, path, conditions, v.limit,
|
|
5235
|
+
return degradable(() => boundedPart(http, path, conditions, v.limit, OP7, fields));
|
|
5200
5236
|
};
|
|
5201
5237
|
const truncatedMonths = {};
|
|
5202
5238
|
const windowedPart = async (name, key, path, cond, fields, dateField) => {
|
|
5203
5239
|
const first = await readPart(path, cond, fields);
|
|
5204
5240
|
if (first.absent !== void 0 || !first.hasMore) return { part: stampPart(key, first, cond), rows: first.items };
|
|
5205
|
-
const wp = await degradable(() => expandByMonth(http, path, cond, v.limit,
|
|
5241
|
+
const wp = await degradable(() => expandByMonth(http, path, cond, v.limit, OP7, fields, dateField, v.dateFrom, v.dateTo, wires));
|
|
5206
5242
|
if (!("truncatedMonths" in wp)) return { part: stampPart(key, wp, cond), rows: [] };
|
|
5207
5243
|
const { truncatedMonths: tm, ...part } = wp;
|
|
5208
5244
|
truncatedMonths[name] = tm;
|
|
5209
5245
|
return { part, rows: wp.items };
|
|
5210
5246
|
};
|
|
5211
|
-
return { v, OP:
|
|
5247
|
+
return { v, OP: OP7, id, idNum, rawHttp, http, wires, windowOn, readPart, windowedPart, truncatedMonths };
|
|
5212
5248
|
}
|
|
5213
5249
|
|
|
5214
5250
|
// src/resources/special/contracts/profitability.stages.ts
|
|
@@ -7131,6 +7167,34 @@ var InvoicesResource = class extends BaseResource {
|
|
|
7131
7167
|
}
|
|
7132
7168
|
};
|
|
7133
7169
|
|
|
7170
|
+
// src/resources/invoice_templates.ts
|
|
7171
|
+
var InvoiceTemplatesResource = class extends BaseResource {
|
|
7172
|
+
constructor(http, pageSize) {
|
|
7173
|
+
super(http, {
|
|
7174
|
+
key: "invoice_templates",
|
|
7175
|
+
resourcePath: "/V1.0/InvoiceTemplates",
|
|
7176
|
+
deletable: false,
|
|
7177
|
+
udfCapable: false
|
|
7178
|
+
}, pageSize);
|
|
7179
|
+
}
|
|
7180
|
+
/** Query InvoiceTemplate records with the G3 filter surface (server-side JSON filter). */
|
|
7181
|
+
query(params) {
|
|
7182
|
+
return this.queryItems(params);
|
|
7183
|
+
}
|
|
7184
|
+
/** Get every InvoiceTemplate record (the MCP-preferred read; 1000-page guarded). */
|
|
7185
|
+
async queryAll(params) {
|
|
7186
|
+
return this.queryAllItems(params);
|
|
7187
|
+
}
|
|
7188
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
7189
|
+
async count(params) {
|
|
7190
|
+
return this.countGlobal(params);
|
|
7191
|
+
}
|
|
7192
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
7193
|
+
async get(id) {
|
|
7194
|
+
return this.getGlobal(id);
|
|
7195
|
+
}
|
|
7196
|
+
};
|
|
7197
|
+
|
|
7134
7198
|
// src/resources/modules.ts
|
|
7135
7199
|
var ModulesResource = class {
|
|
7136
7200
|
http;
|
|
@@ -7369,6 +7433,159 @@ var OpportunityCategoriesResource = class extends BaseResource {
|
|
|
7369
7433
|
}
|
|
7370
7434
|
};
|
|
7371
7435
|
|
|
7436
|
+
// src/resources/organizational_level1s.ts
|
|
7437
|
+
var OrganizationalLevel1sResource = class extends BaseResource {
|
|
7438
|
+
constructor(http, pageSize) {
|
|
7439
|
+
super(http, {
|
|
7440
|
+
key: "organizational_level1s",
|
|
7441
|
+
resourcePath: "/V1.0/OrganizationalLevel1s",
|
|
7442
|
+
deletable: false,
|
|
7443
|
+
udfCapable: false,
|
|
7444
|
+
collectionUpdate: true
|
|
7445
|
+
// D1: the spec's item path is GET-only — confirmed updates PUT the collection (id in the body)
|
|
7446
|
+
}, pageSize);
|
|
7447
|
+
}
|
|
7448
|
+
/** Query OrganizationalLevel1 records with the G3 filter surface (server-side JSON filter). */
|
|
7449
|
+
query(params) {
|
|
7450
|
+
return this.queryItems(params);
|
|
7451
|
+
}
|
|
7452
|
+
/** Get every OrganizationalLevel1 record (the MCP-preferred read; 1000-page guarded). */
|
|
7453
|
+
async queryAll(params) {
|
|
7454
|
+
return this.queryAllItems(params);
|
|
7455
|
+
}
|
|
7456
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
7457
|
+
async count(params) {
|
|
7458
|
+
return this.countGlobal(params);
|
|
7459
|
+
}
|
|
7460
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
7461
|
+
async get(id) {
|
|
7462
|
+
return this.getGlobal(id);
|
|
7463
|
+
}
|
|
7464
|
+
/** Create a record (OperationResultModel → { id}). `dryRun: true` returns the
|
|
7465
|
+
* pinned envelope (section 19.3) and never issues the create. A 2xx that is not the
|
|
7466
|
+
* specced envelope runs the plan-pinned marker recovery (issue #13 — one bounded read;
|
|
7467
|
+
* `recoverIdFromMarker: false` restores the pre-recovery behaviour). */
|
|
7468
|
+
async create(data, opts = {}) {
|
|
7469
|
+
if (opts.dryRun === true) return this.runCreateDryRun(data);
|
|
7470
|
+
return this.createGlobal(data, opts);
|
|
7471
|
+
}
|
|
7472
|
+
/** Update a record (PUT on the COLLECTION — the vendored spec's item path is GET-only; the vendor
|
|
7473
|
+
* keys the record by the id in the body). The vendor validates the FULL model on this route (V2), so a
|
|
7474
|
+
* partial body is merged into the CURRENT record first: one fresh GET (which also serves the
|
|
7475
|
+
* stale-object guard's read) then the collection PUT of the merged model — an explicit null in the
|
|
7476
|
+
* caller body sends null; an omitted field keeps the current value. `raw: true` in the opts bag sends
|
|
7477
|
+
* the body as-is (full model or intentional partial — the compatibility escape hatch; no merge read).
|
|
7478
|
+
* `dryRun: true` returns the pinned envelope whose `data` is the merged body (the exact confirmed
|
|
7479
|
+
* wire) with the best-effort diff, from that same single read; a caller-supplied lastModifiedDate that
|
|
7480
|
+
* mismatches the vendor's current value throws STALE_OBJECT before the mutation. */
|
|
7481
|
+
async update(id, data, opts = {}) {
|
|
7482
|
+
if (opts.dryRun === true) return this.runUpdateDryRun(id, data, opts);
|
|
7483
|
+
return this.updateGlobal(id, data, opts);
|
|
7484
|
+
}
|
|
7485
|
+
};
|
|
7486
|
+
|
|
7487
|
+
// src/resources/organizational_level2s.ts
|
|
7488
|
+
var OrganizationalLevel2sResource = class extends BaseResource {
|
|
7489
|
+
constructor(http, pageSize) {
|
|
7490
|
+
super(http, {
|
|
7491
|
+
key: "organizational_level2s",
|
|
7492
|
+
resourcePath: "/V1.0/OrganizationalLevel2s",
|
|
7493
|
+
deletable: false,
|
|
7494
|
+
udfCapable: false,
|
|
7495
|
+
collectionUpdate: true
|
|
7496
|
+
// D1: the spec's item path is GET-only — confirmed updates PUT the collection (id in the body)
|
|
7497
|
+
}, pageSize);
|
|
7498
|
+
}
|
|
7499
|
+
/** Query OrganizationalLevel2 records with the G3 filter surface (server-side JSON filter). */
|
|
7500
|
+
query(params) {
|
|
7501
|
+
return this.queryItems(params);
|
|
7502
|
+
}
|
|
7503
|
+
/** Get every OrganizationalLevel2 record (the MCP-preferred read; 1000-page guarded). */
|
|
7504
|
+
async queryAll(params) {
|
|
7505
|
+
return this.queryAllItems(params);
|
|
7506
|
+
}
|
|
7507
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
7508
|
+
async count(params) {
|
|
7509
|
+
return this.countGlobal(params);
|
|
7510
|
+
}
|
|
7511
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
7512
|
+
async get(id) {
|
|
7513
|
+
return this.getGlobal(id);
|
|
7514
|
+
}
|
|
7515
|
+
/** Create a record (OperationResultModel → { id}). `dryRun: true` returns the
|
|
7516
|
+
* pinned envelope (section 19.3) and never issues the create. A 2xx that is not the
|
|
7517
|
+
* specced envelope runs the plan-pinned marker recovery (issue #13 — one bounded read;
|
|
7518
|
+
* `recoverIdFromMarker: false` restores the pre-recovery behaviour). */
|
|
7519
|
+
async create(data, opts = {}) {
|
|
7520
|
+
if (opts.dryRun === true) return this.runCreateDryRun(data);
|
|
7521
|
+
return this.createGlobal(data, opts);
|
|
7522
|
+
}
|
|
7523
|
+
/** Update a record (PUT on the COLLECTION — the vendored spec's item path is GET-only; the vendor
|
|
7524
|
+
* keys the record by the id in the body). The vendor validates the FULL model on this route (V2), so a
|
|
7525
|
+
* partial body is merged into the CURRENT record first: one fresh GET (which also serves the
|
|
7526
|
+
* stale-object guard's read) then the collection PUT of the merged model — an explicit null in the
|
|
7527
|
+
* caller body sends null; an omitted field keeps the current value. `raw: true` in the opts bag sends
|
|
7528
|
+
* the body as-is (full model or intentional partial — the compatibility escape hatch; no merge read).
|
|
7529
|
+
* `dryRun: true` returns the pinned envelope whose `data` is the merged body (the exact confirmed
|
|
7530
|
+
* wire) with the best-effort diff, from that same single read; a caller-supplied lastModifiedDate that
|
|
7531
|
+
* mismatches the vendor's current value throws STALE_OBJECT before the mutation. */
|
|
7532
|
+
async update(id, data, opts = {}) {
|
|
7533
|
+
if (opts.dryRun === true) return this.runUpdateDryRun(id, data, opts);
|
|
7534
|
+
return this.updateGlobal(id, data, opts);
|
|
7535
|
+
}
|
|
7536
|
+
};
|
|
7537
|
+
|
|
7538
|
+
// src/resources/organizational_level_associations.ts
|
|
7539
|
+
var OrganizationalLevelAssociationsResource = class extends BaseResource {
|
|
7540
|
+
constructor(http, pageSize) {
|
|
7541
|
+
super(http, {
|
|
7542
|
+
key: "organizational_level_associations",
|
|
7543
|
+
resourcePath: "/V1.0/OrganizationalLevelAssociations",
|
|
7544
|
+
deletable: false,
|
|
7545
|
+
udfCapable: false,
|
|
7546
|
+
collectionUpdate: true
|
|
7547
|
+
// D1: the spec's item path is GET-only — confirmed updates PUT the collection (id in the body)
|
|
7548
|
+
}, pageSize);
|
|
7549
|
+
}
|
|
7550
|
+
/** Query OrganizationalLevelAssociation records with the G3 filter surface (server-side JSON filter). */
|
|
7551
|
+
query(params) {
|
|
7552
|
+
return this.queryItems(params);
|
|
7553
|
+
}
|
|
7554
|
+
/** Get every OrganizationalLevelAssociation record (the MCP-preferred read; 1000-page guarded). */
|
|
7555
|
+
async queryAll(params) {
|
|
7556
|
+
return this.queryAllItems(params);
|
|
7557
|
+
}
|
|
7558
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
7559
|
+
async count(params) {
|
|
7560
|
+
return this.countGlobal(params);
|
|
7561
|
+
}
|
|
7562
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
7563
|
+
async get(id) {
|
|
7564
|
+
return this.getGlobal(id);
|
|
7565
|
+
}
|
|
7566
|
+
/** Create a record (OperationResultModel → { id}). `dryRun: true` returns the
|
|
7567
|
+
* pinned envelope (section 19.3) and never issues the create. A 2xx that is not the
|
|
7568
|
+
* specced envelope runs the plan-pinned marker recovery (issue #13 — one bounded read;
|
|
7569
|
+
* `recoverIdFromMarker: false` restores the pre-recovery behaviour). */
|
|
7570
|
+
async create(data, opts = {}) {
|
|
7571
|
+
if (opts.dryRun === true) return this.runCreateDryRun(data);
|
|
7572
|
+
return this.createGlobal(data, opts);
|
|
7573
|
+
}
|
|
7574
|
+
/** Update a record (PUT on the COLLECTION — the vendored spec's item path is GET-only; the vendor
|
|
7575
|
+
* keys the record by the id in the body). The vendor validates the FULL model on this route (V2), so a
|
|
7576
|
+
* partial body is merged into the CURRENT record first: one fresh GET (which also serves the
|
|
7577
|
+
* stale-object guard's read) then the collection PUT of the merged model — an explicit null in the
|
|
7578
|
+
* caller body sends null; an omitted field keeps the current value. `raw: true` in the opts bag sends
|
|
7579
|
+
* the body as-is (full model or intentional partial — the compatibility escape hatch; no merge read).
|
|
7580
|
+
* `dryRun: true` returns the pinned envelope whose `data` is the merged body (the exact confirmed
|
|
7581
|
+
* wire) with the best-effort diff, from that same single read; a caller-supplied lastModifiedDate that
|
|
7582
|
+
* mismatches the vendor's current value throws STALE_OBJECT before the mutation. */
|
|
7583
|
+
async update(id, data, opts = {}) {
|
|
7584
|
+
if (opts.dryRun === true) return this.runUpdateDryRun(id, data, opts);
|
|
7585
|
+
return this.updateGlobal(id, data, opts);
|
|
7586
|
+
}
|
|
7587
|
+
};
|
|
7588
|
+
|
|
7372
7589
|
// src/resources/phases.ts
|
|
7373
7590
|
var PhasesResource = class extends BaseResource {
|
|
7374
7591
|
constructor(http, pageSize) {
|
|
@@ -8807,6 +9024,49 @@ var RolesResource = class extends BaseResource {
|
|
|
8807
9024
|
}
|
|
8808
9025
|
};
|
|
8809
9026
|
|
|
9027
|
+
// src/resources/sales_orders.ts
|
|
9028
|
+
var SalesOrdersResource = class extends BaseResource {
|
|
9029
|
+
constructor(http, pageSize) {
|
|
9030
|
+
super(http, {
|
|
9031
|
+
key: "sales_orders",
|
|
9032
|
+
resourcePath: "/V1.0/SalesOrders",
|
|
9033
|
+
deletable: false,
|
|
9034
|
+
udfCapable: true,
|
|
9035
|
+
collectionUpdate: true
|
|
9036
|
+
// D1: the spec's item path is GET-only — confirmed updates PUT the collection (id in the body)
|
|
9037
|
+
}, pageSize);
|
|
9038
|
+
}
|
|
9039
|
+
/** Query SalesOrder records with the G3 filter surface (server-side JSON filter). */
|
|
9040
|
+
query(params) {
|
|
9041
|
+
return this.queryItems(params);
|
|
9042
|
+
}
|
|
9043
|
+
/** Get every SalesOrder record (the MCP-preferred read; 1000-page guarded). */
|
|
9044
|
+
async queryAll(params) {
|
|
9045
|
+
return this.queryAllItems(params);
|
|
9046
|
+
}
|
|
9047
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
9048
|
+
async count(params) {
|
|
9049
|
+
return this.countGlobal(params);
|
|
9050
|
+
}
|
|
9051
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
9052
|
+
async get(id) {
|
|
9053
|
+
return this.getGlobal(id);
|
|
9054
|
+
}
|
|
9055
|
+
/** Update a record (PUT on the COLLECTION — the vendored spec's item path is GET-only; the vendor
|
|
9056
|
+
* keys the record by the id in the body). The vendor validates the FULL model on this route (V2), so a
|
|
9057
|
+
* partial body is merged into the CURRENT record first: one fresh GET (which also serves the
|
|
9058
|
+
* stale-object guard's read) then the collection PUT of the merged model — an explicit null in the
|
|
9059
|
+
* caller body sends null; an omitted field keeps the current value. `raw: true` in the opts bag sends
|
|
9060
|
+
* the body as-is (full model or intentional partial — the compatibility escape hatch; no merge read).
|
|
9061
|
+
* `dryRun: true` returns the pinned envelope whose `data` is the merged body (the exact confirmed
|
|
9062
|
+
* wire) with the best-effort diff, from that same single read; a caller-supplied lastModifiedDate that
|
|
9063
|
+
* mismatches the vendor's current value throws STALE_OBJECT before the mutation. */
|
|
9064
|
+
async update(id, data, opts = {}) {
|
|
9065
|
+
if (opts.dryRun === true) return this.runUpdateDryRun(id, data, opts);
|
|
9066
|
+
return this.updateGlobal(id, data, opts);
|
|
9067
|
+
}
|
|
9068
|
+
};
|
|
9069
|
+
|
|
8810
9070
|
// src/resources/service_calls.ts
|
|
8811
9071
|
var ServiceCallsResource = class extends BaseResource {
|
|
8812
9072
|
constructor(http, pageSize) {
|
|
@@ -9762,6 +10022,57 @@ var TasksResource = class extends BaseResource {
|
|
|
9762
10022
|
}
|
|
9763
10023
|
};
|
|
9764
10024
|
|
|
10025
|
+
// src/resources/tax_regions.ts
|
|
10026
|
+
var TaxRegionsResource = class extends BaseResource {
|
|
10027
|
+
constructor(http, pageSize) {
|
|
10028
|
+
super(http, {
|
|
10029
|
+
key: "tax_regions",
|
|
10030
|
+
resourcePath: "/V1.0/TaxRegions",
|
|
10031
|
+
deletable: false,
|
|
10032
|
+
udfCapable: false,
|
|
10033
|
+
collectionUpdate: true
|
|
10034
|
+
// D1: the spec's item path is GET-only — confirmed updates PUT the collection (id in the body)
|
|
10035
|
+
}, pageSize);
|
|
10036
|
+
}
|
|
10037
|
+
/** Query TaxRegion records with the G3 filter surface (server-side JSON filter). */
|
|
10038
|
+
query(params) {
|
|
10039
|
+
return this.queryItems(params);
|
|
10040
|
+
}
|
|
10041
|
+
/** Get every TaxRegion record (the MCP-preferred read; 1000-page guarded). */
|
|
10042
|
+
async queryAll(params) {
|
|
10043
|
+
return this.queryAllItems(params);
|
|
10044
|
+
}
|
|
10045
|
+
/** Count matching records (queryCount envelope unwrapped to a plain number). */
|
|
10046
|
+
async count(params) {
|
|
10047
|
+
return this.countGlobal(params);
|
|
10048
|
+
}
|
|
10049
|
+
/** Get one record by id (item envelope; item: null → NotFoundError). */
|
|
10050
|
+
async get(id) {
|
|
10051
|
+
return this.getGlobal(id);
|
|
10052
|
+
}
|
|
10053
|
+
/** Create a record (OperationResultModel → { id}). `dryRun: true` returns the
|
|
10054
|
+
* pinned envelope (section 19.3) and never issues the create. A 2xx that is not the
|
|
10055
|
+
* specced envelope runs the plan-pinned marker recovery (issue #13 — one bounded read;
|
|
10056
|
+
* `recoverIdFromMarker: false` restores the pre-recovery behaviour). */
|
|
10057
|
+
async create(data, opts = {}) {
|
|
10058
|
+
if (opts.dryRun === true) return this.runCreateDryRun(data);
|
|
10059
|
+
return this.createGlobal(data, opts);
|
|
10060
|
+
}
|
|
10061
|
+
/** Update a record (PUT on the COLLECTION — the vendored spec's item path is GET-only; the vendor
|
|
10062
|
+
* keys the record by the id in the body). The vendor validates the FULL model on this route (V2), so a
|
|
10063
|
+
* partial body is merged into the CURRENT record first: one fresh GET (which also serves the
|
|
10064
|
+
* stale-object guard's read) then the collection PUT of the merged model — an explicit null in the
|
|
10065
|
+
* caller body sends null; an omitted field keeps the current value. `raw: true` in the opts bag sends
|
|
10066
|
+
* the body as-is (full model or intentional partial — the compatibility escape hatch; no merge read).
|
|
10067
|
+
* `dryRun: true` returns the pinned envelope whose `data` is the merged body (the exact confirmed
|
|
10068
|
+
* wire) with the best-effort diff, from that same single read; a caller-supplied lastModifiedDate that
|
|
10069
|
+
* mismatches the vendor's current value throws STALE_OBJECT before the mutation. */
|
|
10070
|
+
async update(id, data, opts = {}) {
|
|
10071
|
+
if (opts.dryRun === true) return this.runUpdateDryRun(id, data, opts);
|
|
10072
|
+
return this.updateGlobal(id, data, opts);
|
|
10073
|
+
}
|
|
10074
|
+
};
|
|
10075
|
+
|
|
9765
10076
|
// src/resources/threshold_information.ts
|
|
9766
10077
|
var ThresholdInformationResource = class {
|
|
9767
10078
|
http;
|
|
@@ -11983,12 +12294,12 @@ async function postedDateStatusQuery(_resource, mode, http, opts) {
|
|
|
11983
12294
|
return items;
|
|
11984
12295
|
}
|
|
11985
12296
|
async function postedWithin(_resource, from, to, http, opts, opLabel = "time_entries.postedWithin") {
|
|
11986
|
-
const
|
|
11987
|
-
if (opts?.tz !== void 0) validateZone(opts.tz,
|
|
11988
|
-
const fromB = customRangeDay(from, "from", void 0,
|
|
11989
|
-
const toB = customRangeDay(to, "to", void 0,
|
|
12297
|
+
const OP7 = opLabel;
|
|
12298
|
+
if (opts?.tz !== void 0) validateZone(opts.tz, OP7);
|
|
12299
|
+
const fromB = customRangeDay(from, "from", void 0, OP7);
|
|
12300
|
+
const toB = customRangeDay(to, "to", void 0, OP7);
|
|
11990
12301
|
if (fromB.ms > toB.ms) {
|
|
11991
|
-
throw new AutotaskConfigError(`${
|
|
12302
|
+
throw new AutotaskConfigError(`${OP7}: from (${iso2(fromB.ms)}) must not be after to (${iso2(toB.ms)})`, { operation: OP7 });
|
|
11992
12303
|
}
|
|
11993
12304
|
const windowToMs = toB.ms + DAY_MS2 - 1;
|
|
11994
12305
|
const filter = [
|
|
@@ -11999,7 +12310,7 @@ async function postedWithin(_resource, from, to, http, opts, opLabel = "time_ent
|
|
|
11999
12310
|
else if (opts?.posted === false) filter.push({ field: "postedDate", op: "notExist" });
|
|
12000
12311
|
if (opts?.ticketID !== void 0) filter.push({ field: "ticketID", op: "eq", value: opts.ticketID });
|
|
12001
12312
|
if (opts?.resourceID !== void 0) filter.push({ field: "resourceID", op: "eq", value: opts.resourceID });
|
|
12002
|
-
const { items, hasMore } = await queryTimeEntries(_resource, filter, clampWindowLimit(opts?.limit),
|
|
12313
|
+
const { items, hasMore } = await queryTimeEntries(_resource, filter, clampWindowLimit(opts?.limit), OP7, http);
|
|
12003
12314
|
let postedCount = 0;
|
|
12004
12315
|
for (const item of items) {
|
|
12005
12316
|
const postedDate = item.postedDate;
|
|
@@ -12500,29 +12811,116 @@ function moveToTicket2(_resource, sourceId, toTicketId, opts, http) {
|
|
|
12500
12811
|
return runMove(http, SPEC2, sourceId, toTicketId, opts);
|
|
12501
12812
|
}
|
|
12502
12813
|
|
|
12814
|
+
// src/resources/special/time_entries/approve.ts
|
|
12815
|
+
var OP5 = "time_entries.approve";
|
|
12816
|
+
var APPROVAL_LEVELS_PATH = "/V1.0/BillingItemApprovalLevels";
|
|
12817
|
+
function toIso(value) {
|
|
12818
|
+
if (value instanceof Date) {
|
|
12819
|
+
if (Number.isNaN(value.getTime())) throw new AutotaskConfigError("time_entries.approve: approvalDateTime is an invalid Date");
|
|
12820
|
+
return value.toISOString();
|
|
12821
|
+
}
|
|
12822
|
+
const parsed = new Date(value);
|
|
12823
|
+
if (Number.isNaN(parsed.getTime())) throw new AutotaskConfigError(`time_entries.approve: approvalDateTime "${value}" is not a parseable date`);
|
|
12824
|
+
return parsed.toISOString();
|
|
12825
|
+
}
|
|
12826
|
+
function toNumber(value) {
|
|
12827
|
+
return typeof value === "number" ? value : Number(value);
|
|
12828
|
+
}
|
|
12829
|
+
function sameInstant(a, b) {
|
|
12830
|
+
if (typeof a !== "string" || a === "") return false;
|
|
12831
|
+
const left = new Date(a).getTime();
|
|
12832
|
+
const right = new Date(b).getTime();
|
|
12833
|
+
return !Number.isNaN(left) && left === right;
|
|
12834
|
+
}
|
|
12835
|
+
async function approve(resource, id, opts = {}, http) {
|
|
12836
|
+
const numericId = toNumber(parseIdentifier(id, "id"));
|
|
12837
|
+
if (opts.approvalLevel !== void 0 && (!Number.isInteger(opts.approvalLevel) || opts.approvalLevel < 1)) {
|
|
12838
|
+
throw new AutotaskConfigError(`time_entries.approve: approvalLevel must be a positive integer (got ${String(opts.approvalLevel)})`);
|
|
12839
|
+
}
|
|
12840
|
+
const approvalLevel = opts.approvalLevel ?? 1;
|
|
12841
|
+
const approvalDateTime = toIso(opts.approvalDateTime ?? /* @__PURE__ */ new Date());
|
|
12842
|
+
const entry = await resource.get(numericId);
|
|
12843
|
+
const approvalResourceID = opts.approvalResourceID === void 0 ? entry.resourceID : toNumber(parseIdentifier(opts.approvalResourceID, "approvalResourceID"));
|
|
12844
|
+
if (approvalResourceID === void 0) {
|
|
12845
|
+
throw new AutotaskConfigError(
|
|
12846
|
+
`time_entries.approve: time entry ${numericId} carries no resourceID and the caller supplied no approvalResourceID \u2014 the vendor requires an approving resource`
|
|
12847
|
+
);
|
|
12848
|
+
}
|
|
12849
|
+
const body = { timeEntryID: numericId, approvalLevel, approvalResourceID, approvalDateTime };
|
|
12850
|
+
if (opts.dryRun === true) {
|
|
12851
|
+
return buildDryRunResult(
|
|
12852
|
+
{
|
|
12853
|
+
operation: OP5,
|
|
12854
|
+
method: "POST",
|
|
12855
|
+
path: APPROVAL_LEVELS_PATH,
|
|
12856
|
+
ids: [numericId],
|
|
12857
|
+
checks: [
|
|
12858
|
+
{ name: "input-validation", ok: true },
|
|
12859
|
+
{ name: "time-entry-exists", ok: true }
|
|
12860
|
+
],
|
|
12861
|
+
impact: { affected: 1, scope: "single-record", reversible: false },
|
|
12862
|
+
warnings: [
|
|
12863
|
+
"two calls: POST the BillingItemApprovalLevels record, then PUT the time entry (billingApprovalDateTime + billingApprovalResourceID) \u2014 the vendor sets BillingApprovalLevelMostRecent from the create but not these two fields",
|
|
12864
|
+
"approval is not posting: the API exposes no post action on BillingItems, so the entry stays unposted until a vendor workflow posts it",
|
|
12865
|
+
`approvalResourceID ${approvalResourceID} is not existence-checked by the dry run`
|
|
12866
|
+
],
|
|
12867
|
+
data: body
|
|
12868
|
+
},
|
|
12869
|
+
{ redactPersonalData: http.redactPersonalData }
|
|
12870
|
+
);
|
|
12871
|
+
}
|
|
12872
|
+
const created = await http.request({
|
|
12873
|
+
method: "POST",
|
|
12874
|
+
path: APPROVAL_LEVELS_PATH,
|
|
12875
|
+
body,
|
|
12876
|
+
operation: OP5,
|
|
12877
|
+
maxRetries: opts.maxRetries
|
|
12878
|
+
});
|
|
12879
|
+
const levelId = toNumber(parseIdentifier(unwrapOperation(created, OP5).id, "billingItemApprovalLevelID"));
|
|
12880
|
+
await resource.update(
|
|
12881
|
+
numericId,
|
|
12882
|
+
{ billingApprovalDateTime: approvalDateTime, billingApprovalResourceID: approvalResourceID },
|
|
12883
|
+
{ maxRetries: opts.maxRetries, lastModifiedDate: opts.lastModifiedDate ?? entry.lastModifiedDateTime }
|
|
12884
|
+
);
|
|
12885
|
+
const fresh = await resource.get(numericId);
|
|
12886
|
+
const persisted = sameInstant(fresh.billingApprovalDateTime, approvalDateTime) && fresh.billingApprovalResourceID === approvalResourceID;
|
|
12887
|
+
return {
|
|
12888
|
+
timeEntryID: numericId,
|
|
12889
|
+
billingItemApprovalLevelID: levelId,
|
|
12890
|
+
approvalLevel,
|
|
12891
|
+
approvalResourceID,
|
|
12892
|
+
approvalDateTime,
|
|
12893
|
+
billingApprovalLevelMostRecent: fresh.billingApprovalLevelMostRecent ?? null,
|
|
12894
|
+
billingApprovalDateTime: fresh.billingApprovalDateTime ?? null,
|
|
12895
|
+
billingApprovalResourceID: fresh.billingApprovalResourceID ?? null,
|
|
12896
|
+
status: persisted ? "approved" : "approval_fields_not_persisted",
|
|
12897
|
+
persisted
|
|
12898
|
+
};
|
|
12899
|
+
}
|
|
12900
|
+
|
|
12503
12901
|
// src/resources/special/time_entries/recentTickets.ts
|
|
12504
|
-
var
|
|
12902
|
+
var OP6 = "time_entries.recentTickets";
|
|
12505
12903
|
var DAY_MS3 = 864e5;
|
|
12506
12904
|
var TICKET_CHUNK = 100;
|
|
12507
12905
|
var TICKET_FIELDS2 = ["id", "ticketNumber", "title", "status", "assignedResourceID", "companyID"];
|
|
12508
12906
|
function positiveId(value, name) {
|
|
12509
12907
|
const n = typeof value === "string" && /^\d+$/.test(value.trim()) ? Number(value) : value;
|
|
12510
12908
|
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 1) {
|
|
12511
|
-
throw new AutotaskConfigError(`${
|
|
12909
|
+
throw new AutotaskConfigError(`${OP6}: ${name} must be a positive integer id (got ${String(value)})`, { operation: OP6 });
|
|
12512
12910
|
}
|
|
12513
12911
|
return n;
|
|
12514
12912
|
}
|
|
12515
12913
|
async function recentTickets(_resource, from, to, http, opts) {
|
|
12516
12914
|
if (opts === void 0 || opts === null || typeof opts !== "object") {
|
|
12517
|
-
throw new AutotaskConfigError(`${
|
|
12915
|
+
throw new AutotaskConfigError(`${OP6}: opts { resourceID, companyID?, tz?, limit? } is required`, { operation: OP6 });
|
|
12518
12916
|
}
|
|
12519
12917
|
const resourceID = positiveId(opts.resourceID, "resourceID");
|
|
12520
12918
|
const companyID = opts.companyID === void 0 ? void 0 : positiveId(opts.companyID, "companyID");
|
|
12521
|
-
if (opts.tz !== void 0) validateZone(opts.tz,
|
|
12522
|
-
const fromB = customRangeDay(from, "from", void 0,
|
|
12523
|
-
const toB = customRangeDay(to, "to", void 0,
|
|
12919
|
+
if (opts.tz !== void 0) validateZone(opts.tz, OP6);
|
|
12920
|
+
const fromB = customRangeDay(from, "from", void 0, OP6);
|
|
12921
|
+
const toB = customRangeDay(to, "to", void 0, OP6);
|
|
12524
12922
|
if (fromB.ms > toB.ms) {
|
|
12525
|
-
throw new AutotaskConfigError(`${
|
|
12923
|
+
throw new AutotaskConfigError(`${OP6}: from (${isoUtc(fromB.ms)}) must not be after to (${isoUtc(toB.ms)})`, { operation: OP6 });
|
|
12526
12924
|
}
|
|
12527
12925
|
const windowToMs = toB.ms + DAY_MS3 - 1;
|
|
12528
12926
|
const { items: entries, hasMore } = await queryTimeEntries(
|
|
@@ -12533,7 +12931,7 @@ async function recentTickets(_resource, from, to, http, opts) {
|
|
|
12533
12931
|
{ field: "resourceID", op: "eq", value: resourceID }
|
|
12534
12932
|
],
|
|
12535
12933
|
clampWindowLimit(opts.limit),
|
|
12536
|
-
|
|
12934
|
+
OP6,
|
|
12537
12935
|
http
|
|
12538
12936
|
);
|
|
12539
12937
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -12559,9 +12957,9 @@ async function recentTickets(_resource, from, to, http, opts) {
|
|
|
12559
12957
|
idempotent: true,
|
|
12560
12958
|
path: "/V1.0/Tickets/query",
|
|
12561
12959
|
body: { MaxRecords: TICKET_CHUNK, filter, IncludeFields: TICKET_FIELDS2 },
|
|
12562
|
-
operation:
|
|
12960
|
+
operation: OP6
|
|
12563
12961
|
});
|
|
12564
|
-
for (const t of unwrapItems(res,
|
|
12962
|
+
for (const t of unwrapItems(res, OP6).items) if (typeof t.id === "number") tickets.set(t.id, t);
|
|
12565
12963
|
}
|
|
12566
12964
|
const items = [];
|
|
12567
12965
|
const unresolvedTicketIDs = [];
|
|
@@ -12665,6 +13063,10 @@ var TimeEntriesResource = class extends BaseResource {
|
|
|
12665
13063
|
return this.resolveBase(identifier);
|
|
12666
13064
|
}
|
|
12667
13065
|
/** Node-parity special op (hand-written in src/resources/special/time_entries.ts). */
|
|
13066
|
+
approve(id, opts = {}) {
|
|
13067
|
+
return approve(this, id, opts, this.http);
|
|
13068
|
+
}
|
|
13069
|
+
/** Node-parity special op (hand-written in src/resources/special/time_entries.ts). */
|
|
12668
13070
|
createForResource(resourceID, params, opts = {}) {
|
|
12669
13071
|
return createForResource(this, resourceID, params, opts, this.http);
|
|
12670
13072
|
}
|
|
@@ -12805,7 +13207,7 @@ var TimeEntryAttachmentsResource = class extends BaseResource {
|
|
|
12805
13207
|
};
|
|
12806
13208
|
|
|
12807
13209
|
// src/resources/special/time_off_requests.ts
|
|
12808
|
-
async function
|
|
13210
|
+
async function approve2(_resource, id, opts = {}, http) {
|
|
12809
13211
|
const numericId = parseIdentifier(id, "id");
|
|
12810
13212
|
if (opts.dryRun === true) {
|
|
12811
13213
|
return buildDryRunResult({
|
|
@@ -12893,7 +13295,7 @@ var TimeOffRequestsResource = class extends BaseResource {
|
|
|
12893
13295
|
}
|
|
12894
13296
|
/** Node-parity special op (hand-written in src/resources/special/time_off_requests.ts). */
|
|
12895
13297
|
approve(id, opts = {}) {
|
|
12896
|
-
return
|
|
13298
|
+
return approve2(this, id, opts, this.http);
|
|
12897
13299
|
}
|
|
12898
13300
|
/** Node-parity special op (hand-written in src/resources/special/time_off_requests.ts). */
|
|
12899
13301
|
reject(id, reason, opts = {}) {
|
|
@@ -12965,6 +13367,7 @@ export {
|
|
|
12965
13367
|
AppointmentsResource,
|
|
12966
13368
|
AuthenticateResource,
|
|
12967
13369
|
BillingCodesResource,
|
|
13370
|
+
BillingItemApprovalLevelsResource,
|
|
12968
13371
|
BillingItemsResource,
|
|
12969
13372
|
ChangeRequestLinksResource,
|
|
12970
13373
|
ChecklistLibrariesResource,
|
|
@@ -13024,11 +13427,15 @@ export {
|
|
|
13024
13427
|
HolidaysResource,
|
|
13025
13428
|
InventoryProductsResource,
|
|
13026
13429
|
InvoicesResource,
|
|
13430
|
+
InvoiceTemplatesResource,
|
|
13027
13431
|
ModulesResource,
|
|
13028
13432
|
NotificationHistoryResource,
|
|
13029
13433
|
OpportunitiesResource,
|
|
13030
13434
|
OpportunityAttachmentsResource,
|
|
13031
13435
|
OpportunityCategoriesResource,
|
|
13436
|
+
OrganizationalLevel1sResource,
|
|
13437
|
+
OrganizationalLevel2sResource,
|
|
13438
|
+
OrganizationalLevelAssociationsResource,
|
|
13032
13439
|
PhasesResource,
|
|
13033
13440
|
ProductsResource,
|
|
13034
13441
|
ProductVendorsResource,
|
|
@@ -13051,6 +13458,7 @@ export {
|
|
|
13051
13458
|
ResourceTimeOffApproversResource,
|
|
13052
13459
|
ResourceTimeOffBalancesResource,
|
|
13053
13460
|
RolesResource,
|
|
13461
|
+
SalesOrdersResource,
|
|
13054
13462
|
ServiceCallsResource,
|
|
13055
13463
|
ServiceCallTaskResourcesResource,
|
|
13056
13464
|
ServiceCallTasksResource,
|
|
@@ -13068,6 +13476,7 @@ export {
|
|
|
13068
13476
|
TagsResource,
|
|
13069
13477
|
TaskSecondaryResourcesResource,
|
|
13070
13478
|
TasksResource,
|
|
13479
|
+
TaxRegionsResource,
|
|
13071
13480
|
ThresholdInformationResource,
|
|
13072
13481
|
TicketAdditionalConfigurationItemsResource,
|
|
13073
13482
|
TicketAdditionalContactsResource,
|