@drip-apex/apex-cli 0.12.0 → 0.12.1
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/README.md +26 -2
- package/dist/cli.js +47 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -352,5 +352,29 @@ config-fetch p50/p95 (milliseconds), and inline/cache/network/none counts.
|
|
|
352
352
|
JSON output includes the API body in the standard envelope and assignment-ready
|
|
353
353
|
percentiles. Fewer than five measured samples have null percentiles. Natural
|
|
354
354
|
loads are shop-wide non-QA loads without forced IDs; a QA-session bucket can
|
|
355
|
-
overlap forced loads. Analytics failures return errors.
|
|
356
|
-
|
|
355
|
+
overlap forced loads. Analytics failures return errors. The API position is
|
|
356
|
+
`runtime_inline_no_change`.
|
|
357
|
+
|
|
358
|
+
The runtime remains unchanged. Natural runtime decides within tens of milliseconds
|
|
359
|
+
of SDK start when config ships inline with the snippet (measured p50 12 ms /
|
|
360
|
+
p95 54 ms on a large storefront). QA previews, screenshot-mode previews and
|
|
361
|
+
cookie-forced sessions take the QA config lane and fetch fresh config over the
|
|
362
|
+
network (measured p50 1.3 s / p95 7 s); they are not representative of launch
|
|
363
|
+
behaviour. URL-forced sessions without a `qa` parameter keep the inline or cached
|
|
364
|
+
config, so these measurements do not describe them. No config preload or
|
|
365
|
+
anti-flicker hold is planned.
|
|
366
|
+
|
|
367
|
+
### Connection troubleshooting
|
|
368
|
+
|
|
369
|
+
Connection errors retain the underlying failure. JSON output exposes
|
|
370
|
+
`error.details.reason` and, when available, `error.details.code`; the numeric
|
|
371
|
+
`error.code` remains the CLI exit code.
|
|
372
|
+
|
|
373
|
+
| Reason | Meaning and usual fix |
|
|
374
|
+
| --- | --- |
|
|
375
|
+
| `dns` | The host could not be resolved. Check `APEX_BASE_URL` (or `DRIP_BASE_URL`), DNS, and whether your sandbox permits network access. |
|
|
376
|
+
| `refused` | The host rejected the connection. Check the base URL, port, and whether the server is running. |
|
|
377
|
+
| `reset` | The connection was interrupted. Check network stability and proxy settings before retrying. |
|
|
378
|
+
| `tls` | Certificate or TLS validation failed. Check expired certificates and your corporate TLS proxy's trusted CA configuration. |
|
|
379
|
+
| `timeout` | The request was aborted or exceeded its deadline. Check server availability and network access. |
|
|
380
|
+
| `unknown` | Another network failure occurred. Use the included cause message to diagnose network or sandbox restrictions. |
|
package/dist/cli.js
CHANGED
|
@@ -7112,7 +7112,7 @@ var import_node_os3 = __toESM(require("node:os"));
|
|
|
7112
7112
|
// package.json
|
|
7113
7113
|
var package_default = {
|
|
7114
7114
|
name: "@drip-apex/apex-cli",
|
|
7115
|
-
version: "0.12.
|
|
7115
|
+
version: "0.12.1",
|
|
7116
7116
|
license: "MIT",
|
|
7117
7117
|
description: "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
|
|
7118
7118
|
private: false,
|
|
@@ -7666,7 +7666,16 @@ function createHttpClient(creds, options) {
|
|
|
7666
7666
|
try {
|
|
7667
7667
|
response = await fetch(`${creds.baseUrl}${path24}`, { method, headers, body: form ? body5 : body5 ? JSON.stringify(body5) : void 0, signal: AbortSignal.timeout(timeoutMs) });
|
|
7668
7668
|
} catch (error) {
|
|
7669
|
-
|
|
7669
|
+
const outer = error && typeof error === "object" ? error : void 0;
|
|
7670
|
+
const nested = outer?.cause && typeof outer.cause === "object" ? outer.cause : void 0;
|
|
7671
|
+
return options.onNetworkError({
|
|
7672
|
+
baseUrl: creds.baseUrl,
|
|
7673
|
+
timeoutMs,
|
|
7674
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
7675
|
+
code: typeof nested?.code === "string" ? nested.code : typeof outer?.code === "string" ? outer.code : void 0,
|
|
7676
|
+
name: typeof outer?.name === "string" ? outer.name : void 0,
|
|
7677
|
+
causeMessage: typeof nested?.message === "string" ? nested.message : void 0
|
|
7678
|
+
});
|
|
7670
7679
|
}
|
|
7671
7680
|
inspectVersion(response.headers);
|
|
7672
7681
|
const json = await response.json().catch(() => null);
|
|
@@ -7739,10 +7748,42 @@ function sharedClient(creds) {
|
|
|
7739
7748
|
transport: testTransport,
|
|
7740
7749
|
testTransportVersion: () => testTransport ? process.env[["APEX", "CLI", "MOCK", "API", "VERSION"].join("_")] : void 0,
|
|
7741
7750
|
onNetworkError: (info) => {
|
|
7751
|
+
let url;
|
|
7752
|
+
try {
|
|
7753
|
+
url = new URL(info.baseUrl);
|
|
7754
|
+
} catch {
|
|
7755
|
+
}
|
|
7756
|
+
const host = url?.hostname ?? info.baseUrl;
|
|
7757
|
+
const code = info.code;
|
|
7758
|
+
let reason = "unknown";
|
|
7759
|
+
let message = info.causeMessage ?? info.cause;
|
|
7760
|
+
if (info.name === "TimeoutError" || info.name === "AbortError" || code === "UND_ERR_CONNECT_TIMEOUT") {
|
|
7761
|
+
reason = "timeout";
|
|
7762
|
+
message = `server did not respond within ${info.timeoutMs / 1e3}s`;
|
|
7763
|
+
} else if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
|
|
7764
|
+
reason = "dns";
|
|
7765
|
+
message = `could not resolve host ${host}`;
|
|
7766
|
+
} else if (code === "ECONNREFUSED") {
|
|
7767
|
+
reason = "refused";
|
|
7768
|
+
message = `connection refused by ${host}:${url?.port || (url?.protocol === "https:" ? "443" : "80")}`;
|
|
7769
|
+
} else if (code === "ECONNRESET" || code === "EPIPE") {
|
|
7770
|
+
reason = "reset";
|
|
7771
|
+
message = `connection reset by ${host}`;
|
|
7772
|
+
} else if (code?.startsWith("CERT_") || code?.startsWith("ERR_TLS_") || [
|
|
7773
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
7774
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
7775
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
7776
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
7777
|
+
"UNABLE_TO_GET_ISSUER_CERT",
|
|
7778
|
+
"HOSTNAME_MISMATCH"
|
|
7779
|
+
].includes(code ?? "")) {
|
|
7780
|
+
reason = "tls";
|
|
7781
|
+
message = `TLS error (${code})`;
|
|
7782
|
+
}
|
|
7742
7783
|
throw new CliError(
|
|
7743
|
-
`Could not reach ${info.baseUrl}: check APEX_BASE_URL (or DRIP_BASE_URL) / network;
|
|
7784
|
+
`Could not reach ${info.baseUrl}: check APEX_BASE_URL (or DRIP_BASE_URL) / network; ${message}.`,
|
|
7744
7785
|
EXIT_CODES.general,
|
|
7745
|
-
{
|
|
7786
|
+
{ reason, code, name: info.name, baseUrl: info.baseUrl, timeoutMs: info.timeoutMs }
|
|
7746
7787
|
);
|
|
7747
7788
|
}
|
|
7748
7789
|
});
|
|
@@ -13153,8 +13194,9 @@ trackingCommand.command("latency").description("Measure forced-preview versus na
|
|
|
13153
13194
|
].join("/")
|
|
13154
13195
|
])
|
|
13155
13196
|
);
|
|
13197
|
+
console.log("Times in ms. Fewer than 5 measured samples: -.");
|
|
13156
13198
|
console.log(
|
|
13157
|
-
"
|
|
13199
|
+
"Position: runtime unchanged (inline config decides within tens of ms; forced previews fetch config over the network and are not representative)"
|
|
13158
13200
|
);
|
|
13159
13201
|
});
|
|
13160
13202
|
});
|