@typescriptprime/securereq 1.0.1 → 1.1.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 CHANGED
@@ -6,6 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // sources/index.ts
8
8
  import * as HTTPS from "node:https";
9
+ import * as HTTP2 from "node:http2";
9
10
  import * as TLS from "node:tls";
10
11
  import * as Process from "node:process";
11
12
 
@@ -4241,6 +4242,7 @@ async function HTTPSRequest(Url, Options) {
4241
4242
  Ciphers: ["TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"],
4242
4243
  KeyExchanges: ["X25519MLKEM768", "X25519"]
4243
4244
  },
4245
+ HttpMethod: "GET",
4244
4246
  HttpHeaders: {
4245
4247
  "User-Agent": `node/${Process.version} ${Process.platform} ${Process.arch} workspace/false`
4246
4248
  }
@@ -4258,6 +4260,7 @@ async function HTTPSRequest(Url, Options) {
4258
4260
  KeyExchanges: array(string2()).optional()
4259
4261
  }).partial().optional(),
4260
4262
  HttpHeaders: record(string2(), string2()).optional(),
4263
+ HttpMethod: _enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional(),
4261
4264
  ExpectedAs: _enum(["JSON", "String", "ArrayBuffer"]).optional()
4262
4265
  }).parseAsync(Options ?? {});
4263
4266
  if (MergedOptions.TLS?.IsHTTPSEnforced && Url.protocol !== "https:") {
@@ -4274,7 +4277,8 @@ async function HTTPSRequest(Url, Options) {
4274
4277
  minVersion: MergedOptions.TLS?.MinTLSVersion,
4275
4278
  maxVersion: MergedOptions.TLS?.MaxTLSVersion,
4276
4279
  ciphers: MergedOptions.TLS?.Ciphers?.join(":"),
4277
- ecdhCurve: MergedOptions.TLS?.KeyExchanges?.join(":")
4280
+ ecdhCurve: MergedOptions.TLS?.KeyExchanges?.join(":"),
4281
+ method: MergedOptions.HttpMethod
4278
4282
  }, (Res) => {
4279
4283
  const Chunks = [];
4280
4284
  Res.on("data", (Chunk) => {
@@ -4311,7 +4315,116 @@ async function HTTPSRequest(Url, Options) {
4311
4315
  });
4312
4316
  return HTTPSResponse;
4313
4317
  }
4318
+ async function HTTPS2Request(Url, Options) {
4319
+ const DefaultOptions = {
4320
+ TLS: {
4321
+ IsHTTPSEnforced: true,
4322
+ MinTLSVersion: "TLSv1.3",
4323
+ MaxTLSVersion: "TLSv1.3",
4324
+ Ciphers: ["TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"],
4325
+ KeyExchanges: ["X25519MLKEM768", "X25519"]
4326
+ },
4327
+ HttpHeaders: {
4328
+ "User-Agent": `node/${Process.version} ${Process.platform} ${Process.arch} workspace/false`
4329
+ },
4330
+ HttpMethod: "GET"
4331
+ };
4332
+ const MergedOptions = { ...DefaultOptions, ...Options ?? {} };
4333
+ if (Url instanceof URL === false) {
4334
+ throw new TypeError("Url must be an instance of URL");
4335
+ }
4336
+ await strictObject({
4337
+ TLS: strictObject({
4338
+ IsHTTPSEnforced: boolean2().optional(),
4339
+ MinTLSVersion: _enum(["TLSv1.2", "TLSv1.3"]).optional(),
4340
+ MaxTLSVersion: _enum(["TLSv1.2", "TLSv1.3"]).optional(),
4341
+ Ciphers: array(string2().refine((Cipher) => TLS.getCiphers().map((C) => C.toLowerCase()).includes(Cipher.toLowerCase()))).optional(),
4342
+ KeyExchanges: array(string2()).optional()
4343
+ }).partial().optional(),
4344
+ HttpHeaders: record(string2(), string2()).optional(),
4345
+ ExpectedAs: _enum(["JSON", "String", "ArrayBuffer"]).optional(),
4346
+ HttpMethod: _enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional()
4347
+ }).parseAsync(Options ?? {});
4348
+ if (MergedOptions.TLS?.IsHTTPSEnforced && Url.protocol !== "https:") {
4349
+ throw new Error("HTTPS is enforced, but the URL protocol is not HTTPS");
4350
+ }
4351
+ const ExpectedAs = Options?.ExpectedAs ?? (Url.pathname.endsWith(".json") ? "JSON" : Url.pathname.endsWith(".txt") ? "String" : "ArrayBuffer");
4352
+ const HTTPSResponse = await new Promise((Resolve, Reject) => {
4353
+ const NormalizedHeaders = Object.fromEntries(Object.entries(MergedOptions.HttpHeaders ?? {}).map(([Key, Value]) => [Key.toLowerCase(), Value]));
4354
+ const HTTP2Session = HTTP2.connect(`https://${Url.hostname}${Url.port ? `:${Url.port}` : ""}`, {
4355
+ createConnection: () => TLS.connect({
4356
+ host: Url.hostname,
4357
+ port: Number(Url.port || 443),
4358
+ servername: Url.hostname,
4359
+ minVersion: MergedOptions.TLS?.MinTLSVersion,
4360
+ maxVersion: MergedOptions.TLS?.MaxTLSVersion,
4361
+ ciphers: MergedOptions.TLS?.Ciphers?.join(":"),
4362
+ ecdhCurve: MergedOptions.TLS?.KeyExchanges?.join(":"),
4363
+ ALPNProtocols: ["h2"]
4364
+ })
4365
+ });
4366
+ HTTP2Session.on("error", (Error2) => {
4367
+ Reject(Error2);
4368
+ });
4369
+ const RequestHeaders = {
4370
+ ":method": MergedOptions.HttpMethod,
4371
+ ":path": Url.pathname + Url.search,
4372
+ ":scheme": "https",
4373
+ ":authority": Url.host,
4374
+ ...NormalizedHeaders
4375
+ };
4376
+ const Request = HTTP2Session.request(RequestHeaders);
4377
+ const Chunks = [];
4378
+ let StatusCode = 0;
4379
+ let ResponseHeaders = {};
4380
+ Request.on("response", (Headers) => {
4381
+ StatusCode = Number(Headers[":status"] ?? 0);
4382
+ ResponseHeaders = Object.fromEntries(Object.entries(Headers).filter(([Key]) => !Key.startsWith(":")).map(([Key, Value]) => {
4383
+ if (Array.isArray(Value)) {
4384
+ return [Key, Value.map((Item) => Item?.toString())];
4385
+ }
4386
+ return [Key, Value?.toString()];
4387
+ }));
4388
+ });
4389
+ Request.on("data", (Chunk) => {
4390
+ Chunks.push(Chunk.buffer.slice(Chunk.byteOffset, Chunk.byteOffset + Chunk.byteLength));
4391
+ });
4392
+ Request.on("end", () => {
4393
+ const BodyBuffer = ConcatArrayBuffers(Chunks);
4394
+ let Body;
4395
+ switch (ExpectedAs) {
4396
+ case "JSON":
4397
+ try {
4398
+ Body = JSON.parse(new TextDecoder("utf-8").decode(BodyBuffer));
4399
+ } catch (Error2) {
4400
+ HTTP2Session.close();
4401
+ return Reject(new Error2("Failed to parse JSON response body"));
4402
+ }
4403
+ break;
4404
+ case "String":
4405
+ Body = new TextDecoder("utf-8").decode(BodyBuffer);
4406
+ break;
4407
+ case "ArrayBuffer":
4408
+ Body = BodyBuffer;
4409
+ break;
4410
+ }
4411
+ HTTP2Session.close();
4412
+ Resolve({
4413
+ StatusCode,
4414
+ Headers: ResponseHeaders,
4415
+ Body
4416
+ });
4417
+ });
4418
+ Request.on("error", (Error2) => {
4419
+ HTTP2Session.close();
4420
+ Reject(Error2);
4421
+ });
4422
+ Request.end();
4423
+ });
4424
+ return HTTPSResponse;
4425
+ }
4314
4426
  export {
4427
+ HTTPS2Request,
4315
4428
  HTTPSRequest
4316
4429
  };
4317
4430
  //# sourceMappingURL=index.js.map