flowingts 0.0.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +74 -3
  3. package/dist/core/abort.d.ts +23 -0
  4. package/dist/core/abort.d.ts.map +1 -0
  5. package/dist/core/abort.js +23 -0
  6. package/dist/core/abort.js.map +1 -0
  7. package/dist/core/app/core.d.ts +35 -0
  8. package/dist/core/app/core.d.ts.map +1 -0
  9. package/dist/core/app/core.js +2 -0
  10. package/dist/core/app/core.js.map +1 -0
  11. package/dist/core/app/options.d.ts +178 -0
  12. package/dist/core/app/options.d.ts.map +1 -0
  13. package/dist/core/app/options.js +2 -0
  14. package/dist/core/app/options.js.map +1 -0
  15. package/dist/core/app.d.ts +143 -0
  16. package/dist/core/app.d.ts.map +1 -0
  17. package/dist/core/app.js +283 -0
  18. package/dist/core/app.js.map +1 -0
  19. package/dist/core/body-parser.d.ts +14 -0
  20. package/dist/core/body-parser.d.ts.map +1 -0
  21. package/dist/core/body-parser.js +76 -0
  22. package/dist/core/body-parser.js.map +1 -0
  23. package/dist/core/compiler.d.ts +104 -0
  24. package/dist/core/compiler.d.ts.map +1 -0
  25. package/dist/core/compiler.js +151 -0
  26. package/dist/core/compiler.js.map +1 -0
  27. package/dist/core/compose.d.ts +16 -0
  28. package/dist/core/compose.d.ts.map +1 -0
  29. package/dist/core/compose.js +41 -0
  30. package/dist/core/compose.js.map +1 -0
  31. package/dist/core/context.d.ts +290 -0
  32. package/dist/core/context.d.ts.map +1 -0
  33. package/dist/core/context.js +460 -0
  34. package/dist/core/context.js.map +1 -0
  35. package/dist/core/contracts.d.ts +76 -0
  36. package/dist/core/contracts.d.ts.map +1 -0
  37. package/dist/core/contracts.js +87 -0
  38. package/dist/core/contracts.js.map +1 -0
  39. package/dist/core/errors.d.ts +50 -0
  40. package/dist/core/errors.d.ts.map +1 -0
  41. package/dist/core/errors.js +25 -0
  42. package/dist/core/errors.js.map +1 -0
  43. package/dist/core/guard.d.ts +10 -0
  44. package/dist/core/guard.d.ts.map +1 -0
  45. package/dist/core/guard.js +14 -0
  46. package/dist/core/guard.js.map +1 -0
  47. package/dist/core/health.d.ts +37 -0
  48. package/dist/core/health.d.ts.map +1 -0
  49. package/dist/core/health.js +68 -0
  50. package/dist/core/health.js.map +1 -0
  51. package/dist/core/hooks.d.ts +34 -0
  52. package/dist/core/hooks.d.ts.map +1 -0
  53. package/dist/core/hooks.js +27 -0
  54. package/dist/core/hooks.js.map +1 -0
  55. package/dist/core/index.d.ts +30 -0
  56. package/dist/core/index.d.ts.map +1 -0
  57. package/dist/core/index.js +11 -0
  58. package/dist/core/index.js.map +1 -0
  59. package/dist/core/infer.d.ts +68 -0
  60. package/dist/core/infer.d.ts.map +1 -0
  61. package/dist/core/infer.js +2 -0
  62. package/dist/core/infer.js.map +1 -0
  63. package/dist/core/inject.d.ts +27 -0
  64. package/dist/core/inject.d.ts.map +1 -0
  65. package/dist/core/inject.js +85 -0
  66. package/dist/core/inject.js.map +1 -0
  67. package/dist/core/logger.d.ts +57 -0
  68. package/dist/core/logger.d.ts.map +1 -0
  69. package/dist/core/logger.js +134 -0
  70. package/dist/core/logger.js.map +1 -0
  71. package/dist/core/metadata.d.ts +83 -0
  72. package/dist/core/metadata.d.ts.map +1 -0
  73. package/dist/core/metadata.js +91 -0
  74. package/dist/core/metadata.js.map +1 -0
  75. package/dist/core/mounted-group.d.ts +77 -0
  76. package/dist/core/mounted-group.d.ts.map +1 -0
  77. package/dist/core/mounted-group.js +131 -0
  78. package/dist/core/mounted-group.js.map +1 -0
  79. package/dist/core/registry/framework-routes.d.ts +28 -0
  80. package/dist/core/registry/framework-routes.d.ts.map +1 -0
  81. package/dist/core/registry/framework-routes.js +83 -0
  82. package/dist/core/registry/framework-routes.js.map +1 -0
  83. package/dist/core/registry/registry.d.ts +58 -0
  84. package/dist/core/registry/registry.d.ts.map +1 -0
  85. package/dist/core/registry/registry.js +208 -0
  86. package/dist/core/registry/registry.js.map +1 -0
  87. package/dist/core/registry/route-program.d.ts +16 -0
  88. package/dist/core/registry/route-program.d.ts.map +1 -0
  89. package/dist/core/registry/route-program.js +62 -0
  90. package/dist/core/registry/route-program.js.map +1 -0
  91. package/dist/core/request-validation.d.ts +15 -0
  92. package/dist/core/request-validation.d.ts.map +1 -0
  93. package/dist/core/request-validation.js +67 -0
  94. package/dist/core/request-validation.js.map +1 -0
  95. package/dist/core/response/pipeline.d.ts +51 -0
  96. package/dist/core/response/pipeline.d.ts.map +1 -0
  97. package/dist/core/response/pipeline.js +169 -0
  98. package/dist/core/response/pipeline.js.map +1 -0
  99. package/dist/core/route-table.d.ts +58 -0
  100. package/dist/core/route-table.d.ts.map +1 -0
  101. package/dist/core/route-table.js +108 -0
  102. package/dist/core/route-table.js.map +1 -0
  103. package/dist/core/runtime/observer.d.ts +47 -0
  104. package/dist/core/runtime/observer.d.ts.map +1 -0
  105. package/dist/core/runtime/observer.js +125 -0
  106. package/dist/core/runtime/observer.js.map +1 -0
  107. package/dist/core/runtime/request-handler.d.ts +62 -0
  108. package/dist/core/runtime/request-handler.d.ts.map +1 -0
  109. package/dist/core/runtime/request-handler.js +256 -0
  110. package/dist/core/runtime/request-handler.js.map +1 -0
  111. package/dist/core/runtime/server.d.ts +59 -0
  112. package/dist/core/runtime/server.d.ts.map +1 -0
  113. package/dist/core/runtime/server.js +180 -0
  114. package/dist/core/runtime/server.js.map +1 -0
  115. package/dist/core/shutdown.d.ts +41 -0
  116. package/dist/core/shutdown.d.ts.map +1 -0
  117. package/dist/core/shutdown.js +53 -0
  118. package/dist/core/shutdown.js.map +1 -0
  119. package/dist/core/streaming/sse.d.ts +35 -0
  120. package/dist/core/streaming/sse.d.ts.map +1 -0
  121. package/dist/core/streaming/sse.js +121 -0
  122. package/dist/core/streaming/sse.js.map +1 -0
  123. package/dist/core/symbols.d.ts +28 -0
  124. package/dist/core/symbols.d.ts.map +1 -0
  125. package/dist/core/symbols.js +28 -0
  126. package/dist/core/symbols.js.map +1 -0
  127. package/dist/core/telemetry.d.ts +83 -0
  128. package/dist/core/telemetry.d.ts.map +1 -0
  129. package/dist/core/telemetry.js +96 -0
  130. package/dist/core/telemetry.js.map +1 -0
  131. package/dist/core/uploads/receive.d.ts +63 -0
  132. package/dist/core/uploads/receive.d.ts.map +1 -0
  133. package/dist/core/uploads/receive.js +342 -0
  134. package/dist/core/uploads/receive.js.map +1 -0
  135. package/dist/core/uploads/types.d.ts +79 -0
  136. package/dist/core/uploads/types.d.ts.map +1 -0
  137. package/dist/core/uploads/types.js +2 -0
  138. package/dist/core/uploads/types.js.map +1 -0
  139. package/dist/decorators/hooks.d.ts +25 -0
  140. package/dist/decorators/hooks.d.ts.map +1 -0
  141. package/dist/decorators/hooks.js +36 -0
  142. package/dist/decorators/hooks.js.map +1 -0
  143. package/dist/decorators/http.d.ts +21 -0
  144. package/dist/decorators/http.d.ts.map +1 -0
  145. package/dist/decorators/http.js +21 -0
  146. package/dist/decorators/http.js.map +1 -0
  147. package/dist/decorators/index.d.ts +7 -0
  148. package/dist/decorators/index.d.ts.map +1 -0
  149. package/dist/decorators/index.js +7 -0
  150. package/dist/decorators/index.js.map +1 -0
  151. package/dist/decorators/log.d.ts +10 -0
  152. package/dist/decorators/log.d.ts.map +1 -0
  153. package/dist/decorators/log.js +32 -0
  154. package/dist/decorators/log.js.map +1 -0
  155. package/dist/decorators/middlewares.d.ts +28 -0
  156. package/dist/decorators/middlewares.d.ts.map +1 -0
  157. package/dist/decorators/middlewares.js +40 -0
  158. package/dist/decorators/middlewares.js.map +1 -0
  159. package/dist/decorators/router.d.ts +12 -0
  160. package/dist/decorators/router.d.ts.map +1 -0
  161. package/dist/decorators/router.js +20 -0
  162. package/dist/decorators/router.js.map +1 -0
  163. package/dist/decorators/schema.d.ts +8 -0
  164. package/dist/decorators/schema.d.ts.map +1 -0
  165. package/dist/decorators/schema.js +14 -0
  166. package/dist/decorators/schema.js.map +1 -0
  167. package/dist/index.d.ts +7 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +10 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/middlewares/auth.d.ts +41 -0
  172. package/dist/middlewares/auth.d.ts.map +1 -0
  173. package/dist/middlewares/auth.js +74 -0
  174. package/dist/middlewares/auth.js.map +1 -0
  175. package/dist/middlewares/cors.d.ts +30 -0
  176. package/dist/middlewares/cors.d.ts.map +1 -0
  177. package/dist/middlewares/cors.js +69 -0
  178. package/dist/middlewares/cors.js.map +1 -0
  179. package/dist/middlewares/csrf.d.ts +42 -0
  180. package/dist/middlewares/csrf.d.ts.map +1 -0
  181. package/dist/middlewares/csrf.js +70 -0
  182. package/dist/middlewares/csrf.js.map +1 -0
  183. package/dist/middlewares/index.d.ts +6 -0
  184. package/dist/middlewares/index.d.ts.map +1 -0
  185. package/dist/middlewares/index.js +6 -0
  186. package/dist/middlewares/index.js.map +1 -0
  187. package/dist/middlewares/rate-limit.d.ts +35 -0
  188. package/dist/middlewares/rate-limit.d.ts.map +1 -0
  189. package/dist/middlewares/rate-limit.js +45 -0
  190. package/dist/middlewares/rate-limit.js.map +1 -0
  191. package/dist/middlewares/security-headers.d.ts +28 -0
  192. package/dist/middlewares/security-headers.d.ts.map +1 -0
  193. package/dist/middlewares/security-headers.js +42 -0
  194. package/dist/middlewares/security-headers.js.map +1 -0
  195. package/dist/openapi/generate.d.ts +51 -0
  196. package/dist/openapi/generate.d.ts.map +1 -0
  197. package/dist/openapi/generate.js +175 -0
  198. package/dist/openapi/generate.js.map +1 -0
  199. package/dist/schema/serialization.d.ts +2 -0
  200. package/dist/schema/serialization.d.ts.map +1 -0
  201. package/dist/schema/serialization.js +11 -0
  202. package/dist/schema/serialization.js.map +1 -0
  203. package/dist/schema/validation.d.ts +22 -0
  204. package/dist/schema/validation.d.ts.map +1 -0
  205. package/dist/schema/validation.js +68 -0
  206. package/dist/schema/validation.js.map +1 -0
  207. package/dist/server/static.d.ts +45 -0
  208. package/dist/server/static.d.ts.map +1 -0
  209. package/dist/server/static.js +204 -0
  210. package/dist/server/static.js.map +1 -0
  211. package/dist/server/tls.d.ts +48 -0
  212. package/dist/server/tls.d.ts.map +1 -0
  213. package/dist/server/tls.js +60 -0
  214. package/dist/server/tls.js.map +1 -0
  215. package/dist/shims/symbol-metadata.d.ts +2 -0
  216. package/dist/shims/symbol-metadata.d.ts.map +1 -0
  217. package/dist/shims/symbol-metadata.js +8 -0
  218. package/dist/shims/symbol-metadata.js.map +1 -0
  219. package/dist/utils/content-type.d.ts +13 -0
  220. package/dist/utils/content-type.d.ts.map +1 -0
  221. package/dist/utils/content-type.js +75 -0
  222. package/dist/utils/content-type.js.map +1 -0
  223. package/dist/utils/cookie.d.ts +34 -0
  224. package/dist/utils/cookie.d.ts.map +1 -0
  225. package/dist/utils/cookie.js +94 -0
  226. package/dist/utils/cookie.js.map +1 -0
  227. package/dist/utils/index.d.ts +7 -0
  228. package/dist/utils/index.d.ts.map +1 -0
  229. package/dist/utils/index.js +7 -0
  230. package/dist/utils/index.js.map +1 -0
  231. package/dist/utils/mime.d.ts +2 -0
  232. package/dist/utils/mime.d.ts.map +1 -0
  233. package/dist/utils/mime.js +52 -0
  234. package/dist/utils/mime.js.map +1 -0
  235. package/dist/utils/origin-match.d.ts +58 -0
  236. package/dist/utils/origin-match.d.ts.map +1 -0
  237. package/dist/utils/origin-match.js +194 -0
  238. package/dist/utils/origin-match.js.map +1 -0
  239. package/dist/utils/path.d.ts +10 -0
  240. package/dist/utils/path.d.ts.map +1 -0
  241. package/dist/utils/path.js +60 -0
  242. package/dist/utils/path.js.map +1 -0
  243. package/dist/utils/query.d.ts +28 -0
  244. package/dist/utils/query.d.ts.map +1 -0
  245. package/dist/utils/query.js +67 -0
  246. package/dist/utils/query.js.map +1 -0
  247. package/dist/utils/request-target.d.ts +31 -0
  248. package/dist/utils/request-target.d.ts.map +1 -0
  249. package/dist/utils/request-target.js +80 -0
  250. package/dist/utils/request-target.js.map +1 -0
  251. package/dist/utils/safe-json.d.ts +24 -0
  252. package/dist/utils/safe-json.d.ts.map +1 -0
  253. package/dist/utils/safe-json.js +83 -0
  254. package/dist/utils/safe-json.js.map +1 -0
  255. package/dist/utils/trace-context.d.ts +17 -0
  256. package/dist/utils/trace-context.d.ts.map +1 -0
  257. package/dist/utils/trace-context.js +30 -0
  258. package/dist/utils/trace-context.js.map +1 -0
  259. package/package.json +85 -6
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Server-Sent Events (F-13). Fica fora do `Context`, que só delega: o modelo da requisição não carrega a
3
+ * lógica de cada forma de envio.
4
+ */
5
+ import type { Context } from '../context.ts';
6
+ /** Um evento de Server-Sent Events (F-13). `data` em objeto vira JSON; strings com várias linhas são divididas. */
7
+ export interface SseEvent {
8
+ data: unknown;
9
+ event?: string;
10
+ id?: string;
11
+ /** Sugestão de espera para o navegador reconectar, em ms. */
12
+ retry?: number;
13
+ }
14
+ /** Conexão SSE aberta por `ctx.sse()`. */
15
+ export interface SseStream {
16
+ send(event: SseEvent | string): void;
17
+ /** Comentário (`: texto`), ignorado pelo navegador; útil como keep-alive. */
18
+ comment(text: string): void;
19
+ /** Encerra a resposta. */
20
+ close(): void;
21
+ /** Chamado quando a conexão termina: o cliente desconectou, `close()` ou encerramento do app. */
22
+ onClose(listener: () => void): void;
23
+ readonly closed: boolean;
24
+ /** `Last-Event-ID` enviado pelo navegador ao reconectar. */
25
+ readonly lastEventId: string | undefined;
26
+ }
27
+ export interface SseOptions {
28
+ /** Comentário periódico para proxies não derrubarem a conexão ociosa. Padrão: 15000 ms; `0` desliga. */
29
+ heartbeatMs?: number;
30
+ /** `retry:` enviado na abertura. */
31
+ retry?: number;
32
+ }
33
+ /** Abre a conexão SSE de `ctx`. `markStreaming` marca a resposta como stream (estado privado do `Context`). */
34
+ export declare function openSse(ctx: Context, opts: SseOptions, markStreaming: () => void): SseStream;
35
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/core/streaming/sse.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,mHAAmH;AACnH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0CAA0C;AAC1C,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,6EAA6E;IAC7E,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0BAA0B;IAC1B,KAAK,IAAI,IAAI,CAAC;IACd,iGAAiG;IACjG,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoCD,+GAA+G;AAC/G,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,GAAG,SAAS,CAqE5F"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Campos de uma linha SSE não podem ter quebra de linha (seria injeção de evento); `id` também não pode
3
+ * ter U+0000, que faz o navegador ignorar o campo.
4
+ */
5
+ const sseField = (name, value) => {
6
+ if (/[\r\n]/.test(value))
7
+ throw new Error(`[flowing] ctx.sse(): "${name}" cannot contain line breaks.`);
8
+ if (name === 'id' && value.includes('\0'))
9
+ throw new Error('[flowing] ctx.sse(): "id" cannot contain U+0000.');
10
+ return `${name}: ${value}\n`;
11
+ };
12
+ /** Maior intervalo dos timers do Node; acima disso, ele usa 1 ms (heartbeat contínuo). */
13
+ const MAX_TIMER_MS = 2_147_483_647;
14
+ /** `retry` e `heartbeatMs`: inteiro não negativo, como o protocolo exige, e dentro do limite dos timers. */
15
+ const nonNegativeInt = (name, value) => {
16
+ if (!Number.isInteger(value) || value < 0 || value > MAX_TIMER_MS) {
17
+ throw new Error(`[flowing] ctx.sse(): "${name}" must be an integer between 0 and ${MAX_TIMER_MS} (got ${value}).`);
18
+ }
19
+ return value;
20
+ };
21
+ /** `data` do evento: strings como estão; o resto em JSON. Valor que não vira JSON gera erro claro, sem escrever nada. */
22
+ function sseData(data) {
23
+ if (typeof data === 'string')
24
+ return data;
25
+ let text;
26
+ try {
27
+ text = JSON.stringify(data);
28
+ }
29
+ catch (err) {
30
+ throw new Error(`[flowing] ctx.sse(): "data" is not JSON-serializable (${err.message}).`, { cause: err });
31
+ }
32
+ if (text === undefined)
33
+ throw new Error(`[flowing] ctx.sse(): "data" of type ${typeof data} is not JSON-serializable.`);
34
+ return text;
35
+ }
36
+ /** Abre a conexão SSE de `ctx`. `markStreaming` marca a resposta como stream (estado privado do `Context`). */
37
+ export function openSse(ctx, opts, markStreaming) {
38
+ if (ctx.sent)
39
+ throw new Error('[flowing] ctx.sse(): the response was already sent.');
40
+ // Valida antes de abrir a resposta: um erro aqui ainda vira um 500 normal.
41
+ const heartbeatMs = nonNegativeInt('heartbeatMs', opts.heartbeatMs ?? 15_000);
42
+ if (opts.retry !== undefined)
43
+ nonNegativeInt('retry', opts.retry);
44
+ const res = ctx.res;
45
+ markStreaming();
46
+ res.statusCode = 200;
47
+ res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
48
+ res.setHeader('Cache-Control', 'no-cache, no-transform');
49
+ res.setHeader('X-Accel-Buffering', 'no');
50
+ res.removeHeader('Content-Length');
51
+ res.flushHeaders();
52
+ const listeners = [];
53
+ let closed = false;
54
+ const finish = () => {
55
+ if (closed)
56
+ return;
57
+ closed = true;
58
+ clearInterval(heartbeat);
59
+ for (const l of listeners.splice(0)) {
60
+ try {
61
+ l();
62
+ }
63
+ catch (err) {
64
+ ctx.log.error({ err }, 'sse onClose listener failed');
65
+ }
66
+ }
67
+ };
68
+ const write = (chunk) => {
69
+ if (!closed && !res.writableEnded)
70
+ res.write(chunk);
71
+ };
72
+ const heartbeat = setInterval(() => write(': ping\n\n'), heartbeatMs || 2 ** 31 - 1);
73
+ heartbeat.unref();
74
+ if (!heartbeatMs)
75
+ clearInterval(heartbeat);
76
+ res.once('close', finish);
77
+ const signal = ctx.signal;
78
+ signal.addEventListener('abort', () => stream.close(), { once: true });
79
+ if (opts.retry !== undefined)
80
+ write(`retry: ${opts.retry}\n\n`);
81
+ const stream = {
82
+ send: (event) => {
83
+ const e = typeof event === 'string' ? { data: event } : event;
84
+ let out = '';
85
+ if (e.event !== undefined)
86
+ out += sseField('event', e.event);
87
+ if (e.id !== undefined)
88
+ out += sseField('id', e.id);
89
+ if (e.retry !== undefined)
90
+ out += `retry: ${nonNegativeInt('retry', e.retry)}\n`;
91
+ if (e.data === undefined)
92
+ throw new Error('[flowing] ctx.sse(): "data" is required; use "" for an empty event.');
93
+ const text = sseData(e.data);
94
+ for (const line of text.split(/\r\n|\r|\n/))
95
+ out += `data: ${line}\n`;
96
+ write(`${out}\n`);
97
+ },
98
+ comment: (text) => write(`: ${text.replace(/[\r\n]+/g, ' ')}\n\n`),
99
+ close: () => {
100
+ if (!res.writableEnded)
101
+ res.end();
102
+ finish();
103
+ },
104
+ onClose: (listener) => {
105
+ if (closed)
106
+ listener();
107
+ else
108
+ listeners.push(listener);
109
+ },
110
+ get closed() {
111
+ return closed;
112
+ },
113
+ lastEventId: ctx.get('last-event-id'),
114
+ };
115
+ // O cliente pode ter desconectado antes do `ctx.sse()` (num `await` anterior): o 'close' e o 'abort' já
116
+ // passaram, e os listeners acima nunca rodariam. Encerra já, limpando o heartbeat e chamando `onClose`.
117
+ if (signal.aborted)
118
+ stream.close();
119
+ return stream;
120
+ }
121
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/core/streaming/sse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /** Símbolos internos do core. Ficam num módulo próprio para quem os usa não depender do `Context` em tempo de execução. */
2
+ /** @internal Envio cru, sem pipeline: usado pelo próprio pipeline, por erros e por 404/405. */
3
+ export declare const kRawSend: unique symbol;
4
+ /** @internal Cancela o `ctx.signal` (encerramento do app) (F-13). */
5
+ export declare const kAbort: unique symbol;
6
+ /** @internal Envio de arquivo em andamento, que o app aguarda mesmo sem `await` no handler (F-13). */
7
+ export declare const kPendingSend: unique symbol;
8
+ /** @internal Liga o contexto aos schemas de resposta da rota, antes do handler (F-32). */
9
+ export declare const kBindResponse: unique symbol;
10
+ /** @internal A cadeia global chegou ao roteamento (o último middleware chamou `next()`). */
11
+ export declare const kRouted: unique symbol;
12
+ /** @internal A rota que atendeu a requisição (`ctx.route`, F-38). */
13
+ export declare const kRoute: unique symbol;
14
+ /** @internal O erro tratado pelo pipeline de erros, para o `onResponse` (F-38). */
15
+ export declare const kError: unique symbol;
16
+ /** @internal Em que etapa a requisição está, para a fase do `onError` (F-38). */
17
+ export declare const kPhase: unique symbol;
18
+ /** @internal Estado do `telemetry` de uma requisição (F-38). */
19
+ export declare const kTelemetry: unique symbol;
20
+ /** @internal Instante em que os headers da resposta saíram, para o `ttfbMs` (F-38). */
21
+ export declare const kHeadersAt: unique symbol;
22
+ /** @internal Hooks com escopo da rota, guardados no `RouteInfo` de cada host (F-43). */
23
+ export declare const kHooks: unique symbol;
24
+ /** @internal O motor dos contratos do app (`contracts`, F-27), lido pelo pipeline de resposta. */
25
+ export declare const kContracts: unique symbol;
26
+ /** @internal Arquivos recebidos de um upload (F-46), lidos por `ctx.file()`/`ctx.files()`. */
27
+ export declare const kFiles: unique symbol;
28
+ //# sourceMappingURL=symbols.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../src/core/symbols.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAE3H,+FAA+F;AAC/F,eAAO,MAAM,QAAQ,eAA4B,CAAC;AAClD,qEAAqE;AACrE,eAAO,MAAM,MAAM,eAA0B,CAAC;AAC9C,sGAAsG;AACtG,eAAO,MAAM,YAAY,eAAgC,CAAC;AAC1D,0FAA0F;AAC1F,eAAO,MAAM,aAAa,eAAiC,CAAC;AAC5D,4FAA4F;AAC5F,eAAO,MAAM,OAAO,eAA2B,CAAC;AAChD,qEAAqE;AACrE,eAAO,MAAM,MAAM,eAA0B,CAAC;AAC9C,mFAAmF;AACnF,eAAO,MAAM,MAAM,eAA0B,CAAC;AAC9C,iFAAiF;AACjF,eAAO,MAAM,MAAM,eAA0B,CAAC;AAC9C,gEAAgE;AAChE,eAAO,MAAM,UAAU,eAA8B,CAAC;AACtD,uFAAuF;AACvF,eAAO,MAAM,UAAU,eAA8B,CAAC;AACtD,wFAAwF;AACxF,eAAO,MAAM,MAAM,eAA0B,CAAC;AAC9C,kGAAkG;AAClG,eAAO,MAAM,UAAU,eAA8B,CAAC;AACtD,8FAA8F;AAC9F,eAAO,MAAM,MAAM,eAA0B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** Símbolos internos do core. Ficam num módulo próprio para quem os usa não depender do `Context` em tempo de execução. */
2
+ /** @internal Envio cru, sem pipeline: usado pelo próprio pipeline, por erros e por 404/405. */
3
+ export const kRawSend = Symbol('flowing.rawSend');
4
+ /** @internal Cancela o `ctx.signal` (encerramento do app) (F-13). */
5
+ export const kAbort = Symbol('flowing.abort');
6
+ /** @internal Envio de arquivo em andamento, que o app aguarda mesmo sem `await` no handler (F-13). */
7
+ export const kPendingSend = Symbol('flowing.pendingSend');
8
+ /** @internal Liga o contexto aos schemas de resposta da rota, antes do handler (F-32). */
9
+ export const kBindResponse = Symbol('flowing.bindResponse');
10
+ /** @internal A cadeia global chegou ao roteamento (o último middleware chamou `next()`). */
11
+ export const kRouted = Symbol('flowing.routed');
12
+ /** @internal A rota que atendeu a requisição (`ctx.route`, F-38). */
13
+ export const kRoute = Symbol('flowing.route');
14
+ /** @internal O erro tratado pelo pipeline de erros, para o `onResponse` (F-38). */
15
+ export const kError = Symbol('flowing.error');
16
+ /** @internal Em que etapa a requisição está, para a fase do `onError` (F-38). */
17
+ export const kPhase = Symbol('flowing.phase');
18
+ /** @internal Estado do `telemetry` de uma requisição (F-38). */
19
+ export const kTelemetry = Symbol('flowing.telemetry');
20
+ /** @internal Instante em que os headers da resposta saíram, para o `ttfbMs` (F-38). */
21
+ export const kHeadersAt = Symbol('flowing.headersAt');
22
+ /** @internal Hooks com escopo da rota, guardados no `RouteInfo` de cada host (F-43). */
23
+ export const kHooks = Symbol('flowing.hooks');
24
+ /** @internal O motor dos contratos do app (`contracts`, F-27), lido pelo pipeline de resposta. */
25
+ export const kContracts = Symbol('flowing.contracts');
26
+ /** @internal Arquivos recebidos de um upload (F-46), lidos por `ctx.file()`/`ctx.files()`. */
27
+ export const kFiles = Symbol('flowing.files');
28
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/core/symbols.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAE3H,+FAA+F;AAC/F,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAClD,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,sGAAsG;AACtG,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAC1D,0FAA0F;AAC1F,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAC5D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAChD,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,mFAAmF;AACnF,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,iFAAiF;AACjF,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,gEAAgE;AAChE,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AACtD,uFAAuF;AACvF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AACtD,wFAAwF;AACxF,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,kGAAkG;AAClG,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AACtD,8FAA8F;AAC9F,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * OpenTelemetry nativo por injeção (F-38): `createApp({ telemetry: otel })`, com o `@opentelemetry/api` que a
3
+ * aplicação já usa. O core não importa o pacote nem prende uma versão: só os tipos estruturais abaixo, o
4
+ * mesmo modelo do `logger: pino()`.
5
+ *
6
+ * Com um span ativo (a auto-instrumentação HTTP do SDK já criou o span SERVER), o FlowingTS **enriquece** esse
7
+ * span, sem duplicar: nome `GET /users/:id`, `http.route` e as exceções com a fase. Esse span é encerrado pela
8
+ * própria auto-instrumentação, dentro do `res.end()`, então o enriquecimento acontece no roteamento e no
9
+ * tratamento de erro, antes da resposta. Sem span ativo, o FlowingTS cria o span SERVER, a partir do
10
+ * `traceparent` recebido, e o encerra no fim da requisição.
11
+ */
12
+ import type { ResponseInfo } from './app/options.ts';
13
+ import type { ErrorPhase } from './abort.ts';
14
+ import type { Context } from './context.ts';
15
+ import type { RouteInfo } from './route-table.ts';
16
+ type Attributes = Record<string, string | number | boolean>;
17
+ /** O subconjunto de um `Span` do OpenTelemetry que o FlowingTS usa. */
18
+ export interface TelemetrySpan {
19
+ setAttribute(key: string, value: string | number | boolean): unknown;
20
+ updateName(name: string): unknown;
21
+ recordException(exception: unknown): unknown;
22
+ setStatus(status: {
23
+ code: number;
24
+ message?: string;
25
+ }): unknown;
26
+ addEvent?(name: string, attributes?: Attributes): unknown;
27
+ end(): void;
28
+ spanContext(): {
29
+ traceId: string;
30
+ spanId: string;
31
+ };
32
+ }
33
+ interface TelemetryInstrument {
34
+ record?(value: number, attributes?: Attributes): void;
35
+ add?(value: number, attributes?: Attributes): void;
36
+ }
37
+ /** O subconjunto do `@opentelemetry/api` que o FlowingTS usa. Passe o módulo inteiro: `import * as otel`. */
38
+ export interface TelemetryApi {
39
+ trace: {
40
+ getActiveSpan(): TelemetrySpan | undefined;
41
+ getTracer(name: string, version?: string): {
42
+ startSpan(name: string, options?: object, context?: unknown): TelemetrySpan;
43
+ };
44
+ setSpan(context: unknown, span: TelemetrySpan): unknown;
45
+ };
46
+ context: {
47
+ active(): unknown;
48
+ with<T>(context: unknown, fn: () => T): T;
49
+ };
50
+ propagation: {
51
+ extract(context: unknown, carrier: unknown): unknown;
52
+ };
53
+ metrics?: {
54
+ getMeter(name: string, version?: string): {
55
+ createHistogram(name: string, options?: object): TelemetryInstrument;
56
+ createUpDownCounter(name: string, options?: object): TelemetryInstrument;
57
+ createCounter(name: string, options?: object): TelemetryInstrument;
58
+ };
59
+ };
60
+ SpanKind: {
61
+ SERVER: number;
62
+ };
63
+ SpanStatusCode: {
64
+ ERROR: number;
65
+ };
66
+ }
67
+ /** Os pontos do pipeline em que o `telemetry` age; chamados pelo request-handler. */
68
+ export interface Telemetry {
69
+ onRequest(ctx: Context): void;
70
+ onRoute(ctx: Context, route: RouteInfo): void;
71
+ onError(ctx: Context, err: unknown, phase: ErrorPhase): void;
72
+ onResponse(ctx: Context, info: ResponseInfo): void;
73
+ /** Roda o pipeline dentro do contexto do span criado pelo FlowingTS (spans do usuário viram filhos). */
74
+ run<T>(ctx: Context, fn: () => T): T;
75
+ /** `traceId`/`spanId` do span da requisição, para o `ctx.log`. */
76
+ spanIds(ctx: Context): {
77
+ traceId: string;
78
+ spanId: string;
79
+ } | undefined;
80
+ }
81
+ export declare function createTelemetry(api: TelemetryApi, version?: string | undefined): Telemetry;
82
+ export {};
83
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { createRequire } from 'node:module';
2
+ import { kTelemetry } from './symbols.js';
3
+ /** O estado deste módulo no `ctx`; o campo é `unknown` no `Context`, para ele não depender do telemetry. */
4
+ const state = (ctx) => ctx[kTelemetry];
5
+ /** Versão do FlowingTS, para o nome do tracer e do meter. Lida só quando o `telemetry` é usado. */
6
+ function packageVersion() {
7
+ try {
8
+ return createRequire(import.meta.url)('../../package.json').version;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ export function createTelemetry(api, version = packageVersion()) {
15
+ const tracer = api.trace.getTracer('flowingts', version);
16
+ const meter = api.metrics?.getMeter('flowingts', version);
17
+ const duration = meter?.createHistogram('http.server.request.duration', {
18
+ unit: 's',
19
+ description: 'Duração das requisições HTTP (sem streams).',
20
+ });
21
+ const streamDuration = meter?.createHistogram('flowing.stream.duration', {
22
+ unit: 's',
23
+ description: 'Duração das respostas em stream (SSE, NDJSON, arquivos).',
24
+ });
25
+ const active = meter?.createUpDownCounter('http.server.active_requests', { unit: '{request}' });
26
+ const aborted = meter?.createCounter('flowing.request.aborted', { unit: '{request}' });
27
+ return {
28
+ onRequest(ctx) {
29
+ const current = api.trace.getActiveSpan();
30
+ let telemetry;
31
+ if (current) {
32
+ telemetry = { span: current, owned: false, activeAttrs: { 'http.request.method': ctx.method } };
33
+ }
34
+ else {
35
+ const parent = api.propagation.extract(api.context.active(), ctx.req.headers);
36
+ const span = tracer.startSpan(ctx.method, { kind: api.SpanKind.SERVER, attributes: { 'http.request.method': ctx.method, 'url.path': ctx.path } }, parent);
37
+ telemetry = { span, owned: true, context: api.trace.setSpan(parent, span), activeAttrs: { 'http.request.method': ctx.method } };
38
+ }
39
+ ctx[kTelemetry] = telemetry;
40
+ active?.add?.(1, telemetry.activeAttrs);
41
+ },
42
+ onRoute(ctx, route) {
43
+ const t = state(ctx);
44
+ if (!t)
45
+ return;
46
+ t.span.updateName(`${ctx.method} ${route.path}`);
47
+ t.span.setAttribute('http.route', route.path);
48
+ },
49
+ onError(ctx, err, phase) {
50
+ const t = state(ctx);
51
+ if (!t)
52
+ return;
53
+ t.span.recordException(err);
54
+ t.span.addEvent?.('flowing.error', { 'flowing.error.phase': phase });
55
+ },
56
+ onResponse(ctx, info) {
57
+ const t = state(ctx);
58
+ if (!t)
59
+ return;
60
+ const attrs = { 'http.request.method': ctx.method, 'http.response.status_code': info.status };
61
+ if (info.route)
62
+ attrs['http.route'] = info.route.path;
63
+ // A regra do virtual host, não o hostname do cliente: mantém baixa a cardinalidade.
64
+ if (info.route?.host)
65
+ attrs['server.address'] = info.route.host;
66
+ if (info.status >= 500)
67
+ attrs['error.type'] = String(info.status);
68
+ if (info.abortReason)
69
+ attrs['flowing.abort.reason'] = info.abortReason;
70
+ active?.add?.(-1, t.activeAttrs);
71
+ if (info.abortReason)
72
+ aborted?.add?.(1, { 'flowing.abort.reason': info.abortReason });
73
+ (info.streaming ? streamDuration : duration)?.record?.(info.ms / 1000, attrs);
74
+ // O span da auto-instrumentação já foi encerrado por ela; só o criado aqui recebe o fim.
75
+ if (!t.owned)
76
+ return;
77
+ for (const [k, v] of Object.entries(attrs))
78
+ t.span.setAttribute(k, v);
79
+ t.span.setAttribute('flowing.outcome', info.outcome);
80
+ if (info.ttfbMs !== undefined)
81
+ t.span.setAttribute('flowing.ttfb_ms', info.ttfbMs);
82
+ // Convenções semânticas: só 5xx marca o span SERVER como erro; um 4xx é resposta normal.
83
+ if (info.status >= 500)
84
+ t.span.setStatus({ code: api.SpanStatusCode.ERROR });
85
+ t.span.end();
86
+ },
87
+ run(ctx, fn) {
88
+ const t = state(ctx);
89
+ return t?.context === undefined ? fn() : api.context.with(t.context, fn);
90
+ },
91
+ spanIds(ctx) {
92
+ return state(ctx)?.span.spanContext();
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { Context } from '../context.ts';
2
+ import type { ContentDetector, FileRule, FileRules, Size, UploadedFile, UploadsOptions } from './types.ts';
3
+ /** `'5mb'` → 5242880. Erro de configuração aparece no registro da rota. */
4
+ export declare function parseSize(size: Size, where: string): number;
5
+ /**
6
+ * Detectores de conteúdo (F-46):
7
+ * - `detectors.magicBytes()`: o padrão, sem dependências (centenas de assinaturas; documentos do Office só como ZIP).
8
+ * - `detectors.fileType(fileTypeFromBuffer)`: o `file-type`, instalado pela aplicação, para conferências mais completas
9
+ * (abre o ZIP para confirmar `.docx`, `.xlsx`, `.pptx`).
10
+ */
11
+ export declare const detectors: {
12
+ magicBytes: () => ContentDetector;
13
+ fileType: (fileTypeFromBuffer: (buffer: Uint8Array) => Promise<{
14
+ mime: string;
15
+ } | undefined>) => ContentDetector;
16
+ };
17
+ /** Limites globais resolvidos, em bytes e contagens. */
18
+ export interface UploadLimits {
19
+ readonly fileSize: number;
20
+ readonly files: number;
21
+ readonly fields: number;
22
+ readonly fieldSize: number;
23
+ readonly parts: number;
24
+ }
25
+ export interface UploadSettings {
26
+ readonly limits: UploadLimits;
27
+ readonly tempDir: string;
28
+ readonly detect: ContentDetector;
29
+ }
30
+ export declare function uploadSettings(opts?: UploadsOptions): UploadSettings;
31
+ /** As regras de um campo, resolvidas no registro da rota. */
32
+ interface CompiledRule {
33
+ readonly required: boolean;
34
+ readonly maxSize: number;
35
+ readonly maxCount: number;
36
+ readonly types: readonly string[] | undefined;
37
+ readonly verify: FileRule['verify'];
38
+ }
39
+ /** O plano de upload de uma rota, montado no registro (nada por requisição). */
40
+ export interface UploadPlan {
41
+ readonly rules: ReadonlyMap<string, CompiledRule>;
42
+ readonly settings: UploadSettings;
43
+ /** O maior tamanho permitido entre os campos: o limite de leitura do busboy. */
44
+ readonly largest: number;
45
+ }
46
+ /**
47
+ * Resolve o `files` do contrato. Uma rota que tenta ampliar um limite global falha aqui, no registro, em vez de ser
48
+ * ignorada em silêncio.
49
+ */
50
+ export declare function uploadPlan(files: FileRules, settings: UploadSettings, where: string): UploadPlan;
51
+ /** O que a recepção deixa no `ctx`: os campos de texto (o body) e os arquivos por nome de campo. */
52
+ export interface Received {
53
+ readonly fields: Record<string, string | string[]>;
54
+ readonly files: ReadonlyMap<string, readonly UploadedFile[]>;
55
+ }
56
+ /**
57
+ * Lê um `multipart/form-data` (F-46). Os arquivos vão para temporários com nome gerado, apagados quando a resposta
58
+ * termina (sucesso, erro ou cancelamento). Limites, tipos, conteúdo e obrigatórios são conferidos aqui, antes do
59
+ * handler; os campos de texto são validados depois pelo contrato `body`.
60
+ */
61
+ export declare function receiveUploads(ctx: Context, plan: UploadPlan): Promise<Received>;
62
+ export {};
63
+ //# sourceMappingURL=receive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive.d.ts","sourceRoot":"","sources":["../../../src/core/uploads/receive.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAY,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOrH,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3D;AAKD;;;;;GAKG;AACH,eAAO,MAAM,SAAS;IACpB,UAAU,QAAM,eAAe;IAC/B,QAAQ,uBACe,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,KAAG,eAAe;CAKvG,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;CAClC;AAED,wBAAgB,cAAc,CAAC,IAAI,GAAE,cAAmB,GAAG,cAAc,CAaxE;AAED,6DAA6D;AAC7D,UAAU,YAAY;IACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAkBhG;AA2CD,oGAAoG;AACpG,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,CAAC;CAC9D;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8IhF"}