@warmhub/sdk-ts 0.44.1 → 0.46.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/dist/{chunk-KFNNTFDG.js → chunk-RX3ZL6P5.js} +551 -33
- package/dist/chunk-RX3ZL6P5.js.map +1 -0
- package/dist/index.d.ts +241 -14
- package/dist/index.js +1 -1
- package/dist/react.js +2 -2
- package/package.json +26 -2
- package/dist/chunk-KFNNTFDG.js.map +0 -1
|
@@ -51,6 +51,115 @@ function splitLocalPath(name) {
|
|
|
51
51
|
return { shapePrefix: name.slice(0, idx), bareName: name.slice(idx + 1) };
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// ../rules/src/component-cli-signing.ts
|
|
55
|
+
var CLI_INSTALL_REPO_HEADER = "X-WarmHub-Install-Repo";
|
|
56
|
+
var CLI_SIGNATURE_HEADER = "X-WarmHub-Signature";
|
|
57
|
+
var CLI_TIMESTAMP_HEADER = "X-WarmHub-Timestamp";
|
|
58
|
+
var RFC3986_UNRESERVED = /^[A-Za-z0-9\-._~]$/;
|
|
59
|
+
function pctEncode(value) {
|
|
60
|
+
let out = "";
|
|
61
|
+
const bytes = new TextEncoder().encode(value);
|
|
62
|
+
for (const byte of bytes) {
|
|
63
|
+
const ch = String.fromCharCode(byte);
|
|
64
|
+
if (RFC3986_UNRESERVED.test(ch)) {
|
|
65
|
+
out += ch;
|
|
66
|
+
} else {
|
|
67
|
+
out += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
function serializeQueryValue(value) {
|
|
73
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
74
|
+
if (typeof value === "number") return JSON.stringify(value);
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
function cliMethodHasBody(method) {
|
|
78
|
+
return method === "POST" || method === "PUT" || method === "PATCH";
|
|
79
|
+
}
|
|
80
|
+
function canonicalCliQueryString(args) {
|
|
81
|
+
const entries = [];
|
|
82
|
+
for (const [k, v] of Object.entries(args)) {
|
|
83
|
+
if (v === void 0 || v === null) continue;
|
|
84
|
+
entries.push([k, serializeQueryValue(v)]);
|
|
85
|
+
}
|
|
86
|
+
entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
87
|
+
return entries.map(([k, v]) => `${pctEncode(k)}=${pctEncode(v)}`).join("&");
|
|
88
|
+
}
|
|
89
|
+
function bytesToHex(bytes) {
|
|
90
|
+
let out = "";
|
|
91
|
+
for (const byte of bytes) {
|
|
92
|
+
out += byte.toString(16).padStart(2, "0");
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
async function sha256Hex(text) {
|
|
97
|
+
const buf = await crypto.subtle.digest(
|
|
98
|
+
"SHA-256",
|
|
99
|
+
new TextEncoder().encode(text)
|
|
100
|
+
);
|
|
101
|
+
return bytesToHex(new Uint8Array(buf));
|
|
102
|
+
}
|
|
103
|
+
var EMPTY_BODY_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
104
|
+
function buildCliSigningInput(input) {
|
|
105
|
+
return [
|
|
106
|
+
input.method,
|
|
107
|
+
input.path,
|
|
108
|
+
input.canonicalQuery,
|
|
109
|
+
input.installRepo,
|
|
110
|
+
input.bodyHash,
|
|
111
|
+
String(input.timestamp)
|
|
112
|
+
].join("\n");
|
|
113
|
+
}
|
|
114
|
+
async function hmacSha256Hex(secret, message) {
|
|
115
|
+
const encoder = new TextEncoder();
|
|
116
|
+
const key = await crypto.subtle.importKey(
|
|
117
|
+
"raw",
|
|
118
|
+
encoder.encode(secret),
|
|
119
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
120
|
+
false,
|
|
121
|
+
["sign"]
|
|
122
|
+
);
|
|
123
|
+
const signature = await crypto.subtle.sign(
|
|
124
|
+
"HMAC",
|
|
125
|
+
key,
|
|
126
|
+
encoder.encode(message)
|
|
127
|
+
);
|
|
128
|
+
return bytesToHex(new Uint8Array(signature));
|
|
129
|
+
}
|
|
130
|
+
var SIGNATURE_RE = /^sha256=([0-9a-f]{64})$/;
|
|
131
|
+
var DEFAULT_TOLERANCE_SEC = 300;
|
|
132
|
+
async function verifyCliRequest(input) {
|
|
133
|
+
const match = SIGNATURE_RE.exec(input.signature);
|
|
134
|
+
if (!match) return { ok: false, reason: "invalid-format" };
|
|
135
|
+
const providedHex = match[1];
|
|
136
|
+
const tolerance = input.toleranceSec ?? DEFAULT_TOLERANCE_SEC;
|
|
137
|
+
const skew = Math.abs(input.nowUnixSeconds - input.timestamp);
|
|
138
|
+
if (skew > tolerance) return { ok: false, reason: "expired" };
|
|
139
|
+
const bodyHash = input.body.length === 0 ? EMPTY_BODY_SHA256 : await sha256Hex(input.body);
|
|
140
|
+
const canonical = buildCliSigningInput({
|
|
141
|
+
method: input.method,
|
|
142
|
+
path: input.path,
|
|
143
|
+
canonicalQuery: canonicalCliQueryString(input.query),
|
|
144
|
+
installRepo: input.installRepo,
|
|
145
|
+
bodyHash,
|
|
146
|
+
timestamp: input.timestamp
|
|
147
|
+
});
|
|
148
|
+
const expectedHex = await hmacSha256Hex(input.secret, canonical);
|
|
149
|
+
if (!constantTimeEqualHex(providedHex, expectedHex)) {
|
|
150
|
+
return { ok: false, reason: "invalid-signature" };
|
|
151
|
+
}
|
|
152
|
+
return { ok: true };
|
|
153
|
+
}
|
|
154
|
+
function constantTimeEqualHex(a, b) {
|
|
155
|
+
if (a.length !== b.length) return false;
|
|
156
|
+
let diff = 0;
|
|
157
|
+
for (let i = 0; i < a.length; i++) {
|
|
158
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
159
|
+
}
|
|
160
|
+
return diff === 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
54
163
|
// ../rules/src/repo-auth-scopes.ts
|
|
55
164
|
var REPO_AUTH_SCOPES = [
|
|
56
165
|
"repo:read",
|
|
@@ -1442,6 +1551,23 @@ function inferKind(name, operation) {
|
|
|
1442
1551
|
// src/stream-submit.ts
|
|
1443
1552
|
var DEFAULT_STREAM_CHUNK_SIZE = DEFAULT_STREAM_APPEND_CHUNK_SIZE;
|
|
1444
1553
|
var MAX_STREAM_APPEND_OPERATION_COUNT2 = MAX_STREAM_APPEND_OPERATION_COUNT;
|
|
1554
|
+
function streamAppendResultStatus(result) {
|
|
1555
|
+
if (result.status === "failed") {
|
|
1556
|
+
return "error";
|
|
1557
|
+
}
|
|
1558
|
+
return result.status === "noop" || result.operation === "noop" ? "noop" : "applied";
|
|
1559
|
+
}
|
|
1560
|
+
function countStreamAppendResultStatuses(results) {
|
|
1561
|
+
const statusCounts = {
|
|
1562
|
+
applied: 0,
|
|
1563
|
+
noop: 0,
|
|
1564
|
+
error: 0
|
|
1565
|
+
};
|
|
1566
|
+
for (const result of results) {
|
|
1567
|
+
statusCounts[streamAppendResultStatus(result)]++;
|
|
1568
|
+
}
|
|
1569
|
+
return statusCounts;
|
|
1570
|
+
}
|
|
1445
1571
|
var DEFAULT_RETRY_POLICY = {
|
|
1446
1572
|
maxAttempts: 3,
|
|
1447
1573
|
baseDelayMs: 250,
|
|
@@ -1509,12 +1635,41 @@ var PartialStreamSubmissionError = class extends Error {
|
|
|
1509
1635
|
this.completedOperations = input.completedOperations;
|
|
1510
1636
|
}
|
|
1511
1637
|
};
|
|
1638
|
+
var AllStreamOperationsFailedError = class extends Error {
|
|
1639
|
+
code = "STREAM_ALL_OPERATIONS_FAILED";
|
|
1640
|
+
result;
|
|
1641
|
+
operations;
|
|
1642
|
+
statusCounts;
|
|
1643
|
+
cause;
|
|
1644
|
+
constructor(result) {
|
|
1645
|
+
const primaryFailure = result.operations.find(
|
|
1646
|
+
(operation) => operation.error !== void 0
|
|
1647
|
+
)?.error;
|
|
1648
|
+
super(
|
|
1649
|
+
primaryFailure ? `All ${result.operationCount} stream operations failed: ${primaryFailure.message}` : `All ${result.operationCount} stream operations failed.`
|
|
1650
|
+
);
|
|
1651
|
+
this.name = "WarmHubError";
|
|
1652
|
+
this.cause = primaryFailure;
|
|
1653
|
+
this.result = result;
|
|
1654
|
+
this.operations = result.operations;
|
|
1655
|
+
this.statusCounts = result.statusCounts ?? {
|
|
1656
|
+
applied: 0,
|
|
1657
|
+
noop: 0,
|
|
1658
|
+
error: result.operationCount
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1512
1662
|
async function submitOperationsViaStream(client, args) {
|
|
1513
1663
|
if (args.operations.length === 0) {
|
|
1514
1664
|
throw new StreamValidationError(
|
|
1515
1665
|
"At least one operation is required for stream submission."
|
|
1516
1666
|
);
|
|
1517
1667
|
}
|
|
1668
|
+
if ((args.allocatedTokens?.length ?? 0) > 0 && args.streamId === void 0) {
|
|
1669
|
+
throw new StreamValidationError(
|
|
1670
|
+
"Manual stream resume with allocatedTokens requires the original streamId."
|
|
1671
|
+
);
|
|
1672
|
+
}
|
|
1518
1673
|
const operations = args.operations.map((operation, index) => {
|
|
1519
1674
|
let streamOperation;
|
|
1520
1675
|
try {
|
|
@@ -1535,8 +1690,13 @@ async function submitOperationsViaStream(client, args) {
|
|
|
1535
1690
|
const isManualResume = args.streamId !== void 0 || (args.allocatedTokens?.length ?? 0) > 0;
|
|
1536
1691
|
const policy = isManualResume ? false : resolveRetryPolicy(args.retry);
|
|
1537
1692
|
let allocatedTokens = args.allocatedTokens ?? [];
|
|
1693
|
+
let createdByEmail;
|
|
1538
1694
|
const chunkResults = [];
|
|
1539
|
-
|
|
1695
|
+
let sawAmbiguousAttempt = false;
|
|
1696
|
+
for (const { operations: chunk, start: chunkStart } of chunkOperations(
|
|
1697
|
+
operations,
|
|
1698
|
+
chunkSize
|
|
1699
|
+
)) {
|
|
1540
1700
|
let attempt = 1;
|
|
1541
1701
|
let priorAttemptAmbiguous = false;
|
|
1542
1702
|
const chunkIsAtomic = chunk.length === 1;
|
|
@@ -1550,10 +1710,16 @@ async function submitOperationsViaStream(client, args) {
|
|
|
1550
1710
|
streamId,
|
|
1551
1711
|
componentId: args.componentId,
|
|
1552
1712
|
committer: args.committer,
|
|
1713
|
+
message: args.message,
|
|
1553
1714
|
operations: chunk
|
|
1554
1715
|
});
|
|
1555
1716
|
allocatedTokens = appendResult.allocatedTokens;
|
|
1556
|
-
|
|
1717
|
+
if (appendResult.createdByEmail !== void 0) {
|
|
1718
|
+
createdByEmail = appendResult.createdByEmail;
|
|
1719
|
+
}
|
|
1720
|
+
chunkResults.push(
|
|
1721
|
+
...offsetChunkResultIndexes(appendResult.results, chunkStart)
|
|
1722
|
+
);
|
|
1557
1723
|
break;
|
|
1558
1724
|
} catch (cause) {
|
|
1559
1725
|
if (chunkResults.length === 0 && !priorAttemptAmbiguous && isDefiniteClientError(cause)) {
|
|
@@ -1563,18 +1729,23 @@ async function submitOperationsViaStream(client, args) {
|
|
|
1563
1729
|
await sleep(computeBackoffDelayMs(attempt, policy));
|
|
1564
1730
|
attempt += 1;
|
|
1565
1731
|
priorAttemptAmbiguous = true;
|
|
1732
|
+
sawAmbiguousAttempt = true;
|
|
1566
1733
|
streamId = createStreamId();
|
|
1567
1734
|
allocatedTokens = [];
|
|
1568
1735
|
continue;
|
|
1569
1736
|
}
|
|
1570
|
-
const completedOperations =
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1737
|
+
const completedOperations = completedOperationsFrom(
|
|
1738
|
+
toSubmittedStreamResult(
|
|
1739
|
+
{
|
|
1740
|
+
operationCount: chunkResults.length
|
|
1741
|
+
},
|
|
1742
|
+
args.committer,
|
|
1743
|
+
createdByEmail,
|
|
1744
|
+
args.message,
|
|
1745
|
+
chunkResults,
|
|
1746
|
+
operations
|
|
1747
|
+
)
|
|
1748
|
+
);
|
|
1578
1749
|
throw new PartialStreamSubmissionError({
|
|
1579
1750
|
cause,
|
|
1580
1751
|
completedOperations
|
|
@@ -1582,20 +1753,54 @@ async function submitOperationsViaStream(client, args) {
|
|
|
1582
1753
|
}
|
|
1583
1754
|
}
|
|
1584
1755
|
}
|
|
1585
|
-
|
|
1756
|
+
const result = toSubmittedStreamResult(
|
|
1586
1757
|
{
|
|
1587
1758
|
operationCount: chunkResults.length
|
|
1588
1759
|
},
|
|
1589
1760
|
args.committer,
|
|
1761
|
+
createdByEmail,
|
|
1590
1762
|
args.message,
|
|
1591
|
-
chunkResults
|
|
1763
|
+
chunkResults,
|
|
1764
|
+
operations
|
|
1592
1765
|
);
|
|
1766
|
+
if (isAllSubmittedOperationsFailed(result, operations.length)) {
|
|
1767
|
+
const failure = new AllStreamOperationsFailedError(result);
|
|
1768
|
+
if (sawAmbiguousAttempt) {
|
|
1769
|
+
throw new PartialStreamSubmissionError({
|
|
1770
|
+
cause: failure,
|
|
1771
|
+
completedOperations: completedOperationsFrom(result)
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
throw failure;
|
|
1775
|
+
}
|
|
1776
|
+
return result;
|
|
1777
|
+
}
|
|
1778
|
+
function isAllSubmittedOperationsFailed(result, submittedOperationCount) {
|
|
1779
|
+
if (submittedOperationCount <= 0) {
|
|
1780
|
+
return false;
|
|
1781
|
+
}
|
|
1782
|
+
const inputRowsFailed = /* @__PURE__ */ new Map();
|
|
1783
|
+
for (const operation of result.operations) {
|
|
1784
|
+
if (operation.opIndex === void 0 || operation.opIndex < 0 || operation.opIndex >= submittedOperationCount) {
|
|
1785
|
+
continue;
|
|
1786
|
+
}
|
|
1787
|
+
inputRowsFailed.set(
|
|
1788
|
+
operation.opIndex,
|
|
1789
|
+
(inputRowsFailed.get(operation.opIndex) ?? true) && operation.status === "error"
|
|
1790
|
+
);
|
|
1791
|
+
}
|
|
1792
|
+
return inputRowsFailed.size === submittedOperationCount && [...inputRowsFailed.values()].every(Boolean);
|
|
1793
|
+
}
|
|
1794
|
+
function completedOperationsFrom(result) {
|
|
1795
|
+
return result.operations.filter((operation) => operation.status !== "error");
|
|
1593
1796
|
}
|
|
1594
1797
|
var DEFINITE_CLIENT_REJECT_CODES = /* @__PURE__ */ new Set([
|
|
1595
1798
|
"UNAUTHENTICATED",
|
|
1596
1799
|
"FORBIDDEN",
|
|
1597
1800
|
"VALIDATION_ERROR",
|
|
1598
1801
|
"SHAPE_MISMATCH",
|
|
1802
|
+
"RESERVED_NAME",
|
|
1803
|
+
"ILLEGAL_OP_SEQUENCE",
|
|
1599
1804
|
"NOT_FOUND",
|
|
1600
1805
|
"KIND_MISMATCH",
|
|
1601
1806
|
"CONFLICT",
|
|
@@ -1625,13 +1830,18 @@ function isDefiniteClientError(cause) {
|
|
|
1625
1830
|
}
|
|
1626
1831
|
function isTransientStreamFailure(cause) {
|
|
1627
1832
|
if (isDefiniteClientError(cause)) return false;
|
|
1833
|
+
if (isFetchNetworkTypeError(cause)) return true;
|
|
1628
1834
|
if (cause instanceof TypeError) return false;
|
|
1629
1835
|
if (cause instanceof SyntaxError) return false;
|
|
1630
1836
|
const inner = cause?.cause;
|
|
1837
|
+
if (isFetchNetworkTypeError(inner)) return true;
|
|
1631
1838
|
if (inner instanceof TypeError) return false;
|
|
1632
1839
|
if (inner instanceof SyntaxError) return false;
|
|
1633
1840
|
return true;
|
|
1634
1841
|
}
|
|
1842
|
+
function isFetchNetworkTypeError(cause) {
|
|
1843
|
+
return cause instanceof TypeError && /fetch/i.test(cause.message);
|
|
1844
|
+
}
|
|
1635
1845
|
function computeBackoffDelayMs(attempt, policy) {
|
|
1636
1846
|
const exponential = policy.baseDelayMs * 2 ** Math.max(0, attempt - 1);
|
|
1637
1847
|
const jitter = Math.random() * policy.baseDelayMs;
|
|
@@ -1644,12 +1854,22 @@ var TOKEN_REF_REGEX = /[$#]\d+/;
|
|
|
1644
1854
|
function stringHasTokenRef(value) {
|
|
1645
1855
|
return typeof value === "string" && TOKEN_REF_REGEX.test(value);
|
|
1646
1856
|
}
|
|
1647
|
-
function
|
|
1648
|
-
if (
|
|
1649
|
-
|
|
1857
|
+
function structuralValueHasTokenRef(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1858
|
+
if (stringHasTokenRef(value)) return true;
|
|
1859
|
+
if (value !== null && typeof value === "object") {
|
|
1860
|
+
if (seen.has(value)) return false;
|
|
1861
|
+
seen.add(value);
|
|
1862
|
+
if (Array.isArray(value)) {
|
|
1863
|
+
return value.some((entry) => structuralValueHasTokenRef(entry, seen));
|
|
1864
|
+
}
|
|
1865
|
+
return Object.values(value).some(
|
|
1866
|
+
(entry) => structuralValueHasTokenRef(entry, seen)
|
|
1867
|
+
);
|
|
1868
|
+
}
|
|
1869
|
+
return false;
|
|
1650
1870
|
}
|
|
1651
1871
|
function opUsesTokens(op) {
|
|
1652
|
-
return stringHasTokenRef(op.name) || stringHasTokenRef(op.wref) ||
|
|
1872
|
+
return stringHasTokenRef(op.name) || stringHasTokenRef(op.wref) || structuralValueHasTokenRef(op.about) || stringHasTokenRef(op.aboutWref) || structuralValueHasTokenRef(op.members) || structuralValueHasTokenRef(op.data);
|
|
1653
1873
|
}
|
|
1654
1874
|
function createStreamId() {
|
|
1655
1875
|
return globalThis.crypto?.randomUUID?.() ?? `stream-${Date.now()}-${Math.random()}`;
|
|
@@ -1667,27 +1887,213 @@ function normalizeChunkSize(chunkSize) {
|
|
|
1667
1887
|
function chunkOperations(operations, chunkSize) {
|
|
1668
1888
|
const chunks = [];
|
|
1669
1889
|
for (let start = 0; start < operations.length; start += chunkSize) {
|
|
1670
|
-
chunks.push(
|
|
1890
|
+
chunks.push({
|
|
1891
|
+
operations: operations.slice(start, start + chunkSize),
|
|
1892
|
+
start
|
|
1893
|
+
});
|
|
1671
1894
|
}
|
|
1672
1895
|
return chunks;
|
|
1673
1896
|
}
|
|
1674
|
-
function
|
|
1897
|
+
function offsetChunkResultIndexes(results, chunkStart) {
|
|
1898
|
+
return results.map((result, index) => ({
|
|
1899
|
+
...result,
|
|
1900
|
+
opIndex: chunkStart + (result.opIndex ?? index)
|
|
1901
|
+
}));
|
|
1902
|
+
}
|
|
1903
|
+
function toSubmittedStreamResult(writeResult, committer, createdByEmail, message, results, operations) {
|
|
1904
|
+
const statusCounts = countStreamAppendResultStatuses(results);
|
|
1905
|
+
const partial = statusCounts.error > 0;
|
|
1675
1906
|
return {
|
|
1676
1907
|
committer,
|
|
1908
|
+
...createdByEmail !== void 0 ? { createdByEmail } : {},
|
|
1677
1909
|
message,
|
|
1678
1910
|
operationCount: writeResult.operationCount,
|
|
1911
|
+
...partial ? { partial, statusCounts } : {},
|
|
1679
1912
|
operations: results.map((result) => ({
|
|
1913
|
+
...result.opIndex !== void 0 ? { opIndex: result.opIndex } : {},
|
|
1680
1914
|
name: result.name ?? "",
|
|
1681
1915
|
operation: result.operation === "revise" || result.operation === "retract" || result.operation === "noop" ? result.operation : "add",
|
|
1682
1916
|
dataHash: result.dataHash ?? "",
|
|
1683
1917
|
version: result.version ?? 0,
|
|
1684
|
-
status: result
|
|
1918
|
+
status: streamAppendResultStatus(result),
|
|
1685
1919
|
error: result.error,
|
|
1920
|
+
...result.status === "failed" && result.opIndex !== void 0 && operations[result.opIndex]?.name !== void 0 ? { submittedName: operations[result.opIndex]?.name } : {},
|
|
1921
|
+
...result.resolvedName !== void 0 ? { resolvedName: result.resolvedName } : {},
|
|
1922
|
+
...result.retryable !== void 0 ? { retryable: result.retryable } : {},
|
|
1686
1923
|
...result.warnings ? { warnings: result.warnings } : {}
|
|
1687
1924
|
}))
|
|
1688
1925
|
};
|
|
1689
1926
|
}
|
|
1690
1927
|
|
|
1928
|
+
// src/component-cli.ts
|
|
1929
|
+
var SUPPORTED_METHODS = /* @__PURE__ */ new Set([
|
|
1930
|
+
"GET",
|
|
1931
|
+
"POST",
|
|
1932
|
+
"PUT",
|
|
1933
|
+
"PATCH",
|
|
1934
|
+
"DELETE"
|
|
1935
|
+
]);
|
|
1936
|
+
var CliCallVerificationError = class extends Error {
|
|
1937
|
+
reason;
|
|
1938
|
+
constructor(reason, message) {
|
|
1939
|
+
super(message);
|
|
1940
|
+
this.name = "CliCallVerificationError";
|
|
1941
|
+
this.reason = reason;
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
async function verifyCliCall(request, secrets, opts) {
|
|
1945
|
+
const method = request.method.toUpperCase();
|
|
1946
|
+
if (!SUPPORTED_METHODS.has(method)) {
|
|
1947
|
+
throw new CliCallVerificationError(
|
|
1948
|
+
"unsupported-method",
|
|
1949
|
+
`Unsupported HTTP method "${request.method}" \u2014 component CLI dispatch only emits GET, POST, PUT, or PATCH`
|
|
1950
|
+
);
|
|
1951
|
+
}
|
|
1952
|
+
const cliMethod = method;
|
|
1953
|
+
const installRepo = request.headers.get(CLI_INSTALL_REPO_HEADER);
|
|
1954
|
+
if (!installRepo) {
|
|
1955
|
+
throw new CliCallVerificationError(
|
|
1956
|
+
"missing-install-repo",
|
|
1957
|
+
`Missing ${CLI_INSTALL_REPO_HEADER} header`
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
const hasSigning = isNonEmpty(secrets.CLI_SIGNING_SECRET);
|
|
1961
|
+
const hasBearer = isNonEmpty(secrets.CLI_BEARER_TOKEN);
|
|
1962
|
+
const hasApiKey = isNonEmpty(secrets.CLI_API_KEY);
|
|
1963
|
+
const hasBasic = isNonEmpty(secrets.CLI_BASIC_USERNAME) && isNonEmpty(secrets.CLI_BASIC_PASSWORD);
|
|
1964
|
+
if (!hasSigning && !hasBearer && !hasApiKey && !hasBasic) {
|
|
1965
|
+
throw new CliCallVerificationError(
|
|
1966
|
+
"no-scheme-configured",
|
|
1967
|
+
"no-scheme-configured: need at least one of CLI_SIGNING_SECRET, CLI_BEARER_TOKEN, CLI_API_KEY, or CLI_BASIC_USERNAME + CLI_BASIC_PASSWORD"
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1970
|
+
const url = new URL(request.url);
|
|
1971
|
+
const path = url.pathname;
|
|
1972
|
+
let query;
|
|
1973
|
+
let body;
|
|
1974
|
+
let args;
|
|
1975
|
+
if (!cliMethodHasBody(cliMethod)) {
|
|
1976
|
+
query = Object.fromEntries(url.searchParams.entries());
|
|
1977
|
+
body = "";
|
|
1978
|
+
args = { ...query };
|
|
1979
|
+
} else {
|
|
1980
|
+
query = {};
|
|
1981
|
+
body = await request.text();
|
|
1982
|
+
let parsed;
|
|
1983
|
+
try {
|
|
1984
|
+
parsed = JSON.parse(body);
|
|
1985
|
+
} catch {
|
|
1986
|
+
throw new CliCallVerificationError(
|
|
1987
|
+
"invalid-body",
|
|
1988
|
+
"POST body is not valid JSON"
|
|
1989
|
+
);
|
|
1990
|
+
}
|
|
1991
|
+
if (!isArgsRecord(parsed)) {
|
|
1992
|
+
throw new CliCallVerificationError(
|
|
1993
|
+
"invalid-body",
|
|
1994
|
+
"POST body must be a JSON object of primitive args (string / number / boolean)"
|
|
1995
|
+
);
|
|
1996
|
+
}
|
|
1997
|
+
args = parsed;
|
|
1998
|
+
}
|
|
1999
|
+
if (hasSigning) {
|
|
2000
|
+
const signature = request.headers.get(CLI_SIGNATURE_HEADER);
|
|
2001
|
+
if (!signature) {
|
|
2002
|
+
throw new CliCallVerificationError(
|
|
2003
|
+
"missing-signature",
|
|
2004
|
+
`Missing ${CLI_SIGNATURE_HEADER} header`
|
|
2005
|
+
);
|
|
2006
|
+
}
|
|
2007
|
+
const timestampHeader = request.headers.get(CLI_TIMESTAMP_HEADER);
|
|
2008
|
+
if (!timestampHeader) {
|
|
2009
|
+
throw new CliCallVerificationError(
|
|
2010
|
+
"missing-timestamp",
|
|
2011
|
+
`Missing ${CLI_TIMESTAMP_HEADER} header`
|
|
2012
|
+
);
|
|
2013
|
+
}
|
|
2014
|
+
const timestamp = Number(timestampHeader);
|
|
2015
|
+
if (!Number.isFinite(timestamp) || !Number.isInteger(timestamp)) {
|
|
2016
|
+
throw new CliCallVerificationError(
|
|
2017
|
+
"invalid-timestamp",
|
|
2018
|
+
`${CLI_TIMESTAMP_HEADER} must be an integer unix seconds value; got "${timestampHeader}"`
|
|
2019
|
+
);
|
|
2020
|
+
}
|
|
2021
|
+
const verification = await verifyCliRequest({
|
|
2022
|
+
secret: secrets.CLI_SIGNING_SECRET,
|
|
2023
|
+
method: cliMethod,
|
|
2024
|
+
path,
|
|
2025
|
+
query,
|
|
2026
|
+
installRepo,
|
|
2027
|
+
body,
|
|
2028
|
+
signature,
|
|
2029
|
+
timestamp,
|
|
2030
|
+
nowUnixSeconds: opts?.nowUnixSeconds ?? Math.floor(Date.now() / 1e3),
|
|
2031
|
+
toleranceSec: opts?.toleranceSec
|
|
2032
|
+
});
|
|
2033
|
+
if (!verification.ok) {
|
|
2034
|
+
throw new CliCallVerificationError(
|
|
2035
|
+
verification.reason,
|
|
2036
|
+
`HMAC verification failed: ${verification.reason}`
|
|
2037
|
+
);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
if (hasBearer) {
|
|
2041
|
+
const expected = `Bearer ${secrets.CLI_BEARER_TOKEN}`;
|
|
2042
|
+
const provided = request.headers.get("authorization") ?? "";
|
|
2043
|
+
if (!constantTimeEqual(provided, expected)) {
|
|
2044
|
+
throw new CliCallVerificationError(
|
|
2045
|
+
"invalid-bearer",
|
|
2046
|
+
"invalid-bearer: bearer token mismatch"
|
|
2047
|
+
);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
if (hasApiKey) {
|
|
2051
|
+
const headerName = isNonEmpty(secrets.CLI_API_KEY_HEADER) ? secrets.CLI_API_KEY_HEADER : "X-API-Key";
|
|
2052
|
+
const provided = request.headers.get(headerName) ?? "";
|
|
2053
|
+
if (!constantTimeEqual(provided, secrets.CLI_API_KEY)) {
|
|
2054
|
+
throw new CliCallVerificationError(
|
|
2055
|
+
"invalid-api-key",
|
|
2056
|
+
`invalid-api-key: mismatch on header "${headerName}"`
|
|
2057
|
+
);
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
if (hasBasic) {
|
|
2061
|
+
const expected = `Basic ${btoa(`${secrets.CLI_BASIC_USERNAME}:${secrets.CLI_BASIC_PASSWORD}`)}`;
|
|
2062
|
+
const provided = request.headers.get("authorization") ?? "";
|
|
2063
|
+
if (!constantTimeEqual(provided, expected)) {
|
|
2064
|
+
throw new CliCallVerificationError(
|
|
2065
|
+
"invalid-basic",
|
|
2066
|
+
"invalid-basic: basic auth mismatch"
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
return { method: cliMethod, installRepo, args };
|
|
2071
|
+
}
|
|
2072
|
+
function isNonEmpty(value) {
|
|
2073
|
+
return typeof value === "string" && value.length > 0;
|
|
2074
|
+
}
|
|
2075
|
+
function isArgsRecord(value) {
|
|
2076
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2077
|
+
return false;
|
|
2078
|
+
}
|
|
2079
|
+
for (const v of Object.values(value)) {
|
|
2080
|
+
if (v === void 0) continue;
|
|
2081
|
+
if (typeof v === "string") continue;
|
|
2082
|
+
if (typeof v === "number") continue;
|
|
2083
|
+
if (typeof v === "boolean") continue;
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
return true;
|
|
2087
|
+
}
|
|
2088
|
+
function constantTimeEqual(a, b) {
|
|
2089
|
+
if (a.length !== b.length) return false;
|
|
2090
|
+
let diff = 0;
|
|
2091
|
+
for (let i = 0; i < a.length; i++) {
|
|
2092
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
2093
|
+
}
|
|
2094
|
+
return diff === 0;
|
|
2095
|
+
}
|
|
2096
|
+
|
|
1691
2097
|
// src/operation-builder.ts
|
|
1692
2098
|
var OperationBuilder = class {
|
|
1693
2099
|
ops = [];
|
|
@@ -1952,7 +2358,7 @@ var OperationBuilder = class {
|
|
|
1952
2358
|
/**
|
|
1953
2359
|
* Validate, submit, and seal the builder.
|
|
1954
2360
|
*
|
|
1955
|
-
* A successful call submits operations through the same stream path as `client.commit.apply` and makes the builder single-use. Validation failures throw before any server request is made. Ambiguous multi-chunk failures surface as `PartialStreamSubmissionError
|
|
2361
|
+
* A successful call submits operations through the same stream path as `client.commit.apply` and makes the builder single-use. Validation failures throw before any server request is made. Ambiguous multi-chunk failures surface as `PartialStreamSubmissionError`; deterministic all-failed batches surface as `AllStreamOperationsFailedError` with per-op failure data.
|
|
1956
2362
|
*
|
|
1957
2363
|
* @param params.client WarmHub client or compatible stream client used for submission.
|
|
1958
2364
|
* @param params.message Optional commit message.
|
|
@@ -2183,7 +2589,7 @@ function preflightCheckRevise(kind, name, data) {
|
|
|
2183
2589
|
function normalizeWref(wref) {
|
|
2184
2590
|
return wref.replace(/@(?:v\d+|HEAD|ALL)$/i, "");
|
|
2185
2591
|
}
|
|
2186
|
-
var SDK_VERSION = "0.
|
|
2592
|
+
var SDK_VERSION = "0.46.0" ;
|
|
2187
2593
|
var DEFAULT_API_URL = "https://api.warmhub.ai";
|
|
2188
2594
|
var UNBATCHED_TRPC_PATHS = /* @__PURE__ */ new Set([
|
|
2189
2595
|
"repo.shapeInstanceCounts",
|
|
@@ -2307,13 +2713,22 @@ var WarmHubError = class extends Error {
|
|
|
2307
2713
|
* responses and other backend signals that carry a Retry-After header.
|
|
2308
2714
|
*/
|
|
2309
2715
|
retryAfter;
|
|
2310
|
-
|
|
2716
|
+
/**
|
|
2717
|
+
* Backend domain code from the response body. Set iff the backend wire
|
|
2718
|
+
* carried a structured `error.code` string. Use this when the question is
|
|
2719
|
+
* "did the backend specifically say this?". For best-effort labelling that
|
|
2720
|
+
* also covers SDK-local transport codes (`NETWORK`, `CANCELLED`, the
|
|
2721
|
+
* generic `BACKEND` fallback), branch on {@link code} or {@link kind}.
|
|
2722
|
+
*/
|
|
2723
|
+
backendCode;
|
|
2724
|
+
constructor(code, message, status, hint, retryAfter, backendCode) {
|
|
2311
2725
|
super(message);
|
|
2312
2726
|
this.name = "WarmHubError";
|
|
2313
2727
|
this.code = code;
|
|
2314
2728
|
this.status = status;
|
|
2315
2729
|
this.hint = hint;
|
|
2316
2730
|
this.retryAfter = retryAfter;
|
|
2731
|
+
this.backendCode = backendCode;
|
|
2317
2732
|
}
|
|
2318
2733
|
get kind() {
|
|
2319
2734
|
return this.code;
|
|
@@ -2334,13 +2749,15 @@ function toWarmHubError(error) {
|
|
|
2334
2749
|
return error.cause;
|
|
2335
2750
|
}
|
|
2336
2751
|
const data = error.data;
|
|
2752
|
+
const wireCode = data?.warmhub?.code;
|
|
2337
2753
|
const message = data?.warmhub?.message ?? sanitizeErrorMessage(error.message);
|
|
2338
2754
|
return new WarmHubError(
|
|
2339
|
-
|
|
2755
|
+
wireCode ?? "BACKEND",
|
|
2340
2756
|
message,
|
|
2341
2757
|
data?.warmhub?.status,
|
|
2342
2758
|
data?.warmhub?.hint,
|
|
2343
|
-
data?.warmhub?.retryAfter
|
|
2759
|
+
data?.warmhub?.retryAfter,
|
|
2760
|
+
wireCode
|
|
2344
2761
|
);
|
|
2345
2762
|
}
|
|
2346
2763
|
if (error instanceof Error) {
|
|
@@ -2351,7 +2768,8 @@ function toWarmHubError(error) {
|
|
|
2351
2768
|
sanitizeErrorMessage(error.message),
|
|
2352
2769
|
typeof warmhubLike.status === "number" ? warmhubLike.status : void 0,
|
|
2353
2770
|
typeof warmhubLike.hint === "string" ? warmhubLike.hint : void 0,
|
|
2354
|
-
typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : void 0
|
|
2771
|
+
typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : void 0,
|
|
2772
|
+
typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : void 0
|
|
2355
2773
|
);
|
|
2356
2774
|
}
|
|
2357
2775
|
if (error.name === "AbortError") {
|
|
@@ -2393,6 +2811,57 @@ function isConnectionError(error) {
|
|
|
2393
2811
|
function connectionErrorMessage(url) {
|
|
2394
2812
|
return `Unable to connect to ${url}. Is the computer able to access the url?`;
|
|
2395
2813
|
}
|
|
2814
|
+
function parseSemver(value) {
|
|
2815
|
+
const match = value.trim().match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.*)?$/);
|
|
2816
|
+
if (!match) return void 0;
|
|
2817
|
+
let prerelease = [];
|
|
2818
|
+
if (match[4]) {
|
|
2819
|
+
prerelease = match[4].split(".");
|
|
2820
|
+
for (const id of prerelease) {
|
|
2821
|
+
if (id.length === 0) return void 0;
|
|
2822
|
+
if (/^\d+$/.test(id) && id.length > 1 && id.startsWith("0")) {
|
|
2823
|
+
return void 0;
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
return {
|
|
2828
|
+
major: Number(match[1]),
|
|
2829
|
+
minor: Number(match[2]),
|
|
2830
|
+
patch: Number(match[3]),
|
|
2831
|
+
prerelease
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
function comparePrereleaseIdentifiers(a, b) {
|
|
2835
|
+
const aNum = /^\d+$/.test(a);
|
|
2836
|
+
const bNum = /^\d+$/.test(b);
|
|
2837
|
+
if (aNum && bNum) return Number(a) - Number(b);
|
|
2838
|
+
if (aNum && !bNum) return -1;
|
|
2839
|
+
if (!aNum && bNum) return 1;
|
|
2840
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
2841
|
+
}
|
|
2842
|
+
function comparePrerelease(a, b) {
|
|
2843
|
+
if (a.length === 0 && b.length > 0) return 1;
|
|
2844
|
+
if (a.length > 0 && b.length === 0) return -1;
|
|
2845
|
+
const max = Math.max(a.length, b.length);
|
|
2846
|
+
for (let i = 0; i < max; i += 1) {
|
|
2847
|
+
const aPart = a[i];
|
|
2848
|
+
const bPart = b[i];
|
|
2849
|
+
if (aPart === void 0) return -1;
|
|
2850
|
+
if (bPart === void 0) return 1;
|
|
2851
|
+
const cmp = comparePrereleaseIdentifiers(aPart, bPart);
|
|
2852
|
+
if (cmp !== 0) return cmp;
|
|
2853
|
+
}
|
|
2854
|
+
return 0;
|
|
2855
|
+
}
|
|
2856
|
+
function sdkVersionIsBelowMinimum(version, minimum) {
|
|
2857
|
+
const v = parseSemver(version);
|
|
2858
|
+
const m = parseSemver(minimum);
|
|
2859
|
+
if (!v || !m) return false;
|
|
2860
|
+
if (v.major !== m.major) return v.major < m.major;
|
|
2861
|
+
if (v.minor !== m.minor) return v.minor < m.minor;
|
|
2862
|
+
if (v.patch !== m.patch) return v.patch < m.patch;
|
|
2863
|
+
return comparePrerelease(v.prerelease, m.prerelease) < 0;
|
|
2864
|
+
}
|
|
2396
2865
|
var WarmHubClient = class _WarmHubClient {
|
|
2397
2866
|
/**
|
|
2398
2867
|
* The resolved API base URL the client issues requests against. Defaults to
|
|
@@ -2403,6 +2872,11 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
2403
2872
|
accessToken;
|
|
2404
2873
|
functionLogMode;
|
|
2405
2874
|
getToken;
|
|
2875
|
+
// Cached promise for diagnostics.assertCompatible(). Stored at instance
|
|
2876
|
+
// level so a successful check is reused across calls, and a failed check
|
|
2877
|
+
// is also cached so a too-old SDK keeps reporting the same actionable
|
|
2878
|
+
// error rather than re-hitting the network. Cleared on construction.
|
|
2879
|
+
compatibilityCheck;
|
|
2406
2880
|
/**
|
|
2407
2881
|
* Authentication helpers for browser sign-in flows, session checks, and token diagnostics.
|
|
2408
2882
|
*/
|
|
@@ -2521,6 +2995,41 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
2521
2995
|
} catch (error) {
|
|
2522
2996
|
throw toWarmHubError(error);
|
|
2523
2997
|
}
|
|
2998
|
+
},
|
|
2999
|
+
/**
|
|
3000
|
+
* Verify the installed SDK is at or above the backend's advertised
|
|
3001
|
+
* minimum supported version, throwing a `WarmHubError` with a clear
|
|
3002
|
+
* "upgrade to >=X" message when it is not.
|
|
3003
|
+
*
|
|
3004
|
+
* Call this once at startup (e.g. immediately after constructing the
|
|
3005
|
+
* client) to fail fast on SDK version skew, rather than discovering a
|
|
3006
|
+
* removed route deep in the commit pipeline as an opaque error.
|
|
3007
|
+
* The result is cached on the client instance — repeated calls reuse
|
|
3008
|
+
* the first network round-trip and re-throw the same error if too old.
|
|
3009
|
+
*
|
|
3010
|
+
* @see https://github.com/warmhub/warmhub-app/issues/3081
|
|
3011
|
+
*/
|
|
3012
|
+
assertCompatible: () => {
|
|
3013
|
+
if (this.compatibilityCheck) return this.compatibilityCheck;
|
|
3014
|
+
const promise = (async () => {
|
|
3015
|
+
const capabilities = await this.diagnostics.capabilities();
|
|
3016
|
+
if (sdkVersionIsBelowMinimum(SDK_VERSION, capabilities.minSupportedSdk)) {
|
|
3017
|
+
throw new WarmHubError(
|
|
3018
|
+
"VALIDATION_ERROR",
|
|
3019
|
+
`@warmhub/sdk-ts ${SDK_VERSION} is older than the backend's minimum supported SDK (${capabilities.minSupportedSdk}). Upgrade to >=${capabilities.minSupportedSdk}.`,
|
|
3020
|
+
400,
|
|
3021
|
+
`Run: npm install @warmhub/sdk-ts@latest (or your package manager's equivalent).`
|
|
3022
|
+
);
|
|
3023
|
+
}
|
|
3024
|
+
})();
|
|
3025
|
+
this.compatibilityCheck = promise;
|
|
3026
|
+
void promise.catch((error) => {
|
|
3027
|
+
if (isWarmHubError(error) && error.code === "VALIDATION_ERROR") return;
|
|
3028
|
+
if (this.compatibilityCheck === promise) {
|
|
3029
|
+
this.compatibilityCheck = void 0;
|
|
3030
|
+
}
|
|
3031
|
+
});
|
|
3032
|
+
return promise;
|
|
2524
3033
|
}
|
|
2525
3034
|
};
|
|
2526
3035
|
/**
|
|
@@ -2710,7 +3219,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
2710
3219
|
/**
|
|
2711
3220
|
* High-level write surface for submitting WarmHub operations through the commit pipeline.
|
|
2712
3221
|
*
|
|
2713
|
-
* @see https://docs.warmhub.ai/sdk/
|
|
3222
|
+
* @see https://docs.warmhub.ai/sdk/write-methods/
|
|
2714
3223
|
*/
|
|
2715
3224
|
commit = {
|
|
2716
3225
|
/**
|
|
@@ -2718,7 +3227,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
2718
3227
|
*
|
|
2719
3228
|
* This is the primary write path for SDK callers. It streams operations to the backend, preserves server-side per-operation results, supports chunking for large submissions, and can attribute writes to a committer wref or installed component.
|
|
2720
3229
|
*
|
|
2721
|
-
* Simple first-chunk transport failures are retried by default.
|
|
3230
|
+
* Simple first-chunk transport failures are retried by default. Ambiguous failures surface as `PartialStreamSubmissionError`, including the case where an ambiguous attempt is followed by an all-failed retry; inspect `error.cause` for the underlying `AllStreamOperationsFailedError` or backend error. Deterministic all-failed submissions without prior ambiguity throw `AllStreamOperationsFailedError` directly so callers can inspect per-operation failure rows. Validation, auth, conflict, rate-limit, and other definite backend failures surface as `WarmHubError`. See [Transient Retry](/sdk/transient-retry/) for the full retry and partial-submission rules.
|
|
2722
3231
|
*
|
|
2723
3232
|
* Writing to an archived organization or repository fails with an `ARCHIVED` error before any operations are applied.
|
|
2724
3233
|
*
|
|
@@ -2748,7 +3257,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
2748
3257
|
operations
|
|
2749
3258
|
});
|
|
2750
3259
|
} catch (error) {
|
|
2751
|
-
if (error instanceof PartialStreamSubmissionError) {
|
|
3260
|
+
if (error instanceof PartialStreamSubmissionError || error instanceof AllStreamOperationsFailedError) {
|
|
2752
3261
|
throw error;
|
|
2753
3262
|
}
|
|
2754
3263
|
throw toWarmHubError(error);
|
|
@@ -3019,7 +3528,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
3019
3528
|
*
|
|
3020
3529
|
* The returned `total` is the sum of active shapes, things, and assertions. Use this when billing, quota checks, health reports, or per-shape breakdowns need single-repo stats.
|
|
3021
3530
|
*
|
|
3022
|
-
* The per-shape breakdown counts active things
|
|
3531
|
+
* The per-shape breakdown counts active things and assertions by shape.
|
|
3023
3532
|
*/
|
|
3024
3533
|
getStats: async (orgName, repoName) => {
|
|
3025
3534
|
try {
|
|
@@ -4718,6 +5227,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
4718
5227
|
if (!response.ok) {
|
|
4719
5228
|
let message = `Request failed with status ${response.status}`;
|
|
4720
5229
|
let code = httpStatusToWarmHubCode(response.status);
|
|
5230
|
+
let backendCode;
|
|
4721
5231
|
let hint;
|
|
4722
5232
|
let retryAfter;
|
|
4723
5233
|
try {
|
|
@@ -4727,6 +5237,7 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
4727
5237
|
}
|
|
4728
5238
|
if (typeof body.error?.code === "string") {
|
|
4729
5239
|
code = body.error.code;
|
|
5240
|
+
backendCode = body.error.code;
|
|
4730
5241
|
}
|
|
4731
5242
|
if (typeof body.error?.hint === "string") {
|
|
4732
5243
|
hint = body.error.hint;
|
|
@@ -4736,7 +5247,14 @@ var WarmHubClient = class _WarmHubClient {
|
|
|
4736
5247
|
}
|
|
4737
5248
|
} catch {
|
|
4738
5249
|
}
|
|
4739
|
-
throw new WarmHubError(
|
|
5250
|
+
throw new WarmHubError(
|
|
5251
|
+
code,
|
|
5252
|
+
message,
|
|
5253
|
+
response.status,
|
|
5254
|
+
hint,
|
|
5255
|
+
retryAfter,
|
|
5256
|
+
backendCode
|
|
5257
|
+
);
|
|
4740
5258
|
}
|
|
4741
5259
|
return response;
|
|
4742
5260
|
}
|
|
@@ -4850,6 +5368,6 @@ function isAbortError(error) {
|
|
|
4850
5368
|
return error instanceof Error && error.name === "AbortError";
|
|
4851
5369
|
}
|
|
4852
5370
|
|
|
4853
|
-
export { CONTENT_FIELD_LIMIT_ERROR, DEFAULT_API_URL, DEFAULT_STREAM_CHUNK_SIZE, MAX_CONTENT_FIELD_BYTES, MAX_STREAM_APPEND_OPERATION_COUNT2 as MAX_STREAM_APPEND_OPERATION_COUNT, OperationBuilder, PartialStreamSubmissionError, SDK_VERSION, WarmHubClient, WarmHubError, connectionErrorMessage, contentFieldLimitError, isConnectionError, isRetryable, isWarmHubError, normalizeWref, resolveFunctionLogMode, sanitizeErrorMessage, submitOperationsViaStream, toWarmHubError, validateAgainstShape };
|
|
4854
|
-
//# sourceMappingURL=chunk-
|
|
4855
|
-
//# sourceMappingURL=chunk-
|
|
5371
|
+
export { AllStreamOperationsFailedError, CLI_INSTALL_REPO_HEADER, CLI_SIGNATURE_HEADER, CLI_TIMESTAMP_HEADER, CONTENT_FIELD_LIMIT_ERROR, CliCallVerificationError, DEFAULT_API_URL, DEFAULT_STREAM_CHUNK_SIZE, MAX_CONTENT_FIELD_BYTES, MAX_STREAM_APPEND_OPERATION_COUNT2 as MAX_STREAM_APPEND_OPERATION_COUNT, OperationBuilder, PartialStreamSubmissionError, SDK_VERSION, WarmHubClient, WarmHubError, connectionErrorMessage, contentFieldLimitError, countStreamAppendResultStatuses, isConnectionError, isRetryable, isWarmHubError, normalizeWref, resolveFunctionLogMode, sanitizeErrorMessage, sdkVersionIsBelowMinimum, streamAppendResultStatus, submitOperationsViaStream, toWarmHubError, validateAgainstShape, verifyCliCall };
|
|
5372
|
+
//# sourceMappingURL=chunk-RX3ZL6P5.js.map
|
|
5373
|
+
//# sourceMappingURL=chunk-RX3ZL6P5.js.map
|