@geekmidas/constructs 10.0.0-alpha.101 → 10.0.0-alpha.102

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.
Files changed (68) hide show
  1. package/dist/{Endpoint-BG4UJ9oA.mjs → Endpoint-BW-nFdL_.mjs} +67 -3
  2. package/dist/Endpoint-BW-nFdL_.mjs.map +1 -0
  3. package/dist/{Endpoint-aCvBMPoH.d.cts → Endpoint-BWyKCa2x.d.cts} +47 -9
  4. package/dist/Endpoint-BWyKCa2x.d.cts.map +1 -0
  5. package/dist/{Endpoint-BoUg8ocM.cjs → Endpoint-B_UHlLxv.cjs} +78 -2
  6. package/dist/Endpoint-B_UHlLxv.cjs.map +1 -0
  7. package/dist/{Endpoint-Du-NwPX2.d.mts → Endpoint-C3r2OzOD.d.mts} +47 -9
  8. package/dist/Endpoint-C3r2OzOD.d.mts.map +1 -0
  9. package/dist/{EndpointFactory-BDtsrEvJ.mjs → EndpointFactory-Bbmx4vXc.mjs} +7 -2
  10. package/dist/EndpointFactory-Bbmx4vXc.mjs.map +1 -0
  11. package/dist/{EndpointFactory-I7s1co3Y.d.cts → EndpointFactory-C1-IBwm4.d.cts} +9 -4
  12. package/dist/EndpointFactory-C1-IBwm4.d.cts.map +1 -0
  13. package/dist/{EndpointFactory-DMYdJCOj.d.mts → EndpointFactory-C9eVhDKF.d.mts} +9 -4
  14. package/dist/EndpointFactory-C9eVhDKF.d.mts.map +1 -0
  15. package/dist/{EndpointFactory-DJ7gXLpR.cjs → EndpointFactory-DeZTvDjU.cjs} +7 -2
  16. package/dist/{EndpointFactory-BDtsrEvJ.mjs.map → EndpointFactory-DeZTvDjU.cjs.map} +1 -1
  17. package/dist/{HonoEndpointAdaptor-zVzVLJEO.cjs → HonoEndpointAdaptor-C_FbrwlA.cjs} +25 -10
  18. package/dist/HonoEndpointAdaptor-C_FbrwlA.cjs.map +1 -0
  19. package/dist/{HonoEndpointAdaptor-PtPlbeKY.mjs → HonoEndpointAdaptor-Cvhfj4gd.mjs} +24 -9
  20. package/dist/HonoEndpointAdaptor-Cvhfj4gd.mjs.map +1 -0
  21. package/dist/adaptors/aws.cjs +35 -21
  22. package/dist/adaptors/aws.cjs.map +1 -1
  23. package/dist/adaptors/aws.d.cts +15 -10
  24. package/dist/adaptors/aws.d.cts.map +1 -1
  25. package/dist/adaptors/aws.d.mts +15 -10
  26. package/dist/adaptors/aws.d.mts.map +1 -1
  27. package/dist/adaptors/aws.mjs +34 -20
  28. package/dist/adaptors/aws.mjs.map +1 -1
  29. package/dist/adaptors/hono.cjs +1 -1
  30. package/dist/adaptors/hono.d.cts +1 -1
  31. package/dist/adaptors/hono.d.cts.map +1 -1
  32. package/dist/adaptors/hono.d.mts +1 -1
  33. package/dist/adaptors/hono.d.mts.map +1 -1
  34. package/dist/adaptors/hono.mjs +1 -1
  35. package/dist/adaptors/testing.cjs +13 -11
  36. package/dist/adaptors/testing.cjs.map +1 -1
  37. package/dist/adaptors/testing.d.cts +1 -1
  38. package/dist/adaptors/testing.d.cts.map +1 -1
  39. package/dist/adaptors/testing.d.mts +1 -1
  40. package/dist/adaptors/testing.d.mts.map +1 -1
  41. package/dist/adaptors/testing.mjs +11 -9
  42. package/dist/adaptors/testing.mjs.map +1 -1
  43. package/dist/endpoints/index.cjs +15 -9
  44. package/dist/endpoints/index.d.cts +57 -3
  45. package/dist/endpoints/index.d.cts.map +1 -1
  46. package/dist/endpoints/index.d.mts +57 -3
  47. package/dist/endpoints/index.d.mts.map +1 -1
  48. package/dist/endpoints/index.mjs +4 -4
  49. package/dist/{lazyAccessors-CFanua0O.mjs → readRequestBody-BTIl3k-D.mjs} +99 -2
  50. package/dist/readRequestBody-BTIl3k-D.mjs.map +1 -0
  51. package/dist/{lazyAccessors-hJKGv8Ay.cjs → readRequestBody-Dej_L3c4.cjs} +122 -1
  52. package/dist/readRequestBody-Dej_L3c4.cjs.map +1 -0
  53. package/dist/rest-api.cjs +1 -1
  54. package/dist/rest-api.d.cts +2 -2
  55. package/dist/rest-api.d.mts +2 -2
  56. package/dist/rest-api.mjs +1 -1
  57. package/package.json +31 -31
  58. package/dist/Endpoint-BG4UJ9oA.mjs.map +0 -1
  59. package/dist/Endpoint-BoUg8ocM.cjs.map +0 -1
  60. package/dist/Endpoint-Du-NwPX2.d.mts.map +0 -1
  61. package/dist/Endpoint-aCvBMPoH.d.cts.map +0 -1
  62. package/dist/EndpointFactory-DJ7gXLpR.cjs.map +0 -1
  63. package/dist/EndpointFactory-DMYdJCOj.d.mts.map +0 -1
  64. package/dist/EndpointFactory-I7s1co3Y.d.cts.map +0 -1
  65. package/dist/HonoEndpointAdaptor-PtPlbeKY.mjs.map +0 -1
  66. package/dist/HonoEndpointAdaptor-zVzVLJEO.cjs.map +0 -1
  67. package/dist/lazyAccessors-CFanua0O.mjs.map +0 -1
  68. package/dist/lazyAccessors-hJKGv8Ay.cjs.map +0 -1
@@ -1,25 +1,31 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_EndpointFactory = require("../EndpointFactory-DJ7gXLpR.cjs");
2
+ const require_EndpointFactory = require("../EndpointFactory-DeZTvDjU.cjs");
3
3
  const require_functions = require("../functions-CfzJG9hK.cjs");
4
- const require_Endpoint = require("../Endpoint-BoUg8ocM.cjs");
4
+ const require_Endpoint = require("../Endpoint-B_UHlLxv.cjs");
5
5
  const require_surfaceEnv = require("../surfaceEnv-CNimK76p.cjs");
6
- const require_lazyAccessors = require("../lazyAccessors-hJKGv8Ay.cjs");
6
+ const require_readRequestBody = require("../readRequestBody-Dej_L3c4.cjs");
7
7
  exports.BUILT_IN_SECURITY_SCHEMES = require_EndpointFactory.BUILT_IN_SECURITY_SCHEMES;
8
8
  exports.Endpoint = require_Endpoint.Endpoint;
9
9
  exports.EndpointBuilder = require_EndpointFactory.EndpointBuilder;
10
10
  exports.EndpointFactory = require_EndpointFactory.EndpointFactory;
11
+ exports.MalformedRequestBody = require_readRequestBody.MalformedRequestBody;
11
12
  exports.NoAuthenticator = require_Endpoint.NoAuthenticator;
12
13
  exports.RLS_BYPASS = require_EndpointFactory.RLS_BYPASS;
14
+ exports.RedirectStatus = require_Endpoint.RedirectStatus;
13
15
  exports.ResponseBuilder = require_Endpoint.ResponseBuilder;
14
- exports.createApiGatewayCookies = require_lazyAccessors.createApiGatewayCookies;
15
- exports.createApiGatewayHeaders = require_lazyAccessors.createApiGatewayHeaders;
16
+ exports.SUPPORTED_BODY_TYPES = require_readRequestBody.SUPPORTED_BODY_TYPES;
17
+ exports.SuccessStatus = require_Endpoint.SuccessStatus;
18
+ exports.UnsupportedRequestContentType = require_readRequestBody.UnsupportedRequestContentType;
19
+ exports.createApiGatewayCookies = require_readRequestBody.createApiGatewayCookies;
20
+ exports.createApiGatewayHeaders = require_readRequestBody.createApiGatewayHeaders;
16
21
  exports.createAuthorizer = require_EndpointFactory.createAuthorizer;
17
- exports.createHonoCookies = require_lazyAccessors.createHonoCookies;
18
- exports.createHonoHeaders = require_lazyAccessors.createHonoHeaders;
19
- exports.createNoopCookies = require_lazyAccessors.createNoopCookies;
20
- exports.createNoopHeaders = require_lazyAccessors.createNoopHeaders;
22
+ exports.createHonoCookies = require_readRequestBody.createHonoCookies;
23
+ exports.createHonoHeaders = require_readRequestBody.createHonoHeaders;
24
+ exports.createNoopCookies = require_readRequestBody.createNoopCookies;
25
+ exports.createNoopHeaders = require_readRequestBody.createNoopHeaders;
21
26
  exports.defaultEnvParser = require_surfaceEnv.defaultEnvParser;
22
27
  exports.envParserFor = require_surfaceEnv.envParserFor;
23
28
  exports.getSecurityScheme = require_EndpointFactory.getSecurityScheme;
24
29
  exports.isBuiltInSecurityScheme = require_EndpointFactory.isBuiltInSecurityScheme;
25
30
  exports.publishConstructEvents = require_functions.publishConstructEvents;
31
+ exports.readRequestBody = require_readRequestBody.readRequestBody;
@@ -1,8 +1,9 @@
1
1
  import { s as publishConstructEvents } from "../Construct-BQALFCh2.cjs";
2
- import { A as getSecurityScheme, C as Authorizer, D as OAuthFlows, E as OAuthFlow, O as SecurityScheme, S as MappedAudit, T as BuiltInSecuritySchemeId, _ as RlsBypass, a as EndpointContext, b as RlsContextExtractor, c as EndpointSchemas, d as ResponseBuilder, g as RLS_BYPASS, h as SessionAuth, i as Endpoint, j as isBuiltInSecurityScheme, k as createAuthorizer, l as EndpointSurface, m as NoAuthenticator, n as ConvertRouteParams, o as EndpointHandler, r as CookieFn, s as EndpointOutput, u as HeaderFn, v as RlsConfig, w as BUILT_IN_SECURITY_SCHEMES, x as ActorExtractor, y as RlsContext } from "../Endpoint-aCvBMPoH.cjs";
3
- import { n as EndpointBuilder, t as EndpointFactory } from "../EndpointFactory-I7s1co3Y.cjs";
2
+ import { A as SecurityScheme, C as ActorExtractor, D as BuiltInSecuritySchemeId, E as BUILT_IN_SECURITY_SCHEMES, M as getSecurityScheme, N as isBuiltInSecurityScheme, O as OAuthFlow, S as RlsContextExtractor, T as Authorizer, _ as SessionAuth, a as EndpointContext, b as RlsConfig, c as EndpointSchemas, d as HeaderFn, f as RedirectStatus, g as NoAuthenticator, h as SuccessStatus, i as Endpoint, j as createAuthorizer, k as OAuthFlows, l as EndpointStatus, n as ConvertRouteParams, o as EndpointHandler, p as ResponseBuilder, r as CookieFn, s as EndpointOutput, u as EndpointSurface, v as RLS_BYPASS, w as MappedAudit, x as RlsContext, y as RlsBypass } from "../Endpoint-BWyKCa2x.cjs";
3
+ import { n as EndpointBuilder, t as EndpointFactory } from "../EndpointFactory-C1-IBwm4.cjs";
4
4
  import { EnvironmentParser } from "@geekmidas/envkit";
5
5
  import { Context } from "hono";
6
+ import { HttpError } from "@geekmidas/errors";
6
7
  //#region src/endpoints/lazyAccessors.d.ts
7
8
  /**
8
9
  * Create a lazy header accessor for Hono.
@@ -35,6 +36,59 @@ export declare function createNoopHeaders(): HeaderFn;
35
36
  */
36
37
  export declare function createNoopCookies(): CookieFn;
37
38
  //#endregion
39
+ //#region src/endpoints/readRequestBody.d.ts
40
+ /**
41
+ * The media types an endpoint's `.body()` schema can be handed — as written
42
+ * in the 415 a request in any other type is answered with.
43
+ */
44
+ export declare const SUPPORTED_BODY_TYPES: readonly ['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data', 'text/*'];
45
+ /**
46
+ * A request whose body is in a media type no endpoint reads — XML, a bare
47
+ * octet stream. Answered with a 415, before the body schema runs.
48
+ */
49
+ export declare class UnsupportedRequestContentType extends HttpError {
50
+ readonly contentType: string;
51
+ constructor(contentType: string);
52
+ }
53
+ /**
54
+ * A body that says it is JSON and is not. Answered with a 400 — the request
55
+ * is broken, not merely invalid against the schema.
56
+ */
57
+ export declare class MalformedRequestBody extends HttpError {
58
+ readonly contentType: string;
59
+ constructor(contentType: string, cause?: Error);
60
+ }
61
+ /**
62
+ * What a body is read from: a `Request`, or Hono's request — which caches
63
+ * what it read, so a later reader is not handed a spent stream.
64
+ */
65
+ interface RequestBodySource {
66
+ json(): Promise<unknown>;
67
+ text(): Promise<string>;
68
+ formData(): Promise<FormData>;
69
+ }
70
+ interface ReadRequestBodyOptions {
71
+ /**
72
+ * A body with no Content-Type: read as JSON (`'json'`, what API Gateway
73
+ * has always done), or not read at all and handed to the schema as `{}`
74
+ * (`'empty'`, what a Hono server has always done).
75
+ */
76
+ untyped: 'json' | 'empty';
77
+ }
78
+ /**
79
+ * A request body, read by its Content-Type into what an endpoint's `.body()`
80
+ * schema validates — the one place every adaptor reads a body:
81
+ *
82
+ * - `application/json` (and `application/*+json`) — the parsed JSON.
83
+ * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain
84
+ * object of fields, as an HTML form posts them. A repeated field, or one
85
+ * named `field[]`, is an array; a file part is a `File`.
86
+ * - `text/*` — the text.
87
+ *
88
+ * Anything else is an {@link UnsupportedRequestContentType}.
89
+ */
90
+ export declare function readRequestBody(source: RequestBodySource, contentType: string | null | undefined, options: ReadRequestBodyOptions): Promise<unknown>;
91
+ //#endregion
38
92
  //#region src/endpoints/surfaceEnv.d.ts
39
93
  /**
40
94
  * The default parser, built once.
@@ -47,5 +101,5 @@ export declare function defaultEnvParser(): EnvironmentParser<{}>;
47
101
  /** The parser for an endpoint, from its surface or the default. */
48
102
  export declare function envParserFor(surface: EndpointSurface | undefined): EnvironmentParser<{}>;
49
103
  //#endregion
50
- export { type ActorExtractor, type Authorizer, BUILT_IN_SECURITY_SCHEMES, type BuiltInSecuritySchemeId, type ConvertRouteParams, Endpoint, EndpointBuilder, type EndpointContext, EndpointFactory, type EndpointHandler, type EndpointOutput, type EndpointSchemas, type MappedAudit, NoAuthenticator, type OAuthFlow, type OAuthFlows, RLS_BYPASS, ResponseBuilder, type RlsBypass, type RlsConfig, type RlsContext, type RlsContextExtractor, type SecurityScheme, type SessionAuth, createAuthorizer, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents };
104
+ export { type ActorExtractor, type Authorizer, BUILT_IN_SECURITY_SCHEMES, type BuiltInSecuritySchemeId, type ConvertRouteParams, Endpoint, EndpointBuilder, type EndpointContext, EndpointFactory, type EndpointHandler, type EndpointOutput, type EndpointSchemas, type EndpointStatus, type MappedAudit, NoAuthenticator, type OAuthFlow, type OAuthFlows, RLS_BYPASS, RedirectStatus, type RequestBodySource, ResponseBuilder, type RlsBypass, type RlsConfig, type RlsContext, type RlsContextExtractor, type SecurityScheme, type SessionAuth, SuccessStatus, createAuthorizer, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents };
51
105
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/endpoints/lazyAccessors.ts","../../src/endpoints/surfaceEnv.ts"],"mappings":";;;;;;;;;;;wBAgBgB,kBAAkB,GAAG,UAAU;;;;;;wBAqB/B,kBAAkB,GAAG,UAAU;;;;;wBAgC/B,wBACf,SAAS,wDACP;;;;;wBAoCa,wBACf,+BACA,mCACE;;;;wBAmHa,qBAAqB;;;;wBAUrB,qBAAqB;;;;;;;;;;wBC1MrB,oBAAoB;;wBASpB,aACf,SAAS,8BACP"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/endpoints/lazyAccessors.ts","../../src/endpoints/readRequestBody.ts","../../src/endpoints/surfaceEnv.ts"],"mappings":";;;;;;;;;;;;wBAgBgB,kBAAkB,GAAG,UAAU;;;;;;wBAqB/B,kBAAkB,GAAG,UAAU;;;;;wBAgC/B,wBACf,SAAS,wDACP;;;;;wBAoCa,wBACf,+BACA,mCACE;;;;wBAmHa,qBAAqB;;;;wBAUrB,qBAAqB;;;;;;;qBCrOxB;;;;;qBAWA,sCAAsC;WAC7B;EAArB,YAAqB;;;;;;qBAiBT,6BAA6B;WAE/B;EADV,YACU,qBACT,QAAQ;;;;;;UAeO;EAChB,QAAQ;EACR,QAAQ;EACR,YAAY,QAAQ;;UAGJ;;;;;;EAMhB;;;;;;;;;;;;;;wBAeqB,gBACrB,QAAQ,mBACR,wCACA,SAAS,yBACP;;;;;;;;;;wBCnDa,oBAAoB;;wBASpB,aACf,SAAS,8BACP"}
@@ -1,6 +1,7 @@
1
1
  import { s as publishConstructEvents } from "../Construct-QXnl3VqT.mjs";
2
- import { A as getSecurityScheme, C as Authorizer, D as OAuthFlows, E as OAuthFlow, O as SecurityScheme, S as MappedAudit, T as BuiltInSecuritySchemeId, _ as RlsBypass, a as EndpointContext, b as RlsContextExtractor, c as EndpointSchemas, d as ResponseBuilder, g as RLS_BYPASS, h as SessionAuth, i as Endpoint, j as isBuiltInSecurityScheme, k as createAuthorizer, l as EndpointSurface, m as NoAuthenticator, n as ConvertRouteParams, o as EndpointHandler, r as CookieFn, s as EndpointOutput, u as HeaderFn, v as RlsConfig, w as BUILT_IN_SECURITY_SCHEMES, x as ActorExtractor, y as RlsContext } from "../Endpoint-Du-NwPX2.mjs";
3
- import { n as EndpointBuilder, t as EndpointFactory } from "../EndpointFactory-DMYdJCOj.mjs";
2
+ import { A as SecurityScheme, C as ActorExtractor, D as BuiltInSecuritySchemeId, E as BUILT_IN_SECURITY_SCHEMES, M as getSecurityScheme, N as isBuiltInSecurityScheme, O as OAuthFlow, S as RlsContextExtractor, T as Authorizer, _ as SessionAuth, a as EndpointContext, b as RlsConfig, c as EndpointSchemas, d as HeaderFn, f as RedirectStatus, g as NoAuthenticator, h as SuccessStatus, i as Endpoint, j as createAuthorizer, k as OAuthFlows, l as EndpointStatus, n as ConvertRouteParams, o as EndpointHandler, p as ResponseBuilder, r as CookieFn, s as EndpointOutput, u as EndpointSurface, v as RLS_BYPASS, w as MappedAudit, x as RlsContext, y as RlsBypass } from "../Endpoint-C3r2OzOD.mjs";
3
+ import { n as EndpointBuilder, t as EndpointFactory } from "../EndpointFactory-C9eVhDKF.mjs";
4
+ import { HttpError } from "@geekmidas/errors";
4
5
  import { EnvironmentParser } from "@geekmidas/envkit";
5
6
  import { Context } from "hono";
6
7
  //#region src/endpoints/lazyAccessors.d.ts
@@ -35,6 +36,59 @@ export declare function createNoopHeaders(): HeaderFn;
35
36
  */
36
37
  export declare function createNoopCookies(): CookieFn;
37
38
  //#endregion
39
+ //#region src/endpoints/readRequestBody.d.ts
40
+ /**
41
+ * The media types an endpoint's `.body()` schema can be handed — as written
42
+ * in the 415 a request in any other type is answered with.
43
+ */
44
+ export declare const SUPPORTED_BODY_TYPES: readonly ['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data', 'text/*'];
45
+ /**
46
+ * A request whose body is in a media type no endpoint reads — XML, a bare
47
+ * octet stream. Answered with a 415, before the body schema runs.
48
+ */
49
+ export declare class UnsupportedRequestContentType extends HttpError {
50
+ readonly contentType: string;
51
+ constructor(contentType: string);
52
+ }
53
+ /**
54
+ * A body that says it is JSON and is not. Answered with a 400 — the request
55
+ * is broken, not merely invalid against the schema.
56
+ */
57
+ export declare class MalformedRequestBody extends HttpError {
58
+ readonly contentType: string;
59
+ constructor(contentType: string, cause?: Error);
60
+ }
61
+ /**
62
+ * What a body is read from: a `Request`, or Hono's request — which caches
63
+ * what it read, so a later reader is not handed a spent stream.
64
+ */
65
+ interface RequestBodySource {
66
+ json(): Promise<unknown>;
67
+ text(): Promise<string>;
68
+ formData(): Promise<FormData>;
69
+ }
70
+ interface ReadRequestBodyOptions {
71
+ /**
72
+ * A body with no Content-Type: read as JSON (`'json'`, what API Gateway
73
+ * has always done), or not read at all and handed to the schema as `{}`
74
+ * (`'empty'`, what a Hono server has always done).
75
+ */
76
+ untyped: 'json' | 'empty';
77
+ }
78
+ /**
79
+ * A request body, read by its Content-Type into what an endpoint's `.body()`
80
+ * schema validates — the one place every adaptor reads a body:
81
+ *
82
+ * - `application/json` (and `application/*+json`) — the parsed JSON.
83
+ * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain
84
+ * object of fields, as an HTML form posts them. A repeated field, or one
85
+ * named `field[]`, is an array; a file part is a `File`.
86
+ * - `text/*` — the text.
87
+ *
88
+ * Anything else is an {@link UnsupportedRequestContentType}.
89
+ */
90
+ export declare function readRequestBody(source: RequestBodySource, contentType: string | null | undefined, options: ReadRequestBodyOptions): Promise<unknown>;
91
+ //#endregion
38
92
  //#region src/endpoints/surfaceEnv.d.ts
39
93
  /**
40
94
  * The default parser, built once.
@@ -47,5 +101,5 @@ export declare function defaultEnvParser(): EnvironmentParser<{}>;
47
101
  /** The parser for an endpoint, from its surface or the default. */
48
102
  export declare function envParserFor(surface: EndpointSurface | undefined): EnvironmentParser<{}>;
49
103
  //#endregion
50
- export { type ActorExtractor, type Authorizer, BUILT_IN_SECURITY_SCHEMES, type BuiltInSecuritySchemeId, type ConvertRouteParams, Endpoint, EndpointBuilder, type EndpointContext, EndpointFactory, type EndpointHandler, type EndpointOutput, type EndpointSchemas, type MappedAudit, NoAuthenticator, type OAuthFlow, type OAuthFlows, RLS_BYPASS, ResponseBuilder, type RlsBypass, type RlsConfig, type RlsContext, type RlsContextExtractor, type SecurityScheme, type SessionAuth, createAuthorizer, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents };
104
+ export { type ActorExtractor, type Authorizer, BUILT_IN_SECURITY_SCHEMES, type BuiltInSecuritySchemeId, type ConvertRouteParams, Endpoint, EndpointBuilder, type EndpointContext, EndpointFactory, type EndpointHandler, type EndpointOutput, type EndpointSchemas, type EndpointStatus, type MappedAudit, NoAuthenticator, type OAuthFlow, type OAuthFlows, RLS_BYPASS, RedirectStatus, type RequestBodySource, ResponseBuilder, type RlsBypass, type RlsConfig, type RlsContext, type RlsContextExtractor, type SecurityScheme, type SessionAuth, SuccessStatus, createAuthorizer, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents };
51
105
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/endpoints/lazyAccessors.ts","../../src/endpoints/surfaceEnv.ts"],"mappings":";;;;;;;;;;;wBAgBgB,kBAAkB,GAAG,UAAU;;;;;;wBAqB/B,kBAAkB,GAAG,UAAU;;;;;wBAgC/B,wBACf,SAAS,wDACP;;;;;wBAoCa,wBACf,+BACA,mCACE;;;;wBAmHa,qBAAqB;;;;wBAUrB,qBAAqB;;;;;;;;;;wBC1MrB,oBAAoB;;wBASpB,aACf,SAAS,8BACP"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/endpoints/lazyAccessors.ts","../../src/endpoints/readRequestBody.ts","../../src/endpoints/surfaceEnv.ts"],"mappings":";;;;;;;;;;;;wBAgBgB,kBAAkB,GAAG,UAAU;;;;;;wBAqB/B,kBAAkB,GAAG,UAAU;;;;;wBAgC/B,wBACf,SAAS,wDACP;;;;;wBAoCa,wBACf,+BACA,mCACE;;;;wBAmHa,qBAAqB;;;;wBAUrB,qBAAqB;;;;;;;qBCrOxB;;;;;qBAWA,sCAAsC;WAC7B;EAArB,YAAqB;;;;;;qBAiBT,6BAA6B;WAE/B;EADV,YACU,qBACT,QAAQ;;;;;;UAeO;EAChB,QAAQ;EACR,QAAQ;EACR,YAAY,QAAQ;;UAGJ;;;;;;EAMhB;;;;;;;;;;;;;;wBAeqB,gBACrB,QAAQ,mBACR,wCACA,SAAS,yBACP;;;;;;;;;;wBCnDa,oBAAoB;;wBASpB,aACf,SAAS,8BACP"}
@@ -1,6 +1,6 @@
1
- import { a as createAuthorizer, i as BUILT_IN_SECURITY_SCHEMES, n as EndpointBuilder, o as getSecurityScheme, r as RLS_BYPASS, s as isBuiltInSecurityScheme, t as EndpointFactory } from "../EndpointFactory-BDtsrEvJ.mjs";
1
+ import { a as createAuthorizer, i as BUILT_IN_SECURITY_SCHEMES, n as EndpointBuilder, o as getSecurityScheme, r as RLS_BYPASS, s as isBuiltInSecurityScheme, t as EndpointFactory } from "../EndpointFactory-Bbmx4vXc.mjs";
2
2
  import { i as publishConstructEvents } from "../functions-BFizikJU.mjs";
3
- import { n as ResponseBuilder, r as NoAuthenticator, t as Endpoint } from "../Endpoint-BG4UJ9oA.mjs";
3
+ import { a as NoAuthenticator, i as SuccessStatus, n as RedirectStatus, r as ResponseBuilder, t as Endpoint } from "../Endpoint-BW-nFdL_.mjs";
4
4
  import { n as envParserFor, t as defaultEnvParser } from "../surfaceEnv-wMT5QzgZ.mjs";
5
- import { a as createHonoHeaders, i as createHonoCookies, n as createApiGatewayHeaders, o as createNoopCookies, s as createNoopHeaders, t as createApiGatewayCookies } from "../lazyAccessors-CFanua0O.mjs";
6
- export { BUILT_IN_SECURITY_SCHEMES, Endpoint, EndpointBuilder, EndpointFactory, NoAuthenticator, RLS_BYPASS, ResponseBuilder, createApiGatewayCookies, createApiGatewayHeaders, createAuthorizer, createHonoCookies, createHonoHeaders, createNoopCookies, createNoopHeaders, defaultEnvParser, envParserFor, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents };
5
+ import { a as createApiGatewayCookies, c as createHonoCookies, d as createNoopHeaders, i as readRequestBody, l as createHonoHeaders, n as SUPPORTED_BODY_TYPES, o as createApiGatewayHeaders, r as UnsupportedRequestContentType, t as MalformedRequestBody, u as createNoopCookies } from "../readRequestBody-BTIl3k-D.mjs";
6
+ export { BUILT_IN_SECURITY_SCHEMES, Endpoint, EndpointBuilder, EndpointFactory, MalformedRequestBody, NoAuthenticator, RLS_BYPASS, RedirectStatus, ResponseBuilder, SUPPORTED_BODY_TYPES, SuccessStatus, UnsupportedRequestContentType, createApiGatewayCookies, createApiGatewayHeaders, createAuthorizer, createHonoCookies, createHonoHeaders, createNoopCookies, createNoopHeaders, defaultEnvParser, envParserFor, getSecurityScheme, isBuiltInSecurityScheme, publishConstructEvents, readRequestBody };
@@ -1,3 +1,4 @@
1
+ import { HttpError } from "@geekmidas/errors";
1
2
  import { getCookie } from "hono/cookie";
2
3
  //#region src/endpoints/lazyAccessors.ts
3
4
  /**
@@ -169,6 +170,102 @@ function createNoopCookies() {
169
170
  });
170
171
  }
171
172
  //#endregion
172
- export { createHonoHeaders as a, createObjectHeaders as c, createHonoCookies as i, createApiGatewayHeaders as n, createNoopCookies as o, createCookieHeaderAccessor as r, createNoopHeaders as s, createApiGatewayCookies as t };
173
+ //#region src/endpoints/readRequestBody.ts
174
+ /**
175
+ * The media types an endpoint's `.body()` schema can be handed — as written
176
+ * in the 415 a request in any other type is answered with.
177
+ */
178
+ const SUPPORTED_BODY_TYPES = [
179
+ "application/json",
180
+ "application/x-www-form-urlencoded",
181
+ "multipart/form-data",
182
+ "text/*"
183
+ ];
184
+ /**
185
+ * A request whose body is in a media type no endpoint reads — XML, a bare
186
+ * octet stream. Answered with a 415, before the body schema runs.
187
+ */
188
+ var UnsupportedRequestContentType = class extends HttpError {
189
+ contentType;
190
+ constructor(contentType) {
191
+ super(415, `A body sent as '${contentType}' can't be read. Send it as ${SUPPORTED_BODY_TYPES.join(", ")}.`, {
192
+ statusMessage: "Unsupported Media Type",
193
+ details: {
194
+ contentType,
195
+ supported: [...SUPPORTED_BODY_TYPES]
196
+ }
197
+ });
198
+ this.contentType = contentType;
199
+ this.name = "UnsupportedRequestContentType";
200
+ }
201
+ };
202
+ /**
203
+ * A body that says it is JSON and is not. Answered with a 400 — the request
204
+ * is broken, not merely invalid against the schema.
205
+ */
206
+ var MalformedRequestBody = class extends HttpError {
207
+ contentType;
208
+ constructor(contentType, cause) {
209
+ super(400, `The body says it is '${contentType}' but can't be parsed as that. Send a well-formed body, with the Content-Type it is written in.`, { cause });
210
+ this.contentType = contentType;
211
+ this.name = "MalformedRequestBody";
212
+ }
213
+ };
214
+ /**
215
+ * A request body, read by its Content-Type into what an endpoint's `.body()`
216
+ * schema validates — the one place every adaptor reads a body:
217
+ *
218
+ * - `application/json` (and `application/*+json`) — the parsed JSON.
219
+ * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain
220
+ * object of fields, as an HTML form posts them. A repeated field, or one
221
+ * named `field[]`, is an array; a file part is a `File`.
222
+ * - `text/*` — the text.
223
+ *
224
+ * Anything else is an {@link UnsupportedRequestContentType}.
225
+ */
226
+ async function readRequestBody(source, contentType, options) {
227
+ const mediaType = contentType?.split(";")[0]?.trim().toLowerCase();
228
+ if (!mediaType) {
229
+ if (options.untyped === "empty") return {};
230
+ return readJson(source, "application/json");
231
+ }
232
+ if (isJson(mediaType)) return readJson(source, mediaType);
233
+ if (mediaType === "application/x-www-form-urlencoded" || mediaType === "multipart/form-data") return formFields(await readForm(source, mediaType));
234
+ if (mediaType.startsWith("text/")) return source.text();
235
+ throw new UnsupportedRequestContentType(mediaType);
236
+ }
237
+ function isJson(mediaType) {
238
+ return mediaType === "application/json" || mediaType.startsWith("application/") && mediaType.endsWith("+json");
239
+ }
240
+ async function readJson(source, mediaType) {
241
+ try {
242
+ return await source.json();
243
+ } catch (error) {
244
+ throw new MalformedRequestBody(mediaType, error);
245
+ }
246
+ }
247
+ async function readForm(source, mediaType) {
248
+ try {
249
+ return await source.formData();
250
+ } catch (error) {
251
+ throw new MalformedRequestBody(mediaType, error);
252
+ }
253
+ }
254
+ /**
255
+ * A form's fields as an object, the way Hono's `parseBody({ all: true })`
256
+ * reads them. Without a prototype, so a field named `__proto__` is a field.
257
+ */
258
+ function formFields(form) {
259
+ const fields = Object.create(null);
260
+ for (const [key, value] of form.entries()) {
261
+ const existing = fields[key];
262
+ if (existing === void 0) fields[key] = key.endsWith("[]") ? [value] : value;
263
+ else if (Array.isArray(existing)) existing.push(value);
264
+ else fields[key] = [existing, value];
265
+ }
266
+ return fields;
267
+ }
268
+ //#endregion
269
+ export { createApiGatewayCookies as a, createHonoCookies as c, createNoopHeaders as d, createObjectHeaders as f, readRequestBody as i, createHonoHeaders as l, SUPPORTED_BODY_TYPES as n, createApiGatewayHeaders as o, UnsupportedRequestContentType as r, createCookieHeaderAccessor as s, MalformedRequestBody as t, createNoopCookies as u };
173
270
 
174
- //# sourceMappingURL=lazyAccessors-CFanua0O.mjs.map
271
+ //# sourceMappingURL=readRequestBody-BTIl3k-D.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readRequestBody-BTIl3k-D.mjs","names":[],"sources":["../src/endpoints/lazyAccessors.ts","../src/endpoints/readRequestBody.ts"],"sourcesContent":["/**\n * Lazy header and cookie accessors for different adaptors.\n *\n * Instead of parsing all headers/cookies upfront, these accessors\n * use native adaptor methods for single lookups and only parse\n * everything when `header()` or `cookie()` is called without arguments.\n */\nimport type { Context } from 'hono';\nimport { getCookie } from 'hono/cookie';\nimport type { CookieFn, HeaderFn } from './Endpoint';\n\n/**\n * Create a lazy header accessor for Hono.\n * Uses `c.req.header(name)` for single lookups (native, case-insensitive).\n * Only calls `c.req.header()` to get all headers when needed.\n */\nexport function createHonoHeaders(c: Context): HeaderFn {\n\tlet allHeaders: Record<string, string> | null = null;\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Single header lookup - use native Hono method (case-insensitive)\n\t\t\treturn c.req.header(key);\n\t\t}\n\t\t// Get all headers - cache the result\n\t\tif (!allHeaders) {\n\t\t\tallHeaders = c.req.header();\n\t\t}\n\t\treturn allHeaders;\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor for Hono.\n * Uses `getCookie(c, name)` for single lookups (native).\n * Only parses the cookie header when all cookies are requested.\n */\nexport function createHonoCookies(c: Context): CookieFn {\n\tlet allCookies: Record<string, string> | null = null;\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\t// Single cookie lookup - use native Hono method\n\t\t\treturn getCookie(c, name);\n\t\t}\n\t\t// Get all cookies - parse and cache\n\t\tif (!allCookies) {\n\t\t\tallCookies = {};\n\t\t\tconst cookieHeader = c.req.header('cookie');\n\t\t\tif (cookieHeader) {\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\tallCookies[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allCookies;\n\t}) as CookieFn;\n}\n\n/**\n * Create a lazy header accessor for API Gateway events.\n * Handles case-insensitive lookups.\n */\nexport function createApiGatewayHeaders(\n\theaders: Record<string, string | undefined> | null | undefined,\n): HeaderFn {\n\tlet normalizedHeaders: Record<string, string> | null = null;\n\n\tconst normalize = () => {\n\t\tif (!normalizedHeaders) {\n\t\t\tnormalizedHeaders = {};\n\t\t\tif (headers) {\n\t\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\t\tif (v !== undefined) {\n\t\t\t\t\t\tnormalizedHeaders[k.toLowerCase()] = v;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn normalizedHeaders;\n\t};\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Try direct lookup first (common case: headers already lowercase)\n\t\t\tif (headers) {\n\t\t\t\tconst direct = headers[key] ?? headers[key.toLowerCase()];\n\t\t\t\tif (direct !== undefined) return direct;\n\t\t\t\t// Fall back to normalized lookup\n\t\t\t\treturn normalize()[key.toLowerCase()];\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn normalize();\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor for API Gateway events.\n * Decodes URL-encoded values to match browser behavior.\n */\nexport function createApiGatewayCookies(\n\tcookies: string[] | undefined,\n\tcookieHeader: string | undefined,\n): CookieFn {\n\tlet parsed: Record<string, string> | null = null;\n\n\tconst parse = () => {\n\t\tif (!parsed) {\n\t\t\tparsed = {};\n\t\t\t// API Gateway v2 provides cookies as array\n\t\t\tif (cookies) {\n\t\t\t\tfor (const cookie of cookies) {\n\t\t\t\t\tconst eqIndex = cookie.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = cookie.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = cookie.slice(eqIndex + 1);\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (cookieHeader) {\n\t\t\t\t// Fall back to parsing cookie header\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn parsed;\n\t};\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\treturn parse()[name];\n\t\t}\n\t\treturn parse();\n\t}) as CookieFn;\n}\n\n/**\n * Create a lazy header accessor for plain object headers (test adaptor, etc).\n * Headers are already available as an object, just provide lazy access.\n */\nexport function createObjectHeaders(\n\theaders: Record<string, string> | undefined,\n): HeaderFn {\n\tlet normalized: Record<string, string> | null = null;\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Try direct lookup first (common case)\n\t\t\tif (headers) {\n\t\t\t\tconst direct = headers[key] ?? headers[key.toLowerCase()];\n\t\t\t\tif (direct !== undefined) return direct;\n\t\t\t}\n\t\t\t// Fall back to normalized lookup for case-insensitivity\n\t\t\tif (!normalized && headers) {\n\t\t\t\tnormalized = {};\n\t\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\t\tnormalized[k.toLowerCase()] = v;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn normalized?.[key.toLowerCase()];\n\t\t}\n\t\t// Return all headers\n\t\tif (!normalized && headers) {\n\t\t\tnormalized = {};\n\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\tnormalized[k.toLowerCase()] = v;\n\t\t\t}\n\t\t}\n\t\treturn normalized ?? {};\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor from a cookie header string.\n * Decodes URL-encoded values to match browser behavior.\n */\nexport function createCookieHeaderAccessor(\n\tcookieHeader: string | undefined,\n): CookieFn {\n\tlet parsed: Record<string, string> | null = null;\n\n\tconst parse = () => {\n\t\tif (!parsed) {\n\t\t\tparsed = {};\n\t\t\tif (cookieHeader) {\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\t// Decode URL-encoded values to match Endpoint.createCookies behavior\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn parsed;\n\t};\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\treturn parse()[name];\n\t\t}\n\t\treturn parse();\n\t}) as CookieFn;\n}\n\n/**\n * Create a no-op header accessor (for minimal endpoints that don't use headers).\n */\nexport function createNoopHeaders(): HeaderFn {\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) return undefined;\n\t\treturn {};\n\t}) as HeaderFn;\n}\n\n/**\n * Create a no-op cookie accessor (for minimal endpoints that don't use cookies).\n */\nexport function createNoopCookies(): CookieFn {\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) return undefined;\n\t\treturn {};\n\t}) as CookieFn;\n}\n","import { HttpError } from '@geekmidas/errors';\n\n/**\n * The media types an endpoint's `.body()` schema can be handed — as written\n * in the 415 a request in any other type is answered with.\n */\nexport const SUPPORTED_BODY_TYPES = [\n\t'application/json',\n\t'application/x-www-form-urlencoded',\n\t'multipart/form-data',\n\t'text/*',\n] as const;\n\n/**\n * A request whose body is in a media type no endpoint reads — XML, a bare\n * octet stream. Answered with a 415, before the body schema runs.\n */\nexport class UnsupportedRequestContentType extends HttpError {\n\tconstructor(readonly contentType: string) {\n\t\tsuper(\n\t\t\t415,\n\t\t\t`A body sent as '${contentType}' can't be read. Send it as ${SUPPORTED_BODY_TYPES.join(', ')}.`,\n\t\t\t{\n\t\t\t\tstatusMessage: 'Unsupported Media Type',\n\t\t\t\tdetails: { contentType, supported: [...SUPPORTED_BODY_TYPES] },\n\t\t\t},\n\t\t);\n\t\tthis.name = 'UnsupportedRequestContentType';\n\t}\n}\n\n/**\n * A body that says it is JSON and is not. Answered with a 400 — the request\n * is broken, not merely invalid against the schema.\n */\nexport class MalformedRequestBody extends HttpError {\n\tconstructor(\n\t\treadonly contentType: string,\n\t\tcause?: Error,\n\t) {\n\t\tsuper(\n\t\t\t400,\n\t\t\t`The body says it is '${contentType}' but can't be parsed as that. Send a well-formed body, with the Content-Type it is written in.`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = 'MalformedRequestBody';\n\t}\n}\n\n/**\n * What a body is read from: a `Request`, or Hono's request — which caches\n * what it read, so a later reader is not handed a spent stream.\n */\nexport interface RequestBodySource {\n\tjson(): Promise<unknown>;\n\ttext(): Promise<string>;\n\tformData(): Promise<FormData>;\n}\n\nexport interface ReadRequestBodyOptions {\n\t/**\n\t * A body with no Content-Type: read as JSON (`'json'`, what API Gateway\n\t * has always done), or not read at all and handed to the schema as `{}`\n\t * (`'empty'`, what a Hono server has always done).\n\t */\n\tuntyped: 'json' | 'empty';\n}\n\n/**\n * A request body, read by its Content-Type into what an endpoint's `.body()`\n * schema validates — the one place every adaptor reads a body:\n *\n * - `application/json` (and `application/*+json`) — the parsed JSON.\n * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain\n * object of fields, as an HTML form posts them. A repeated field, or one\n * named `field[]`, is an array; a file part is a `File`.\n * - `text/*` — the text.\n *\n * Anything else is an {@link UnsupportedRequestContentType}.\n */\nexport async function readRequestBody(\n\tsource: RequestBodySource,\n\tcontentType: string | null | undefined,\n\toptions: ReadRequestBodyOptions,\n): Promise<unknown> {\n\tconst mediaType = contentType?.split(';')[0]?.trim().toLowerCase();\n\n\tif (!mediaType) {\n\t\tif (options.untyped === 'empty') return {};\n\t\treturn readJson(source, 'application/json');\n\t}\n\n\tif (isJson(mediaType)) return readJson(source, mediaType);\n\n\tif (\n\t\tmediaType === 'application/x-www-form-urlencoded' ||\n\t\tmediaType === 'multipart/form-data'\n\t) {\n\t\treturn formFields(await readForm(source, mediaType));\n\t}\n\n\tif (mediaType.startsWith('text/')) return source.text();\n\n\tthrow new UnsupportedRequestContentType(mediaType);\n}\n\nfunction isJson(mediaType: string): boolean {\n\treturn (\n\t\tmediaType === 'application/json' ||\n\t\t(mediaType.startsWith('application/') && mediaType.endsWith('+json'))\n\t);\n}\n\nasync function readJson(\n\tsource: RequestBodySource,\n\tmediaType: string,\n): Promise<unknown> {\n\ttry {\n\t\treturn await source.json();\n\t} catch (error) {\n\t\tthrow new MalformedRequestBody(mediaType, error as Error);\n\t}\n}\n\nasync function readForm(\n\tsource: RequestBodySource,\n\tmediaType: string,\n): Promise<FormData> {\n\ttry {\n\t\treturn await source.formData();\n\t} catch (error) {\n\t\tthrow new MalformedRequestBody(mediaType, error as Error);\n\t}\n}\n\n/** A form field's value: its text, or a `File` for a file part. */\ntype FormValue = NonNullable<ReturnType<FormData['get']>>;\n\n/**\n * A form's fields as an object, the way Hono's `parseBody({ all: true })`\n * reads them. Without a prototype, so a field named `__proto__` is a field.\n */\nfunction formFields(form: FormData): Record<string, FormValue | FormValue[]> {\n\tconst fields: Record<string, FormValue | FormValue[]> = Object.create(null);\n\n\tfor (const [key, value] of form.entries()) {\n\t\tconst existing = fields[key];\n\t\tif (existing === undefined) {\n\t\t\tfields[key] = key.endsWith('[]') ? [value] : value;\n\t\t} else if (Array.isArray(existing)) {\n\t\t\texisting.push(value);\n\t\t} else {\n\t\t\tfields[key] = [existing, value];\n\t\t}\n\t}\n\n\treturn fields;\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ let _geekmidas_errors = require("@geekmidas/errors");
1
2
  let hono_cookie = require("hono/cookie");
2
3
  //#region src/endpoints/lazyAccessors.ts
3
4
  /**
@@ -169,6 +170,120 @@ function createNoopCookies() {
169
170
  });
170
171
  }
171
172
  //#endregion
173
+ //#region src/endpoints/readRequestBody.ts
174
+ /**
175
+ * The media types an endpoint's `.body()` schema can be handed — as written
176
+ * in the 415 a request in any other type is answered with.
177
+ */
178
+ const SUPPORTED_BODY_TYPES = [
179
+ "application/json",
180
+ "application/x-www-form-urlencoded",
181
+ "multipart/form-data",
182
+ "text/*"
183
+ ];
184
+ /**
185
+ * A request whose body is in a media type no endpoint reads — XML, a bare
186
+ * octet stream. Answered with a 415, before the body schema runs.
187
+ */
188
+ var UnsupportedRequestContentType = class extends _geekmidas_errors.HttpError {
189
+ contentType;
190
+ constructor(contentType) {
191
+ super(415, `A body sent as '${contentType}' can't be read. Send it as ${SUPPORTED_BODY_TYPES.join(", ")}.`, {
192
+ statusMessage: "Unsupported Media Type",
193
+ details: {
194
+ contentType,
195
+ supported: [...SUPPORTED_BODY_TYPES]
196
+ }
197
+ });
198
+ this.contentType = contentType;
199
+ this.name = "UnsupportedRequestContentType";
200
+ }
201
+ };
202
+ /**
203
+ * A body that says it is JSON and is not. Answered with a 400 — the request
204
+ * is broken, not merely invalid against the schema.
205
+ */
206
+ var MalformedRequestBody = class extends _geekmidas_errors.HttpError {
207
+ contentType;
208
+ constructor(contentType, cause) {
209
+ super(400, `The body says it is '${contentType}' but can't be parsed as that. Send a well-formed body, with the Content-Type it is written in.`, { cause });
210
+ this.contentType = contentType;
211
+ this.name = "MalformedRequestBody";
212
+ }
213
+ };
214
+ /**
215
+ * A request body, read by its Content-Type into what an endpoint's `.body()`
216
+ * schema validates — the one place every adaptor reads a body:
217
+ *
218
+ * - `application/json` (and `application/*+json`) — the parsed JSON.
219
+ * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain
220
+ * object of fields, as an HTML form posts them. A repeated field, or one
221
+ * named `field[]`, is an array; a file part is a `File`.
222
+ * - `text/*` — the text.
223
+ *
224
+ * Anything else is an {@link UnsupportedRequestContentType}.
225
+ */
226
+ async function readRequestBody(source, contentType, options) {
227
+ const mediaType = contentType?.split(";")[0]?.trim().toLowerCase();
228
+ if (!mediaType) {
229
+ if (options.untyped === "empty") return {};
230
+ return readJson(source, "application/json");
231
+ }
232
+ if (isJson(mediaType)) return readJson(source, mediaType);
233
+ if (mediaType === "application/x-www-form-urlencoded" || mediaType === "multipart/form-data") return formFields(await readForm(source, mediaType));
234
+ if (mediaType.startsWith("text/")) return source.text();
235
+ throw new UnsupportedRequestContentType(mediaType);
236
+ }
237
+ function isJson(mediaType) {
238
+ return mediaType === "application/json" || mediaType.startsWith("application/") && mediaType.endsWith("+json");
239
+ }
240
+ async function readJson(source, mediaType) {
241
+ try {
242
+ return await source.json();
243
+ } catch (error) {
244
+ throw new MalformedRequestBody(mediaType, error);
245
+ }
246
+ }
247
+ async function readForm(source, mediaType) {
248
+ try {
249
+ return await source.formData();
250
+ } catch (error) {
251
+ throw new MalformedRequestBody(mediaType, error);
252
+ }
253
+ }
254
+ /**
255
+ * A form's fields as an object, the way Hono's `parseBody({ all: true })`
256
+ * reads them. Without a prototype, so a field named `__proto__` is a field.
257
+ */
258
+ function formFields(form) {
259
+ const fields = Object.create(null);
260
+ for (const [key, value] of form.entries()) {
261
+ const existing = fields[key];
262
+ if (existing === void 0) fields[key] = key.endsWith("[]") ? [value] : value;
263
+ else if (Array.isArray(existing)) existing.push(value);
264
+ else fields[key] = [existing, value];
265
+ }
266
+ return fields;
267
+ }
268
+ //#endregion
269
+ Object.defineProperty(exports, "MalformedRequestBody", {
270
+ enumerable: true,
271
+ get: function() {
272
+ return MalformedRequestBody;
273
+ }
274
+ });
275
+ Object.defineProperty(exports, "SUPPORTED_BODY_TYPES", {
276
+ enumerable: true,
277
+ get: function() {
278
+ return SUPPORTED_BODY_TYPES;
279
+ }
280
+ });
281
+ Object.defineProperty(exports, "UnsupportedRequestContentType", {
282
+ enumerable: true,
283
+ get: function() {
284
+ return UnsupportedRequestContentType;
285
+ }
286
+ });
172
287
  Object.defineProperty(exports, "createApiGatewayCookies", {
173
288
  enumerable: true,
174
289
  get: function() {
@@ -217,5 +332,11 @@ Object.defineProperty(exports, "createObjectHeaders", {
217
332
  return createObjectHeaders;
218
333
  }
219
334
  });
335
+ Object.defineProperty(exports, "readRequestBody", {
336
+ enumerable: true,
337
+ get: function() {
338
+ return readRequestBody;
339
+ }
340
+ });
220
341
 
221
- //# sourceMappingURL=lazyAccessors-hJKGv8Ay.cjs.map
342
+ //# sourceMappingURL=readRequestBody-Dej_L3c4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readRequestBody-Dej_L3c4.cjs","names":["getCookie","HttpError"],"sources":["../src/endpoints/lazyAccessors.ts","../src/endpoints/readRequestBody.ts"],"sourcesContent":["/**\n * Lazy header and cookie accessors for different adaptors.\n *\n * Instead of parsing all headers/cookies upfront, these accessors\n * use native adaptor methods for single lookups and only parse\n * everything when `header()` or `cookie()` is called without arguments.\n */\nimport type { Context } from 'hono';\nimport { getCookie } from 'hono/cookie';\nimport type { CookieFn, HeaderFn } from './Endpoint';\n\n/**\n * Create a lazy header accessor for Hono.\n * Uses `c.req.header(name)` for single lookups (native, case-insensitive).\n * Only calls `c.req.header()` to get all headers when needed.\n */\nexport function createHonoHeaders(c: Context): HeaderFn {\n\tlet allHeaders: Record<string, string> | null = null;\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Single header lookup - use native Hono method (case-insensitive)\n\t\t\treturn c.req.header(key);\n\t\t}\n\t\t// Get all headers - cache the result\n\t\tif (!allHeaders) {\n\t\t\tallHeaders = c.req.header();\n\t\t}\n\t\treturn allHeaders;\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor for Hono.\n * Uses `getCookie(c, name)` for single lookups (native).\n * Only parses the cookie header when all cookies are requested.\n */\nexport function createHonoCookies(c: Context): CookieFn {\n\tlet allCookies: Record<string, string> | null = null;\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\t// Single cookie lookup - use native Hono method\n\t\t\treturn getCookie(c, name);\n\t\t}\n\t\t// Get all cookies - parse and cache\n\t\tif (!allCookies) {\n\t\t\tallCookies = {};\n\t\t\tconst cookieHeader = c.req.header('cookie');\n\t\t\tif (cookieHeader) {\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\tallCookies[key] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allCookies;\n\t}) as CookieFn;\n}\n\n/**\n * Create a lazy header accessor for API Gateway events.\n * Handles case-insensitive lookups.\n */\nexport function createApiGatewayHeaders(\n\theaders: Record<string, string | undefined> | null | undefined,\n): HeaderFn {\n\tlet normalizedHeaders: Record<string, string> | null = null;\n\n\tconst normalize = () => {\n\t\tif (!normalizedHeaders) {\n\t\t\tnormalizedHeaders = {};\n\t\t\tif (headers) {\n\t\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\t\tif (v !== undefined) {\n\t\t\t\t\t\tnormalizedHeaders[k.toLowerCase()] = v;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn normalizedHeaders;\n\t};\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Try direct lookup first (common case: headers already lowercase)\n\t\t\tif (headers) {\n\t\t\t\tconst direct = headers[key] ?? headers[key.toLowerCase()];\n\t\t\t\tif (direct !== undefined) return direct;\n\t\t\t\t// Fall back to normalized lookup\n\t\t\t\treturn normalize()[key.toLowerCase()];\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn normalize();\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor for API Gateway events.\n * Decodes URL-encoded values to match browser behavior.\n */\nexport function createApiGatewayCookies(\n\tcookies: string[] | undefined,\n\tcookieHeader: string | undefined,\n): CookieFn {\n\tlet parsed: Record<string, string> | null = null;\n\n\tconst parse = () => {\n\t\tif (!parsed) {\n\t\t\tparsed = {};\n\t\t\t// API Gateway v2 provides cookies as array\n\t\t\tif (cookies) {\n\t\t\t\tfor (const cookie of cookies) {\n\t\t\t\t\tconst eqIndex = cookie.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = cookie.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = cookie.slice(eqIndex + 1);\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (cookieHeader) {\n\t\t\t\t// Fall back to parsing cookie header\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn parsed;\n\t};\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\treturn parse()[name];\n\t\t}\n\t\treturn parse();\n\t}) as CookieFn;\n}\n\n/**\n * Create a lazy header accessor for plain object headers (test adaptor, etc).\n * Headers are already available as an object, just provide lazy access.\n */\nexport function createObjectHeaders(\n\theaders: Record<string, string> | undefined,\n): HeaderFn {\n\tlet normalized: Record<string, string> | null = null;\n\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) {\n\t\t\t// Try direct lookup first (common case)\n\t\t\tif (headers) {\n\t\t\t\tconst direct = headers[key] ?? headers[key.toLowerCase()];\n\t\t\t\tif (direct !== undefined) return direct;\n\t\t\t}\n\t\t\t// Fall back to normalized lookup for case-insensitivity\n\t\t\tif (!normalized && headers) {\n\t\t\t\tnormalized = {};\n\t\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\t\tnormalized[k.toLowerCase()] = v;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn normalized?.[key.toLowerCase()];\n\t\t}\n\t\t// Return all headers\n\t\tif (!normalized && headers) {\n\t\t\tnormalized = {};\n\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\tnormalized[k.toLowerCase()] = v;\n\t\t\t}\n\t\t}\n\t\treturn normalized ?? {};\n\t}) as HeaderFn;\n}\n\n/**\n * Create a lazy cookie accessor from a cookie header string.\n * Decodes URL-encoded values to match browser behavior.\n */\nexport function createCookieHeaderAccessor(\n\tcookieHeader: string | undefined,\n): CookieFn {\n\tlet parsed: Record<string, string> | null = null;\n\n\tconst parse = () => {\n\t\tif (!parsed) {\n\t\t\tparsed = {};\n\t\t\tif (cookieHeader) {\n\t\t\t\tfor (const part of cookieHeader.split(';')) {\n\t\t\t\t\tconst trimmed = part.trim();\n\t\t\t\t\tconst eqIndex = trimmed.indexOf('=');\n\t\t\t\t\tif (eqIndex > 0) {\n\t\t\t\t\t\tconst key = trimmed.slice(0, eqIndex);\n\t\t\t\t\t\tconst value = trimmed.slice(eqIndex + 1);\n\t\t\t\t\t\t// Decode URL-encoded values to match Endpoint.createCookies behavior\n\t\t\t\t\t\tparsed[key] = decodeURIComponent(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn parsed;\n\t};\n\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) {\n\t\t\treturn parse()[name];\n\t\t}\n\t\treturn parse();\n\t}) as CookieFn;\n}\n\n/**\n * Create a no-op header accessor (for minimal endpoints that don't use headers).\n */\nexport function createNoopHeaders(): HeaderFn {\n\treturn ((key?: string) => {\n\t\tif (key !== undefined) return undefined;\n\t\treturn {};\n\t}) as HeaderFn;\n}\n\n/**\n * Create a no-op cookie accessor (for minimal endpoints that don't use cookies).\n */\nexport function createNoopCookies(): CookieFn {\n\treturn ((name?: string) => {\n\t\tif (name !== undefined) return undefined;\n\t\treturn {};\n\t}) as CookieFn;\n}\n","import { HttpError } from '@geekmidas/errors';\n\n/**\n * The media types an endpoint's `.body()` schema can be handed — as written\n * in the 415 a request in any other type is answered with.\n */\nexport const SUPPORTED_BODY_TYPES = [\n\t'application/json',\n\t'application/x-www-form-urlencoded',\n\t'multipart/form-data',\n\t'text/*',\n] as const;\n\n/**\n * A request whose body is in a media type no endpoint reads — XML, a bare\n * octet stream. Answered with a 415, before the body schema runs.\n */\nexport class UnsupportedRequestContentType extends HttpError {\n\tconstructor(readonly contentType: string) {\n\t\tsuper(\n\t\t\t415,\n\t\t\t`A body sent as '${contentType}' can't be read. Send it as ${SUPPORTED_BODY_TYPES.join(', ')}.`,\n\t\t\t{\n\t\t\t\tstatusMessage: 'Unsupported Media Type',\n\t\t\t\tdetails: { contentType, supported: [...SUPPORTED_BODY_TYPES] },\n\t\t\t},\n\t\t);\n\t\tthis.name = 'UnsupportedRequestContentType';\n\t}\n}\n\n/**\n * A body that says it is JSON and is not. Answered with a 400 — the request\n * is broken, not merely invalid against the schema.\n */\nexport class MalformedRequestBody extends HttpError {\n\tconstructor(\n\t\treadonly contentType: string,\n\t\tcause?: Error,\n\t) {\n\t\tsuper(\n\t\t\t400,\n\t\t\t`The body says it is '${contentType}' but can't be parsed as that. Send a well-formed body, with the Content-Type it is written in.`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = 'MalformedRequestBody';\n\t}\n}\n\n/**\n * What a body is read from: a `Request`, or Hono's request — which caches\n * what it read, so a later reader is not handed a spent stream.\n */\nexport interface RequestBodySource {\n\tjson(): Promise<unknown>;\n\ttext(): Promise<string>;\n\tformData(): Promise<FormData>;\n}\n\nexport interface ReadRequestBodyOptions {\n\t/**\n\t * A body with no Content-Type: read as JSON (`'json'`, what API Gateway\n\t * has always done), or not read at all and handed to the schema as `{}`\n\t * (`'empty'`, what a Hono server has always done).\n\t */\n\tuntyped: 'json' | 'empty';\n}\n\n/**\n * A request body, read by its Content-Type into what an endpoint's `.body()`\n * schema validates — the one place every adaptor reads a body:\n *\n * - `application/json` (and `application/*+json`) — the parsed JSON.\n * - `application/x-www-form-urlencoded` and `multipart/form-data` — a plain\n * object of fields, as an HTML form posts them. A repeated field, or one\n * named `field[]`, is an array; a file part is a `File`.\n * - `text/*` — the text.\n *\n * Anything else is an {@link UnsupportedRequestContentType}.\n */\nexport async function readRequestBody(\n\tsource: RequestBodySource,\n\tcontentType: string | null | undefined,\n\toptions: ReadRequestBodyOptions,\n): Promise<unknown> {\n\tconst mediaType = contentType?.split(';')[0]?.trim().toLowerCase();\n\n\tif (!mediaType) {\n\t\tif (options.untyped === 'empty') return {};\n\t\treturn readJson(source, 'application/json');\n\t}\n\n\tif (isJson(mediaType)) return readJson(source, mediaType);\n\n\tif (\n\t\tmediaType === 'application/x-www-form-urlencoded' ||\n\t\tmediaType === 'multipart/form-data'\n\t) {\n\t\treturn formFields(await readForm(source, mediaType));\n\t}\n\n\tif (mediaType.startsWith('text/')) return source.text();\n\n\tthrow new UnsupportedRequestContentType(mediaType);\n}\n\nfunction isJson(mediaType: string): boolean {\n\treturn (\n\t\tmediaType === 'application/json' ||\n\t\t(mediaType.startsWith('application/') && mediaType.endsWith('+json'))\n\t);\n}\n\nasync function readJson(\n\tsource: RequestBodySource,\n\tmediaType: string,\n): Promise<unknown> {\n\ttry {\n\t\treturn await source.json();\n\t} catch (error) {\n\t\tthrow new MalformedRequestBody(mediaType, error as Error);\n\t}\n}\n\nasync function readForm(\n\tsource: RequestBodySource,\n\tmediaType: string,\n): Promise<FormData> {\n\ttry {\n\t\treturn await source.formData();\n\t} catch (error) {\n\t\tthrow new MalformedRequestBody(mediaType, error as Error);\n\t}\n}\n\n/** A form field's value: its text, or a `File` for a file part. */\ntype FormValue = NonNullable<ReturnType<FormData['get']>>;\n\n/**\n * A form's fields as an object, the way Hono's `parseBody({ all: true })`\n * reads them. Without a prototype, so a field named `__proto__` is a field.\n */\nfunction formFields(form: FormData): Record<string, FormValue | FormValue[]> {\n\tconst fields: Record<string, FormValue | FormValue[]> = Object.create(null);\n\n\tfor (const [key, value] of form.entries()) {\n\t\tconst existing = fields[key];\n\t\tif (existing === undefined) {\n\t\t\tfields[key] = key.endsWith('[]') ? [value] : value;\n\t\t} else if (Array.isArray(existing)) {\n\t\t\texisting.push(value);\n\t\t} else {\n\t\t\tfields[key] = [existing, value];\n\t\t}\n\t}\n\n\treturn fields;\n}\n"],"mappings":"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"}
package/dist/rest-api.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_construct_interface = require("./construct-interface.cjs");
3
- const require_EndpointFactory = require("./EndpointFactory-DJ7gXLpR.cjs");
3
+ const require_EndpointFactory = require("./EndpointFactory-DeZTvDjU.cjs");
4
4
  const require_surfaceEnv = require("./surfaceEnv-CNimK76p.cjs");
5
5
  let _geekmidas_manifest = require("@geekmidas/manifest");
6
6
  let _geekmidas_logger_console = require("@geekmidas/logger/console");
@@ -1,7 +1,7 @@
1
1
  import { i as Declarable, t as Authenticator } from "./construct-interface-B1AfqRl4.cjs";
2
2
  import { n as Telemetry } from "./telemetry-B48RLjyk.cjs";
3
- import { T as BuiltInSecuritySchemeId } from "./Endpoint-aCvBMPoH.cjs";
4
- import { t as EndpointFactory } from "./EndpointFactory-I7s1co3Y.cjs";
3
+ import { D as BuiltInSecuritySchemeId } from "./Endpoint-BWyKCa2x.cjs";
4
+ import { t as EndpointFactory } from "./EndpointFactory-C1-IBwm4.cjs";
5
5
  import { EnvironmentParser } from "@geekmidas/envkit";
6
6
  import { Logger } from "@geekmidas/logger";
7
7
  import { ConstructName, Declaration, Dependency } from "@geekmidas/manifest";
@@ -1,7 +1,7 @@
1
1
  import { i as Declarable, t as Authenticator } from "./construct-interface-DluK3_da.mjs";
2
2
  import { n as Telemetry } from "./telemetry-DRtT1_0A.mjs";
3
- import { T as BuiltInSecuritySchemeId } from "./Endpoint-Du-NwPX2.mjs";
4
- import { t as EndpointFactory } from "./EndpointFactory-DMYdJCOj.mjs";
3
+ import { D as BuiltInSecuritySchemeId } from "./Endpoint-C3r2OzOD.mjs";
4
+ import { t as EndpointFactory } from "./EndpointFactory-C9eVhDKF.mjs";
5
5
  import { ConstructName, Declaration, Dependency } from "@geekmidas/manifest";
6
6
  import { EnvironmentParser } from "@geekmidas/envkit";
7
7
  import { Logger } from "@geekmidas/logger";
package/dist/rest-api.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { edgeTo } from "./construct-interface.mjs";
2
- import { o as getSecurityScheme, t as EndpointFactory } from "./EndpointFactory-BDtsrEvJ.mjs";
2
+ import { o as getSecurityScheme, t as EndpointFactory } from "./EndpointFactory-Bbmx4vXc.mjs";
3
3
  import { n as envParserFor } from "./surfaceEnv-wMT5QzgZ.mjs";
4
4
  import { canonicalId, provideKey } from "@geekmidas/manifest";
5
5
  import { DEFAULT_LOGGER } from "@geekmidas/logger/console";