@farthershore/backend 0.20.0 → 0.21.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.
@@ -1,154 +1,6 @@
1
1
  import { createRequire as __createRequire } from "node:module";const require=__createRequire(import.meta.url);
2
2
 
3
3
  // src/generated/runtime-contract.ts
4
- var RUNTIME_CONTRACT_VERSION = 1;
5
- var RUNTIME_TOKEN_ENV = "FS_RUNTIME_TOKEN";
6
- var RUNTIME_TOKEN_CONTRACT = {
7
- environmentVariable: "FS_RUNTIME_TOKEN",
8
- prefixes: {
9
- live: "fsrt_live_",
10
- test: "fsrt_test_"
11
- },
12
- opaque: true,
13
- storage: "sha256-hash-only",
14
- lastFour: true,
15
- capabilities: ["gateway_verification", "metering", "health", "tunnel"]
16
- };
17
- var RUNTIME_BOOTSTRAP_CONTRACT = {
18
- method: "POST",
19
- path: "/v1/runtime/bootstrap",
20
- authorization: "Bearer fsrt_...",
21
- request: {
22
- instanceId: "string?",
23
- sdkVersion: "string?",
24
- sdkLanguage: "string?"
25
- },
26
- response: {
27
- product: {
28
- id: "string",
29
- slug: "string"
30
- },
31
- backend: {
32
- id: "string",
33
- slug: "string",
34
- name: "string"
35
- },
36
- environment: {
37
- id: "string?",
38
- kind: "live | test"
39
- },
40
- capabilities: "string[]",
41
- verification: {
42
- required: "boolean",
43
- jwksUrl: "string",
44
- clockSkewSeconds: "number",
45
- replayWindowSeconds: "number",
46
- headerNames: "object"
47
- },
48
- metering: {
49
- enabled: "boolean",
50
- endpoint: "string",
51
- credential: "string",
52
- allowedMeters: "string[]",
53
- allowedRoutes: "string[]",
54
- perEventMax: "number"
55
- },
56
- transport: {
57
- mode: "direct | tunnel",
58
- runner: "embedded | sidecar | null",
59
- originUrl: "string?",
60
- originHostname: "string?",
61
- localTarget: "string?",
62
- cloudflared: "object?"
63
- },
64
- routes: "object[]",
65
- policyVersion: "string",
66
- refreshAfterSeconds: "number"
67
- }
68
- };
69
- var RUNTIME_SIGNING_CONTRACT = {
70
- algorithm: "Ed25519",
71
- encoding: "base64url",
72
- keyMaterial: "service-jwt-jwks",
73
- canonicalString: {
74
- description: "Byte-exact, language-neutral serialization of the signed claim set. Fields are emitted in the FIXED order below, one per line, each as `name:value`, joined by a single newline (\\n, U+000A). NO trailing newline. The serialization depends on neither JSON key ordering nor any Node.js Buffer/serialization detail \u2014 only UTF-8 byte encoding of the field values. Empty/absent values are emitted as the empty string after the colon. Go/Python/Java/Rust reproduce this identically.",
75
- fieldSeparator: "\n",
76
- keyValueSeparator: ":",
77
- trailingNewline: false,
78
- fieldEncoding: "utf-8",
79
- fields: [
80
- "method",
81
- "path",
82
- "query",
83
- "body-hash",
84
- "request-id",
85
- "timestamp",
86
- "business-id",
87
- "backend-id",
88
- "route-id",
89
- "policy-version",
90
- "context-hash"
91
- ],
92
- fieldRules: {
93
- method: "Uppercased HTTP method (e.g. GET, POST).",
94
- path: "Request path, percent-encoded as received, no host, no query string. Always begins with '/'.",
95
- query: "The request's query string bytes VERBATIM, after the caller has stripped the URL's single leading '?' delimiter. Use the RAW wire query exactly as received \u2014 NO sorting, NO filtering, NO re-stripping a leading '?', NO dropping empty pairs, NO re-encoding. The signature binds to the exact query bytes: any reorder, added/removed/relocated pair, or re-encoding changes the bytes and MUST fail verification. Every SDK verifier MUST read the raw wire query (never a re-parsed/re-serialized form, which could reorder or re-encode and would then fail legitimate requests). Any normalization (sorting by name or value, dropping/moving empty pairs, re-stripping '?') is FORBIDDEN \u2014 each collapses distinct wire queries under one signature. Empty string when there is no query.",
96
- "body-hash": "Lowercase hex SHA-256 of the RAW request body bytes. For an empty body, the SHA-256 of zero bytes (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855). Streaming-exempt requests use the literal token 'STREAM'.",
97
- "request-id": "Opaque unique request id minted by the gateway (also the replay-cache nonce).",
98
- timestamp: "Integer Unix epoch seconds (UTC) at signing time, as a base-10 string with no padding.",
99
- "business-id": "Business id the request is routed to.",
100
- "backend-id": "Backend id the route binds to.",
101
- "route-id": "Resolved route id; empty string if the route is unresolved.",
102
- "policy-version": "Tenant artifact / policy version the gateway signed under.",
103
- "context-hash": "Lowercase hex SHA-256 of the presented X-Fs-Context JWT string (identity-context binding). For a request with no signed context, the SHA-256 of the empty string (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855). Binds the identity context into the request signature so one verification covers both."
104
- }
105
- }
106
- };
107
- var RUNTIME_CANONICAL_FIELDS = [
108
- "method",
109
- "path",
110
- "query",
111
- "body-hash",
112
- "request-id",
113
- "timestamp",
114
- "business-id",
115
- "backend-id",
116
- "route-id",
117
- "policy-version",
118
- "context-hash"
119
- ];
120
- var RUNTIME_BODY_HASH_CONTRACT = {
121
- algorithm: "SHA-256",
122
- encoding: "hex-lower",
123
- source: "raw-request-bytes",
124
- emptyBodyHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
125
- maxBodyBytes: 10485760,
126
- streamingExemptToken: "STREAM",
127
- streamingExemptContentTypes: [
128
- "text/event-stream",
129
- "application/octet-stream",
130
- "multipart/form-data"
131
- ],
132
- overMaxStatus: 413
133
- };
134
- var RUNTIME_HEADERS = {
135
- signature: "x-fs-signature",
136
- keyId: "x-fs-key-id",
137
- requestId: "x-fs-request-id",
138
- timestamp: "x-fs-timestamp",
139
- businessId: "x-fs-business-id",
140
- backendId: "x-fs-backend-id",
141
- routeId: "x-fs-route-id",
142
- policyVersion: "x-fs-policy-version",
143
- bodyHash: "x-fs-body-hash"
144
- };
145
- var RUNTIME_REPLAY_CONTRACT = {
146
- windowSeconds: 300,
147
- clockSkewSeconds: 5,
148
- nonce: "x-fs-request-id",
149
- nonceCache: "bounded-lru",
150
- policy: "fail-closed"
151
- };
152
4
  var RUNTIME_ERROR_CODES = {
153
5
  missingSignature: "missing_signature",
154
6
  malformedSignature: "malformed_signature",
@@ -169,40 +21,19 @@ var RUNTIME_ERROR_CODES = {
169
21
  serviceSubjectRequired: "service_subject_required",
170
22
  surfaceNotAllowed: "surface_not_allowed"
171
23
  };
172
- var RUNTIME_METERING_CONTRACT = {
173
- endpoint: "/v1/metering/events",
174
- method: "POST",
175
- credential: "reusable-bearer",
176
- event: {
177
- event_id: "string",
178
- business_id: "string",
179
- backend_id: "string",
180
- route_id: "string?",
181
- request_id: "string?",
182
- requestId: "string?",
183
- subscriptionId: "string",
184
- nonce: "string?",
185
- meter: "string",
186
- qty: "number",
187
- timestamp: "string"
188
- },
189
- postStreamEvent: {
190
- requestId: "string",
191
- subscriptionId: "string?",
192
- nonce: "string",
193
- meters: "Record<string, number>",
194
- creditUnitsConsumed: "Record<string, number>?",
195
- measureContext: "Record<string, unknown>?",
196
- signature: "string"
197
- },
198
- idempotencyKey: "event_id",
199
- delivery: "at-least-once",
200
- billingOnly: true,
201
- realtimeEnforced: false,
202
- postStreamBillingOnly: true,
203
- postStreamRealtimeEnforced: false,
204
- postStreamTrustModel: "HMAC-attested and bound to one served postStreamBilling gateway request. Core writes one billable UsageEvent using the served plan and time. The callback never mutates Durable Object enforcement windows.",
205
- trustModel: "upstream-reported values are NOT cryptographically attested; a buggy or compromised upstream can self-report arbitrary values for its OWN product only. Core enforces allowedMeters/allowedRoutes from the authoritative token record at ingest, applies a per-event sanity max (perEventMax), and raises an implausible-volume alert."
24
+ var RUNTIME_BODY_HASH_CONTRACT = {
25
+ algorithm: "SHA-256",
26
+ encoding: "hex-lower",
27
+ source: "raw-request-bytes",
28
+ emptyBodyHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
29
+ maxBodyBytes: 10485760,
30
+ streamingExemptToken: "STREAM",
31
+ streamingExemptContentTypes: [
32
+ "text/event-stream",
33
+ "application/octet-stream",
34
+ "multipart/form-data"
35
+ ],
36
+ overMaxStatus: 413
206
37
  };
207
38
  var RUNTIME_RESPONSE_METERING_CONTRACT = {
208
39
  headers: {
@@ -224,14 +55,18 @@ var RUNTIME_RESPONSE_METERING_CONTRACT = {
224
55
  payload: {
225
56
  method: "string",
226
57
  path: "string",
227
- rawDimsUnits: "Record<string, number>",
58
+ rawDimsUnits: "Record<string, number>?",
228
59
  measureContext: "Record<string, unknown>?",
229
- creditUnitsConsumed: "Record<string, number>?"
60
+ creditUnitsConsumed: "Record<string, number>?",
61
+ measurementsVersion: "1?",
62
+ measurements: "Array<{ meter: string; values: Record<string, number>; dims?: Record<string, string> }>?",
63
+ quote: "{ currency: string; amountNanos: string }?"
230
64
  },
231
65
  errors: {
232
66
  missingToken: "missing_token",
233
67
  invalidMeterKey: "invalid_meter_key",
234
- invalidMeterValue: "invalid_meter_value"
68
+ invalidMeterValue: "invalid_meter_value",
69
+ invalidQuote: "invalid_quote"
235
70
  },
236
71
  httpAdapter: {
237
72
  input: "Request",
@@ -241,58 +76,8 @@ var RUNTIME_RESPONSE_METERING_CONTRACT = {
241
76
  gatewayStripsInternalHeaders: true
242
77
  }
243
78
  };
244
- var RUNTIME_HEALTH_CONTRACT = {
245
- endpoint: "/v1/runtime/health",
246
- method: "POST",
247
- request: {
248
- instanceId: "string?",
249
- status: "starting | ready | degraded | stopping"
250
- },
251
- readinessStates: ["UNKNOWN", "WAITING", "READY", "DEGRADED", "OFFLINE"],
252
- checks: [
253
- "runtime_token_valid",
254
- "bootstrapped",
255
- "tunnel_running",
256
- "signed_request_2xx",
257
- "unsigned_request_401",
258
- "stale_signature_401",
259
- "wrong_route_401",
260
- "metering_observed"
261
- ],
262
- report: {
263
- runtimeToken: "boolean",
264
- bootstrap: "boolean",
265
- tunnel: "string?",
266
- verification: "boolean",
267
- metering: "boolean"
268
- }
269
- };
270
- var RUNTIME_TRANSPORT_CONTRACT = {
271
- modes: {
272
- direct: "Gateway fetches the builder's public origin URL; the SDK middleware fail-closed-verifies every request via Ed25519 request signing. Provisions zero Cloudflare objects. Available on all tiers; also the dev path.",
273
- tunnel: "Farther Shore provisions a private outbound Cloudflare Tunnel; no inbound port. The Production-secure tier. Consumes Cloudflare tunnel/route slots."
274
- },
275
- runners: {
276
- embedded: "fs.start() supervises cloudflared as a child process (default DX).",
277
- sidecar: "Vanilla cloudflare/cloudflared container beside the app (production / non-Node)."
278
- },
279
- channelTrust: ["tunnel"],
280
- requestTrust: "x-fs-signature",
281
- invariant: "Channel trust (tunnel) and request trust (the X-FS-* signature) are distinct layers; both always apply. CF-Access-* headers are transport-layer only and are IGNORED by the SDK."
282
- };
283
79
  export {
284
80
  RUNTIME_BODY_HASH_CONTRACT,
285
- RUNTIME_BOOTSTRAP_CONTRACT,
286
- RUNTIME_CANONICAL_FIELDS,
287
- RUNTIME_CONTRACT_VERSION,
288
81
  RUNTIME_ERROR_CODES,
289
- RUNTIME_HEADERS,
290
- RUNTIME_HEALTH_CONTRACT,
291
- RUNTIME_METERING_CONTRACT,
292
- RUNTIME_REPLAY_CONTRACT,
293
- RUNTIME_RESPONSE_METERING_CONTRACT,
294
- RUNTIME_SIGNING_CONTRACT,
295
- RUNTIME_TOKEN_CONTRACT,
296
- RUNTIME_TOKEN_ENV,
297
- RUNTIME_TRANSPORT_CONTRACT
82
+ RUNTIME_RESPONSE_METERING_CONTRACT
298
83
  };