@aexhq/sdk 0.37.2 → 0.37.4

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.
@@ -2,8 +2,8 @@ import { redactSecrets } from "./sdk-secrets.js";
2
2
  export class AexError extends Error {
3
3
  code;
4
4
  details;
5
- constructor(code, message, details) {
6
- super(redactSecrets(message));
5
+ constructor(code, message, details, options) {
6
+ super(redactSecrets(message), options?.cause === undefined ? undefined : { cause: options.cause });
7
7
  this.name = this.constructor.name;
8
8
  this.code = code;
9
9
  this.details = details === undefined ? undefined : redactSecrets(details);
@@ -49,4 +49,106 @@ export class AexApiError extends AexError {
49
49
  this.body = redactSecrets(body);
50
50
  }
51
51
  }
52
+ /**
53
+ * Thrown when a BFF-bound request fails BEFORE any HTTP response exists — DNS
54
+ * failure, connection refused, TLS error, socket reset. Wraps the raw fetch
55
+ * rejection (whose undici form is a bare `TypeError: fetch failed` with the
56
+ * useful code hidden on `cause.code`) into a message that names the request
57
+ * and the transport failure, e.g.
58
+ * `POST api.aex.dev/assets/presign failed: ECONNREFUSED (connect ECONNREFUSED 127.0.0.1:443)`.
59
+ * The original rejection is preserved on `cause`.
60
+ */
61
+ export class AexNetworkError extends AexError {
62
+ method;
63
+ /** Request host — never carries credentials or the query string. */
64
+ host;
65
+ path;
66
+ /** Transport failure code (e.g. `ECONNREFUSED`), when detectable. */
67
+ causeCode;
68
+ /** Attempts made when a retry layer exhausted its budget; `1` otherwise. */
69
+ attempts;
70
+ constructor(args) {
71
+ const causeCode = extractErrorCode(args.cause);
72
+ super("NETWORK_ERROR", networkErrorMessage(args, causeCode), { method: args.method, host: args.host, path: args.path, ...(causeCode ? { code: causeCode } : {}) }, { cause: args.cause });
73
+ this.method = args.method;
74
+ this.host = args.host;
75
+ this.path = args.path;
76
+ this.causeCode = causeCode;
77
+ this.attempts = args.attempts ?? 1;
78
+ }
79
+ }
80
+ function networkErrorMessage(args, causeCode) {
81
+ const target = args.host ? `${args.host}${args.path}` : "request";
82
+ const detail = shortCauseMessage(args.cause, causeCode);
83
+ const suffix = args.attempts === undefined
84
+ ? ""
85
+ : ` after ${args.attempts} attempt${args.attempts === 1 ? "" : "s"} over ${args.elapsedMs ?? 0}ms`;
86
+ let message = `${args.method} ${target} failed`;
87
+ if (causeCode)
88
+ message += `: ${causeCode}`;
89
+ if (detail)
90
+ message += causeCode ? ` (${detail})` : `: ${detail}`;
91
+ return message + suffix;
92
+ }
93
+ /** The innermost useful message off the rejection, URL-redacted and bounded. */
94
+ function shortCauseMessage(cause, causeCode) {
95
+ const nested = cause instanceof Error && cause.cause instanceof Error ? cause.cause : cause;
96
+ const message = nested instanceof Error ? nested.message || nested.name : typeof nested === "string" ? nested : undefined;
97
+ if (!message || message === causeCode)
98
+ return undefined;
99
+ return message.replace(/https?:\/\/[^\s<>"'`]+/g, (raw) => redactUrl(raw)).slice(0, 200);
100
+ }
101
+ /**
102
+ * Best-effort transport error code (`ECONNREFUSED`, `ENOTFOUND`, …): checks
103
+ * `err.code`, then `err.cause.code` (where undici hides it), then falls back
104
+ * to an `E…`-shaped token in the message.
105
+ */
106
+ export function extractErrorCode(err) {
107
+ const code = stringProperty(err, "code");
108
+ if (code)
109
+ return code;
110
+ const cause = objectProperty(err, "cause");
111
+ const causeCode = stringProperty(cause, "code");
112
+ if (causeCode)
113
+ return causeCode;
114
+ const match = /\bE[A-Z0-9_]+\b/.exec(errorMessageOf(err));
115
+ return match?.[0];
116
+ }
117
+ /**
118
+ * Redact a URL down to protocol + host + path: credentials become
119
+ * `[redacted]@` and any query string becomes `?[redacted]` (presigned URLs
120
+ * carry signatures there). Tolerates unparseable input.
121
+ */
122
+ export function redactUrl(url) {
123
+ try {
124
+ const parsed = new URL(url);
125
+ const auth = parsed.username || parsed.password ? "[redacted]@" : "";
126
+ const query = parsed.search ? "?[redacted]" : "";
127
+ return `${parsed.protocol}//${auth}${parsed.host}${parsed.pathname}${query}`;
128
+ }
129
+ catch {
130
+ const withoutAuth = url.replace(/\/\/[^/?#\s]+@/, "//[redacted]@");
131
+ const queryStart = withoutAuth.indexOf("?");
132
+ return queryStart === -1 ? withoutAuth : `${withoutAuth.slice(0, queryStart)}?[redacted]`;
133
+ }
134
+ }
135
+ function errorMessageOf(err) {
136
+ if (err instanceof Error)
137
+ return err.message || err.name;
138
+ if (typeof err === "string")
139
+ return err;
140
+ return String(err);
141
+ }
142
+ function objectProperty(value, key) {
143
+ if (!value || typeof value !== "object")
144
+ return undefined;
145
+ const prop = value[key];
146
+ return prop && typeof prop === "object" ? prop : undefined;
147
+ }
148
+ function stringProperty(value, key) {
149
+ if (!value || typeof value !== "object")
150
+ return undefined;
151
+ const prop = value[key];
152
+ return typeof prop === "string" && prop.length > 0 ? prop : undefined;
153
+ }
52
154
  //# sourceMappingURL=sdk-errors.js.map
@@ -61,6 +61,20 @@ const MIN_CHAR_CLASSES = 2;
61
61
  * still catches the rare long digit-free secret.
62
62
  */
63
63
  const HIGH_ENTROPY_NO_DIGIT_MIN_LEN = 40;
64
+ /**
65
+ * Canonical aex run-id hex: exactly 32 lowercase hex chars directly preceded
66
+ * by `run_`. The HIGH_ENTROPY_CANDIDATE class excludes `_`, so the candidate
67
+ * run for a run id is the bare hex — dense enough to trip the entropy gate.
68
+ * Masking it destroys the ONE identifier every error message needs for
69
+ * traceability (`cancel via openSession("run_[REDACTED]")` is useless
70
+ * guidance). A run id is not a credential: it grants nothing without the
71
+ * bearer token. Mirrors the platform-side redactor's canonical-id exemption.
72
+ */
73
+ function isCanonicalRunIdHex(input, matchStart, match) {
74
+ if (!/^[0-9a-f]{32}$/.test(match))
75
+ return false;
76
+ return input.slice(Math.max(0, matchStart - 4), matchStart) === "run_";
77
+ }
64
78
  export class SecretString {
65
79
  #value;
66
80
  constructor(value, label = "secret") {
@@ -119,7 +133,7 @@ export function redactString(input, known = []) {
119
133
  // Patterns with a captured prefix (Authorization header) keep the
120
134
  // prefix; the rest replace the whole match.
121
135
  typeof captured === "string" ? `${captured} ${REDACTED}` : REDACTED), out);
122
- return out.replace(HIGH_ENTROPY_CANDIDATE, (match) => looksHighEntropySecret(match) ? REDACTED : match);
136
+ return out.replace(HIGH_ENTROPY_CANDIDATE, (match, offset, whole) => !isCanonicalRunIdHex(whole, offset, match) && looksHighEntropySecret(match) ? REDACTED : match);
123
137
  }
124
138
  export function containsSecretLikeValue(input) {
125
139
  if (SECRET_PATTERNS.some((pattern) => {
@@ -131,6 +145,9 @@ export function containsSecretLikeValue(input) {
131
145
  HIGH_ENTROPY_CANDIDATE.lastIndex = 0;
132
146
  let candidate;
133
147
  while ((candidate = HIGH_ENTROPY_CANDIDATE.exec(input)) !== null) {
148
+ if (isCanonicalRunIdHex(input, candidate.index, candidate[0])) {
149
+ continue;
150
+ }
134
151
  if (looksHighEntropySecret(candidate[0])) {
135
152
  return true;
136
153
  }
@@ -19,6 +19,8 @@
19
19
  * 3. POST /assets/finalize → confirms the object exists (HEAD only).
20
20
  *
21
21
  */
22
+ import { extractErrorCode, redactUrl } from "./_contracts/index.js";
23
+ const DIRECT_UPLOAD_MAX_ATTEMPTS = 3;
22
24
  /**
23
25
  * Upload `bytes` to the hosted API's content-addressable asset store via the
24
26
  * direct-to-storage presign flow.
@@ -36,17 +38,13 @@ export async function uploadAsset(args) {
36
38
  }
37
39
  const contentHashHeader = `sha256:${actual}`;
38
40
  // ---- Step 1: presign (control plane) ----
39
- let presign;
40
- try {
41
- presign = await args.http.request("/assets/presign", {
42
- method: "POST",
43
- headers: { "content-type": "application/json" },
44
- body: JSON.stringify({ hash: contentHashHeader, sizeBytes: args.bytes.byteLength })
45
- });
46
- }
47
- catch (err) {
48
- throw err;
49
- }
41
+ // A network failure here surfaces as the transport's AexNetworkError,
42
+ // which already names the method, host, path, and transport code.
43
+ const presign = await args.http.request("/assets/presign", {
44
+ method: "POST",
45
+ headers: { "content-type": "application/json" },
46
+ body: JSON.stringify({ hash: contentHashHeader, sizeBytes: args.bytes.byteLength })
47
+ });
50
48
  // Dedup hit — identical bytes already vaulted under this workspace.
51
49
  if (presign.exists) {
52
50
  const contentHash = presign.contentHash ?? contentHashHeader;
@@ -66,16 +64,11 @@ export async function uploadAsset(args) {
66
64
  "content-type": args.contentType ?? "application/zip",
67
65
  ...(presign.requiredHeaders ?? {})
68
66
  };
69
- const putRes = await doFetch(presign.uploadUrl, {
67
+ await putWithRetry(doFetch, presign.uploadUrl, {
70
68
  method: "PUT",
71
69
  headers: putHeaders,
72
70
  body: args.bytes
73
71
  });
74
- if (!putRes.ok) {
75
- const detail = await putRes.text().catch(() => "");
76
- throw new Error(`uploadAsset: direct upload PUT failed with status ${putRes.status}` +
77
- (detail ? `: ${detail.slice(0, 500)}` : ""));
78
- }
79
72
  // ---- Step 3: finalize (control plane confirms existence via HEAD) ----
80
73
  const fin = await args.http.request("/assets/finalize", {
81
74
  method: "POST",
@@ -113,6 +106,81 @@ function assetIdFromContentHash(contentHash) {
113
106
  const hex = contentHash.startsWith("sha256:") ? contentHash.slice("sha256:".length) : contentHash;
114
107
  return `asset_${hex}`;
115
108
  }
109
+ async function putWithRetry(fetchImpl, uploadUrl, init) {
110
+ for (let attempt = 1; attempt <= DIRECT_UPLOAD_MAX_ATTEMPTS; attempt++) {
111
+ let response;
112
+ try {
113
+ response = await fetchImpl(uploadUrl, init);
114
+ }
115
+ catch (err) {
116
+ if (attempt < DIRECT_UPLOAD_MAX_ATTEMPTS && isRetryableUploadError(err)) {
117
+ continue;
118
+ }
119
+ throw directUploadNetworkError(uploadUrl, err, attempt);
120
+ }
121
+ if (response.ok)
122
+ return;
123
+ if (attempt < DIRECT_UPLOAD_MAX_ATTEMPTS && isRetryableUploadStatus(response.status)) {
124
+ await response.text().catch(() => "");
125
+ continue;
126
+ }
127
+ const detail = await response.text().catch(() => "");
128
+ throw directUploadResponseError(uploadUrl, response.status, detail, attempt);
129
+ }
130
+ }
131
+ function isRetryableUploadStatus(status) {
132
+ return status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599);
133
+ }
134
+ function isRetryableUploadError(err) {
135
+ if (isNamedError(err, "AbortError"))
136
+ return false;
137
+ return true;
138
+ }
139
+ function directUploadNetworkError(uploadUrl, err, attempts) {
140
+ const safeUrl = redactUrl(uploadUrl);
141
+ const code = extractErrorCode(err);
142
+ const detail = sanitizeUploadText(errorMessage(err)).slice(0, 500);
143
+ return new Error(`uploadAsset: direct upload PUT failed for ${safeUrl} after ${attemptsLabel(attempts)}` +
144
+ (code ? ` (${code})` : "") +
145
+ (detail ? `: ${detail}` : ""));
146
+ }
147
+ function directUploadResponseError(uploadUrl, status, detail, attempts) {
148
+ const safeUrl = redactUrl(uploadUrl);
149
+ const safeDetail = sanitizeUploadText(detail).slice(0, 500);
150
+ return new Error(`uploadAsset: direct upload PUT failed for ${safeUrl} with status ${status}` +
151
+ (attempts > 1 ? ` after ${attemptsLabel(attempts)}` : "") +
152
+ (safeDetail ? `: ${safeDetail}` : ""));
153
+ }
154
+ function attemptsLabel(attempts) {
155
+ return attempts === 1 ? "1 attempt" : `${attempts} attempts`;
156
+ }
157
+ function errorMessage(err) {
158
+ if (err instanceof Error)
159
+ return err.message || err.name;
160
+ if (typeof err === "string")
161
+ return err;
162
+ return String(err);
163
+ }
164
+ function isNamedError(err, name) {
165
+ return stringProperty(err, "name") === name;
166
+ }
167
+ function stringProperty(value, key) {
168
+ if (!value || typeof value !== "object")
169
+ return undefined;
170
+ const prop = value[key];
171
+ return typeof prop === "string" && prop.length > 0 ? prop : undefined;
172
+ }
173
+ function sanitizeUploadText(text) {
174
+ return text
175
+ .replace(/https?:\/\/[^\s<>"'`]+/g, (raw) => redactUrlPreservingTrailingPunctuation(raw))
176
+ .replace(/\b(?:X-Amz-(?:Algorithm|Credential|Date|Expires|Security-Token|Signature|SignedHeaders)|AWSAccessKeyId|Signature|Credential|Security-Token|AccessKeyId|SecretAccessKey|SessionToken)=([^&\s<>"'`]+)/gi, "[redacted]")
177
+ .replace(/\bAKIA[0-9A-Z]{8,}\b/g, "[redacted]");
178
+ }
179
+ function redactUrlPreservingTrailingPunctuation(raw) {
180
+ const trailing = raw.match(/[),.;:!?]+$/)?.[0] ?? "";
181
+ const candidate = trailing ? raw.slice(0, -trailing.length) : raw;
182
+ return `${redactUrl(candidate)}${trailing}`;
183
+ }
116
184
  function bufferToHex(buffer) {
117
185
  const view = new Uint8Array(buffer);
118
186
  let out = "";
@@ -1 +1 @@
1
- {"version":3,"file":"asset-upload.js","sourceRoot":"","sources":["../src/asset-upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"asset-upload.js","sourceRoot":"","sources":["../src/asset-upload.ts"],"names":[],"mappings":"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"}