@aiwg/cli 2026.9.18 → 2026.9.19

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.
Files changed (35) hide show
  1. package/dist/src/api/index.d.ts +1 -0
  2. package/dist/src/api/index.js +1 -0
  3. package/dist/src/artifacts/index-builder.js +44 -9
  4. package/dist/src/artifacts/query-engine.js +4 -1
  5. package/dist/src/artifacts/types.js +3 -0
  6. package/dist/src/cli/handlers/bot-handoff.js +35 -0
  7. package/dist/src/cli/handlers/build-verify.js +50 -0
  8. package/dist/src/cli/handlers/index.js +5 -1
  9. package/dist/src/cli/handlers/provider-command-options.js +24 -0
  10. package/dist/src/cli/services/deployment-verification.js +8 -5
  11. package/dist/src/decision/adapters/jev.js +515 -0
  12. package/dist/src/decision/adapters/llm-subagent.js +174 -0
  13. package/dist/src/decision/compose.js +54 -0
  14. package/dist/src/decision/convert.js +14 -0
  15. package/dist/src/decision/entry.js +183 -0
  16. package/dist/src/decision/evaluate.js +508 -0
  17. package/dist/src/decision/export.js +16 -0
  18. package/dist/src/decision/index.js +12 -0
  19. package/dist/src/decision/predicates.js +74 -0
  20. package/dist/src/decision/receipts.js +291 -0
  21. package/dist/src/decision/types.js +3 -0
  22. package/dist/src/decision/validate.js +303 -0
  23. package/dist/src/extensions/commands/definitions.js +20 -0
  24. package/dist/src/providers/bot-handoff.js +83 -0
  25. package/dist/src/providers/grokbot-handoff-guidance.js +26 -0
  26. package/dist/src/providers/grokbot-natives/connector-install-profile.js +59 -0
  27. package/dist/src/providers/grokbot-natives/create-agent.js +54 -0
  28. package/dist/src/providers/grokbot-natives/evidence.js +92 -0
  29. package/dist/src/providers/grokbot-natives/flags.js +47 -0
  30. package/dist/src/providers/grokbot-natives/index.js +67 -0
  31. package/dist/src/providers/grokbot-natives/memory-reference-helper.js +114 -0
  32. package/dist/src/providers/grokbot-natives/registered-machine-health.js +51 -0
  33. package/dist/src/providers/grokbot-natives/routines.js +57 -0
  34. package/dist/src/providers/grokbot-natives/types.js +20 -0
  35. package/package.json +1 -1
@@ -0,0 +1,515 @@
1
+ import { DecisionValidationError, validateDecisionValue, validateDistribution } from '../validate.js';
2
+ import { canonicalJson } from '../../security/artifact-trust.js';
3
+ import { runInNewContext } from 'node:vm';
4
+ import { lookup } from 'node:dns/promises';
5
+ import { isIP } from 'node:net';
6
+ import { request as httpsRequest } from 'node:https';
7
+ import { Readable } from 'node:stream';
8
+ import { createBrotliDecompress, createGunzip, createInflate } from 'node:zlib';
9
+ export const JEV_ENDPOINT = 'https://api.typesafe.ai/v1/systemone';
10
+ const MAX_HEADER_BYTES = 32 * 1024;
11
+ const MAX_BODY_BYTES = 1024 * 1024;
12
+ const MAX_REQUEST_ID_LENGTH = 128;
13
+ const MAX_PARSE_MS = 50;
14
+ /** Safe resolver taxonomy; messages are intentionally discarded at this boundary. */
15
+ export class JevCredentialError extends Error {
16
+ category;
17
+ constructor(category) {
18
+ super('Jev credential resolution failed');
19
+ this.category = category;
20
+ this.name = 'JevCredentialError';
21
+ }
22
+ }
23
+ class JevTransportResponseError extends Error {
24
+ }
25
+ export class JevDecisionAdapter {
26
+ id = 'jev';
27
+ version = '1.0.0';
28
+ endpoint;
29
+ fetchImpl;
30
+ allowedOrigins;
31
+ resolveAddresses;
32
+ pinnedFetch;
33
+ now;
34
+ constructor(options = {}) {
35
+ this.endpoint = options.endpoint ?? JEV_ENDPOINT;
36
+ this.fetchImpl = options.fetch ?? fetch;
37
+ this.allowedOrigins = options.allowedOrigins ?? [];
38
+ this.resolveAddresses = options.resolveAddresses ?? systemResolveAddresses;
39
+ this.pinnedFetch = options.pinnedFetch ?? pinnedHttpsFetch;
40
+ this.now = options.now ?? Date.now;
41
+ }
42
+ async capabilities() {
43
+ return {
44
+ answerKinds: ['choice', 'ordinal-score', 'truth-probability'],
45
+ features: ['typed-output', 'probability-distribution', 'structured-entries'],
46
+ maxOptions: 255,
47
+ maxLevels: 10,
48
+ confidenceProfiles: ['typesafe-distribution-v1', 'typesafe-truth-v1'],
49
+ executable: true,
50
+ };
51
+ }
52
+ async evaluate(request) {
53
+ if (request.signal.aborted)
54
+ return externalInterruption(request, 'not-sent');
55
+ if (this.now() >= request.deadlineEpochMs)
56
+ return failure('timeout', { termination: 'target-timeout', dispatchCertainty: 'not-sent' });
57
+ let pin;
58
+ try {
59
+ pin = await withAbort(authorizeEndpoint(this.endpoint, this.allowedOrigins, this.resolveAddresses), request.signal);
60
+ }
61
+ catch {
62
+ return request.signal.aborted ? externalInterruption(request, 'not-sent')
63
+ : failure('data-boundary-denied', { dispatchCertainty: 'not-sent' });
64
+ }
65
+ if (request.signal.aborted)
66
+ return externalInterruption(request, 'not-sent');
67
+ let token;
68
+ try {
69
+ if (!request.target.credentialRef)
70
+ return failure('unauthorized', { dispatchCertainty: 'not-sent' });
71
+ const credential = new Uint8Array(await withAbort(request.resolveCredential(request.target.credentialRef), request.signal));
72
+ try {
73
+ token = new TextDecoder('utf-8', { fatal: true }).decode(credential);
74
+ }
75
+ finally {
76
+ credential.fill(0);
77
+ }
78
+ if (!token || /[\r\n\u0000-\u001f\u007f]/.test(token))
79
+ return failure('authentication', { dispatchCertainty: 'not-sent' });
80
+ }
81
+ catch (error) {
82
+ if (request.signal.aborted)
83
+ return externalInterruption(request, 'not-sent');
84
+ const category = error instanceof JevCredentialError ? error.category : null;
85
+ const reason = category === 'missing' ? 'authentication'
86
+ : category === 'denied' || category === 'configuration' || error instanceof DecisionValidationError ? 'unauthorized'
87
+ : 'executor-unavailable';
88
+ return failure(reason, { dispatchCertainty: 'not-sent' });
89
+ }
90
+ if (request.signal.aborted)
91
+ return externalInterruption(request, 'not-sent');
92
+ const timeoutMs = Math.max(1, request.deadlineEpochMs - this.now());
93
+ const deadline = AbortSignal.timeout(timeoutMs);
94
+ const signal = AbortSignal.any([request.signal, deadline]);
95
+ let body;
96
+ try {
97
+ body = JSON.stringify({ state: request.input, model: request.target.model,
98
+ questions: { [request.alias]: toJevQuestion(request) } });
99
+ }
100
+ catch {
101
+ return failure('invalid-request', { dispatchCertainty: 'not-sent' });
102
+ }
103
+ if (request.signal.aborted)
104
+ return externalInterruption(request, 'not-sent');
105
+ let response;
106
+ try {
107
+ const init = {
108
+ method: 'POST',
109
+ headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' },
110
+ body,
111
+ signal,
112
+ redirect: 'error',
113
+ };
114
+ response = pin ? await this.pinnedFetch(new URL(this.endpoint), init, pin)
115
+ : await this.fetchImpl(this.endpoint, init);
116
+ }
117
+ catch (error) {
118
+ return request.signal.aborted ? externalInterruption(request, 'unknown')
119
+ : deadline.aborted ? failure('timeout', { termination: 'target-timeout', remoteExecution: 'unknown', dispatchCertainty: 'unknown' })
120
+ : error instanceof Error && error.name === 'AbortError'
121
+ ? failure('cancelled', { termination: 'backend-cancelled', remoteExecution: 'unknown', dispatchCertainty: 'unknown' })
122
+ : error instanceof JevTransportResponseError || error && typeof error === 'object' && 'code' in error && error.code === 'HPE_HEADER_OVERFLOW'
123
+ ? failure('invalid-output', { remoteExecution: 'unknown', dispatchCertainty: 'unknown' })
124
+ : failure('network-transient', { remoteExecution: 'unknown', dispatchCertainty: 'unknown' });
125
+ }
126
+ const correlation = requestId(response.headers);
127
+ let metadata = { ...correlation, httpStatus: response.status, dispatchCertainty: 'terminal-response' };
128
+ if (request.signal.aborted)
129
+ return externalInterruption(request, 'terminal-response', metadata);
130
+ if (deadline.aborted)
131
+ return failure('timeout', { ...metadata, termination: 'target-timeout', remoteExecution: 'unknown' });
132
+ if (!headersWithinLimit(response.headers)) {
133
+ await response.body?.cancel().catch(() => undefined);
134
+ return failure('invalid-output', metadata);
135
+ }
136
+ let finalOrigin = null;
137
+ try {
138
+ if (response.url)
139
+ finalOrigin = new URL(response.url).origin;
140
+ }
141
+ catch {
142
+ finalOrigin = 'invalid';
143
+ }
144
+ if (finalOrigin && finalOrigin !== new URL(this.endpoint).origin) {
145
+ await response.body?.cancel().catch(() => undefined);
146
+ return failure('data-boundary-denied', metadata);
147
+ }
148
+ if (response.status >= 300 && response.status < 400) {
149
+ await response.body?.cancel().catch(() => undefined);
150
+ return failure('data-boundary-denied', metadata);
151
+ }
152
+ if (!response.ok) {
153
+ try {
154
+ const errorBody = await readBoundedBody(response, signal);
155
+ if (!metadata.requestId && response.headers.get('content-type')?.includes('json')) {
156
+ let parsedError;
157
+ try {
158
+ parsedError = parseBoundedJson(errorBody);
159
+ }
160
+ catch (error) {
161
+ if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_SCRIPT_EXECUTION_TIMEOUT')
162
+ throw error;
163
+ parsedError = null;
164
+ }
165
+ if (parsedError && typeof parsedError === 'object' && !Array.isArray(parsedError)) {
166
+ const field = parsedError.request_id ?? parsedError.requestId;
167
+ const safe = safeRequestId(field);
168
+ if (safe)
169
+ metadata = { ...metadata, requestId: safe, requestIdSource: 'body' };
170
+ }
171
+ }
172
+ }
173
+ catch {
174
+ if (request.signal.aborted)
175
+ return externalInterruption(request, 'terminal-response', metadata);
176
+ if (deadline.aborted)
177
+ return failure('timeout', { ...metadata, termination: 'target-timeout', remoteExecution: 'unknown' });
178
+ return failure('invalid-output', metadata);
179
+ }
180
+ const retryAfterMs = parseRetryAfter(response.headers, this.now());
181
+ return failure(mapStatus(response.status), { ...metadata, ...(retryAfterMs === null ? {} : { retryAfterMs }) });
182
+ }
183
+ let parsed;
184
+ try {
185
+ const encoded = await readBoundedBody(response, signal);
186
+ parsed = parseBoundedJson(encoded);
187
+ if (request.signal.aborted)
188
+ return externalInterruption(request, 'terminal-response', metadata);
189
+ if (deadline.aborted)
190
+ return failure('timeout', { ...metadata, termination: 'target-timeout', remoteExecution: 'unknown' });
191
+ const normalized = normalizeResponse(request, parsed);
192
+ return { ...normalized, ...metadata };
193
+ }
194
+ catch {
195
+ return request.signal.aborted ? externalInterruption(request, 'terminal-response', metadata)
196
+ : deadline.aborted ? failure('timeout', { ...metadata, termination: 'target-timeout', remoteExecution: 'unknown' })
197
+ : failure('invalid-output', metadata);
198
+ }
199
+ }
200
+ }
201
+ async function withAbort(promise, signal) {
202
+ if (signal.aborted)
203
+ throw new DOMException('Aborted', 'AbortError');
204
+ let onAbort = () => undefined;
205
+ const cancelled = new Promise((_, reject) => {
206
+ onAbort = () => reject(new DOMException('Aborted', 'AbortError'));
207
+ signal.addEventListener('abort', onAbort, { once: true });
208
+ });
209
+ try {
210
+ return await Promise.race([promise, cancelled]);
211
+ }
212
+ finally {
213
+ signal.removeEventListener('abort', onAbort);
214
+ }
215
+ }
216
+ function toJevQuestion(request) {
217
+ const { answer } = request.definition.spec;
218
+ if (answer.kind === 'choice') {
219
+ return {
220
+ type: 'choice',
221
+ instructions: request.definition.spec.question,
222
+ criteria: Object.fromEntries(answer.options.map(option => [option.id, option.description])),
223
+ };
224
+ }
225
+ if (answer.kind === 'ordinal-score') {
226
+ return { type: 'score', instructions: request.definition.spec.question, criteria: answer.levels };
227
+ }
228
+ return {
229
+ type: 'noul',
230
+ instructions: request.definition.spec.question,
231
+ criteria: { true: answer.trueDescription, false: answer.falseDescription },
232
+ };
233
+ }
234
+ function normalizeResponse(request, value) {
235
+ const body = asRecord(value);
236
+ const answers = asRecord(body.answers);
237
+ if (Object.keys(answers).length !== 1 || !Object.prototype.hasOwnProperty.call(answers, request.alias)) {
238
+ throw new DecisionValidationError('Jev response must contain exactly the requested answer key');
239
+ }
240
+ const answer = asRecord(answers[request.alias]);
241
+ const model = typeof body.model === 'string' && body.model ? body.model : null;
242
+ const usage = normalizeUsage(body.usage);
243
+ const kind = request.definition.spec.answer.kind;
244
+ if (kind === 'choice') {
245
+ if (answer.type !== 'choice' || typeof answer.choice !== 'string')
246
+ throw new DecisionValidationError('invalid Choice response');
247
+ const distribution = numericRecord(answer.probabilities);
248
+ validateDistribution(request.definition, distribution);
249
+ validateDecisionValue(request.definition, answer.choice);
250
+ const maximum = Math.max(...Object.values(distribution));
251
+ if (distribution[answer.choice] !== maximum)
252
+ throw new DecisionValidationError('Choice value must have maximal probability');
253
+ return success(answer.choice, model, usage, uncertainty(answer.confidence, distribution, 'typesafe-distribution-v1'));
254
+ }
255
+ if (kind === 'ordinal-score') {
256
+ if (answer.type !== 'score' || typeof answer.score !== 'number')
257
+ throw new DecisionValidationError('invalid Score response');
258
+ const distribution = numericRecord(answer.probabilities);
259
+ validateDistribution(request.definition, distribution);
260
+ const legend = asRecord(answer.legend);
261
+ request.definition.spec.answer.levels.forEach((level, index) => {
262
+ if (canonicalJson(legend[String(index)]) !== canonicalJson(level))
263
+ throw new DecisionValidationError('Score legend does not match declared levels');
264
+ });
265
+ const mean = Object.entries(distribution).reduce((sum, [index, probability]) => sum + Number(index) * probability, 0);
266
+ if (Math.abs(mean - answer.score) > 0.02)
267
+ throw new DecisionValidationError('Score is not the distribution weighted mean');
268
+ validateDecisionValue(request.definition, answer.score);
269
+ return success(answer.score, model, usage, uncertainty(answer.confidence, distribution, 'typesafe-distribution-v1'));
270
+ }
271
+ if (answer.type !== 'noul' || typeof answer.noul !== 'number')
272
+ throw new DecisionValidationError('invalid Noul response');
273
+ validateDecisionValue(request.definition, answer.noul);
274
+ return success(answer.noul, model, usage, {
275
+ source: 'provider', profile: 'typesafe-truth-v1', calibration: 'vendor-claimed',
276
+ confidence: null, distribution: null, calibrationRef: null,
277
+ });
278
+ }
279
+ function success(value, actualModel, usage, uncertaintyValue) {
280
+ return { status: 'success', reason: 'none', value, uncertainty: uncertaintyValue, actualModel, usage, requestId: null };
281
+ }
282
+ function failure(reason, extra = {}) {
283
+ const status = reason === 'unsupported-capability' ? 'unsupported' : reason === 'cancelled' ? 'cancelled' : 'error';
284
+ return { status, reason, uncertainty: null, actualModel: null, usage: emptyUsage(), requestId: null, ...extra };
285
+ }
286
+ function externalInterruption(request, certainty, metadata = {}) {
287
+ const caller = request.callerSignal ? request.callerSignal.aborted : request.signal.aborted;
288
+ const termination = caller ? 'caller-cancelled' : request.totalSignal?.aborted ? 'total-deadline' : 'target-timeout';
289
+ return failure(caller ? 'cancelled' : 'timeout', {
290
+ ...metadata,
291
+ termination,
292
+ dispatchCertainty: certainty,
293
+ ...(certainty === 'not-sent' ? {} : { remoteExecution: 'unknown' }),
294
+ });
295
+ }
296
+ function uncertainty(confidence, distribution, profile) {
297
+ if (typeof confidence !== 'number' || !Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
298
+ throw new DecisionValidationError('confidence must be a finite probability');
299
+ }
300
+ return { source: 'provider', profile, calibration: 'vendor-claimed', confidence, distribution, calibrationRef: null };
301
+ }
302
+ function normalizeUsage(value) {
303
+ const usage = asRecord(value);
304
+ return {
305
+ inputTokens: integerOrNull(usage.input_tokens),
306
+ outputTokens: integerOrNull(usage.output_tokens),
307
+ costUsd: null,
308
+ };
309
+ }
310
+ function emptyUsage() {
311
+ return { inputTokens: null, outputTokens: null, costUsd: null };
312
+ }
313
+ function integerOrNull(value) {
314
+ return Number.isSafeInteger(value) && value >= 0 ? value : null;
315
+ }
316
+ function numericRecord(value) {
317
+ const record = asRecord(value);
318
+ if (Object.values(record).some(entry => typeof entry !== 'number'))
319
+ throw new DecisionValidationError('probability map must be numeric');
320
+ return record;
321
+ }
322
+ function asRecord(value) {
323
+ if (!value || typeof value !== 'object' || Array.isArray(value))
324
+ throw new DecisionValidationError('expected object');
325
+ return value;
326
+ }
327
+ function mapStatus(status) {
328
+ if (status === 401 || status === 403)
329
+ return 'authentication';
330
+ if (status === 400 || status === 404 || status === 422)
331
+ return 'invalid-request';
332
+ if (status === 408)
333
+ return 'timeout';
334
+ if (status === 429)
335
+ return 'rate-limited';
336
+ if (status === 529)
337
+ return 'overloaded';
338
+ if (status >= 500)
339
+ return 'service-error';
340
+ return 'invalid-request';
341
+ }
342
+ function parseRetryAfter(headers, now) {
343
+ const milliseconds = headers.get('retry-after-ms');
344
+ if (milliseconds !== null && /^\d+(?:\.\d+)?$/.test(milliseconds.trim())) {
345
+ const value = Number(milliseconds);
346
+ if (Number.isSafeInteger(value) && value >= 0)
347
+ return value;
348
+ }
349
+ const value = headers.get('retry-after');
350
+ if (!value)
351
+ return null;
352
+ if (/^\d+(?:\.\d+)?$/.test(value.trim())) {
353
+ const seconds = Number(value);
354
+ return Number.isSafeInteger(Math.ceil(seconds * 1000)) ? Math.ceil(seconds * 1000) : null;
355
+ }
356
+ const date = Date.parse(value);
357
+ return Number.isFinite(date) && date > now ? date - now : null;
358
+ }
359
+ function requestId(headers) {
360
+ for (const [name, source] of [['x-typesafe-request-id', 'typesafe'], ['x-request-id', 'legacy']]) {
361
+ const value = safeRequestId(headers.get(name));
362
+ if (value) {
363
+ return { requestId: value, requestIdSource: source };
364
+ }
365
+ }
366
+ return { requestId: null };
367
+ }
368
+ function safeRequestId(value) {
369
+ // A comma indicates merged duplicate headers; decline ambiguous correlation values.
370
+ return typeof value === 'string' && value.length > 0 && value.length <= MAX_REQUEST_ID_LENGTH
371
+ && /^[\x21-\x7e]+$/.test(value) && !value.includes(',') ? value : null;
372
+ }
373
+ function parseBoundedJson(text) {
374
+ // VM timeout interrupts synchronous parsing; input is a value, never source code.
375
+ // Clone into this realm so entry admission sees ordinary local JSON prototypes.
376
+ return structuredClone(runInNewContext('JSON.parse(input)', { input: text }, { timeout: MAX_PARSE_MS }));
377
+ }
378
+ function headersWithinLimit(headers) {
379
+ let bytes = 0;
380
+ for (const [name, value] of headers) {
381
+ bytes += name.length + value.length;
382
+ if (bytes > MAX_HEADER_BYTES)
383
+ return false;
384
+ }
385
+ return true;
386
+ }
387
+ async function readBoundedBody(response, signal) {
388
+ const declared = response.headers.get('content-length');
389
+ if (declared && /^\d+$/.test(declared) && Number(declared) > MAX_BODY_BYTES)
390
+ throw new Error('response too large');
391
+ if (!response.body)
392
+ return '';
393
+ const reader = response.body.getReader();
394
+ const chunks = [];
395
+ let total = 0;
396
+ let onAbort = () => undefined;
397
+ const aborted = new Promise((_, reject) => {
398
+ if (signal.aborted)
399
+ reject(new Error('aborted'));
400
+ else {
401
+ onAbort = () => reject(new Error('aborted'));
402
+ signal.addEventListener('abort', onAbort, { once: true });
403
+ }
404
+ });
405
+ try {
406
+ while (true) {
407
+ const part = await Promise.race([reader.read(), aborted]);
408
+ if (part.done)
409
+ break;
410
+ total += part.value.byteLength;
411
+ if (total > MAX_BODY_BYTES)
412
+ throw new Error('response too large');
413
+ chunks.push(part.value);
414
+ }
415
+ const bytes = new Uint8Array(total);
416
+ let offset = 0;
417
+ for (const chunk of chunks) {
418
+ bytes.set(chunk, offset);
419
+ offset += chunk.byteLength;
420
+ }
421
+ return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
422
+ }
423
+ finally {
424
+ signal.removeEventListener('abort', onAbort);
425
+ void reader.cancel().catch(() => undefined);
426
+ reader.releaseLock();
427
+ }
428
+ }
429
+ async function systemResolveAddresses(hostname) {
430
+ return (await lookup(hostname, { all: true })).map(address => address.address);
431
+ }
432
+ async function authorizeEndpoint(endpoint, allowedOrigins, resolveAddresses) {
433
+ const url = new URL(endpoint);
434
+ if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash || url.port && url.port !== '443')
435
+ throw new Error('unsafe endpoint');
436
+ if (url.origin === new URL(JEV_ENDPOINT).origin)
437
+ return null;
438
+ if (isIP(url.hostname))
439
+ throw new Error('literal endpoint address');
440
+ if (!allowedOrigins.some(origin => {
441
+ try {
442
+ const approved = new URL(origin);
443
+ return approved.protocol === 'https:' && !approved.username && !approved.password && !approved.search && !approved.hash
444
+ && approved.pathname === '/' && approved.origin === url.origin;
445
+ }
446
+ catch {
447
+ return false;
448
+ }
449
+ }))
450
+ throw new Error('unapproved endpoint');
451
+ const addresses = await resolveAddresses(url.hostname);
452
+ if (!addresses.length || addresses.some(address => !publicIpv4(address)))
453
+ throw new Error('unsafe endpoint address');
454
+ return { address: addresses[0], family: 4 };
455
+ }
456
+ function publicIpv4(address) {
457
+ if (isIP(address) !== 4)
458
+ return false; // IPv6 is denied until its full special-use range policy is implemented.
459
+ const [a, b, c] = address.split('.').map(Number);
460
+ if (a === 0 || a === 10 || a === 127 || a >= 224 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31
461
+ || a === 192 && (b === 168 || b === 0) || a === 100 && b >= 64 && b <= 127
462
+ || a === 198 && (b === 18 || b === 19 || b === 51 && c === 100) || a === 203 && b === 0 && c === 113)
463
+ return false;
464
+ return true;
465
+ }
466
+ async function pinnedHttpsFetch(url, init, pin) {
467
+ return new Promise((resolve, reject) => {
468
+ const headers = init.headers;
469
+ const outgoing = httpsRequest(url, {
470
+ method: 'POST', headers, maxHeaderSize: MAX_HEADER_BYTES, agent: false,
471
+ servername: url.hostname, rejectUnauthorized: true,
472
+ lookup: (hostname, _options, callback) => {
473
+ if (hostname !== url.hostname) {
474
+ callback(new Error('hostname mismatch'), '', 4);
475
+ return;
476
+ }
477
+ callback(null, pin.address, pin.family);
478
+ },
479
+ }, incoming => {
480
+ try {
481
+ let stream = incoming;
482
+ const encoding = incoming.headers['content-encoding'];
483
+ if (encoding === 'gzip')
484
+ stream = incoming.pipe(createGunzip());
485
+ else if (encoding === 'deflate')
486
+ stream = incoming.pipe(createInflate());
487
+ else if (encoding === 'br')
488
+ stream = incoming.pipe(createBrotliDecompress());
489
+ else if (encoding && encoding !== 'identity')
490
+ throw new JevTransportResponseError();
491
+ const responseHeaders = new Headers();
492
+ for (let index = 0; index < incoming.rawHeaders.length; index += 2) {
493
+ responseHeaders.append(incoming.rawHeaders[index], incoming.rawHeaders[index + 1]);
494
+ }
495
+ const status = incoming.statusCode ?? 502;
496
+ const noBody = status === 204 || status === 205 || status === 304;
497
+ const response = new Response(noBody ? null : Readable.toWeb(stream), {
498
+ status, headers: responseHeaders,
499
+ });
500
+ Object.defineProperty(response, 'url', { value: url.toString() });
501
+ resolve(response);
502
+ }
503
+ catch (error) {
504
+ incoming.destroy();
505
+ reject(error instanceof JevTransportResponseError ? error : new JevTransportResponseError());
506
+ }
507
+ });
508
+ outgoing.on('error', reject);
509
+ const onAbort = () => { outgoing.destroy(new DOMException('Aborted', 'AbortError')); };
510
+ init.signal?.addEventListener('abort', onAbort, { once: true });
511
+ outgoing.on('close', () => init.signal?.removeEventListener('abort', onAbort));
512
+ outgoing.end(init.body);
513
+ });
514
+ }
515
+ //# sourceMappingURL=jev.js.map