Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 28x 28x 28x 9x 9x 5x | /**
* @module
*
* @author Bayu Dwiyan Satria
* @version 1.0.0
* @since 1.3.0
*/
import { Binding } from '@/core/bindings/Binding'
import { lazySettings } from '@/utils/lazySettings'
import { VpcServiceSettings } from '@/types/VpcServiceSettings'
import type { CloudflareEnv } from '@/types/CloudflareEnv'
/**
* Accessor for a VPC Service binding.
*
* @remarks
* Reaches one service on a private network — an internal API, a database's HTTP
* front, something in an AWS VPC or on a rack — without that service being
* exposed to the internet. Traffic goes through a Cloudflare Tunnel, so the
* private side needs no inbound firewall rule at all.
*
* The destination is fixed in `wrangler.json` as a `service_id`, which is the
* property worth understanding rather than working around: a Worker holding
* this binding can reach exactly one private endpoint, and no request it
* handles can talk it into reaching another. {@link VpcNetworkBinding} trades
* that away deliberately, and the choice between them is a security decision
* before it is an ergonomic one.
*
* ## `Fetcher`, and no invented type
*
* The binding offers `fetch` and nothing else, which is `Fetcher` structurally
* — the same reasoning that types {@link BrowserBinding}. That matters more
* here than it did there, because `@cloudflare/workers-types` declares nothing
* for Workers VPC at the version this package pins. Naming `Fetcher` means this
* class describes no shape of its own while the product is in beta.
*
* {@link VpcNetworkBinding} could not manage the same trick, and says so.
*
* @example
* ```ts
* const internal = new VpcServiceBinding()
*
* const response = await internal.fetch(env, 'https://internal-api.example.com/positions')
* ```
*
* @class
*
* @author Bayu Dwiyan Satria
* @version 1.0.0
* @since 1.3.0
*/
export class VpcServiceBinding<E extends CloudflareEnv = CloudflareEnv> extends Binding<Fetcher, E> {
/**
* Constructs a VpcServiceBinding instance.
*
* @param settings Resolved settings. Defaults to `resolve('vpcService')`, so callers
* normally construct this with no arguments at all.
*/
constructor(settings?: VpcServiceSettings) {
const settle = lazySettings<VpcServiceSettings>('vpcService', settings)
super(() => settle().binding)
}
/**
* Sends a request to the bound private service.
*
* @remarks
* The hostname in the URL is resolved on the private side, so it needs to be
* the name that side answers to rather than anything public. The binding
* decides where the request goes regardless; the URL supplies the path,
* method and body.
*
* Failures arrive as they would from any `fetch` — an unreachable tunnel is a
* rejected promise, not a status code — so a caller that must not fail with
* the private side should catch here rather than inspect the response.
*
* @param env The Worker environment.
* @param resource The request, as a URL, string, or `Request`.
* @param options Standard request options.
* @returns The response from the private service.
* @throws {@link MissingBindingError} When the VPC Service binding is absent.
*/
public async fetch(env: E, resource: string | URL | Request, options?: RequestInit): Promise<Response> {
return await this.resolve(env).fetch(resource as RequestInfo, options)
}
}
|