gigadrive 2.15.0 → 2.16.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.mjs CHANGED
@@ -9,7 +9,7 @@ import { Effect as Effect29, Layer, LogLevel, Logger } from "effect";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "gigadrive",
12
- version: "2.15.0",
12
+ version: "2.16.0",
13
13
  repository: {
14
14
  type: "git",
15
15
  url: "https://github.com/Gigadrive/sdk.git",
@@ -3063,6 +3063,7 @@ var describeMicroVm = (vm, now = Date.now()) => {
3063
3063
  `Size: ${vm.vcpus} vCPU, ${formatMemory(vm.memoryMb)} memory, ${formatMemory(vm.diskMb)} disk`,
3064
3064
  `Region: ${vm.region}`,
3065
3065
  `Network: ${vm.network.egress === "deny" ? "outbound traffic blocked" : vm.network.allow && vm.network.allow.length > 0 ? `only ${vm.network.allow.join(", ")}` : "internet access"}`,
3066
+ ...(vm.network.inject ?? []).map((rule) => `Injects: ${rule.headers.join(", ")} for ${rule.domain}`),
3066
3067
  `Previews: ${vm.network.previews === "private" ? "private (preview token required)" : "public"}`,
3067
3068
  `Application: ${vm.applicationId}`,
3068
3069
  `Created: ${vm.createdAt}`
@@ -3373,6 +3374,26 @@ var parseVolumeFlags = (values) => Effect22.gen(function* () {
3373
3374
  }
3374
3375
  return volumes;
3375
3376
  });
3377
+ var parseInjectFlags = (values) => Effect22.gen(function* () {
3378
+ const rules = /* @__PURE__ */ new Map();
3379
+ for (const value of values) {
3380
+ const colon = value.indexOf(":");
3381
+ const equals = value.indexOf("=", colon + 1);
3382
+ const domain = colon > 0 ? value.slice(0, colon).trim().toLowerCase() : "";
3383
+ const name = colon > 0 && equals > colon ? value.slice(colon + 1, equals).trim() : "";
3384
+ if (domain === "" || name === "" || equals === value.length - 1) {
3385
+ return yield* new InvalidMicroVmOptionsError({
3386
+ // The entry is not echoed: it may hold the credential.
3387
+ message: '--inject must be DOMAIN:HEADER=VALUE, such as "api.openai.com:Authorization=Bearer $OPENAI_API_KEY".'
3388
+ });
3389
+ }
3390
+ rules.set(domain, { ...rules.get(domain), [name]: value.slice(equals + 1) });
3391
+ }
3392
+ if (rules.size > 8) {
3393
+ return yield* new InvalidMicroVmOptionsError({ message: "--inject takes at most 8 domains." });
3394
+ }
3395
+ return [...rules].map(([domain, headers]) => ({ domain, headers }));
3396
+ });
3376
3397
  var checkEgressFlags = (denyEgress, allowEgress) => Effect22.gen(function* () {
3377
3398
  if (denyEgress && allowEgress.length > 0) {
3378
3399
  return yield* new InvalidMicroVmOptionsError({
@@ -3403,6 +3424,10 @@ var createInput = (flags) => Effect22.gen(function* () {
3403
3424
  if (badPort !== void 0) {
3404
3425
  return yield* new InvalidMicroVmOptionsError({ message: `--port must be between 1 and 65535 (got ${badPort}).` });
3405
3426
  }
3427
+ const inject = yield* parseInjectFlags(flags.inject);
3428
+ if (inject.length > 0 && flags.denyEgress) {
3429
+ return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
3430
+ }
3406
3431
  const volumes = yield* parseVolumeFlags(flags.volumes);
3407
3432
  if (volumes.length > 0 && flags.pauseOnTimeout) {
3408
3433
  return yield* new InvalidMicroVmOptionsError({ message: "--volume cannot be combined with --pause-on-timeout." });
@@ -3424,11 +3449,12 @@ var createInput = (flags) => Effect22.gen(function* () {
3424
3449
  ...env ? { env } : {},
3425
3450
  ...metadata ? { metadata } : {},
3426
3451
  ...volumes.length > 0 ? { volumes } : {},
3427
- ...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 ? {
3452
+ ...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 || inject.length > 0 ? {
3428
3453
  network: {
3429
3454
  egress: flags.denyEgress ? "deny" : "allow",
3430
3455
  ...flags.privatePreviews ? { previews: "private" } : {},
3431
- ...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {}
3456
+ ...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
3457
+ ...inject.length > 0 ? { inject } : {}
3432
3458
  }
3433
3459
  } : {},
3434
3460
  ...Option14.match(flags.region, { onNone: () => ({}), onSome: (region) => ({ region }) })
@@ -3519,6 +3545,12 @@ var createCommand = Command12.make(
3519
3545
  ),
3520
3546
  Options7.repeated
3521
3547
  ),
3548
+ inject: Options7.text("inject").pipe(
3549
+ Options7.withDescription(
3550
+ "Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
3551
+ ),
3552
+ Options7.repeated
3553
+ ),
3522
3554
  pauseOnTimeout: Options7.boolean("pause-on-timeout").pipe(
3523
3555
  Options7.withDescription("Pause the microVM when its timeout ends instead of stopping it")
3524
3556
  ),
@@ -3888,15 +3920,31 @@ var updateMicroVmNetwork = (microvmId, flags) => Effect22.gen(function* () {
3888
3920
  });
3889
3921
  }
3890
3922
  yield* checkEgressFlags(flags.denyEgress, flags.allowEgress);
3923
+ const inject = yield* parseInjectFlags(flags.inject);
3924
+ if (inject.length > 0 && flags.denyEgress) {
3925
+ return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
3926
+ }
3927
+ if (flags.clearInject && (inject.length > 0 || flags.denyEgress)) {
3928
+ return yield* new InvalidMicroVmOptionsError({
3929
+ message: "--clear-inject cannot be combined with --inject or --deny-egress."
3930
+ });
3931
+ }
3891
3932
  const apiClient = yield* ApiClientService;
3892
3933
  const vm = yield* apiClient.request(
3893
3934
  (client) => client.microvms.updateNetwork(
3894
3935
  microvmId,
3895
- flags.denyEgress ? { egress: "deny" } : flags.allowEgress.length > 0 ? { egress: "allow", allow: flags.allowEgress.map((entry) => entry.trim()) } : { egress: "allow" }
3936
+ flags.denyEgress ? { egress: "deny" } : {
3937
+ egress: "allow",
3938
+ ...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
3939
+ ...inject.length > 0 || flags.clearInject ? { inject } : {}
3940
+ }
3896
3941
  )
3897
3942
  );
3898
3943
  const reach = vm.network.egress === "deny" ? "no outbound traffic" : vm.network.allow ? vm.network.allow.join(", ") : "the whole internet";
3899
3944
  yield* Console12.log(`${vm.id} now reaches ${reach}.`);
3945
+ for (const rule of vm.network.inject ?? []) {
3946
+ yield* Console12.log(`Adds ${rule.headers.join(", ")} to HTTPS requests to ${rule.domain}.`);
3947
+ }
3900
3948
  return vm;
3901
3949
  });
3902
3950
  var networkCommand = Command12.make(
@@ -3912,6 +3960,15 @@ var networkCommand = Command12.make(
3912
3960
  ),
3913
3961
  allowAllEgress: Options7.boolean("allow-all-egress").pipe(
3914
3962
  Options7.withDescription("Reach the whole internet again (private networks stay blocked)")
3963
+ ),
3964
+ inject: Options7.text("inject").pipe(
3965
+ Options7.withDescription(
3966
+ "Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
3967
+ ),
3968
+ Options7.repeated
3969
+ ),
3970
+ clearInject: Options7.boolean("clear-inject").pipe(
3971
+ Options7.withDescription("Remove every header rule added with --inject")
3915
3972
  )
3916
3973
  },
3917
3974
  ({ microvmId, ...flags }) => updateMicroVmNetwork(microvmId, flags).pipe(Effect22.asVoid, reportErrors2("update the microVM network"))