@vonpay/checkout-cli 0.12.0 → 0.14.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/index.js +2397 -12
- package/package.json +6 -4
- package/dist/app-info.d.ts +0 -5
- package/dist/app-info.d.ts.map +0 -1
- package/dist/app-info.js +0 -11
- package/dist/app-info.js.map +0 -1
- package/dist/client-factory.d.ts +0 -10
- package/dist/client-factory.d.ts.map +0 -1
- package/dist/client-factory.js +0 -31
- package/dist/client-factory.js.map +0 -1
- package/dist/commands/capabilities.d.ts +0 -15
- package/dist/commands/capabilities.d.ts.map +0 -1
- package/dist/commands/capabilities.js +0 -99
- package/dist/commands/capabilities.js.map +0 -1
- package/dist/commands/checkout.d.ts +0 -3
- package/dist/commands/checkout.d.ts.map +0 -1
- package/dist/commands/checkout.js +0 -39
- package/dist/commands/checkout.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -59
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js +0 -366
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/health.d.ts +0 -3
- package/dist/commands/health.d.ts.map +0 -1
- package/dist/commands/health.js +0 -52
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/init.d.ts +0 -10
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -112
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/listen.d.ts +0 -19
- package/dist/commands/listen.d.ts.map +0 -1
- package/dist/commands/listen.js +0 -249
- package/dist/commands/listen.js.map +0 -1
- package/dist/commands/login.d.ts +0 -27
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -75
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -3
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js +0 -23
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/payment-intents.d.ts +0 -62
- package/dist/commands/payment-intents.d.ts.map +0 -1
- package/dist/commands/payment-intents.js +0 -271
- package/dist/commands/payment-intents.js.map +0 -1
- package/dist/commands/refunds.d.ts +0 -40
- package/dist/commands/refunds.d.ts.map +0 -1
- package/dist/commands/refunds.js +0 -142
- package/dist/commands/refunds.js.map +0 -1
- package/dist/commands/sessions.d.ts +0 -16
- package/dist/commands/sessions.d.ts.map +0 -1
- package/dist/commands/sessions.js +0 -152
- package/dist/commands/sessions.js.map +0 -1
- package/dist/commands/tokens.d.ts +0 -3
- package/dist/commands/tokens.d.ts.map +0 -1
- package/dist/commands/tokens.js +0 -73
- package/dist/commands/tokens.js.map +0 -1
- package/dist/commands/trigger.d.ts +0 -38
- package/dist/commands/trigger.d.ts.map +0 -1
- package/dist/commands/trigger.js +0 -246
- package/dist/commands/trigger.js.map +0 -1
- package/dist/config.d.ts +0 -22
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -72
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -80
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -179
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/forward-to.d.ts +0 -38
- package/dist/utils/forward-to.d.ts.map +0 -1
- package/dist/utils/forward-to.js +0 -92
- package/dist/utils/forward-to.js.map +0 -1
- package/dist/utils/json-errors.d.ts +0 -16
- package/dist/utils/json-errors.d.ts.map +0 -1
- package/dist/utils/json-errors.js +0 -41
- package/dist/utils/json-errors.js.map +0 -1
- package/dist/utils/listen-forward.d.ts +0 -49
- package/dist/utils/listen-forward.d.ts.map +0 -1
- package/dist/utils/listen-forward.js +0 -113
- package/dist/utils/listen-forward.js.map +0 -1
- package/dist/utils/listen-output.d.ts +0 -52
- package/dist/utils/listen-output.d.ts.map +0 -1
- package/dist/utils/listen-output.js +0 -85
- package/dist/utils/listen-output.js.map +0 -1
- package/dist/utils/live-key.d.ts +0 -22
- package/dist/utils/live-key.d.ts.map +0 -1
- package/dist/utils/live-key.js +0 -37
- package/dist/utils/live-key.js.map +0 -1
- package/dist/utils/metadata.d.ts +0 -2
- package/dist/utils/metadata.d.ts.map +0 -1
- package/dist/utils/metadata.js +0 -31
- package/dist/utils/metadata.js.map +0 -1
- package/dist/utils/sanitize.d.ts +0 -4
- package/dist/utils/sanitize.d.ts.map +0 -1
- package/dist/utils/sanitize.js +0 -18
- package/dist/utils/sanitize.js.map +0 -1
- package/dist/utils/spinner.d.ts +0 -15
- package/dist/utils/spinner.d.ts.map +0 -1
- package/dist/utils/spinner.js +0 -18
- package/dist/utils/spinner.js.map +0 -1
- package/dist/utils/sse-consumer.d.ts +0 -81
- package/dist/utils/sse-consumer.d.ts.map +0 -1
- package/dist/utils/sse-consumer.js +0 -172
- package/dist/utils/sse-consumer.js.map +0 -1
- package/dist/utils/sse-parser.d.ts +0 -63
- package/dist/utils/sse-parser.d.ts.map +0 -1
- package/dist/utils/sse-parser.js +0 -149
- package/dist/utils/sse-parser.js.map +0 -1
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
export function formatAttemptHuman(payload, forward) {
|
|
3
|
-
const ts = formatTimestamp(payload.timestamp);
|
|
4
|
-
const eventType = chalk.cyan(payload.event_type.padEnd(24));
|
|
5
|
-
const eventId = chalk.gray(payload.event_id.padEnd(28));
|
|
6
|
-
const attempt = chalk.gray(`attempt ${payload.attempt}`);
|
|
7
|
-
const arrow = chalk.gray("→");
|
|
8
|
-
const upstream = formatUpstream(payload);
|
|
9
|
-
const latency = chalk.gray(`${payload.latency_ms}ms`);
|
|
10
|
-
const liveBadge = payload.livemode ? chalk.red(" [LIVE]") : "";
|
|
11
|
-
let line = `[${ts}] ${eventType} ${eventId} ${attempt} ${arrow} ${upstream} ${latency}${liveBadge}`;
|
|
12
|
-
if (forward && forward.attempted) {
|
|
13
|
-
const fwdArrow = chalk.gray("→ local");
|
|
14
|
-
if (forward.error) {
|
|
15
|
-
line += ` ${fwdArrow} ${chalk.red(forward.error)}`;
|
|
16
|
-
}
|
|
17
|
-
else if (forward.status !== null) {
|
|
18
|
-
const fwdStatus = formatStatus(forward.status);
|
|
19
|
-
const fwdLatency = chalk.gray(`${forward.latencyMs}ms`);
|
|
20
|
-
line += ` ${fwdArrow} ${fwdStatus} ${fwdLatency}`;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return line;
|
|
24
|
-
}
|
|
25
|
-
export function formatAttemptJson(payload, forward) {
|
|
26
|
-
const body = {
|
|
27
|
-
type: "webhook.attempt",
|
|
28
|
-
event_id: payload.event_id,
|
|
29
|
-
event_type: payload.event_type,
|
|
30
|
-
subscription_id: payload.subscription_id,
|
|
31
|
-
attempt: payload.attempt,
|
|
32
|
-
succeeded: payload.succeeded,
|
|
33
|
-
response_status: payload.response_status,
|
|
34
|
-
latency_ms: payload.latency_ms,
|
|
35
|
-
timestamp: payload.timestamp,
|
|
36
|
-
livemode: payload.livemode,
|
|
37
|
-
};
|
|
38
|
-
if (forward && forward.attempted) {
|
|
39
|
-
body.forward = {
|
|
40
|
-
status: forward.status,
|
|
41
|
-
latency_ms: forward.latencyMs,
|
|
42
|
-
error: forward.error,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
return JSON.stringify(body);
|
|
46
|
-
}
|
|
47
|
-
/** Lifecycle line for human mode (stderr). */
|
|
48
|
-
export function formatLifecycleHuman(message, kind) {
|
|
49
|
-
const tag = kind === "info"
|
|
50
|
-
? chalk.cyan("[vonpay]")
|
|
51
|
-
: kind === "warn"
|
|
52
|
-
? chalk.yellow("[vonpay]")
|
|
53
|
-
: chalk.red("[vonpay]");
|
|
54
|
-
return `${tag} ${message}`;
|
|
55
|
-
}
|
|
56
|
-
/** Lifecycle line for JSON mode (stderr). */
|
|
57
|
-
export function formatLifecycleJson(kind, extra = {}) {
|
|
58
|
-
return JSON.stringify({ type: `cli.${kind}`, ...extra, timestamp: new Date().toISOString() });
|
|
59
|
-
}
|
|
60
|
-
function formatStatus(status) {
|
|
61
|
-
if (status >= 200 && status < 300)
|
|
62
|
-
return chalk.green(String(status));
|
|
63
|
-
if (status >= 400 && status < 500)
|
|
64
|
-
return chalk.yellow(String(status));
|
|
65
|
-
if (status >= 500)
|
|
66
|
-
return chalk.red(String(status));
|
|
67
|
-
return chalk.gray(String(status));
|
|
68
|
-
}
|
|
69
|
-
function formatUpstream(payload) {
|
|
70
|
-
if (payload.response_status === null) {
|
|
71
|
-
return chalk.red("timeout");
|
|
72
|
-
}
|
|
73
|
-
return formatStatus(payload.response_status);
|
|
74
|
-
}
|
|
75
|
-
/** Local-time `HH:mm:ss` for the human stream. */
|
|
76
|
-
function formatTimestamp(iso) {
|
|
77
|
-
const date = new Date(iso);
|
|
78
|
-
if (isNaN(date.getTime()))
|
|
79
|
-
return iso.slice(0, 19);
|
|
80
|
-
const h = String(date.getHours()).padStart(2, "0");
|
|
81
|
-
const m = String(date.getMinutes()).padStart(2, "0");
|
|
82
|
-
const s = String(date.getSeconds()).padStart(2, "0");
|
|
83
|
-
return `${h}:${m}:${s}`;
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=listen-output.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listen-output.js","sourceRoot":"","sources":["../../src/utils/listen-output.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/live-key.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { isLiveKey } from "@vonpay/checkout-node";
|
|
2
|
-
export { isLiveKey };
|
|
3
|
-
export interface LiveGateOpts {
|
|
4
|
-
confirmLive?: boolean;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Refuse to run a destructive/irreversible operation on a live key unless the
|
|
8
|
-
* caller explicitly passes --confirm-live. Pattern mirrors --confirm-cli-exposure
|
|
9
|
-
* in `login.ts` — a deliberate friction step, not a TTY check (CI pseudo-TTYs
|
|
10
|
-
* are unreliable signals).
|
|
11
|
-
*
|
|
12
|
-
* `consequence` completes the sentence "Live key in use — <operation>
|
|
13
|
-
* <consequence>." printed when the caller DID confirm. It defaults to
|
|
14
|
-
* "is irreversible", which is right for money calls; pass a truthful one for
|
|
15
|
-
* anything else.
|
|
16
|
-
*
|
|
17
|
-
* Exits the process with code 1 on refusal so callers can `requireLiveConfirmation(...)`
|
|
18
|
-
* as an early guard at the top of an action handler.
|
|
19
|
-
*/
|
|
20
|
-
export declare function requireLiveConfirmation(key: string, opts: LiveGateOpts, operation: string, consequence?: string): void;
|
|
21
|
-
export declare function warnLiveSecretFlag(key: string, flag: string): void;
|
|
22
|
-
//# sourceMappingURL=live-key.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"live-key.d.ts","sourceRoot":"","sources":["../../src/utils/live-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMlD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAoB,GAC9B,IAAI,CAYN;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAOlE"}
|
package/dist/utils/live-key.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { isLiveKey } from "@vonpay/checkout-node";
|
|
3
|
-
import { exitWithCliError } from "./errors.js";
|
|
4
|
-
// The ONE definition of "live key", owned by the SDK (3.0.0+). Re-exported so
|
|
5
|
-
// existing imports of `isLiveKey` from this module keep working; do not
|
|
6
|
-
// re-implement the prefix check here.
|
|
7
|
-
export { isLiveKey };
|
|
8
|
-
/**
|
|
9
|
-
* Refuse to run a destructive/irreversible operation on a live key unless the
|
|
10
|
-
* caller explicitly passes --confirm-live. Pattern mirrors --confirm-cli-exposure
|
|
11
|
-
* in `login.ts` — a deliberate friction step, not a TTY check (CI pseudo-TTYs
|
|
12
|
-
* are unreliable signals).
|
|
13
|
-
*
|
|
14
|
-
* `consequence` completes the sentence "Live key in use — <operation>
|
|
15
|
-
* <consequence>." printed when the caller DID confirm. It defaults to
|
|
16
|
-
* "is irreversible", which is right for money calls; pass a truthful one for
|
|
17
|
-
* anything else.
|
|
18
|
-
*
|
|
19
|
-
* Exits the process with code 1 on refusal so callers can `requireLiveConfirmation(...)`
|
|
20
|
-
* as an early guard at the top of an action handler.
|
|
21
|
-
*/
|
|
22
|
-
export function requireLiveConfirmation(key, opts, operation, consequence = "is irreversible") {
|
|
23
|
-
if (!isLiveKey(key))
|
|
24
|
-
return;
|
|
25
|
-
if (opts.confirmLive) {
|
|
26
|
-
console.warn(chalk.yellow(`Live key in use — ${operation} ${consequence}. Proceeding because --confirm-live was passed.`));
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const message = `Refusing to ${operation} with a live key. Pass --confirm-live to acknowledge this is intentional.`;
|
|
30
|
-
exitWithCliError(message, chalk.red(message));
|
|
31
|
-
}
|
|
32
|
-
export function warnLiveSecretFlag(key, flag) {
|
|
33
|
-
if (!isLiveKey(key))
|
|
34
|
-
return;
|
|
35
|
-
console.warn(chalk.yellow(`Warning: passing ${flag} as a command argument with a live key exposes it to shell history and process-list (\`ps\`). Consider piping or env-injecting the value instead.`));
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=live-key.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"live-key.js","sourceRoot":"","sources":["../../src/utils/live-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,8EAA8E;AAC9E,wEAAwE;AACxE,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,CAAC;AAMrB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAW,EACX,IAAkB,EAClB,SAAiB,EACjB,WAAW,GAAG,iBAAiB;IAE/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO;IAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,MAAM,CACV,qBAAqB,SAAS,IAAI,WAAW,iDAAiD,CAC/F,CACF,CAAC;QACF,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,SAAS,2EAA2E,CAAC;IACpH,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,IAAY;IAC1D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO;IAC5B,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,MAAM,CACV,oBAAoB,IAAI,mJAAmJ,CAC5K,CACF,CAAC;AACJ,CAAC"}
|
package/dist/utils/metadata.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/utils/metadata.ts"],"names":[],"mappings":"AAIA,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAmCpC"}
|
package/dist/utils/metadata.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const MAX_LEN = 256;
|
|
2
|
-
// Allow tab and newline in values (rare but valid); reject all other C0 controls + DEL.
|
|
3
|
-
const CONTROL_CHARS = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/;
|
|
4
|
-
export function parseMetadata(pairs) {
|
|
5
|
-
if (!pairs || pairs.length === 0)
|
|
6
|
-
return undefined;
|
|
7
|
-
const out = {};
|
|
8
|
-
for (const pair of pairs) {
|
|
9
|
-
const idx = pair.indexOf("=");
|
|
10
|
-
if (idx === -1) {
|
|
11
|
-
throw new Error(`Invalid --metadata value "${pair}". Expected key=value (use multiple --metadata flags for multiple pairs).`);
|
|
12
|
-
}
|
|
13
|
-
const key = pair.slice(0, idx);
|
|
14
|
-
const value = pair.slice(idx + 1);
|
|
15
|
-
if (key.length === 0) {
|
|
16
|
-
throw new Error(`Invalid --metadata value "${pair}": key is empty. Expected key=value with a non-empty key.`);
|
|
17
|
-
}
|
|
18
|
-
if (key.length > MAX_LEN) {
|
|
19
|
-
throw new Error(`--metadata key too long (${key.length} > ${MAX_LEN}).`);
|
|
20
|
-
}
|
|
21
|
-
if (value.length > MAX_LEN) {
|
|
22
|
-
throw new Error(`--metadata value too long (${value.length} > ${MAX_LEN}).`);
|
|
23
|
-
}
|
|
24
|
-
if (CONTROL_CHARS.test(key) || CONTROL_CHARS.test(value)) {
|
|
25
|
-
throw new Error(`--metadata "${key}" contains control characters; metadata must be printable text.`);
|
|
26
|
-
}
|
|
27
|
-
out[key] = value;
|
|
28
|
-
}
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=metadata.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/utils/metadata.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,wFAAwF;AACxF,MAAM,aAAa,GAAG,kCAAkC,CAAC;AAEzD,MAAM,UAAU,aAAa,CAC3B,KAA2B;IAE3B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,2EAA2E,CAC7G,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,2DAA2D,CAC7F,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,4BAA4B,GAAG,CAAC,MAAM,MAAM,OAAO,IAAI,CACxD,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,8BAA8B,KAAK,CAAC,MAAM,MAAM,OAAO,IAAI,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,eAAe,GAAG,iEAAiE,CACpF,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/utils/sanitize.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAOA,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAM,GAAG,MAAM,CAExD"}
|
package/dist/utils/sanitize.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Strip CSI escape sequences (e.g. ANSI color, cursor movement) from text we
|
|
2
|
-
// echo back to the terminal. Server-supplied strings should not be able to
|
|
3
|
-
// repaint the user's terminal.
|
|
4
|
-
const ANSI_PATTERN = /\x1B\[[0-9;?]*[A-Za-z]/g;
|
|
5
|
-
// Strip C0 controls + DEL except tab/newline (kept for readability).
|
|
6
|
-
const C0_CONTROL_PATTERN = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
|
|
7
|
-
export function stripAnsi(s) {
|
|
8
|
-
return s.replace(ANSI_PATTERN, "").replace(C0_CONTROL_PATTERN, "");
|
|
9
|
-
}
|
|
10
|
-
export function truncate(s, max) {
|
|
11
|
-
if (s.length <= max)
|
|
12
|
-
return s;
|
|
13
|
-
return s.slice(0, max - 1) + "…";
|
|
14
|
-
}
|
|
15
|
-
export function safeDisplay(s, max = 200) {
|
|
16
|
-
return truncate(stripAnsi(s), max);
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=sanitize.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,+BAA+B;AAC/B,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAC/C,qEAAqE;AACrE,MAAM,kBAAkB,GAAG,mCAAmC,CAAC;AAE/D,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,GAAW;IAC7C,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS,EAAE,GAAG,GAAG,GAAG;IAC9C,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC"}
|
package/dist/utils/spinner.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type Ora } from "ora";
|
|
2
|
-
/**
|
|
3
|
-
* Start the progress spinner for a command — silent under `--json`.
|
|
4
|
-
*
|
|
5
|
-
* ⛔ When stderr is not a terminal (a script, a CI step) ora does not animate:
|
|
6
|
-
* it prints its text once, as `- Capturing payment intent...`, to stderr. Under
|
|
7
|
-
* `--json` that put a non-JSON line in front of the JSON error, so stderr did
|
|
8
|
-
* not parse. `doctor` already silenced its spinner under `--json` for the same
|
|
9
|
-
* reason; every command now does. Without `--json` nothing changes.
|
|
10
|
-
*
|
|
11
|
-
* Reads the per-run `--json` setting made by the `preAction` hook in
|
|
12
|
-
* `commands/checkout.ts`, which runs before any command's action.
|
|
13
|
-
*/
|
|
14
|
-
export declare function startSpinner(text: string): Ora;
|
|
15
|
-
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAGpC;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAE9C"}
|
package/dist/utils/spinner.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import ora from "ora";
|
|
2
|
-
import { jsonErrorsEnabled } from "./json-errors.js";
|
|
3
|
-
/**
|
|
4
|
-
* Start the progress spinner for a command — silent under `--json`.
|
|
5
|
-
*
|
|
6
|
-
* ⛔ When stderr is not a terminal (a script, a CI step) ora does not animate:
|
|
7
|
-
* it prints its text once, as `- Capturing payment intent...`, to stderr. Under
|
|
8
|
-
* `--json` that put a non-JSON line in front of the JSON error, so stderr did
|
|
9
|
-
* not parse. `doctor` already silenced its spinner under `--json` for the same
|
|
10
|
-
* reason; every command now does. Without `--json` nothing changes.
|
|
11
|
-
*
|
|
12
|
-
* Reads the per-run `--json` setting made by the `preAction` hook in
|
|
13
|
-
* `commands/checkout.ts`, which runs before any command's action.
|
|
14
|
-
*/
|
|
15
|
-
export function startSpinner(text) {
|
|
16
|
-
return ora({ text, isSilent: jsonErrorsEnabled() }).start();
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=spinner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,GAAiB,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { type SseEvent } from "./sse-parser.js";
|
|
2
|
-
/**
|
|
3
|
-
* Long-lived SSE consumer with WHATWG-spec reconnect semantics.
|
|
4
|
-
*
|
|
5
|
-
* Wraps native `fetch()` against a streaming endpoint, parses incoming
|
|
6
|
-
* bytes via {@link SseParser}, yields events to the caller, and
|
|
7
|
-
* transparently reconnects on disconnect with exponential backoff.
|
|
8
|
-
*
|
|
9
|
-
* The `Last-Event-ID` header is sent on every reconnect after the first
|
|
10
|
-
* event. The server emits sticky `id: <event_id>:<attempt>` per frame,
|
|
11
|
-
* so a clean reconnect with the header in place skips duplicate events
|
|
12
|
-
* the consumer has already surfaced — at-least-once → effectively
|
|
13
|
-
* exactly-once for SSE.
|
|
14
|
-
*
|
|
15
|
-
* Cancellation: pass an `AbortSignal`. The consumer terminates cleanly
|
|
16
|
-
* (closes the response body reader, no more events, no more reconnects)
|
|
17
|
-
* when the signal aborts. This is the SIGINT / SIGTERM path.
|
|
18
|
-
*
|
|
19
|
-
* Backoff is exponential 1s → 2s → 4s → 8s → 30s cap with infinite
|
|
20
|
-
* retries — matches Stripe CLI / kubectl / aws CLI patterns for
|
|
21
|
-
* long-lived streaming connections. Reset to 1s after a successful
|
|
22
|
-
* read of at least one byte.
|
|
23
|
-
*/
|
|
24
|
-
export interface SseConsumerOptions {
|
|
25
|
-
/** Full URL of the SSE endpoint. */
|
|
26
|
-
url: string;
|
|
27
|
-
/** Headers to send on every connection. Authorization / Accept set automatically. */
|
|
28
|
-
headers?: Record<string, string>;
|
|
29
|
-
/** AbortSignal for graceful shutdown. */
|
|
30
|
-
signal: AbortSignal;
|
|
31
|
-
/**
|
|
32
|
-
* Logger for connection-lifecycle events (connect, disconnect, reconnect).
|
|
33
|
-
* The consumer never logs to stdout directly — the CLI command owns
|
|
34
|
-
* output formatting. Default is a no-op.
|
|
35
|
-
*/
|
|
36
|
-
onLifecycle?: (event: LifecycleEvent) => void;
|
|
37
|
-
/** Max backoff in ms. Default 30000 (30s). */
|
|
38
|
-
maxBackoffMs?: number;
|
|
39
|
-
/** Initial backoff in ms. Default 1000 (1s). */
|
|
40
|
-
initialBackoffMs?: number;
|
|
41
|
-
}
|
|
42
|
-
export type LifecycleEvent = {
|
|
43
|
-
kind: "connecting";
|
|
44
|
-
lastEventId: string | undefined;
|
|
45
|
-
} | {
|
|
46
|
-
kind: "connected";
|
|
47
|
-
} | {
|
|
48
|
-
kind: "disconnected";
|
|
49
|
-
reason: string;
|
|
50
|
-
willRetryInMs: number;
|
|
51
|
-
} | {
|
|
52
|
-
kind: "auth_failed";
|
|
53
|
-
status: number;
|
|
54
|
-
body: string;
|
|
55
|
-
} | {
|
|
56
|
-
kind: "fatal";
|
|
57
|
-
error: Error;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Returns an async iterator of SseEvent. Iterates until the signal
|
|
61
|
-
* aborts OR an unrecoverable error occurs (e.g. 401 / 403 auth failure
|
|
62
|
-
* — those throw because retrying with the same key won't help).
|
|
63
|
-
*
|
|
64
|
-
* The 1h server ceiling fires as `event: timeout` with
|
|
65
|
-
* `data: {"reason":"server-ceiling"}` (per Phase 3d event-format.ts).
|
|
66
|
-
* The consumer surfaces the timeout event to the caller AND triggers
|
|
67
|
-
* an immediate reconnect — same as the upstream-disconnect path,
|
|
68
|
-
* but without the backoff delay.
|
|
69
|
-
*/
|
|
70
|
-
export declare function consumeSse(opts: SseConsumerOptions): AsyncGenerator<SseEvent, void, void>;
|
|
71
|
-
/**
|
|
72
|
-
* Thrown when the server responds 401 or 403. Auth errors do not get
|
|
73
|
-
* retried — the caller is responsible for surfacing the error to the
|
|
74
|
-
* user and exiting non-zero.
|
|
75
|
-
*/
|
|
76
|
-
export declare class SseAuthError extends Error {
|
|
77
|
-
readonly status: number;
|
|
78
|
-
readonly body: string;
|
|
79
|
-
constructor(status: number, body: string);
|
|
80
|
-
}
|
|
81
|
-
//# sourceMappingURL=sse-consumer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sse-consumer.d.ts","sourceRoot":"","sources":["../../src/utils/sse-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,yCAAyC;IACzC,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,wBAAuB,UAAU,CAC/B,IAAI,EAAE,kBAAkB,GACvB,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAsHtC;AAED;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAEnB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAO/B"}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { SseParser } from "./sse-parser.js";
|
|
2
|
-
/**
|
|
3
|
-
* Returns an async iterator of SseEvent. Iterates until the signal
|
|
4
|
-
* aborts OR an unrecoverable error occurs (e.g. 401 / 403 auth failure
|
|
5
|
-
* — those throw because retrying with the same key won't help).
|
|
6
|
-
*
|
|
7
|
-
* The 1h server ceiling fires as `event: timeout` with
|
|
8
|
-
* `data: {"reason":"server-ceiling"}` (per Phase 3d event-format.ts).
|
|
9
|
-
* The consumer surfaces the timeout event to the caller AND triggers
|
|
10
|
-
* an immediate reconnect — same as the upstream-disconnect path,
|
|
11
|
-
* but without the backoff delay.
|
|
12
|
-
*/
|
|
13
|
-
export async function* consumeSse(opts) {
|
|
14
|
-
const initialBackoffMs = opts.initialBackoffMs ?? 1000;
|
|
15
|
-
const maxBackoffMs = opts.maxBackoffMs ?? 30_000;
|
|
16
|
-
const parser = new SseParser();
|
|
17
|
-
let backoffMs = initialBackoffMs;
|
|
18
|
-
const onLifecycle = opts.onLifecycle ?? noop;
|
|
19
|
-
while (!opts.signal.aborted) {
|
|
20
|
-
const headers = {
|
|
21
|
-
Accept: "text/event-stream",
|
|
22
|
-
"Cache-Control": "no-cache",
|
|
23
|
-
...opts.headers,
|
|
24
|
-
};
|
|
25
|
-
const lastEventId = parser.getLastEventId();
|
|
26
|
-
if (lastEventId !== undefined) {
|
|
27
|
-
headers["Last-Event-ID"] = lastEventId;
|
|
28
|
-
}
|
|
29
|
-
onLifecycle({ kind: "connecting", lastEventId });
|
|
30
|
-
let response;
|
|
31
|
-
try {
|
|
32
|
-
response = await fetch(opts.url, {
|
|
33
|
-
method: "GET",
|
|
34
|
-
headers,
|
|
35
|
-
signal: opts.signal,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch (err) {
|
|
39
|
-
if (opts.signal.aborted)
|
|
40
|
-
return;
|
|
41
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
42
|
-
onLifecycle({ kind: "disconnected", reason, willRetryInMs: backoffMs });
|
|
43
|
-
await sleep(backoffMs, opts.signal);
|
|
44
|
-
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (response.status === 401 || response.status === 403) {
|
|
48
|
-
const body = await safeReadText(response);
|
|
49
|
-
onLifecycle({ kind: "auth_failed", status: response.status, body });
|
|
50
|
-
throw new SseAuthError(response.status, body);
|
|
51
|
-
}
|
|
52
|
-
if (!response.ok) {
|
|
53
|
-
const body = await safeReadText(response);
|
|
54
|
-
onLifecycle({
|
|
55
|
-
kind: "disconnected",
|
|
56
|
-
reason: `HTTP ${response.status}: ${truncate(body, 200)}`,
|
|
57
|
-
willRetryInMs: backoffMs,
|
|
58
|
-
});
|
|
59
|
-
await sleep(backoffMs, opts.signal);
|
|
60
|
-
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (!response.body) {
|
|
64
|
-
onLifecycle({
|
|
65
|
-
kind: "disconnected",
|
|
66
|
-
reason: "response has no body",
|
|
67
|
-
willRetryInMs: backoffMs,
|
|
68
|
-
});
|
|
69
|
-
await sleep(backoffMs, opts.signal);
|
|
70
|
-
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
onLifecycle({ kind: "connected" });
|
|
74
|
-
backoffMs = initialBackoffMs; // reset after a successful connect
|
|
75
|
-
const reader = response.body.getReader();
|
|
76
|
-
const decoder = new TextDecoder("utf-8");
|
|
77
|
-
let serverInitiatedReconnect = false;
|
|
78
|
-
try {
|
|
79
|
-
while (!opts.signal.aborted) {
|
|
80
|
-
const { value, done } = await reader.read();
|
|
81
|
-
if (done)
|
|
82
|
-
break;
|
|
83
|
-
const events = parser.feed(decoder.decode(value, { stream: true }));
|
|
84
|
-
for (const ev of events) {
|
|
85
|
-
// Server-ceiling timeout: surface to caller AND mark for
|
|
86
|
-
// immediate reconnect without backoff. Per Phase 3d
|
|
87
|
-
// event-format.ts the server sends this right before
|
|
88
|
-
// closing the connection.
|
|
89
|
-
if (ev.type === "timeout") {
|
|
90
|
-
yield ev;
|
|
91
|
-
serverInitiatedReconnect = true;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
yield ev;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
if (opts.signal.aborted)
|
|
101
|
-
return;
|
|
102
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
103
|
-
onLifecycle({ kind: "disconnected", reason, willRetryInMs: backoffMs });
|
|
104
|
-
}
|
|
105
|
-
finally {
|
|
106
|
-
// Best-effort cancel — fetch already releases on abort but be defensive.
|
|
107
|
-
try {
|
|
108
|
-
await reader.cancel();
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// ignore
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (opts.signal.aborted)
|
|
115
|
-
return;
|
|
116
|
-
if (serverInitiatedReconnect) {
|
|
117
|
-
// Skip the backoff sleep; server politely told us to reconnect.
|
|
118
|
-
// backoffMs already at initial because we successfully connected.
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
onLifecycle({
|
|
122
|
-
kind: "disconnected",
|
|
123
|
-
reason: "stream ended",
|
|
124
|
-
willRetryInMs: backoffMs,
|
|
125
|
-
});
|
|
126
|
-
await sleep(backoffMs, opts.signal);
|
|
127
|
-
backoffMs = Math.min(backoffMs * 2, maxBackoffMs);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Thrown when the server responds 401 or 403. Auth errors do not get
|
|
132
|
-
* retried — the caller is responsible for surfacing the error to the
|
|
133
|
-
* user and exiting non-zero.
|
|
134
|
-
*/
|
|
135
|
-
export class SseAuthError extends Error {
|
|
136
|
-
status;
|
|
137
|
-
body;
|
|
138
|
-
constructor(status, body) {
|
|
139
|
-
super(`SSE auth failed: HTTP ${status}${body ? ` — ${truncate(body, 200)}` : ""}`);
|
|
140
|
-
this.status = status;
|
|
141
|
-
this.body = body;
|
|
142
|
-
this.name = "SseAuthError";
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function sleep(ms, signal) {
|
|
146
|
-
return new Promise((resolve) => {
|
|
147
|
-
const timer = setTimeout(() => {
|
|
148
|
-
signal.removeEventListener("abort", onAbort);
|
|
149
|
-
resolve();
|
|
150
|
-
}, ms);
|
|
151
|
-
const onAbort = () => {
|
|
152
|
-
clearTimeout(timer);
|
|
153
|
-
resolve();
|
|
154
|
-
};
|
|
155
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
async function safeReadText(response) {
|
|
159
|
-
try {
|
|
160
|
-
return await response.text();
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
return "";
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
function truncate(s, n) {
|
|
167
|
-
return s.length <= n ? s : `${s.slice(0, n - 3)}...`;
|
|
168
|
-
}
|
|
169
|
-
function noop() {
|
|
170
|
-
/* no-op */
|
|
171
|
-
}
|
|
172
|
-
//# sourceMappingURL=sse-consumer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sse-consumer.js","sourceRoot":"","sources":["../../src/utils/sse-consumer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure incremental parser for the Server-Sent Events wire format
|
|
3
|
-
* (WHATWG HTML §9.2.6 "Parsing an event stream").
|
|
4
|
-
*
|
|
5
|
-
* Decoupled from I/O so the consumer can drive it from any byte source
|
|
6
|
-
* (fetch ReadableStream, Node Readable, in-memory buffer in tests).
|
|
7
|
-
*
|
|
8
|
-
* Spec details that are easy to get wrong:
|
|
9
|
-
* - Frame separator is one blank line — any of `\n\n`, `\r\n\r\n`, `\r\r`.
|
|
10
|
-
* - A line starting with `:` is a comment — ignored (used as heartbeat).
|
|
11
|
-
* - `field: value` — the single space after `:` is stripped if present.
|
|
12
|
-
* - Multiple `data:` lines within a frame concatenate with `\n` between them.
|
|
13
|
-
* - `id:` sets the parser's lastEventId for the NEXT and subsequent
|
|
14
|
-
* dispatched events (sticky across frames until overridden).
|
|
15
|
-
* - `event:` defaults to `"message"` when absent.
|
|
16
|
-
* - `retry:` is reported on the event but the consumer decides whether
|
|
17
|
-
* to honor it (we expose it; consumer caps with its own backoff).
|
|
18
|
-
* - Unknown fields are ignored — additive evolution is safe.
|
|
19
|
-
*
|
|
20
|
-
* Stateful only in `lastEventId` (per spec). Caller drives by repeatedly
|
|
21
|
-
* calling feed(chunk) on incoming bytes; events come back per call.
|
|
22
|
-
*/
|
|
23
|
-
export interface SseEvent {
|
|
24
|
-
/** Event type from `event:` field. Defaults to `"message"`. */
|
|
25
|
-
type: string;
|
|
26
|
-
/** Joined data payload — `data:` lines joined with `\n`. */
|
|
27
|
-
data: string;
|
|
28
|
-
/** Sticky id from `id:`. Undefined until the stream emits one. */
|
|
29
|
-
lastEventId: string | undefined;
|
|
30
|
-
/** Reconnect-time hint from `retry:` (ms). Undefined when absent. */
|
|
31
|
-
retry: number | undefined;
|
|
32
|
-
}
|
|
33
|
-
export declare class SseBufferOverflowError extends Error {
|
|
34
|
-
readonly cap: number;
|
|
35
|
-
constructor(cap: number);
|
|
36
|
-
}
|
|
37
|
-
export interface SseParserOptions {
|
|
38
|
-
/** Hard cap on in-flight bytes before {@link SseBufferOverflowError}. */
|
|
39
|
-
maxBufferBytes?: number;
|
|
40
|
-
}
|
|
41
|
-
export declare class SseParser {
|
|
42
|
-
private buffer;
|
|
43
|
-
private lastEventId;
|
|
44
|
-
private readonly maxBufferBytes;
|
|
45
|
-
constructor(options?: SseParserOptions);
|
|
46
|
-
/**
|
|
47
|
-
* Feed a chunk of decoded text. Returns any events that completed within
|
|
48
|
-
* this chunk. The remainder (partial frame) is held internally and
|
|
49
|
-
* concatenated with the next chunk.
|
|
50
|
-
*
|
|
51
|
-
* Throws {@link SseBufferOverflowError} when the in-flight buffer
|
|
52
|
-
* exceeds `maxBufferBytes` — the consumer's reconnect-on-error loop
|
|
53
|
-
* recovers by discarding the buffer and re-establishing the
|
|
54
|
-
* connection.
|
|
55
|
-
*/
|
|
56
|
-
feed(chunk: string): SseEvent[];
|
|
57
|
-
/** Drain any in-flight buffer as a final event. Used when the source closes mid-frame and the consumer wants to surface the partial. Returns at most one event. Most callers don't need this — for a well-behaved server-side stream the parser never holds a complete trailing event without a separator. */
|
|
58
|
-
flush(): SseEvent | undefined;
|
|
59
|
-
private parseFrame;
|
|
60
|
-
/** Current sticky id. Consumer uses this for the Last-Event-ID header on reconnect. */
|
|
61
|
-
getLastEventId(): string | undefined;
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=sse-parser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sse-parser.d.ts","sourceRoot":"","sources":["../../src/utils/sse-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAeD,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,OAAO,GAAE,gBAAqB;IAI1C;;;;;;;;;OASG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE;IAoB/B,8SAA8S;IAC9S,KAAK,IAAI,QAAQ,GAAG,SAAS;IAO7B,OAAO,CAAC,UAAU;IA+DlB,uFAAuF;IACvF,cAAc,IAAI,MAAM,GAAG,SAAS;CAGrC"}
|