@or3/intern-client 0.1.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 +76 -0
- package/dist/index.js +1362 -0
- package/package.json +34 -0
- package/src/client.ts +676 -0
- package/src/errors.ts +131 -0
- package/src/index.ts +6 -0
- package/src/protocol.ts +692 -0
- package/src/redaction.ts +114 -0
- package/src/sse.ts +151 -0
- package/src/transport.ts +915 -0
package/src/errors.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { redactInternSecrets } from './redaction';
|
|
2
|
+
|
|
3
|
+
export type InternErrorCode =
|
|
4
|
+
| 'aborted'
|
|
5
|
+
| 'conflict'
|
|
6
|
+
| 'forbidden'
|
|
7
|
+
| 'http'
|
|
8
|
+
| 'not_found'
|
|
9
|
+
| 'offline'
|
|
10
|
+
| 'protocol'
|
|
11
|
+
| 'timeout'
|
|
12
|
+
| 'unauthorized'
|
|
13
|
+
| 'unavailable'
|
|
14
|
+
| 'validation_failed';
|
|
15
|
+
|
|
16
|
+
export interface InternErrorOptions {
|
|
17
|
+
status?: number;
|
|
18
|
+
remoteCode?: string;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
retryable?: boolean;
|
|
21
|
+
details?: unknown;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
secrets?: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function safeCause(cause: unknown, secrets: readonly string[]): Error | undefined {
|
|
27
|
+
if (cause === undefined) return undefined;
|
|
28
|
+
const message =
|
|
29
|
+
cause instanceof Error
|
|
30
|
+
? cause.message
|
|
31
|
+
: typeof cause === 'string'
|
|
32
|
+
? cause
|
|
33
|
+
: 'Request failed';
|
|
34
|
+
const safe = new Error(String(redactInternSecrets(message, secrets)));
|
|
35
|
+
safe.name = cause instanceof Error ? cause.name : 'Error';
|
|
36
|
+
return safe;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class InternClientError extends Error {
|
|
40
|
+
readonly code: InternErrorCode;
|
|
41
|
+
readonly status?: number;
|
|
42
|
+
readonly remoteCode?: string;
|
|
43
|
+
readonly requestId?: string;
|
|
44
|
+
readonly retryable: boolean;
|
|
45
|
+
readonly details?: unknown;
|
|
46
|
+
override readonly cause?: Error;
|
|
47
|
+
|
|
48
|
+
constructor(
|
|
49
|
+
code: InternErrorCode,
|
|
50
|
+
message: string,
|
|
51
|
+
options: InternErrorOptions = {}
|
|
52
|
+
) {
|
|
53
|
+
const secrets = options.secrets ?? [];
|
|
54
|
+
super(String(redactInternSecrets(message, secrets)));
|
|
55
|
+
this.name = 'InternClientError';
|
|
56
|
+
this.code = code;
|
|
57
|
+
this.status = options.status;
|
|
58
|
+
this.remoteCode = options.remoteCode;
|
|
59
|
+
this.requestId = options.requestId;
|
|
60
|
+
this.retryable = options.retryable ?? false;
|
|
61
|
+
this.details =
|
|
62
|
+
options.details === undefined
|
|
63
|
+
? undefined
|
|
64
|
+
: redactInternSecrets(options.details, secrets);
|
|
65
|
+
this.cause = safeCause(options.cause, secrets);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class InternUnavailableError extends InternClientError {
|
|
70
|
+
readonly capability?: string;
|
|
71
|
+
|
|
72
|
+
constructor(
|
|
73
|
+
message: string,
|
|
74
|
+
options: InternErrorOptions & { capability?: string } = {}
|
|
75
|
+
) {
|
|
76
|
+
super('unavailable', message, {
|
|
77
|
+
retryable: false,
|
|
78
|
+
...options,
|
|
79
|
+
});
|
|
80
|
+
this.name = 'InternUnavailableError';
|
|
81
|
+
this.capability = options.capability;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type InternResult<T> =
|
|
86
|
+
| { ok: true; value: T }
|
|
87
|
+
| { ok: false; error: InternClientError };
|
|
88
|
+
|
|
89
|
+
export function internOk<T>(value: T): InternResult<T> {
|
|
90
|
+
return { ok: true, value };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function internErr<T = never>(
|
|
94
|
+
error: InternClientError
|
|
95
|
+
): InternResult<T> {
|
|
96
|
+
return { ok: false, error };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function asInternClientError(error: unknown): InternClientError {
|
|
100
|
+
if (error instanceof InternClientError) return error;
|
|
101
|
+
return new InternClientError('protocol', 'Unexpected client failure', {
|
|
102
|
+
cause: error,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function toInternResult<T>(
|
|
107
|
+
value: Promise<T> | (() => Promise<T>)
|
|
108
|
+
): Promise<InternResult<T>> {
|
|
109
|
+
try {
|
|
110
|
+
return internOk(
|
|
111
|
+
await (typeof value === 'function' ? value() : value)
|
|
112
|
+
);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return internErr(asInternClientError(error));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function requireInternCapability<T>(
|
|
119
|
+
value: T | null | undefined | false,
|
|
120
|
+
capability: string
|
|
121
|
+
): InternResult<T> {
|
|
122
|
+
if (value === undefined || value === null || value === false) {
|
|
123
|
+
return internErr(
|
|
124
|
+
new InternUnavailableError(
|
|
125
|
+
`The selected host does not advertise ${capability}.`,
|
|
126
|
+
{ capability }
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return internOk(value);
|
|
131
|
+
}
|