@owlmeans/server-api 0.1.18-rc.8 → 0.1.18

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 (140) hide show
  1. package/README.md +203 -46
  2. package/agent-meta/manifest.json +3 -3
  3. package/agent-meta/skills/server-api/SKILL.md +142 -22
  4. package/build/consts.local.d.ts +2 -0
  5. package/build/consts.local.d.ts.map +1 -0
  6. package/build/consts.local.js +2 -0
  7. package/build/consts.local.js.map +1 -0
  8. package/build/errors.d.ts +12 -0
  9. package/build/errors.d.ts.map +1 -1
  10. package/build/errors.js +16 -0
  11. package/build/errors.js.map +1 -1
  12. package/build/helper.d.ts +3 -6
  13. package/build/helper.d.ts.map +1 -1
  14. package/build/helper.js +10 -1
  15. package/build/helper.js.map +1 -1
  16. package/build/hold.d.ts +35 -0
  17. package/build/hold.d.ts.map +1 -0
  18. package/build/hold.js +57 -0
  19. package/build/hold.js.map +1 -0
  20. package/build/index.d.ts +2 -0
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +2 -0
  23. package/build/index.js.map +1 -1
  24. package/build/protocol.d.ts +18 -0
  25. package/build/protocol.d.ts.map +1 -0
  26. package/build/protocol.js +87 -0
  27. package/build/protocol.js.map +1 -0
  28. package/build/server.d.ts +2 -3
  29. package/build/server.d.ts.map +1 -1
  30. package/build/server.js +42 -34
  31. package/build/server.js.map +1 -1
  32. package/build/types.d.ts +31 -2
  33. package/build/types.d.ts.map +1 -1
  34. package/build/types.local.d.ts +38 -0
  35. package/build/types.local.d.ts.map +1 -0
  36. package/build/types.local.js +2 -0
  37. package/build/types.local.js.map +1 -0
  38. package/build/utils/consts.d.ts +2 -0
  39. package/build/utils/consts.d.ts.map +1 -0
  40. package/build/utils/consts.js +2 -0
  41. package/build/utils/consts.js.map +1 -0
  42. package/build/utils/consts.local.d.ts +5 -0
  43. package/build/utils/consts.local.d.ts.map +1 -0
  44. package/build/utils/consts.local.js +5 -0
  45. package/build/utils/consts.local.js.map +1 -0
  46. package/build/utils/context/types.d.ts +13 -0
  47. package/build/utils/context/types.d.ts.map +1 -0
  48. package/build/utils/context/types.js +2 -0
  49. package/build/utils/context/types.js.map +1 -0
  50. package/build/utils/context.d.ts +3 -3
  51. package/build/utils/context.d.ts.map +1 -1
  52. package/build/utils/context.js +5 -2
  53. package/build/utils/context.js.map +1 -1
  54. package/build/utils/error/types.d.ts +52 -0
  55. package/build/utils/error/types.d.ts.map +1 -0
  56. package/build/utils/error/types.js +2 -0
  57. package/build/utils/error/types.js.map +1 -0
  58. package/build/utils/error.d.ts +5 -15
  59. package/build/utils/error.d.ts.map +1 -1
  60. package/build/utils/error.js +134 -29
  61. package/build/utils/error.js.map +1 -1
  62. package/build/utils/guards.d.ts +1 -5
  63. package/build/utils/guards.d.ts.map +1 -1
  64. package/build/utils/guards.js +15 -19
  65. package/build/utils/guards.js.map +1 -1
  66. package/build/utils/index.d.ts +6 -1
  67. package/build/utils/index.d.ts.map +1 -1
  68. package/build/utils/index.js +2 -1
  69. package/build/utils/index.js.map +1 -1
  70. package/build/utils/log/consts.d.ts +14 -0
  71. package/build/utils/log/consts.d.ts.map +1 -0
  72. package/build/utils/log/consts.js +17 -0
  73. package/build/utils/log/consts.js.map +1 -0
  74. package/build/utils/log/types.d.ts +42 -0
  75. package/build/utils/log/types.d.ts.map +1 -0
  76. package/build/utils/log/types.js +2 -0
  77. package/build/utils/log/types.js.map +1 -0
  78. package/build/utils/log.d.ts +4 -0
  79. package/build/utils/log.d.ts.map +1 -0
  80. package/build/utils/log.js +170 -0
  81. package/build/utils/log.js.map +1 -0
  82. package/build/utils/payload/types.d.ts +18 -0
  83. package/build/utils/payload/types.d.ts.map +1 -0
  84. package/build/utils/payload/types.js +2 -0
  85. package/build/utils/payload/types.js.map +1 -0
  86. package/build/utils/payload.d.ts +3 -15
  87. package/build/utils/payload.d.ts.map +1 -1
  88. package/build/utils/payload.js +41 -57
  89. package/build/utils/payload.js.map +1 -1
  90. package/build/utils/schema.d.ts +7 -0
  91. package/build/utils/schema.d.ts.map +1 -0
  92. package/build/utils/schema.js +20 -0
  93. package/build/utils/schema.js.map +1 -0
  94. package/build/utils/server.d.ts +3 -6
  95. package/build/utils/server.d.ts.map +1 -1
  96. package/build/utils/server.js +12 -13
  97. package/build/utils/server.js.map +1 -1
  98. package/build/utils/types.d.ts +18 -0
  99. package/build/utils/types.d.ts.map +1 -0
  100. package/build/utils/types.js +2 -0
  101. package/build/utils/types.js.map +1 -0
  102. package/build/utils/types.local.d.ts +9 -0
  103. package/build/utils/types.local.d.ts.map +1 -0
  104. package/build/utils/types.local.js +2 -0
  105. package/build/utils/types.local.js.map +1 -0
  106. package/package.json +23 -19
  107. package/src/consts.local.ts +1 -0
  108. package/src/errors.ts +18 -0
  109. package/src/helper.ts +13 -8
  110. package/src/hold.ts +66 -0
  111. package/src/index.ts +2 -0
  112. package/src/protocol.ts +149 -0
  113. package/src/server.ts +72 -69
  114. package/src/types.local.ts +44 -0
  115. package/src/types.ts +38 -4
  116. package/src/utils/consts.local.ts +7 -0
  117. package/src/utils/consts.ts +1 -0
  118. package/src/utils/context/types.ts +13 -0
  119. package/src/utils/context.ts +9 -4
  120. package/src/utils/error/types.ts +52 -0
  121. package/src/utils/error.ts +156 -29
  122. package/src/utils/guards.ts +16 -26
  123. package/src/utils/index.ts +6 -1
  124. package/src/utils/log/consts.ts +18 -0
  125. package/src/utils/log/types.ts +43 -0
  126. package/src/utils/log.ts +193 -0
  127. package/src/utils/payload/types.ts +18 -0
  128. package/src/utils/payload.ts +42 -60
  129. package/src/utils/schema.ts +23 -0
  130. package/src/utils/server.ts +16 -21
  131. package/src/utils/types.local.ts +12 -0
  132. package/src/utils/types.ts +18 -0
  133. package/tests/error-status.spec.ts +349 -0
  134. package/tests/handlers.spec.ts +83 -0
  135. package/tests/json-body.spec.ts +72 -0
  136. package/tests/log-adapter.spec.ts +62 -0
  137. package/tests/log-redaction.spec.ts +181 -0
  138. package/tests/tsconfig.json +12 -0
  139. package/tsconfig.json +1 -0
  140. package/build/.gitkeep +0 -0
@@ -0,0 +1,35 @@
1
+ import type { ServerConfig } from '@owlmeans/server-context';
2
+ import type { ApiPortHold, ApiPortHoldOptions } from './types.js';
3
+ /**
4
+ * Own the app's port while the context initializes, and answer for the app until `listen()`
5
+ * takes over.
6
+ *
7
+ * The API server itself cannot do this: it builds its route table from the entrypoints the
8
+ * context knows about, so it can only bind AFTER `init()` resolves — and Fastify refuses new
9
+ * routes once it is listening. Without a hold, the whole boot window, and every way a boot can
10
+ * fail, leaves nothing on the port; the edge then answers a bare upstream connect error that
11
+ * names neither the app nor the reason, which is indistinguishable from a crashed pod or an app
12
+ * that was never installed.
13
+ *
14
+ * So the boot sequence an app wants is:
15
+ *
16
+ * const hold = await holdApiPort(cfg, { okPath, payload }) // bind FIRST
17
+ * try { ...initialize... } catch { record the failure; return } // hold keeps answering
18
+ * await hold.release()
19
+ * await context.getApiServer().listen()
20
+ *
21
+ * Everything that is not the health path answers **503, not 404**: the routes the app really
22
+ * serves do not exist yet, and "no such route" would be a lie that outlives the boot.
23
+ *
24
+ * The port and host are resolved exactly as `listen()` resolves them — from the service's own
25
+ * declaration in `cfg.services[cfg.service]` — so the hold and the server can never disagree
26
+ * about which socket they are trading.
27
+ *
28
+ * A bind failure here (EADDRINUSE above all) throws to the caller and must be treated as fatal:
29
+ * a process that continues past it ends the boot with nothing listening and nothing holding the
30
+ * event loop, i.e. a clean exit 0 while a predecessor keeps serving stale code. Name the error
31
+ * and exit non-zero — that is what makes a supervisor reclaim the port instead of respawning
32
+ * into it.
33
+ */
34
+ export declare const holdApiPort: (cfg: ServerConfig, opts?: ApiPortHoldOptions) => Promise<ApiPortHold>;
35
+ //# sourceMappingURL=hold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hold.d.ts","sourceRoot":"","sources":["../src/hold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,WAAW,QACjB,YAAY,SAAQ,kBAAkB,KAC1C,OAAO,CAAC,WAAW,CA0BrB,CAAA"}
package/build/hold.js ADDED
@@ -0,0 +1,57 @@
1
+ import Fastify from 'fastify';
2
+ import { logger } from '@owlmeans/log';
3
+ import { CLOSED_HOST, OPENED_HOST, PORT } from './consts.js';
4
+ /**
5
+ * Own the app's port while the context initializes, and answer for the app until `listen()`
6
+ * takes over.
7
+ *
8
+ * The API server itself cannot do this: it builds its route table from the entrypoints the
9
+ * context knows about, so it can only bind AFTER `init()` resolves — and Fastify refuses new
10
+ * routes once it is listening. Without a hold, the whole boot window, and every way a boot can
11
+ * fail, leaves nothing on the port; the edge then answers a bare upstream connect error that
12
+ * names neither the app nor the reason, which is indistinguishable from a crashed pod or an app
13
+ * that was never installed.
14
+ *
15
+ * So the boot sequence an app wants is:
16
+ *
17
+ * const hold = await holdApiPort(cfg, { okPath, payload }) // bind FIRST
18
+ * try { ...initialize... } catch { record the failure; return } // hold keeps answering
19
+ * await hold.release()
20
+ * await context.getApiServer().listen()
21
+ *
22
+ * Everything that is not the health path answers **503, not 404**: the routes the app really
23
+ * serves do not exist yet, and "no such route" would be a lie that outlives the boot.
24
+ *
25
+ * The port and host are resolved exactly as `listen()` resolves them — from the service's own
26
+ * declaration in `cfg.services[cfg.service]` — so the hold and the server can never disagree
27
+ * about which socket they are trading.
28
+ *
29
+ * A bind failure here (EADDRINUSE above all) throws to the caller and must be treated as fatal:
30
+ * a process that continues past it ends the boot with nothing listening and nothing holding the
31
+ * event loop, i.e. a clean exit 0 while a predecessor keeps serving stale code. Name the error
32
+ * and exit non-zero — that is what makes a supervisor reclaim the port instead of respawning
33
+ * into it.
34
+ */
35
+ export const holdApiPort = async (cfg, opts = {}) => {
36
+ const config = cfg.services[cfg.service];
37
+ const port = config?.internalPort ?? config?.port ?? PORT;
38
+ const host = config?.opened === true ? OPENED_HOST : CLOSED_HOST;
39
+ const payload = opts.payload ?? (() => ({ status: 'OK' }));
40
+ // Quiet and disposable: no logger, no plugins, and connections are force-closed on release so
41
+ // the handover to the real server is bounded rather than waiting out a keep-alive.
42
+ const server = Fastify({ logger: false, forceCloseConnections: true });
43
+ if (opts.okPath != null) {
44
+ server.all(opts.okPath, async (_request, reply) => {
45
+ return await reply.code(200).send(payload());
46
+ });
47
+ }
48
+ server.setNotFoundHandler(async (_request, reply) => {
49
+ return await reply.code(503).send(payload());
50
+ });
51
+ await server.listen({ port, host });
52
+ logger('server').info(`api-server: holding ${host}:${port} for the boot${opts.okPath != null ? ` (${opts.okPath})` : ''}`, undefined, { event: 'server.hold' });
53
+ return {
54
+ release: async () => { await server.close(); },
55
+ };
56
+ };
57
+ //# sourceMappingURL=hold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hold.js","sourceRoot":"","sources":["../src/hold.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAG5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAiB,EAAE,IAAI,GAAuB,EAAE,EAC1B,EAAE;IACxB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,YAAY,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA;IACzD,MAAM,IAAI,GAAG,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;IAEhE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAE1D,8FAA8F;IAC9F,mFAAmF;IACnF,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAA;IAEtE,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAChD,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAClD,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,uBAAuB,IAAI,IAAI,IAAI,gBAAgB,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAA;IAE/J,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA,CAAC,CAAC;KAC9C,CAAA;AACH,CAAC,CAAA"}
package/build/index.d.ts CHANGED
@@ -3,4 +3,6 @@ export * from './server.js';
3
3
  export * from './consts.js';
4
4
  export * from './errors.js';
5
5
  export * from './helper.js';
6
+ export * from './hold.js';
7
+ export * from './protocol.js';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
package/build/index.js CHANGED
@@ -2,4 +2,6 @@ export * from './server.js';
2
2
  export * from './consts.js';
3
3
  export * from './errors.js';
4
4
  export * from './helper.js';
5
+ export * from './hold.js';
6
+ export * from './protocol.js';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { type BasicConfig, type BasicContext } from '@owlmeans/context';
2
+ import { type BodyOf, type EntrypointProtocolDeclaration, type HandlerRequest, type ParamsOf, type RequestOf, type ResponseOf } from '@owlmeans/entrypoint';
3
+ import type { BoundEntrypointHandler } from '@owlmeans/server-entrypoint';
4
+ import type { BodyProtocol, HandlerResponse, MaybePromise, ParamsProtocol } from './types.local.js';
5
+ /**
6
+ * Make server handlers that infer request sections and response values from their protocol.
7
+ * The protocol is passed once; application callbacks never name request or reply generics.
8
+ */
9
+ export declare const handlers: <Context extends BasicContext<BasicConfig>>() => {
10
+ body: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: Protocol extends BodyProtocol<Protocol> ? (payload: BodyOf<Protocol>, context: Context, request: HandlerRequest<RequestOf<Protocol>>) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>> : never) => BoundEntrypointHandler<Protocol>;
11
+ params: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: Protocol extends ParamsProtocol<Protocol> ? (payload: ParamsOf<Protocol>, context: Context, request: HandlerRequest<RequestOf<Protocol>>) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>> : never) => BoundEntrypointHandler<Protocol>;
12
+ request: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: (request: HandlerRequest<RequestOf<Protocol>>, context: Context) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>>) => BoundEntrypointHandler<Protocol>;
13
+ };
14
+ /** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
15
+ export declare const uploadedFile: (request: HandlerRequest<{
16
+ body: object;
17
+ }>) => Promise<import('@fastify/multipart').MultipartFile | undefined>;
18
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACtF,OAAO,EAAqB,KAAK,MAAM,EAAE,KAAK,6BAA6B,EAAE,KAAK,cAAc,EAAoB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAwB,MAAM,sBAAsB,CAAA;AACtN,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAGzE,OAAO,KAAK,EAAmB,YAAY,EAAkB,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AA+FpI;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,SAAS,YAAY,CAAC,WAAW,CAAC;IAChE,IAAI,GAAG,QAAQ,SAAS,6BAA6B,YACzC,QAAQ,WACT,QAAQ,SAAS,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC/C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,EACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,KACzC,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GACtD,KAAK,KACR,sBAAsB,CAAC,QAAQ,CAAC;IAKnC,MAAM,GAAG,QAAQ,SAAS,6BAA6B,YAC3C,QAAQ,WACT,QAAQ,SAAS,cAAc,CAAC,QAAQ,CAAC,GAAG,CACjD,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,KACzC,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GACtD,KAAK,KACR,sBAAsB,CAAC,QAAQ,CAAC;IAKnC,OAAO,GAAG,QAAQ,SAAS,6BAA6B,YAC5C,QAAQ,WACT,CACP,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAC5C,OAAO,EAAE,OAAO,KACb,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,KACvD,sBAAsB,CAAC,QAAQ,CAAC;CACnC,CAAA;AAEF,sGAAsG;AACtG,eAAO,MAAM,YAAY,YACd,cAAc,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,KACxC,OAAO,CAAC,OAAO,oBAAoB,EAAE,aAAa,GAAG,SAAS,CAKhE,CAAA"}
@@ -0,0 +1,87 @@
1
+ import { assertContext } from '@owlmeans/context';
2
+ import { EntrypointOutcome } from '@owlmeans/entrypoint';
3
+ import { HandlerMisconfiguredError } from './errors.js';
4
+ import { logger } from '@owlmeans/log';
5
+ const contextFor = (request, fallback) => {
6
+ const original = request.original;
7
+ if (original != null && typeof original === 'object' && '_ctx' in original) {
8
+ return original._ctx ?? fallback;
9
+ }
10
+ return fallback;
11
+ };
12
+ const bind = (protocol, execute) => ({
13
+ protocol,
14
+ bind: ref => async (request, response) => {
15
+ const fallback = assertContext(ref.ref?.ctx, protocol.alias);
16
+ try {
17
+ const typedRequest = request;
18
+ const value = await execute(typedRequest, contextFor(request, fallback));
19
+ response.resolve(value, EntrypointOutcome.Ok);
20
+ }
21
+ catch (error) {
22
+ response.reject(error);
23
+ }
24
+ return response.value;
25
+ },
26
+ });
27
+ /**
28
+ * `value` is shaped like a `BoundEntrypointHandler` — never a plain function, which also carries
29
+ * its own `.bind` and would otherwise pass a `typeof value.bind === 'function'` check alone.
30
+ */
31
+ const isBoundHandler = (value) => typeof value === 'object' && value != null
32
+ && typeof value.bind === 'function'
33
+ && value.protocol != null;
34
+ const warnedAliases = new Set();
35
+ /**
36
+ * What `body`/`params`/`request` do with something that is not the plain callback they declare —
37
+ * the shape a handler module wraps its own export in when it is bound TWICE. `null` means the
38
+ * second argument really is a callback and the caller should wrap it as usual.
39
+ *
40
+ * A handler bound to THIS protocol is returned unchanged, with a one-time warning: the module
41
+ * already produced a working `BoundEntrypointHandler`, and re-wrapping it here would only wrap it
42
+ * again — returning it as-is is what makes `bind(protocol, api.body(protocol, alreadyBound))`
43
+ * behave exactly like `bind(protocol, alreadyBound)`, which is what a wrap-once file looks like at
44
+ * this call site. Anything else — a handler bound to a DIFFERENT protocol, or a value that is
45
+ * neither a function nor a bound handler at all — answers every request on this route with
46
+ * {@link HandlerMisconfiguredError} instead of throwing `TypeError: handler is not a function`
47
+ * out of the request pipeline's own `try`, where the type name and the alias it happened on are
48
+ * both lost.
49
+ */
50
+ const toleratedHandler = (protocol, handler) => {
51
+ if (typeof handler === 'function')
52
+ return null;
53
+ if (isBoundHandler(handler)) {
54
+ if (handler.protocol.alias === protocol.alias) {
55
+ if (!warnedAliases.has(protocol.alias)) {
56
+ warnedAliases.add(protocol.alias);
57
+ logger('server-api').warn(`${protocol.alias}: handler is already bound — pass it to bind() directly; `
58
+ + 'wrapping it again here is a type error (TS2345 "BoundEntrypointHandler<…> is not '
59
+ + 'assignable"), tolerated at runtime for a project generated before the wrap-once rule.');
60
+ }
61
+ return handler;
62
+ }
63
+ return bind(protocol, () => {
64
+ throw new HandlerMisconfiguredError(`${protocol.alias}: handler is bound to a different protocol ('${handler.protocol.alias}')`);
65
+ });
66
+ }
67
+ return bind(protocol, () => {
68
+ throw new HandlerMisconfiguredError(`${protocol.alias}: handler is not a function`);
69
+ });
70
+ };
71
+ /**
72
+ * Make server handlers that infer request sections and response values from their protocol.
73
+ * The protocol is passed once; application callbacks never name request or reply generics.
74
+ */
75
+ export const handlers = () => ({
76
+ body: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, (request, context) => handler(request.body, context, request)),
77
+ params: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, (request, context) => handler(request.params, context, request)),
78
+ request: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, handler),
79
+ });
80
+ /** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
81
+ export const uploadedFile = async (request) => {
82
+ const original = request.original;
83
+ if (original == null || typeof original !== 'object' || !('file' in original))
84
+ return undefined;
85
+ return original.file();
86
+ };
87
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuC,MAAM,mBAAmB,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAgK,MAAM,sBAAsB,CAAA;AAEtN,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAItC,MAAM,UAAU,GAAG,CACjB,OAAwB,EACxB,QAAiB,EACR,EAAE;IACX,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC3E,OAAQ,QAAoC,CAAC,IAAI,IAAI,QAAQ,CAAA;IAC/D,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CACX,QAAkB,EAClB,OAAgI,EAC9F,EAAE,CAAC,CAAC;IACtC,QAAQ;IACR,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,aAAa,CAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;QAElF,IAAI,CAAC;YACH,MAAM,YAAY,GAAI,OAA8E,CAAA;YACpG,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB,YAAY,EACZ,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAC9B,CAAA;YACD,QAAQ,CAAC,OAAO,CAAC,KAA6B,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAA;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,MAAM,CAAC,KAAc,CAAC,CAAA;QACjC,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAA;IACvB,CAAC;CACF,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,cAAc,GAAG,CAAC,KAAc,EAA4B,EAAE,CAClE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,IAAI;OACvC,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU;OACvD,KAAgC,CAAC,QAAQ,IAAI,IAAI,CAAA;AAEvD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,gBAAgB,GAAG,CACvB,QAAkB,EAAE,OAAgB,EACK,EAAE;IAC3C,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IAE9C,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACjC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CACvB,GAAG,QAAQ,CAAC,KAAK,2DAA2D;sBAC1E,mFAAmF;sBACnF,uFAAuF,CAC1F,CAAA;YACH,CAAC;YAED,OAAO,OAAsD,CAAA;QAC/D,CAAC;QAED,OAAO,IAAI,CAAsC,QAAQ,EAAE,GAAG,EAAE;YAC9D,MAAM,IAAI,yBAAyB,CACjC,GAAG,QAAQ,CAAC,KAAK,gDAAgD,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAC5F,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,IAAI,CAAsC,QAAQ,EAAE,GAAG,EAAE;QAC9D,MAAM,IAAI,yBAAyB,CAAC,GAAG,QAAQ,CAAC,KAAK,6BAA6B,CAAC,CAAA;IACrF,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA8C,EAAE,CAAC,CAAC;IACxE,IAAI,EAAE,CACJ,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAClI,OAEwD,CAAC,OAAO,CAAC,IAAwB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhH,MAAM,EAAE,CACN,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAClI,OAEwD,CAAC,OAAO,CAAC,MAA4B,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEpH,OAAO,EAAE,CACP,QAAkB,EAClB,OAGwD,EACtB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,OAAO,CAAC;CACzH,CAAC,CAAA;AAEF,sGAAsG;AACtG,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,OAAyC,EACwB,EAAE;IACnE,MAAM,QAAQ,GAAI,OAA2B,CAAC,QAAQ,CAAA;IACtD,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAE/F,OAAQ,QAA6C,CAAC,IAAI,EAAE,CAAA;AAC9D,CAAC,CAAA"}
package/build/server.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
1
+ import type { ServerContext } from '@owlmeans/server-context';
2
2
  import type { ApiServer, ApiServerAppend } from './types.js';
3
- type Config = ServerConfig;
3
+ import type { Config } from './types.local.js';
4
4
  export declare const createApiServer: (alias: string) => ApiServer;
5
5
  export declare const appendApiServer: <C extends Config, T extends ServerContext<C>>(ctx: T, alias?: string) => T & ApiServerAppend;
6
- export {};
7
6
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiC5D,KAAK,MAAM,GAAG,YAAY,CAAA;AAK1B,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,SA0J/C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,EAC1E,KAAK,CAAC,EAAE,QAAO,MAAsB,KACpC,CAAC,GAAG,eAWN,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyB5D,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,kBAAkB,CAAA;AA8BvD,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,SA8I/C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OACrE,CAAC,UAAS,MAAM,KACpB,CAAC,GAAG,eAWN,CAAA"}
package/build/server.js CHANGED
@@ -1,10 +1,13 @@
1
- import { Layer, assertContext, createService } from '@owlmeans/context';
2
- import { canServeModule, executeResponse, provideRequest } from './utils/index.js';
1
+ import { assertContext, createService } from '@owlmeans/context';
2
+ import { canServeModule, payloadHelper, createServerHandler, fixFormatDates } from './utils/index.js';
3
3
  import { DEFAULT_ALIAS, CLOSED_HOST, PORT, OPENED_HOST } from './consts.js';
4
4
  import { RouteMethod } from '@owlmeans/route';
5
- import { createServerHandler, fixFormatDates } from './utils/index.js';
6
5
  import { provideResponse } from '@owlmeans/entrypoint';
7
6
  import { TOKEN_UPDATE } from '@owlmeans/auth-common';
7
+ import { INCIDENT_ID_HEADER } from './utils/consts.js';
8
+ import { DENIAL_KIND_HEADER } from '@owlmeans/api';
9
+ import { logger } from '@owlmeans/log';
10
+ import { fastifyLogUtils } from './utils/log.js';
8
11
  import Fastify from 'fastify';
9
12
  import cors from '@fastify/cors';
10
13
  import rawBody from 'fastify-raw-body';
@@ -14,6 +17,7 @@ import Multipart from '@fastify/multipart';
14
17
  import formatsPlugin from 'ajv-formats';
15
18
  import Ajv from 'ajv';
16
19
  import ajvErrors from "ajv-errors";
20
+ import { bodyLimit } from './consts.local.js';
17
21
  const ajv = new Ajv({
18
22
  removeAdditional: true,
19
23
  useDefaults: true,
@@ -23,33 +27,32 @@ const ajv = new Ajv({
23
27
  });
24
28
  formatsPlugin(ajv);
25
29
  ajvErrors(ajv, { singleError: true });
26
- const bodyLimit = 1024 * 1024 * 20;
30
+ const http = logger('http');
31
+ /**
32
+ * Fastify logging through `@owlmeans/log`, never with what a caller sent. The adapter writes every
33
+ * record's data through `safeData` (no body, raw body, multipart bytes, headers, cookies or query);
34
+ * the log controller drops Fastify's per-request pair — a request is a debug record written once
35
+ * from `onResponse` (below) — and logs a request Fastify itself refuses (a schema-invalid body, an
36
+ * unparsable payload, a size limit) like `handleError` logs a failed handler: method, path, status,
37
+ * error code and message.
38
+ */
39
+ const createFastify = () => Fastify({
40
+ loggerInstance: fastifyLogUtils.logger(http),
41
+ logController: fastifyLogUtils.controller(),
42
+ bodyLimit,
43
+ });
27
44
  export const createApiServer = (alias) => {
28
45
  const location = `service:${alias}`;
29
46
  const _assertContext = (context) => assertContext(context, location);
30
47
  const service = createService(alias, {
31
- server: Fastify({
32
- logger: true,
33
- bodyLimit,
34
- /*{
35
- transport: {
36
- target: 'pino-pretty',
37
- options: {
38
- singleLine: true,
39
- translateTime: 'HH:MM:ss Z',
40
- ignore: 'pid,hostname',
41
- },
42
- },
43
- }*/
44
- }),
45
- layers: [Layer.System],
48
+ server: createFastify(),
46
49
  listen: async () => {
47
50
  const context = _assertContext(service.ctx);
48
51
  const config = context.cfg.services[context.cfg.service];
49
52
  const port = config?.internalPort ?? config?.port ?? PORT;
50
53
  const host = config.opened === true ? OPENED_HOST : CLOSED_HOST;
51
54
  await service.server.listen({ port, host });
52
- console.info(`${location}: server listening on ${host}${port != null ? `:${port}` : ''}`);
55
+ logger('server').info(`${location}: server listening on ${host}${port != null ? `:${port}` : ''}`, undefined, { event: 'server.listening' });
53
56
  process.on('SIGTERM', () => {
54
57
  service.server.close().then(() => {
55
58
  process.exit(0);
@@ -59,12 +62,21 @@ export const createApiServer = (alias) => {
59
62
  }, service => async () => {
60
63
  if (service.server.server.listening) {
61
64
  await service.server.close();
62
- service.server = Fastify({ logger: true, bodyLimit });
65
+ service.server = createFastify();
63
66
  }
64
67
  const context = _assertContext(service.ctx);
65
68
  const server = service.server;
66
69
  // @TODO We should ensure some way that Resilient Error is thrown and go to the flow
67
70
  server.setValidatorCompiler(opts => ajv.compile(opts.schema));
71
+ server.addHook('onResponse', (request, reply, done) => {
72
+ if (http.enabled('debug')) {
73
+ // The path only: a query string can carry a token.
74
+ http.debug('request', {
75
+ ...fastifyLogUtils.requestOf(request), status: reply.statusCode, ms: Math.round(reply.elapsedTime),
76
+ });
77
+ }
78
+ done();
79
+ });
68
80
  // @TODO It's quite unsafe and should be properly configured
69
81
  await server.register(cors, {
70
82
  origin: '*',
@@ -80,7 +92,7 @@ export const createApiServer = (alias) => {
80
92
  ...Object.values(RouteMethod).map(method => method.toUpperCase()),
81
93
  'HEAD', 'OPTIONS'
82
94
  ],
83
- exposedHeaders: [TOKEN_UPDATE]
95
+ exposedHeaders: [TOKEN_UPDATE, INCIDENT_ID_HEADER, DENIAL_KIND_HEADER]
84
96
  });
85
97
  await server.register(Multipart, {
86
98
  throwFileSizeLimit: true,
@@ -107,33 +119,29 @@ export const createApiServer = (alias) => {
107
119
  if (responded || reply.sent) {
108
120
  return context;
109
121
  }
110
- // await module.route.resolve(context as any)
111
- await module.resolve();
112
- // Actually intermediate module can be created without handler by elevate function
113
- if (module.route.match(request) && module.handle != null) {
122
+ // An intermediate route can be created without a handler by the binding layer.
123
+ if (module.route.match(request, module.mount()) && module.handle != null) {
114
124
  const response = provideResponse(reply);
115
- const currentRequest = provideRequest(module.alias, request, true);
125
+ const currentRequest = payloadHelper.provideRequest(module.alias, request, true);
116
126
  currentRequest.original._ctx = context;
117
127
  const result = await module.handle(currentRequest, response);
118
128
  if (result != null) {
119
129
  context = result;
120
130
  }
121
- responded = executeResponse(response, reply, true) || responded;
131
+ responded = payloadHelper.executeResponse(response, reply, true) || responded;
122
132
  }
123
133
  return context;
124
134
  }, Promise.resolve(context));
125
135
  });
126
- await Promise.all(context.entrypoints()
136
+ context.entrypoints()
127
137
  .filter(module => canServeModule(context, module) && !module.route.isIntermediate())
128
- .map(async (module) => {
129
- // await module.route.resolve(context as any)
130
- await module.resolve();
138
+ .forEach(module => {
131
139
  const method = module.route.route.method ?? RouteMethod.GET;
132
140
  if (module.handle == null) {
133
141
  return;
134
142
  }
135
143
  server.route({
136
- url: module.getPath(), method,
144
+ url: module.mount(), method,
137
145
  schema: {
138
146
  consumes: [
139
147
  'application/json',
@@ -154,7 +162,7 @@ export const createApiServer = (alias) => {
154
162
  },
155
163
  handler: createServerHandler(module, location)
156
164
  });
157
- }));
165
+ });
158
166
  service.initialized = true;
159
167
  });
160
168
  return service;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/build/types.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { InitializedService, Layer } from '@owlmeans/context';
1
+ import type { InitializedService } from '@owlmeans/context';
2
2
  import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
3
3
  import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
4
4
  import '@fastify/middie/types/index.d.ts';
5
+ import type { MultipartFile } from '@fastify/multipart';
5
6
  export interface ApiServer extends InitializedService {
6
7
  server: FastifyInstance;
7
- layers: [Layer.System];
8
8
  listen: () => Promise<void>;
9
9
  }
10
10
  export interface Request extends FastifyRequest {
@@ -14,8 +14,37 @@ export interface Response extends FastifyReply {
14
14
  export interface ApiServerAppend {
15
15
  getApiServer: () => ApiServer;
16
16
  }
17
+ export type HttpErrorExposure = 'production' | 'development';
18
+ export interface HttpErrorsConfig {
19
+ /** Production is the safe default; development is the only mode that exposes stacks. */
20
+ exposure?: HttpErrorExposure;
21
+ }
22
+ export interface HttpConfig {
23
+ errors?: HttpErrorsConfig;
24
+ }
17
25
  export interface Config extends ServerConfig {
26
+ http?: HttpConfig;
18
27
  }
19
28
  export interface Context<C extends Config = Config> extends ServerContext<C>, ApiServerAppend {
20
29
  }
30
+ export interface UploadedFile extends MultipartFile {
31
+ }
32
+ export interface ApiPortHoldOptions {
33
+ /**
34
+ * The one path answered 200 while the hold is in place — the app's health endpoint, so
35
+ * whatever supervises the process keeps a conventional liveness answer through the boot.
36
+ * Everything else answers 503 with the same body. Absent, everything is 503.
37
+ */
38
+ okPath?: string;
39
+ /** Body of every answer, evaluated per request so a changing boot phase is reported live. */
40
+ payload?: () => unknown;
41
+ }
42
+ export interface ApiPortHold {
43
+ /**
44
+ * Free the port for the real server. Awaits the actual close — `listen()` follows immediately,
45
+ * and a predecessor still bound makes it throw — and force-closes keep-alive sockets, so a
46
+ * supervisor's own poller cannot hold the release open.
47
+ */
48
+ release: () => Promise<void>;
49
+ }
21
50
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,kCAAkC,CAAA;AAEzC,MAAM,WAAW,SAAU,SAAQ,kBAAkB;IACnD,MAAM,EAAE,eAAe,CAAA;IAEvB,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAEtB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,cAAc;CAAI;AAEnD,MAAM,WAAW,QAAS,SAAQ,YAAY;CAAI;AAElD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,SAAS,CAAA;CAC9B;AAED,MAAM,WAAW,MAAO,SAAQ,YAAY;CAAI;AAEhD,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe;CAAI"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,WAAW,SAAU,SAAQ,kBAAkB;IACnD,MAAM,EAAE,eAAe,CAAA;IAEvB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,cAAc;CAAI;AAEnD,MAAM,WAAW,QAAS,SAAQ,YAAY;CAAI;AAElD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,SAAS,CAAA;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,aAAa,CAAA;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAC1B;AAED,MAAM,WAAW,MAAO,SAAQ,YAAY;IAC1C,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe;CAAI;AAErB,MAAM,WAAW,YAAa,SAAQ,aAAa;CAAI;AAEvD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B"}
@@ -0,0 +1,38 @@
1
+ import type { EntrypointProtocolDeclaration, OpenValue, RequestOf } from '@owlmeans/entrypoint';
2
+ import type { BoundEntrypointHandler } from '@owlmeans/server-entrypoint';
3
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
4
+ /**
5
+ * True for a response the declaration left with no compile-time contract: `typed<any>()` (an
6
+ * `[any] extends [X]` conditional does not produce `any`'s usual both-branches union once the
7
+ * checked type is wrapped in a tuple, so it resolves to a single branch like any other type) and
8
+ * a response inferred as bare `typed()` with nothing to infer from, which resolves to `undefined`
9
+ * with no shape to validate a handler's return against — the same signal a zero-argument
10
+ * `contract()` produces for a genuinely response-less route. Neither means "this handler must
11
+ * return void": it means the declaration did not constrain the response, so the handler is free to
12
+ * return whatever its route actually sends.
13
+ */
14
+ export type IsUntypedResponse<T> = 0 extends (1 & T) ? true : [T] extends [undefined] ? true : false;
15
+ /**
16
+ * The type a bound handler is allowed to return for a given protocol response.
17
+ *
18
+ * A concretely typed or schema-backed `Response` is returned unchanged — the handler must produce
19
+ * exactly that shape. An untyped one (see `IsUntypedResponse` above) relaxes to `any`: the
20
+ * declaration made no promise about the response, so nothing here should force a handler bound to
21
+ * it into returning `void`.
22
+ */
23
+ export type HandlerResponse<Response> = IsUntypedResponse<Response> extends true ? any : Response;
24
+ export type MaybePromise<Value> = Value | Promise<Value>;
25
+ export type BodyProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
26
+ body: OpenValue;
27
+ } ? Protocol : never;
28
+ export type ParamsProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
29
+ params: object;
30
+ } ? Protocol : never;
31
+ export type Config = ServerConfig;
32
+ export type Context = ServerContext<Config>;
33
+ export interface ContextCarrier<Context> {
34
+ _ctx?: Context;
35
+ }
36
+ /** Structural, not `instanceof`: a `BoundEntrypointHandler` crosses no class boundary a runtime check could use. */
37
+ export type AnyBoundHandler = BoundEntrypointHandler<EntrypointProtocolDeclaration>;
38
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC/F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE3E;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK,CAAA;AAEpG;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,SAAS,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAA;AAEjG,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;AAExD,MAAM,MAAM,YAAY,CAAC,QAAQ,SAAS,6BAA6B,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACtH,QAAQ,GAAG,KAAK,CAAA;AAEpB,MAAM,MAAM,cAAc,CAAC,QAAQ,SAAS,6BAA6B,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GACvH,QAAQ,GAAG,KAAK,CAAA;AAEpB,MAAM,MAAM,MAAM,GAAG,YAAY,CAAA;AAEjC,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AAE3C,MAAM,WAAW,cAAc,CAAC,OAAO;IACrC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,oHAAoH;AACpH,MAAM,MAAM,eAAe,GAAG,sBAAsB,CAAC,6BAA6B,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const INCIDENT_ID_HEADER = "X-Incident-ID";
2
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/utils/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,kBAAkB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export const INCIDENT_ID_HEADER = 'X-Incident-ID';
2
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/utils/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAA"}
@@ -0,0 +1,5 @@
1
+ export declare const CLIENT_ERROR_FIRST = 400;
2
+ export declare const CLIENT_ERROR_LAST = 499;
3
+ export declare const SERVER_ERROR_FIRST = 500;
4
+ export declare const SERVER_ERROR_LAST = 599;
5
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../src/utils/consts.local.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,eAAO,MAAM,iBAAiB,MAAM,CAAA"}
@@ -0,0 +1,5 @@
1
+ export const CLIENT_ERROR_FIRST = 400;
2
+ export const CLIENT_ERROR_LAST = 499;
3
+ export const SERVER_ERROR_FIRST = 500;
4
+ export const SERVER_ERROR_LAST = 599;
5
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../../src/utils/consts.local.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { Config, Context } from '../../types.js';
2
+ /** Carries the serving context on one raw request. */
3
+ export interface RequestContextHelper {
4
+ /** Stores the context on the request. */
5
+ populateContext: <C extends Config, T extends Context<C>>(context: T) => void;
6
+ /**
7
+ * The context stored on the request, else `ctx`.
8
+ *
9
+ * @throws {SyntaxError} when neither is there
10
+ */
11
+ extractContext: <C extends Config, T extends Context<C>>(ctx?: T, location?: string) => T;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map