@lovrozagar/honey 0.1.0 → 0.2.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/README.md +1596 -6
- package/dist/accepts.d.ts +6 -0
- package/dist/accepts.d.ts.map +1 -0
- package/dist/body-limit.d.ts +22 -0
- package/dist/body-limit.d.ts.map +1 -0
- package/dist/build/index.d.ts +42 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/client/error.d.ts +14 -0
- package/dist/client/error.d.ts.map +1 -0
- package/dist/client/http.d.ts +88 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/index.d.ts +22 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/sdk.d.ts +34 -0
- package/dist/client/sdk.d.ts.map +1 -0
- package/dist/client/sse.d.ts +10 -0
- package/dist/client/sse.d.ts.map +1 -0
- package/dist/client/types.d.ts +124 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/ws.d.ts +15 -0
- package/dist/client/ws.d.ts.map +1 -0
- package/dist/client-mcp/server.d.ts +10 -0
- package/dist/client-mcp/server.d.ts.map +1 -0
- package/dist/client-mcp/types.d.ts +16 -0
- package/dist/client-mcp/types.d.ts.map +1 -0
- package/dist/cloudflare/realtime.d.ts +30 -0
- package/dist/cloudflare/realtime.d.ts.map +1 -0
- package/dist/codegen-go-cli.d.ts +22 -0
- package/dist/codegen-go-cli.d.ts.map +1 -0
- package/dist/codegen-go.d.ts +29 -0
- package/dist/codegen-go.d.ts.map +1 -0
- package/dist/codegen-hash.d.ts +3 -0
- package/dist/codegen-hash.d.ts.map +1 -0
- package/dist/codegen-ir.d.ts +123 -0
- package/dist/codegen-ir.d.ts.map +1 -0
- package/dist/codegen-loaders.d.ts +12 -0
- package/dist/codegen-loaders.d.ts.map +1 -0
- package/dist/codegen-mcp.d.ts +13 -0
- package/dist/codegen-mcp.d.ts.map +1 -0
- package/dist/codegen-python.d.ts +21 -0
- package/dist/codegen-python.d.ts.map +1 -0
- package/dist/codegen-rust.d.ts +18 -0
- package/dist/codegen-rust.d.ts.map +1 -0
- package/dist/codegen-sanitize.d.ts +3 -0
- package/dist/codegen-sanitize.d.ts.map +1 -0
- package/dist/codegen-schema-naming.d.ts +22 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -0
- package/dist/codegen.d.ts +178 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/context.d.ts +56 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/cookie-sign.d.ts +3 -0
- package/dist/cookie-sign.d.ts.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cors.d.ts +13 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/crypto.d.ts +2 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/csrf.d.ts +9 -0
- package/dist/csrf.d.ts.map +1 -0
- package/dist/curl-logger.d.ts +33 -0
- package/dist/curl-logger.d.ts.map +1 -0
- package/dist/detect-runtime.d.ts +16 -0
- package/dist/detect-runtime.d.ts.map +1 -0
- package/dist/error.d.ts +21 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/errors.d.ts +40 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/etag.d.ts +9 -0
- package/dist/etag.d.ts.map +1 -0
- package/dist/feature-load.d.ts +3 -0
- package/dist/feature-load.d.ts.map +1 -0
- package/dist/go-type-emitter.d.ts +33 -0
- package/dist/go-type-emitter.d.ts.map +1 -0
- package/dist/honey-response.d.ts +82 -0
- package/dist/honey-response.d.ts.map +1 -0
- package/dist/i18n-slot.d.ts +7 -0
- package/dist/i18n-slot.d.ts.map +1 -0
- package/dist/i18n.d.ts +26 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.d.ts +470 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init.d.ts +7 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/input.d.ts +6 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/ip-restrict.d.ts +12 -0
- package/dist/ip-restrict.d.ts.map +1 -0
- package/dist/logger.d.ts +45 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/meta-spec.d.ts +81 -0
- package/dist/meta-spec.d.ts.map +1 -0
- package/dist/middleware.d.ts +60 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/node-request.d.ts +59 -0
- package/dist/node-request.d.ts.map +1 -0
- package/dist/node.d.ts +13 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/openapi/register.d.ts +3 -0
- package/dist/openapi/register.d.ts.map +1 -0
- package/dist/openapi/scalar.d.ts +12 -0
- package/dist/openapi/scalar.d.ts.map +1 -0
- package/dist/openapi/spec-factory.d.ts +31 -0
- package/dist/openapi/spec-factory.d.ts.map +1 -0
- package/dist/openapi/spec.d.ts +19 -0
- package/dist/openapi/spec.d.ts.map +1 -0
- package/dist/openapi/swagger.d.ts +12 -0
- package/dist/openapi/swagger.d.ts.map +1 -0
- package/dist/plugin.d.ts +167 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/powered-by.d.ts +7 -0
- package/dist/powered-by.d.ts.map +1 -0
- package/dist/pretty-json.d.ts +10 -0
- package/dist/pretty-json.d.ts.map +1 -0
- package/dist/proxy.d.ts +51 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/python-type-emitter.d.ts +11 -0
- package/dist/python-type-emitter.d.ts.map +1 -0
- package/dist/realtime/buffer.d.ts +18 -0
- package/dist/realtime/buffer.d.ts.map +1 -0
- package/dist/realtime/bus.d.ts +11 -0
- package/dist/realtime/bus.d.ts.map +1 -0
- package/dist/realtime/longpoll.d.ts +23 -0
- package/dist/realtime/longpoll.d.ts.map +1 -0
- package/dist/realtime/protocol.d.ts +50 -0
- package/dist/realtime/protocol.d.ts.map +1 -0
- package/dist/realtime/route.d.ts +42 -0
- package/dist/realtime/route.d.ts.map +1 -0
- package/dist/realtime/runtime.d.ts +74 -0
- package/dist/realtime/runtime.d.ts.map +1 -0
- package/dist/request-id.d.ts +12 -0
- package/dist/request-id.d.ts.map +1 -0
- package/dist/request-to-curl.d.ts +9 -0
- package/dist/request-to-curl.d.ts.map +1 -0
- package/dist/response.d.ts +57 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/rust-type-emitter.d.ts +32 -0
- package/dist/rust-type-emitter.d.ts.map +1 -0
- package/dist/secure-headers.d.ts +16 -0
- package/dist/secure-headers.d.ts.map +1 -0
- package/dist/serve-register.d.ts +2 -0
- package/dist/serve-register.d.ts.map +1 -0
- package/dist/serve-slot.d.ts +6 -0
- package/dist/serve-slot.d.ts.map +1 -0
- package/dist/serve.d.ts +21 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/server-timing.d.ts +9 -0
- package/dist/server-timing.d.ts.map +1 -0
- package/dist/static.d.ts +12 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/telemetry/otel.d.ts +59 -0
- package/dist/telemetry/otel.d.ts.map +1 -0
- package/dist/testing.d.ts +24 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/timeout.d.ts +7 -0
- package/dist/timeout.d.ts.map +1 -0
- package/dist/tree.d.ts +90 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/ts-type-emitter.d.ts +4 -0
- package/dist/ts-type-emitter.d.ts.map +1 -0
- package/dist/type-emitter.d.ts +8 -0
- package/dist/type-emitter.d.ts.map +1 -0
- package/dist/type-extractor.d.ts +39 -0
- package/dist/type-extractor.d.ts.map +1 -0
- package/dist/types.d.ts +451 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/validation.d.ts +18 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/ws/bun.d.ts +28 -0
- package/dist/ws/bun.d.ts.map +1 -0
- package/dist/ws/cloudflare.d.ts +55 -0
- package/dist/ws/cloudflare.d.ts.map +1 -0
- package/dist/ws/deno.d.ts +13 -0
- package/dist/ws/deno.d.ts.map +1 -0
- package/dist/ws/node.d.ts +10 -0
- package/dist/ws/node.d.ts.map +1 -0
- package/dist/yaml.d.ts +4 -0
- package/dist/yaml.d.ts.map +1 -0
- package/docs/api-ref/go.md +82 -82
- package/docs/api-ref/python.md +82 -82
- package/docs/api-ref/rust.md +82 -82
- package/docs/api-ref/typescript.md +82 -82
- package/docs/invalidate-spec.md +13 -13
- package/docs/meta-spec.md +513 -0
- package/docs/packaging.md +85 -0
- package/docs/sdk.md +87 -73
- package/package.json +195 -51
- package/src/body-limit.ts +2 -1
- package/src/build/index.ts +2 -9
- package/src/cli.ts +2 -3
- package/src/client/http.ts +204 -223
- package/src/client/index.ts +6 -14
- package/src/client/sdk.ts +24 -17
- package/src/client/types.ts +4 -9
- package/src/client/ws.ts +3 -5
- package/src/client-mcp/server.ts +1 -4
- package/src/cloudflare/realtime.ts +8 -10
- package/src/codegen-go-cli.ts +74 -67
- package/src/codegen-go.ts +71 -51
- package/src/codegen-ir.ts +16 -27
- package/src/codegen-loaders.ts +5 -8
- package/src/codegen-mcp.ts +9 -27
- package/src/codegen-python.ts +47 -27
- package/src/codegen-rust.ts +110 -66
- package/src/codegen-sanitize.ts +1 -7
- package/src/codegen-schema-naming.ts +8 -2
- package/src/codegen.ts +299 -196
- package/src/context.ts +91 -95
- package/src/cookie-sign.ts +5 -13
- package/src/cookie.ts +1 -2
- package/src/cors.ts +4 -6
- package/src/crypto.ts +1 -4
- package/src/csrf.ts +3 -3
- package/src/curl-logger.ts +14 -32
- package/src/detect-runtime.ts +1 -3
- package/src/errors.ts +1 -3
- package/src/etag.ts +3 -4
- package/src/go-type-emitter.ts +45 -40
- package/src/honey-response.ts +1 -3
- package/src/i18n.ts +3 -12
- package/src/index.ts +1168 -1412
- package/src/ip-restrict.ts +2 -1
- package/src/logger.ts +13 -13
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +111 -79
- package/src/node-request.ts +2 -1
- package/src/node.ts +9 -10
- package/src/openapi/register.ts +1 -2
- package/src/openapi/scalar.ts +9 -9
- package/src/openapi/spec-factory.ts +2 -2
- package/src/openapi/spec.ts +26 -19
- package/src/openapi/swagger.ts +9 -9
- package/src/plugin.ts +226 -256
- package/src/powered-by.ts +2 -1
- package/src/pretty-json.ts +2 -1
- package/src/proxy.ts +1 -3
- package/src/python-type-emitter.ts +37 -12
- package/src/realtime/route.ts +1 -1
- package/src/realtime/runtime.ts +9 -12
- package/src/request-id.ts +3 -4
- package/src/request-to-curl.ts +1 -4
- package/src/response.ts +150 -199
- package/src/rust-type-emitter.ts +66 -25
- package/src/secure-headers.ts +2 -1
- package/src/serve.ts +3 -12
- package/src/server-timing.ts +2 -1
- package/src/static.ts +3 -4
- package/src/telemetry/otel.ts +1 -6
- package/src/testing.ts +2 -11
- package/src/timeout.ts +2 -1
- package/src/tree.ts +12 -27
- package/src/ts-type-emitter.ts +71 -15
- package/src/type-emitter.ts +226 -237
- package/src/type-extractor.ts +260 -334
- package/src/types.ts +168 -68
- package/src/validation.ts +7 -30
- package/src/ws/bun.ts +2 -9
- package/src/ws/cloudflare.ts +13 -16
- package/src/ws/deno.ts +31 -40
- package/src/ws/node.ts +4 -19
package/src/types.ts
CHANGED
|
@@ -171,10 +171,7 @@ export type FieldError = {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/* shared frozen empty objects — avoid per-call {} allocations */
|
|
174
|
-
export const EMPTY_OBJ: Record<string, never> = Object.freeze(Object.create(null)) as Record<
|
|
175
|
-
string,
|
|
176
|
-
never
|
|
177
|
-
>
|
|
174
|
+
export const EMPTY_OBJ: Record<string, never> = Object.freeze(Object.create(null)) as Record<string, never>
|
|
178
175
|
export const EMPTY_FIELDS: Record<string, FieldError[]> = EMPTY_OBJ as Record<string, FieldError[]>
|
|
179
176
|
|
|
180
177
|
export type NormalizedIssue = {
|
|
@@ -233,9 +230,7 @@ export type InferOutput<T> = T extends {
|
|
|
233
230
|
|
|
234
231
|
/** Map input schema definitions to their inferred output types, dropping undefined keys */
|
|
235
232
|
export type InferInputMap<T> = {
|
|
236
|
-
[K in keyof T as T[K] extends undefined | null ? never : K]-?: InferOutput<
|
|
237
|
-
UnwrapInputSchema<NonNullable<T[K]>>
|
|
238
|
-
>
|
|
233
|
+
[K in keyof T as T[K] extends undefined | null ? never : K]-?: InferOutput<UnwrapInputSchema<NonNullable<T[K]>>>
|
|
239
234
|
}
|
|
240
235
|
|
|
241
236
|
/**
|
|
@@ -326,7 +321,7 @@ export type OutputSchemaDef = {
|
|
|
326
321
|
"application/octet-stream"?: StatusSchemaMap
|
|
327
322
|
"application/pdf"?: StatusSchemaMap
|
|
328
323
|
"application/xml"?: StatusSchemaMap
|
|
329
|
-
|
|
324
|
+
redirect?: RedirectSchemaMap
|
|
330
325
|
"text/csv"?: StatusSchemaMap
|
|
331
326
|
"text/event-stream"?: StatusSchemaMap
|
|
332
327
|
"text/html"?: StatusSchemaMap
|
|
@@ -372,6 +367,8 @@ export type OpenApiMeta = {
|
|
|
372
367
|
internal?: boolean
|
|
373
368
|
deprecated?: boolean
|
|
374
369
|
description?: string
|
|
370
|
+
/** Escape hatch — emitted verbatim at the highest precedence. Prefer a `.metaSpec()` entry. */
|
|
371
|
+
extensions?: Record<`x-${string}`, unknown>
|
|
375
372
|
invalidate?: readonly string[] | null
|
|
376
373
|
mcp?: boolean
|
|
377
374
|
operationId?: string
|
|
@@ -380,20 +377,156 @@ export type OpenApiMeta = {
|
|
|
380
377
|
tags?: string | string[]
|
|
381
378
|
}
|
|
382
379
|
|
|
380
|
+
/* ---- Meta spec (codegen-time policy: meta → OpenAPI operation) ---- */
|
|
381
|
+
|
|
382
|
+
/** Which operation kinds a policy entry applies to */
|
|
383
|
+
export type MetaSpecTarget = "both" | "http" | "ws"
|
|
384
|
+
|
|
385
|
+
/** Where a schema-derived policy entry reads its source key from */
|
|
386
|
+
export type MetaSpecSchemaSource =
|
|
387
|
+
| "input.cookies"
|
|
388
|
+
| "input.form"
|
|
389
|
+
| "input.headers"
|
|
390
|
+
| "input.json"
|
|
391
|
+
| "input.search"
|
|
392
|
+
| "output"
|
|
393
|
+
|
|
394
|
+
/** Passed to a policy entry's `map` / `expand` */
|
|
395
|
+
export type MetaSpecContext = {
|
|
396
|
+
meta: Record<string, unknown>
|
|
397
|
+
method: string
|
|
398
|
+
path: string
|
|
399
|
+
profile: string
|
|
400
|
+
/** Where the source value came from — `"meta"`, or the schema source for schema entries */
|
|
401
|
+
source: "meta" | MetaSpecSchemaSource
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
type MetaSpecEntryBase = {
|
|
405
|
+
/** Which operation kinds this entry applies to. Default `"both"` */
|
|
406
|
+
on?: MetaSpecTarget
|
|
407
|
+
/** Restrict this entry to named profiles. Default: every profile */
|
|
408
|
+
profiles?: readonly string[]
|
|
409
|
+
/** Validates the produced value at codegen time. A failure is a build error */
|
|
410
|
+
schema?: StandardSchemaLike
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/** Policy entry writing one operation key */
|
|
414
|
+
export type MetaSpecSingle<TValue = unknown> = MetaSpecEntryBase & {
|
|
415
|
+
/** Target operation key — an `x-*` extension or an allowed standard field */
|
|
416
|
+
key: string
|
|
417
|
+
/** Transform the source value. Returning `undefined` omits the key for that operation */
|
|
418
|
+
map?: (value: TValue, ctx: MetaSpecContext) => unknown
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/** Policy entry fanning one source value out to several operation keys */
|
|
422
|
+
export type MetaSpecExpand<TValue = unknown> = MetaSpecEntryBase & {
|
|
423
|
+
/** Returns operation keys → values. `undefined` (returned or per key) omits */
|
|
424
|
+
expand: (value: TValue, ctx: MetaSpecContext) => Record<string, unknown> | undefined
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** One policy entry: hidden (`false`), verbatim (`"x-foo"`), single target, or fan-out */
|
|
428
|
+
export type MetaSpecEntry<TValue = unknown> = false | MetaSpecExpand<TValue> | MetaSpecSingle<TValue> | string
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* How deeply to look for a schema-metadata key.
|
|
432
|
+
* `"root"` reads the schema root, reading through one level of `items` for a bare array output.
|
|
433
|
+
* `"deep"` walks the schema (properties, items, composition members) and takes the shallowest
|
|
434
|
+
* match — for envelope shapes like `{ articles: [Article], nextCursor, count }`.
|
|
435
|
+
*/
|
|
436
|
+
export type MetaSpecSchemaSearch = "deep" | "root"
|
|
437
|
+
|
|
438
|
+
/** Refuse a descriptor whose publisher contract version is newer than this policy understands */
|
|
439
|
+
export type MetaSpecVersionGuard = {
|
|
440
|
+
/** Field carrying the contract version. Default `"v"` */
|
|
441
|
+
field?: string
|
|
442
|
+
/** Highest version this entry's `map`/`expand` was written against */
|
|
443
|
+
max: number
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Policy entry reading its source key off a route schema instead of route meta.
|
|
448
|
+
*
|
|
449
|
+
* The object key names the entry; `read` says which schema-metadata key it reads, so several
|
|
450
|
+
* entries can read one reserved key — the shape a publisher takes when it stamps a
|
|
451
|
+
* discriminated union under a single key.
|
|
452
|
+
*/
|
|
453
|
+
export type MetaSpecSchemaEntry<TValue = unknown> = (MetaSpecExpand<TValue> | MetaSpecSingle<TValue>) & {
|
|
454
|
+
/** Schema sources to search, in order. First one carrying a matching descriptor wins */
|
|
455
|
+
from?: readonly MetaSpecSchemaSource[]
|
|
456
|
+
/**
|
|
457
|
+
* Shallow subset the descriptor must satisfy for this entry to claim it — the discriminant
|
|
458
|
+
* of a union, e.g. `{ kind: "entity" }`. A descriptor found under `read` that satisfies no
|
|
459
|
+
* entry's `match` is a build error, never a silently missing tag.
|
|
460
|
+
*/
|
|
461
|
+
match?: Record<string, unknown>
|
|
462
|
+
/** Schema-metadata key to read. Defaults to this entry's own name */
|
|
463
|
+
read?: string
|
|
464
|
+
/** Where in the schema to look. Default `"root"` */
|
|
465
|
+
search?: MetaSpecSchemaSearch
|
|
466
|
+
/** Fail the build on a descriptor from a newer publisher contract than this entry handles */
|
|
467
|
+
version?: MetaSpecVersionGuard
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/** Per-document filter over emitted operation keys */
|
|
471
|
+
export type MetaSpecProfile = {
|
|
472
|
+
/** Denylist of emitted keys */
|
|
473
|
+
exclude?: readonly string[]
|
|
474
|
+
/** Allowlist of emitted `x-*` keys — standard fields are always kept unless excluded */
|
|
475
|
+
include?: readonly string[]
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** How an unmapped meta key is reported at codegen time */
|
|
479
|
+
export type MetaSpecStrictness = "error" | "off" | "warn"
|
|
480
|
+
|
|
481
|
+
type MetaSpecSections<TMetaSection> = {
|
|
482
|
+
/** Route-meta entries, keyed by meta key */
|
|
483
|
+
meta?: TMetaSection
|
|
484
|
+
/** Named per-document filters. `"default"` filters nothing */
|
|
485
|
+
profiles?: Record<string, MetaSpecProfile>
|
|
486
|
+
/** Schema-derived entries, keyed by the key read off the schema's metadata */
|
|
487
|
+
schema?: Record<string, MetaSpecSchemaEntry<never>>
|
|
488
|
+
/** How to report a meta key with no entry. Default `"error"` */
|
|
489
|
+
strict?: MetaSpecStrictness
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/** Built-in meta keys ship with a default policy — overriding them is optional */
|
|
493
|
+
type MetaSpecOptionalKeys<TMeta> = {
|
|
494
|
+
[K in Extract<keyof TMeta, keyof OpenApiMeta>]?: MetaSpecEntry<Exclude<TMeta[K], undefined>>
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** Every app-defined meta key must have an entry — a missing key is a type error */
|
|
498
|
+
type MetaSpecRequiredKeys<TMeta> = {
|
|
499
|
+
[K in Exclude<keyof TMeta, keyof OpenApiMeta>]-?: MetaSpecEntry<Exclude<TMeta[K], undefined>>
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/** Declarative policy for what flows from route meta and route schemas into the document */
|
|
503
|
+
export type HoneyMetaSpec<TMeta = unknown> = [TMeta] extends [never]
|
|
504
|
+
? MetaSpecSections<Record<string, MetaSpecEntry>>
|
|
505
|
+
: TMeta extends Record<string, unknown>
|
|
506
|
+
? MetaSpecSections<MetaSpecOptionalKeys<TMeta> & MetaSpecRequiredKeys<TMeta>>
|
|
507
|
+
: MetaSpecSections<Record<string, MetaSpecEntry>>
|
|
508
|
+
|
|
509
|
+
/** Erased runtime shape of a resolved policy — what codegen consumes */
|
|
510
|
+
export type MetaSpecConfig = {
|
|
511
|
+
meta?: Record<string, MetaSpecEntry>
|
|
512
|
+
profiles?: Record<string, MetaSpecProfile>
|
|
513
|
+
schema?: Record<string, MetaSpecSchemaEntry>
|
|
514
|
+
strict?: MetaSpecStrictness
|
|
515
|
+
}
|
|
516
|
+
|
|
383
517
|
/** Built-in meta shape — always available on .meta() */
|
|
384
518
|
export type DefaultMeta = OpenApiMeta
|
|
385
519
|
|
|
386
520
|
/** Augmented by generated code per-app to narrow invalidate selectors */
|
|
387
521
|
export interface HoneyCodegen {}
|
|
388
522
|
|
|
389
|
-
type ResolveSelector = HoneyCodegen extends { routeSelector: infer R }
|
|
390
|
-
? R extends string ? R : string
|
|
391
|
-
: string
|
|
523
|
+
type ResolveSelector = HoneyCodegen extends { routeSelector: infer R } ? (R extends string ? R : string) : string
|
|
392
524
|
|
|
393
525
|
/** Utility: merges built-in meta, custom meta T, and type-safe invalidate from codegen */
|
|
394
|
-
export type HoneyMeta<T = {}> = DefaultMeta &
|
|
395
|
-
|
|
396
|
-
|
|
526
|
+
export type HoneyMeta<T = {}> = DefaultMeta &
|
|
527
|
+
T & {
|
|
528
|
+
invalidate?: readonly ResolveSelector[] | null
|
|
529
|
+
}
|
|
397
530
|
|
|
398
531
|
/** Accumulated route schema entry for RPC client generation */
|
|
399
532
|
export type RouteRecord<
|
|
@@ -450,17 +583,15 @@ export type InferCtx<T> = T extends { readonly $ctx: infer TCtx } ? Omit<TCtx, "
|
|
|
450
583
|
export type InferEnv<T> = T extends { readonly $env: infer TEnv } ? TEnv : never
|
|
451
584
|
|
|
452
585
|
/** All HTTP methods used across all routes */
|
|
453
|
-
export type InferMethods<T> =
|
|
454
|
-
InferRoutes<T> extends infer R ? { [P in keyof R]: keyof R[P] & string }[keyof R] : never
|
|
586
|
+
export type InferMethods<T> = InferRoutes<T> extends infer R ? { [P in keyof R]: keyof R[P] & string }[keyof R] : never
|
|
455
587
|
|
|
456
588
|
/** Available route paths registered on a Honey instance */
|
|
457
589
|
export type InferRoutePaths<T> = keyof InferRoutes<T> & string
|
|
458
590
|
|
|
459
591
|
/** Available methods for a given path ("get", "post", etc.) */
|
|
460
|
-
export type InferRouteMethods<
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
> = InferRoutes<T>[TPath] extends infer M ? keyof M & string : never
|
|
592
|
+
export type InferRouteMethods<T, TPath extends InferRoutePaths<T>> = InferRoutes<T>[TPath] extends infer M
|
|
593
|
+
? keyof M & string
|
|
594
|
+
: never
|
|
464
595
|
|
|
465
596
|
/** Lookup a specific route's record from the accumulated route map */
|
|
466
597
|
type RouteLookup<T, TPath extends string, TMethod extends string> =
|
|
@@ -478,39 +609,24 @@ type RouteLookup<T, TPath extends string, TMethod extends string> =
|
|
|
478
609
|
export type InferMeta<T> = T extends { readonly $meta: infer M } ? M : never
|
|
479
610
|
|
|
480
611
|
/** Extract the full handler context type for a specific route */
|
|
481
|
-
export type InferRouteCtx<
|
|
482
|
-
T,
|
|
483
|
-
TPath extends InferRoutePaths<T>,
|
|
484
|
-
TMethod extends InferRouteMethods<T, TPath>,
|
|
485
|
-
> = RouteLookup<T, TPath, TMethod> extends { ctx: infer C } ? C : never
|
|
612
|
+
export type InferRouteCtx<T, TPath extends InferRoutePaths<T>, TMethod extends InferRouteMethods<T, TPath>> =
|
|
613
|
+
RouteLookup<T, TPath, TMethod> extends { ctx: infer C } ? C : never
|
|
486
614
|
|
|
487
615
|
/** Extract input type for a specific route */
|
|
488
|
-
export type InferRouteInput<
|
|
489
|
-
T,
|
|
490
|
-
TPath extends InferRoutePaths<T>,
|
|
491
|
-
TMethod extends InferRouteMethods<T, TPath>,
|
|
492
|
-
> = RouteLookup<T, TPath, TMethod> extends { input: infer I } ? I : never
|
|
616
|
+
export type InferRouteInput<T, TPath extends InferRoutePaths<T>, TMethod extends InferRouteMethods<T, TPath>> =
|
|
617
|
+
RouteLookup<T, TPath, TMethod> extends { input: infer I } ? I : never
|
|
493
618
|
|
|
494
619
|
/** Extract meta type for a specific route */
|
|
495
|
-
export type InferRouteMeta<
|
|
496
|
-
T,
|
|
497
|
-
TPath extends InferRoutePaths<T>,
|
|
498
|
-
TMethod extends InferRouteMethods<T, TPath>,
|
|
499
|
-
> = RouteLookup<T, TPath, TMethod> extends { meta: infer M } ? M : never
|
|
620
|
+
export type InferRouteMeta<T, TPath extends InferRoutePaths<T>, TMethod extends InferRouteMethods<T, TPath>> =
|
|
621
|
+
RouteLookup<T, TPath, TMethod> extends { meta: infer M } ? M : never
|
|
500
622
|
|
|
501
623
|
/** Extract output type for a specific route */
|
|
502
|
-
export type InferRouteOutput<
|
|
503
|
-
T,
|
|
504
|
-
TPath extends InferRoutePaths<T>,
|
|
505
|
-
TMethod extends InferRouteMethods<T, TPath>,
|
|
506
|
-
> = RouteLookup<T, TPath, TMethod> extends { output: infer O } ? O : never
|
|
624
|
+
export type InferRouteOutput<T, TPath extends InferRoutePaths<T>, TMethod extends InferRouteMethods<T, TPath>> =
|
|
625
|
+
RouteLookup<T, TPath, TMethod> extends { output: infer O } ? O : never
|
|
507
626
|
|
|
508
627
|
/** Extract error keys for a specific route */
|
|
509
|
-
export type InferRouteErrors<
|
|
510
|
-
T,
|
|
511
|
-
TPath extends InferRoutePaths<T>,
|
|
512
|
-
TMethod extends InferRouteMethods<T, TPath>,
|
|
513
|
-
> = RouteLookup<T, TPath, TMethod> extends { errors: infer E } ? E : never
|
|
628
|
+
export type InferRouteErrors<T, TPath extends InferRoutePaths<T>, TMethod extends InferRouteMethods<T, TPath>> =
|
|
629
|
+
RouteLookup<T, TPath, TMethod> extends { errors: infer E } ? E : never
|
|
514
630
|
|
|
515
631
|
/** Extract the error factory type from a Honey instance */
|
|
516
632
|
export type InferErrorFactory<T> = T extends { readonly $errorFactory: infer F } ? F : never
|
|
@@ -519,26 +635,17 @@ export type InferErrorFactory<T> = T extends { readonly $errorFactory: infer F }
|
|
|
519
635
|
* Compute errorsByStatus from error factory + declared error keys.
|
|
520
636
|
* Maps status codes to body shapes for client-side discrimination.
|
|
521
637
|
*/
|
|
522
|
-
export type ComputeErrorsByStatus<
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
TMetaSymbol extends symbol,
|
|
526
|
-
> = TFactory extends { readonly [K in TMetaSymbol]: infer TMeta }
|
|
638
|
+
export type ComputeErrorsByStatus<TFactory, TErrorKeys extends string, TMetaSymbol extends symbol> = TFactory extends {
|
|
639
|
+
readonly [K in TMetaSymbol]: infer TMeta
|
|
640
|
+
}
|
|
527
641
|
? TMeta extends Record<string, { schema: infer _S; statusKey: infer _SK }>
|
|
528
642
|
? _BuildByStatus<TMeta, TErrorKeys>
|
|
529
643
|
: never
|
|
530
644
|
: never
|
|
531
645
|
|
|
532
646
|
/** Internal: build { [statusCode]: bodyShape } from meta + error keys */
|
|
533
|
-
type _BuildByStatus<
|
|
534
|
-
|
|
535
|
-
TKeys extends string,
|
|
536
|
-
> = {
|
|
537
|
-
[SK in _UsedStatusKeys<TMeta, TKeys> & StatusKey as StatusKeyToCodeType<SK>]: _ShapesForStatus<
|
|
538
|
-
TMeta,
|
|
539
|
-
TKeys,
|
|
540
|
-
SK
|
|
541
|
-
>
|
|
647
|
+
type _BuildByStatus<TMeta extends Record<string, { schema: unknown; statusKey: unknown }>, TKeys extends string> = {
|
|
648
|
+
[SK in _UsedStatusKeys<TMeta, TKeys> & StatusKey as StatusKeyToCodeType<SK>]: _ShapesForStatus<TMeta, TKeys, SK>
|
|
542
649
|
}
|
|
543
650
|
|
|
544
651
|
/** Internal: collect all statusKeys used by the declared error keys */
|
|
@@ -607,11 +714,7 @@ type StatusKeyToCodeType<SK extends StatusKey> = SK extends "ok"
|
|
|
607
714
|
export type InferBasePath<T> = T extends { readonly $basePath: infer P } ? P : never
|
|
608
715
|
|
|
609
716
|
/** Merge two path segments — "/" is identity */
|
|
610
|
-
export type MergePath<A extends string, B extends string> = A extends "/"
|
|
611
|
-
? B
|
|
612
|
-
: B extends "/"
|
|
613
|
-
? A
|
|
614
|
-
: `${A}${B}`
|
|
717
|
+
export type MergePath<A extends string, B extends string> = A extends "/" ? B : B extends "/" ? A : `${A}${B}`
|
|
615
718
|
|
|
616
719
|
/* ── Tap types ── */
|
|
617
720
|
|
|
@@ -619,10 +722,7 @@ export type MergePath<A extends string, B extends string> = A extends "/"
|
|
|
619
722
|
export type PendingTap = { key: string; payload: unknown }
|
|
620
723
|
|
|
621
724
|
/** Handler registered via app.tap(key, handler) — receives context + payload */
|
|
622
|
-
export type TapHandler<TEnv = unknown> = (
|
|
623
|
-
ctx: TapContext<TEnv>,
|
|
624
|
-
payload: unknown,
|
|
625
|
-
) => void | Promise<void>
|
|
725
|
+
export type TapHandler<TEnv = unknown> = (ctx: TapContext<TEnv>, payload: unknown) => void | Promise<void>
|
|
626
726
|
|
|
627
727
|
/** Subset of HoneyContext exposed to tap handlers — no res, no recursive tap */
|
|
628
728
|
export type TapContext<TEnv = unknown> = {
|
package/src/validation.ts
CHANGED
|
@@ -64,11 +64,7 @@ export function parseCookies(header: string): Record<string, string> {
|
|
|
64
64
|
let value = trimmed.slice(eqIdx + 1)
|
|
65
65
|
if (value.indexOf("%") !== -1) value = tryDecodeCookieValue(value)
|
|
66
66
|
/* RFC 6265: strip surrounding double quotes */
|
|
67
|
-
if (
|
|
68
|
-
value.length >= 2 &&
|
|
69
|
-
value.charCodeAt(0) === 34 &&
|
|
70
|
-
value.charCodeAt(value.length - 1) === 34
|
|
71
|
-
) {
|
|
67
|
+
if (value.length >= 2 && value.charCodeAt(0) === 34 && value.charCodeAt(value.length - 1) === 34) {
|
|
72
68
|
value = value.slice(1, -1)
|
|
73
69
|
}
|
|
74
70
|
result[name] = value
|
|
@@ -96,10 +92,7 @@ function extractVendorCode(issue: StandardSchemaIssue, vendor: string): string {
|
|
|
96
92
|
return "unknown"
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
export function normalizeIssues(
|
|
100
|
-
issues: ReadonlyArray<StandardSchemaIssue>,
|
|
101
|
-
vendor: string,
|
|
102
|
-
): NormalizedIssue[] {
|
|
95
|
+
export function normalizeIssues(issues: ReadonlyArray<StandardSchemaIssue>, vendor: string): NormalizedIssue[] {
|
|
103
96
|
return issues.map((issue) => {
|
|
104
97
|
const path = issue.path ? issue.path.map(toPropertyKey) : []
|
|
105
98
|
return {
|
|
@@ -113,10 +106,7 @@ export function normalizeIssues(
|
|
|
113
106
|
})
|
|
114
107
|
}
|
|
115
108
|
|
|
116
|
-
export function issuesToFieldErrors(
|
|
117
|
-
issues: NormalizedIssue[],
|
|
118
|
-
prefix: string,
|
|
119
|
-
): Record<string, FieldError[]> {
|
|
109
|
+
export function issuesToFieldErrors(issues: NormalizedIssue[], prefix: string): Record<string, FieldError[]> {
|
|
120
110
|
const fields: Record<string, FieldError[]> = {}
|
|
121
111
|
for (const issue of issues) {
|
|
122
112
|
const fieldName = issue.path.at(-1)?.toString() ?? "unknown"
|
|
@@ -134,11 +124,7 @@ export function issuesToFieldErrors(
|
|
|
134
124
|
return fields
|
|
135
125
|
}
|
|
136
126
|
|
|
137
|
-
async function runSchema(
|
|
138
|
-
schema: StandardSchemaLike,
|
|
139
|
-
data: unknown,
|
|
140
|
-
prefix: string,
|
|
141
|
-
): Promise<unknown> {
|
|
127
|
+
async function runSchema(schema: StandardSchemaLike, data: unknown, prefix: string): Promise<unknown> {
|
|
142
128
|
const result = await schema["~standard"].validate(data)
|
|
143
129
|
if (result.issues) {
|
|
144
130
|
const normalized = normalizeIssues(result.issues, schema["~standard"].vendor)
|
|
@@ -234,8 +220,7 @@ export async function validateInput(
|
|
|
234
220
|
if (schemas.headers) {
|
|
235
221
|
const { mode, schema } = resolveSchema(schemas.headers)
|
|
236
222
|
const headerRecord = headersToRecord(req.headers)
|
|
237
|
-
result.headers =
|
|
238
|
-
mode === "readableStream" ? headerRecord : await runSchema(schema, headerRecord, "headers")
|
|
223
|
+
result.headers = mode === "readableStream" ? headerRecord : await runSchema(schema, headerRecord, "headers")
|
|
239
224
|
}
|
|
240
225
|
|
|
241
226
|
/* cookies */
|
|
@@ -247,11 +232,7 @@ export async function validateInput(
|
|
|
247
232
|
}
|
|
248
233
|
|
|
249
234
|
/* body-based: json or form — skip for methods without a request body */
|
|
250
|
-
const hasBody =
|
|
251
|
-
req.method !== "DELETE" &&
|
|
252
|
-
req.method !== "GET" &&
|
|
253
|
-
req.method !== "HEAD" &&
|
|
254
|
-
req.method !== "OPTIONS"
|
|
235
|
+
const hasBody = req.method !== "DELETE" && req.method !== "GET" && req.method !== "HEAD" && req.method !== "OPTIONS"
|
|
255
236
|
if (hasBody && (schemas.json || schemas.form)) {
|
|
256
237
|
const contentType = req.headers.get("content-type")
|
|
257
238
|
const parser = selectParser(contentType)
|
|
@@ -284,11 +265,7 @@ export async function validateInput(
|
|
|
284
265
|
return result
|
|
285
266
|
}
|
|
286
267
|
|
|
287
|
-
export async function validateOutput(
|
|
288
|
-
schema: StandardSchemaLike,
|
|
289
|
-
statusKey: string,
|
|
290
|
-
data: unknown,
|
|
291
|
-
): Promise<void> {
|
|
268
|
+
export async function validateOutput(schema: StandardSchemaLike, statusKey: string, data: unknown): Promise<void> {
|
|
292
269
|
const result = await schema["~standard"].validate(data)
|
|
293
270
|
if (result.issues) {
|
|
294
271
|
throw new HoneyError({
|
package/src/ws/bun.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
type RawSocket,
|
|
3
|
-
type WSAdapter,
|
|
4
|
-
type WSContext,
|
|
5
|
-
WSContextImpl,
|
|
6
|
-
type WSHandler,
|
|
7
|
-
} from "./cloudflare.ts"
|
|
1
|
+
export { type RawSocket, type WSAdapter, type WSContext, WSContextImpl, type WSHandler } from "./cloudflare.ts"
|
|
8
2
|
|
|
9
3
|
import type { WSAdapter, WSContext, WSHandler } from "./cloudflare.ts"
|
|
10
4
|
import { WSContextImpl } from "./cloudflare.ts"
|
|
@@ -76,8 +70,7 @@ export function bunWebSocket(): BunWSAdapter {
|
|
|
76
70
|
message(ws: BunRawSocket, data: ArrayBufferView | string) {
|
|
77
71
|
if (!ws.data.socket) ws.data.socket = new WSContextImpl(ws)
|
|
78
72
|
/* Bun passes Buffer (Uint8Array) for binary — normalize to ArrayBuffer for WSHandler */
|
|
79
|
-
const normalized =
|
|
80
|
-
typeof data === "string" ? data : ((data as Uint8Array).buffer as ArrayBuffer)
|
|
73
|
+
const normalized = typeof data === "string" ? data : ((data as Uint8Array).buffer as ArrayBuffer)
|
|
81
74
|
ws.data.handler.onMessage?.(undefined, ws.data.socket, normalized)
|
|
82
75
|
},
|
|
83
76
|
open(ws: BunRawSocket) {
|
package/src/ws/cloudflare.ts
CHANGED
|
@@ -87,13 +87,10 @@ export class WSContextImpl<T extends RawSocket = RawSocket> implements WSContext
|
|
|
87
87
|
* Uses WebSocketPair + server.accept() + addEventListener.
|
|
88
88
|
*/
|
|
89
89
|
export function cfWebSocket(): WSAdapter {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
CFWebSocket,
|
|
95
|
-
CFWebSocket,
|
|
96
|
-
]
|
|
90
|
+
return {
|
|
91
|
+
upgrade(_req: Request, _env: unknown, handler: WSHandler<unknown>) {
|
|
92
|
+
type CFWebSocket = RawSocket & { accept(): void }
|
|
93
|
+
const Ctor = (globalThis as Record<string, unknown>)["WebSocketPair"] as new () => [CFWebSocket, CFWebSocket]
|
|
97
94
|
const [client, server] = new Ctor()
|
|
98
95
|
server.accept()
|
|
99
96
|
const socket = new WSContextImpl(server)
|
|
@@ -120,14 +117,14 @@ export function cfWebSocket(): WSAdapter {
|
|
|
120
117
|
}
|
|
121
118
|
handler.onOpen?.(undefined, socket)
|
|
122
119
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
return {
|
|
121
|
+
response: new Response(null, {
|
|
122
|
+
headers: { upgrade: "websocket" },
|
|
123
|
+
status: 101,
|
|
124
|
+
webSocket: client,
|
|
125
|
+
} as unknown as ResponseInit),
|
|
126
|
+
socket,
|
|
127
|
+
}
|
|
128
|
+
},
|
|
132
129
|
}
|
|
133
130
|
}
|
package/src/ws/deno.ts
CHANGED
|
@@ -5,30 +5,27 @@ export {
|
|
|
5
5
|
type WSPreUpgrade,
|
|
6
6
|
WSContextImpl,
|
|
7
7
|
type WSHandler,
|
|
8
|
-
} from "./cloudflare.ts"
|
|
8
|
+
} from "./cloudflare.ts"
|
|
9
9
|
|
|
10
|
-
import type { WSAdapter, WSHandler, WSPreUpgrade } from "./cloudflare.ts"
|
|
11
|
-
import { WSContextImpl } from "./cloudflare.ts"
|
|
10
|
+
import type { WSAdapter, WSHandler, WSPreUpgrade } from "./cloudflare.ts"
|
|
11
|
+
import { WSContextImpl } from "./cloudflare.ts"
|
|
12
12
|
|
|
13
13
|
type DenoNs = {
|
|
14
14
|
Deno: {
|
|
15
15
|
upgradeWebSocket(req: Request): {
|
|
16
|
-
response: Response
|
|
16
|
+
response: Response
|
|
17
17
|
socket: {
|
|
18
|
-
addEventListener(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
};
|
|
18
|
+
addEventListener(type: string, listener: (...args: never[]) => void): void
|
|
19
|
+
} & DenoRawSocket
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
26
23
|
|
|
27
24
|
type DenoRawSocket = {
|
|
28
|
-
close(code?: number, reason?: string): void
|
|
29
|
-
readyState: number
|
|
30
|
-
send(data: ArrayBuffer | Uint8Array | string): void
|
|
31
|
-
}
|
|
25
|
+
close(code?: number, reason?: string): void
|
|
26
|
+
readyState: number
|
|
27
|
+
send(data: ArrayBuffer | Uint8Array | string): void
|
|
28
|
+
}
|
|
32
29
|
|
|
33
30
|
type DenoSocket = {
|
|
34
31
|
addEventListener(type: string, listener: (...args: never[]) => void): void
|
|
@@ -36,23 +33,17 @@ type DenoSocket = {
|
|
|
36
33
|
|
|
37
34
|
function bindHandlers(rawSocket: DenoSocket, socket: WSContextImpl<DenoRawSocket>, handler: WSHandler<unknown>): void {
|
|
38
35
|
rawSocket.addEventListener("open", () => {
|
|
39
|
-
handler.onOpen?.(undefined, socket)
|
|
40
|
-
})
|
|
41
|
-
rawSocket.addEventListener(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
47
|
-
rawSocket.addEventListener(
|
|
48
|
-
"close",
|
|
49
|
-
(evt: { code: number; reason: string }) => {
|
|
50
|
-
handler.onClose?.(undefined, socket, evt.code, evt.reason);
|
|
51
|
-
},
|
|
52
|
-
);
|
|
36
|
+
handler.onOpen?.(undefined, socket)
|
|
37
|
+
})
|
|
38
|
+
rawSocket.addEventListener("message", (evt: { data: ArrayBuffer | string }) => {
|
|
39
|
+
handler.onMessage?.(undefined, socket, evt.data)
|
|
40
|
+
})
|
|
41
|
+
rawSocket.addEventListener("close", (evt: { code: number; reason: string }) => {
|
|
42
|
+
handler.onClose?.(undefined, socket, evt.code, evt.reason)
|
|
43
|
+
})
|
|
53
44
|
rawSocket.addEventListener("error", (evt: unknown) => {
|
|
54
|
-
handler.onError?.(undefined, socket, evt)
|
|
55
|
-
})
|
|
45
|
+
handler.onError?.(undefined, socket, evt)
|
|
46
|
+
})
|
|
56
47
|
}
|
|
57
48
|
|
|
58
49
|
/**
|
|
@@ -69,9 +60,9 @@ export function denoWebSocket(): WSAdapter {
|
|
|
69
60
|
|
|
70
61
|
return {
|
|
71
62
|
preUpgrade(req: Request): WSPreUpgrade {
|
|
72
|
-
const denoNs = globalThis as unknown as DenoNs
|
|
73
|
-
const { response, socket: rawSocket } = denoNs.Deno.upgradeWebSocket(req)
|
|
74
|
-
const socket = new WSContextImpl(rawSocket as DenoRawSocket)
|
|
63
|
+
const denoNs = globalThis as unknown as DenoNs
|
|
64
|
+
const { response, socket: rawSocket } = denoNs.Deno.upgradeWebSocket(req)
|
|
65
|
+
const socket = new WSContextImpl(rawSocket as DenoRawSocket)
|
|
75
66
|
const pre: WSPreUpgrade = {
|
|
76
67
|
response,
|
|
77
68
|
socket,
|
|
@@ -99,11 +90,11 @@ export function denoWebSocket(): WSAdapter {
|
|
|
99
90
|
}
|
|
100
91
|
|
|
101
92
|
/* globalThis cast: Deno namespace only exists at runtime on Deno — no way to type it statically */
|
|
102
|
-
const denoNs = globalThis as unknown as DenoNs
|
|
103
|
-
const { response, socket: rawSocket } = denoNs.Deno.upgradeWebSocket(req)
|
|
104
|
-
const socket = new WSContextImpl(rawSocket as DenoRawSocket)
|
|
93
|
+
const denoNs = globalThis as unknown as DenoNs
|
|
94
|
+
const { response, socket: rawSocket } = denoNs.Deno.upgradeWebSocket(req)
|
|
95
|
+
const socket = new WSContextImpl(rawSocket as DenoRawSocket)
|
|
105
96
|
bindHandlers(rawSocket, socket, handler)
|
|
106
|
-
return { response, socket }
|
|
97
|
+
return { response, socket }
|
|
107
98
|
},
|
|
108
|
-
}
|
|
99
|
+
}
|
|
109
100
|
}
|
package/src/ws/node.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
export {
|
|
2
|
-
type RawSocket,
|
|
3
|
-
type WSAdapter,
|
|
4
|
-
type WSContext,
|
|
5
|
-
WSContextImpl,
|
|
6
|
-
type WSHandler,
|
|
7
|
-
} from "./cloudflare.ts"
|
|
1
|
+
export { type RawSocket, type WSAdapter, type WSContext, WSContextImpl, type WSHandler } from "./cloudflare.ts"
|
|
8
2
|
|
|
9
3
|
import type { WSAdapter, WSHandler } from "./cloudflare.ts"
|
|
10
4
|
import { WSContextImpl } from "./cloudflare.ts"
|
|
11
5
|
|
|
12
6
|
type WsModule = {
|
|
13
|
-
WebSocketServer: new (opts: {
|
|
14
|
-
noServer: true
|
|
15
|
-
perMessageDeflate: boolean
|
|
16
|
-
}) => {
|
|
7
|
+
WebSocketServer: new (opts: { noServer: true; perMessageDeflate: boolean }) => {
|
|
17
8
|
handleUpgrade(req: unknown, socket: unknown, head: unknown, cb: (ws: NodeWS) => void): void
|
|
18
9
|
}
|
|
19
10
|
}
|
|
@@ -88,20 +79,14 @@ export function nodeWebSocket(opts?: { keepalive?: KeepaliveConfig }): WSAdapter
|
|
|
88
79
|
handler.onMessage?.(
|
|
89
80
|
undefined,
|
|
90
81
|
socket,
|
|
91
|
-
data.buffer.slice(
|
|
92
|
-
data.byteOffset,
|
|
93
|
-
data.byteOffset + data.byteLength,
|
|
94
|
-
) as ArrayBuffer,
|
|
82
|
+
data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer,
|
|
95
83
|
)
|
|
96
84
|
} else if (Array.isArray(data)) {
|
|
97
85
|
const merged = Buffer.concat(data)
|
|
98
86
|
handler.onMessage?.(
|
|
99
87
|
undefined,
|
|
100
88
|
socket,
|
|
101
|
-
merged.buffer.slice(
|
|
102
|
-
merged.byteOffset,
|
|
103
|
-
merged.byteOffset + merged.byteLength,
|
|
104
|
-
) as ArrayBuffer,
|
|
89
|
+
merged.buffer.slice(merged.byteOffset, merged.byteOffset + merged.byteLength) as ArrayBuffer,
|
|
105
90
|
)
|
|
106
91
|
} else {
|
|
107
92
|
handler.onMessage?.(undefined, socket, data)
|