node-autotask 0.18.0 → 0.19.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/ARCHITECTURE.md +15 -8
- package/CHANGELOG.md +574 -0
- package/MCP_TOOL_CATALOG.json +2 -2
- package/MCP_TOOL_MANIFEST.md +5 -5
- package/N8N_MCP_MANIFEST.json +2 -2
- package/N8N_MCP_MANIFEST.md +3 -3
- package/README.md +8 -4
- package/capabilities.json +1223 -1223
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-W2WSZOZA.js → chunk-4YKV7ORF.js} +2 -2
- package/dist/{chunk-7I3F3AJJ.cjs → chunk-7RDR5DSI.cjs} +393 -393
- package/dist/{chunk-HXOWEYV3.js → chunk-D5RAQ4DE.js} +2 -2
- package/dist/{chunk-5O5EPYBO.cjs → chunk-JM52ZU7T.cjs} +1222 -1222
- package/dist/{chunk-VYUZZIEE.js → chunk-LB2X4X4B.js} +86 -8
- package/dist/{chunk-VV2UUW2J.js → chunk-NDK7WYWA.js} +1222 -1222
- package/dist/{chunk-WRWX6WIK.cjs → chunk-QDYSHAU6.cjs} +147 -69
- package/dist/{chunk-G564CHXM.cjs → chunk-TIM75K3G.cjs} +135 -135
- package/dist/{index-BqPY04ZG.d.ts → index-DLugNSr7.d.ts} +27 -13
- package/dist/{index-D7x3MkLK.d.cts → index-aZ3tCh1h.d.cts} +27 -13
- package/dist/index.cjs +24 -22
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -4
- package/dist/operations/index.cjs +109 -109
- package/dist/operations/index.d.cts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +2 -2
- 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 +48 -18
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CAPABILITIES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NDK7WYWA.js";
|
|
4
4
|
|
|
5
5
|
// src/auth.ts
|
|
6
6
|
var AUTH_HEADERS = {
|
|
@@ -1536,6 +1536,7 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
1536
1536
|
var DEFAULT_MAX_RETRIES = 3;
|
|
1537
1537
|
var DEFAULT_MAINTENANCE_MAX_WAIT_MS = 36e5;
|
|
1538
1538
|
var DEFAULT_MAINTENANCE_POLL_MS = 3e4;
|
|
1539
|
+
var MAINTENANCE_WINDOW_MAX_MS = 4 * 36e5;
|
|
1539
1540
|
var DEFAULT_MAX_CONCURRENT = 10;
|
|
1540
1541
|
var DEFAULT_MAX_RESPONSE_BYTES = 64 * 1024 * 1024;
|
|
1541
1542
|
var DEFAULT_MAX_SCAN_RECORDS = 500;
|
|
@@ -14779,9 +14780,21 @@ function backoffDelay(attempt) {
|
|
|
14779
14780
|
const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
|
|
14780
14781
|
return Math.floor(exp / 2 + Math.random() * (exp / 2));
|
|
14781
14782
|
}
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
return
|
|
14783
|
+
var MAINTENANCE_PROBE_BYTES = 256;
|
|
14784
|
+
function maintenanceProbe(text) {
|
|
14785
|
+
return Buffer.from(text, "utf8").subarray(0, MAINTENANCE_PROBE_BYTES).toString("utf8");
|
|
14786
|
+
}
|
|
14787
|
+
function looksLikeMaintenanceText(text) {
|
|
14788
|
+
return /maintenance|temporarily unavailable|service unavailable|outage|downtime|down for/i.test(
|
|
14789
|
+
maintenanceProbe(text)
|
|
14790
|
+
);
|
|
14791
|
+
}
|
|
14792
|
+
function isHtmlLike(contentType, body) {
|
|
14793
|
+
if (contentType !== null && /text\/html|application\/xhtml/i.test(contentType)) return true;
|
|
14794
|
+
return body.trimStart().startsWith("<");
|
|
14795
|
+
}
|
|
14796
|
+
function maintenanceExhaustedAction(maxWaitMs, waits) {
|
|
14797
|
+
return `The zone stayed in a maintenance window for ${Math.round(maxWaitMs / 6e4)} min \u2014 the SDK waited and retried ${waits} time(s) and gave up. Re-run after the window (the observed median is about 2 h; the ceiling is 4 h \u2014 MAINTENANCE_WINDOW_MAX_MS), or raise maintenanceMaxWaitMs.`;
|
|
14785
14798
|
}
|
|
14786
14799
|
function parseRetryAfter(value) {
|
|
14787
14800
|
if (value === null || value.length === 0) return void 0;
|
|
@@ -15217,6 +15230,7 @@ var HttpClient = class {
|
|
|
15217
15230
|
const maintenancePollMs = opts.maintenancePollMs ?? this.maintenancePollMs;
|
|
15218
15231
|
let firstMaintenanceAt;
|
|
15219
15232
|
let maintenanceWaits = 0;
|
|
15233
|
+
let maintenanceBudgetSpent = false;
|
|
15220
15234
|
const started = Date.now();
|
|
15221
15235
|
let deadlineAt = started + timeoutMs;
|
|
15222
15236
|
const callerSignal = opts.signal ?? ambientSignal.getStore();
|
|
@@ -15437,12 +15451,13 @@ var HttpClient = class {
|
|
|
15437
15451
|
httpStatus: status,
|
|
15438
15452
|
suggestedAction: "The zone returned a non-JSON 2xx body; verify baseUrl points at the REST API."
|
|
15439
15453
|
});
|
|
15440
|
-
if (err2.code === "UNEXPECTED_CONTENT_TYPE" && maintenanceMaxWaitMs > 0 &&
|
|
15454
|
+
if (err2.code === "UNEXPECTED_CONTENT_TYPE" && maintenanceMaxWaitMs > 0 && looksLikeMaintenanceText(text)) {
|
|
15441
15455
|
const now = Date.now();
|
|
15442
15456
|
firstMaintenanceAt ??= now;
|
|
15443
15457
|
const remaining = maintenanceMaxWaitMs - (now - firstMaintenanceAt);
|
|
15444
15458
|
if (remaining > 0) {
|
|
15445
15459
|
const wait = Math.min(maintenancePollMs, remaining);
|
|
15460
|
+
if (wait >= remaining) maintenanceBudgetSpent = true;
|
|
15446
15461
|
maintenanceWaits += 1;
|
|
15447
15462
|
this.logger.warn?.(
|
|
15448
15463
|
`[autotask] maintenance window on ${method} ${opts.path}; waiting ${Math.round(wait / 1e3)}s (retry ${maintenanceWaits}, up to ${Math.round(maintenanceMaxWaitMs / 6e4)} min)`,
|
|
@@ -15453,6 +15468,7 @@ var HttpClient = class {
|
|
|
15453
15468
|
await pause(wait);
|
|
15454
15469
|
continue;
|
|
15455
15470
|
}
|
|
15471
|
+
maintenanceBudgetSpent = true;
|
|
15456
15472
|
}
|
|
15457
15473
|
if (err2.code === "UNEXPECTED_CONTENT_TYPE" && retriable5xx && attempt < maxRetries) {
|
|
15458
15474
|
const retryAfter = parseRetryAfter(res.headers.get("Retry-After"));
|
|
@@ -15467,17 +15483,27 @@ var HttpClient = class {
|
|
|
15467
15483
|
continue;
|
|
15468
15484
|
}
|
|
15469
15485
|
}
|
|
15470
|
-
|
|
15486
|
+
const pageSnippet = typeof err2.details?.bodySnippet === "string" ? err2.details.bodySnippet : "";
|
|
15487
|
+
if (maintenanceWaits > 0) {
|
|
15471
15488
|
err2.details = {
|
|
15472
15489
|
...err2.details ?? {},
|
|
15473
15490
|
maintenance: {
|
|
15474
15491
|
waits: maintenanceWaits,
|
|
15475
15492
|
waitedMs: Date.now() - (firstMaintenanceAt ?? Date.now()),
|
|
15476
15493
|
maxWaitMs: maintenanceMaxWaitMs,
|
|
15477
|
-
exhausted:
|
|
15494
|
+
exhausted: maintenanceBudgetSpent
|
|
15478
15495
|
}
|
|
15479
15496
|
};
|
|
15480
|
-
|
|
15497
|
+
if (maintenanceBudgetSpent) {
|
|
15498
|
+
err2.suggestedAction = maintenanceExhaustedAction(maintenanceMaxWaitMs, maintenanceWaits);
|
|
15499
|
+
}
|
|
15500
|
+
}
|
|
15501
|
+
if (err2.code === "UNEXPECTED_CONTENT_TYPE" && !looksLikeMaintenanceText(text) && isHtmlLike(res.headers.get("Content-Type"), text)) {
|
|
15502
|
+
err2.details = { ...err2.details ?? {}, maintenancePatternMiss: true };
|
|
15503
|
+
this.logger.debug?.(
|
|
15504
|
+
`[autotask] non-JSON body did not match the maintenance vocabulary on ${method} ${opts.path}: ${pageSnippet}`,
|
|
15505
|
+
correlationId
|
|
15506
|
+
);
|
|
15481
15507
|
}
|
|
15482
15508
|
attachEmptyReasonDetails(err2);
|
|
15483
15509
|
throw err2;
|
|
@@ -15489,12 +15515,37 @@ var HttpClient = class {
|
|
|
15489
15515
|
break;
|
|
15490
15516
|
}
|
|
15491
15517
|
let body;
|
|
15518
|
+
let nonJsonBody;
|
|
15492
15519
|
if (text.length > 0) {
|
|
15493
15520
|
try {
|
|
15494
15521
|
body = JSON.parse(text);
|
|
15495
15522
|
} catch {
|
|
15496
15523
|
body = text;
|
|
15524
|
+
nonJsonBody = text;
|
|
15525
|
+
}
|
|
15526
|
+
}
|
|
15527
|
+
const nonJsonSnippet = nonJsonBody === void 0 ? void 0 : bodySnippet(nonJsonBody, this.redactPersonalData);
|
|
15528
|
+
const nonJsonIsMaintenance = nonJsonBody !== void 0 && looksLikeMaintenanceText(nonJsonBody);
|
|
15529
|
+
const nonJsonIsHtmlCandidate = nonJsonBody !== void 0 && isHtmlLike(res.headers.get("Content-Type"), nonJsonBody);
|
|
15530
|
+
const nonJsonMaintenanceMayWait = nonJsonIsMaintenance && retriable5xx;
|
|
15531
|
+
if (nonJsonBody !== void 0 && maintenanceMaxWaitMs > 0 && nonJsonMaintenanceMayWait) {
|
|
15532
|
+
const now = Date.now();
|
|
15533
|
+
firstMaintenanceAt ??= now;
|
|
15534
|
+
const remaining = maintenanceMaxWaitMs - (now - firstMaintenanceAt);
|
|
15535
|
+
if (remaining > 0) {
|
|
15536
|
+
const wait = Math.min(maintenancePollMs, remaining);
|
|
15537
|
+
if (wait >= remaining) maintenanceBudgetSpent = true;
|
|
15538
|
+
maintenanceWaits += 1;
|
|
15539
|
+
this.logger.warn?.(
|
|
15540
|
+
`[autotask] maintenance window on ${method} ${opts.path} (HTTP ${status}); waiting ${Math.round(wait / 1e3)}s (retry ${maintenanceWaits}, up to ${Math.round(maintenanceMaxWaitMs / 6e4)} min)`,
|
|
15541
|
+
correlationId
|
|
15542
|
+
);
|
|
15543
|
+
deadlineAt = Date.now() + wait + timeoutMs;
|
|
15544
|
+
armDeadline(deadlineAt - Date.now());
|
|
15545
|
+
await pause(wait);
|
|
15546
|
+
continue;
|
|
15497
15547
|
}
|
|
15548
|
+
maintenanceBudgetSpent = true;
|
|
15498
15549
|
}
|
|
15499
15550
|
const deterministic500 = status >= 500 && isDeterministicVendor500(parseVendorErrors(body));
|
|
15500
15551
|
const retryableStatus = status === 429 || status >= 500;
|
|
@@ -15537,6 +15588,32 @@ var HttpClient = class {
|
|
|
15537
15588
|
credentialShapeExpectation(headers, this.auth)
|
|
15538
15589
|
);
|
|
15539
15590
|
err.correlationId = correlationId;
|
|
15591
|
+
if (maintenanceWaits > 0) {
|
|
15592
|
+
err.details = {
|
|
15593
|
+
...err.details ?? {},
|
|
15594
|
+
maintenance: {
|
|
15595
|
+
waits: maintenanceWaits,
|
|
15596
|
+
waitedMs: Date.now() - (firstMaintenanceAt ?? Date.now()),
|
|
15597
|
+
maxWaitMs: maintenanceMaxWaitMs,
|
|
15598
|
+
exhausted: maintenanceBudgetSpent
|
|
15599
|
+
}
|
|
15600
|
+
};
|
|
15601
|
+
if (maintenanceBudgetSpent) {
|
|
15602
|
+
err.suggestedAction = maintenanceExhaustedAction(maintenanceMaxWaitMs, maintenanceWaits);
|
|
15603
|
+
}
|
|
15604
|
+
}
|
|
15605
|
+
if (nonJsonBody !== void 0) {
|
|
15606
|
+
if (nonJsonIsMaintenance && !retriable5xx) {
|
|
15607
|
+
err.details = { ...err.details ?? {}, maintenanceDetected: true };
|
|
15608
|
+
err.suggestedAction = `A maintenance-shaped page answered ${method} ${opts.path} (HTTP ${status}); it was NOT waited out or re-sent \u2014 a non-2xx edge page can arrive after the request was forwarded, so verify the record before re-issuing (only a GET or an explicitly idempotent-flagged call waits this window out).`;
|
|
15609
|
+
} else if (!nonJsonIsMaintenance && nonJsonIsHtmlCandidate) {
|
|
15610
|
+
err.details = { ...err.details ?? {}, maintenancePatternMiss: true };
|
|
15611
|
+
this.logger.debug?.(
|
|
15612
|
+
`[autotask] non-JSON body did not match the maintenance vocabulary on ${method} ${opts.path}: ${nonJsonSnippet}`,
|
|
15613
|
+
correlationId
|
|
15614
|
+
);
|
|
15615
|
+
}
|
|
15616
|
+
}
|
|
15540
15617
|
if (status === 401 && zoneRetry !== void 0) {
|
|
15541
15618
|
err.details = {
|
|
15542
15619
|
...err.details ?? {},
|
|
@@ -18702,6 +18779,7 @@ export {
|
|
|
18702
18779
|
DEFAULT_MAX_RETRIES,
|
|
18703
18780
|
DEFAULT_MAINTENANCE_MAX_WAIT_MS,
|
|
18704
18781
|
DEFAULT_MAINTENANCE_POLL_MS,
|
|
18782
|
+
MAINTENANCE_WINDOW_MAX_MS,
|
|
18705
18783
|
DEFAULT_MAX_CONCURRENT,
|
|
18706
18784
|
DEFAULT_MAX_RESPONSE_BYTES,
|
|
18707
18785
|
DEFAULT_MAX_SCAN_RECORDS,
|