@thymian/plugin-sampler 0.3.0-canary.20261007-e6cb8dc → 0.3.0-canary.20261007-cdbe1d3

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 (264) hide show
  1. package/dist/cli/check-result.d.ts +88 -0
  2. package/dist/cli/check-result.d.ts.map +1 -0
  3. package/dist/cli/check-result.js +160 -0
  4. package/dist/cli/check-result.js.map +1 -0
  5. package/dist/cli/commands/sampler/check.d.ts +32 -4
  6. package/dist/cli/commands/sampler/check.d.ts.map +1 -1
  7. package/dist/cli/commands/sampler/check.js +126 -88
  8. package/dist/cli/commands/sampler/check.js.map +1 -1
  9. package/dist/cli/commands/sampler/init.d.ts +4 -6
  10. package/dist/cli/commands/sampler/init.d.ts.map +1 -1
  11. package/dist/cli/commands/sampler/init.js +33 -49
  12. package/dist/cli/commands/sampler/init.js.map +1 -1
  13. package/dist/cli/commands/sampler/show.d.ts +11 -0
  14. package/dist/cli/commands/sampler/show.d.ts.map +1 -0
  15. package/dist/cli/commands/sampler/show.js +36 -0
  16. package/dist/cli/commands/sampler/show.js.map +1 -0
  17. package/dist/cli/commands/sampler/sync.d.ts +11 -0
  18. package/dist/cli/commands/sampler/sync.d.ts.map +1 -0
  19. package/dist/cli/commands/sampler/sync.js +65 -0
  20. package/dist/cli/commands/sampler/sync.js.map +1 -0
  21. package/dist/cli/commands/sampler/validate.d.ts +3 -10
  22. package/dist/cli/commands/sampler/validate.d.ts.map +1 -1
  23. package/dist/cli/commands/sampler/validate.js +57 -126
  24. package/dist/cli/commands/sampler/validate.js.map +1 -1
  25. package/dist/generation/closed-schema.d.ts +22 -0
  26. package/dist/generation/closed-schema.d.ts.map +1 -0
  27. package/dist/generation/closed-schema.js +45 -0
  28. package/dist/generation/closed-schema.js.map +1 -0
  29. package/dist/generation/content-type-strategies/json.content-type-strategy.d.ts.map +1 -1
  30. package/dist/generation/content-type-strategies/json.content-type-strategy.js +3 -1
  31. package/dist/generation/content-type-strategies/json.content-type-strategy.js.map +1 -1
  32. package/dist/generation/content-type-strategies/xml.content-type-strategy.d.ts.map +1 -1
  33. package/dist/generation/content-type-strategies/xml.content-type-strategy.js +3 -1
  34. package/dist/generation/content-type-strategies/xml.content-type-strategy.js.map +1 -1
  35. package/dist/generation/generate-request-sample.d.ts +12 -0
  36. package/dist/generation/generate-request-sample.d.ts.map +1 -0
  37. package/dist/generation/{generate-samples.js → generate-request-sample.js} +11 -4
  38. package/dist/generation/generate-request-sample.js.map +1 -0
  39. package/dist/generation/request-generators/default-request-generator.d.ts +14 -0
  40. package/dist/generation/request-generators/default-request-generator.d.ts.map +1 -1
  41. package/dist/generation/request-generators/default-request-generator.js +18 -1
  42. package/dist/generation/request-generators/default-request-generator.js.map +1 -1
  43. package/dist/generation/types/declaration-set.d.ts +124 -0
  44. package/dist/generation/types/declaration-set.d.ts.map +1 -0
  45. package/dist/generation/types/declaration-set.js +389 -0
  46. package/dist/generation/types/declaration-set.js.map +1 -0
  47. package/dist/generation/types/example-reflection.d.ts +21 -0
  48. package/dist/generation/types/example-reflection.d.ts.map +1 -0
  49. package/dist/generation/types/example-reflection.js +135 -0
  50. package/dist/generation/types/example-reflection.js.map +1 -0
  51. package/dist/generation/types/generate-type-surface.d.ts +23 -0
  52. package/dist/generation/types/generate-type-surface.d.ts.map +1 -0
  53. package/dist/generation/types/generate-type-surface.js +671 -0
  54. package/dist/generation/types/generate-type-surface.js.map +1 -0
  55. package/dist/generation/types/schema-type.d.ts +20 -0
  56. package/dist/generation/types/schema-type.d.ts.map +1 -0
  57. package/dist/generation/types/schema-type.js +203 -0
  58. package/dist/generation/types/schema-type.js.map +1 -0
  59. package/dist/generation/types/self-check-surface.d.ts +32 -0
  60. package/dist/generation/types/self-check-surface.d.ts.map +1 -0
  61. package/dist/generation/types/self-check-surface.js +92 -0
  62. package/dist/generation/types/self-check-surface.js.map +1 -0
  63. package/dist/generation/types/type-names.d.ts +135 -0
  64. package/dist/generation/types/type-names.d.ts.map +1 -0
  65. package/dist/generation/types/type-names.js +213 -0
  66. package/dist/generation/types/type-names.js.map +1 -0
  67. package/dist/generation/types/write-type-surface.d.ts +58 -0
  68. package/dist/generation/types/write-type-surface.d.ts.map +1 -0
  69. package/dist/generation/types/write-type-surface.js +119 -0
  70. package/dist/generation/types/write-type-surface.js.map +1 -0
  71. package/dist/hooks/create-hook-utils.d.ts +22 -6
  72. package/dist/hooks/create-hook-utils.d.ts.map +1 -1
  73. package/dist/hooks/create-hook-utils.js +74 -96
  74. package/dist/hooks/create-hook-utils.js.map +1 -1
  75. package/dist/hooks/hook-api.d.ts +49 -0
  76. package/dist/hooks/hook-api.d.ts.map +1 -0
  77. package/dist/hooks/hook-api.js +105 -0
  78. package/dist/hooks/hook-api.js.map +1 -0
  79. package/dist/hooks/hook-diagnostics.d.ts +45 -0
  80. package/dist/hooks/hook-diagnostics.d.ts.map +1 -0
  81. package/dist/hooks/hook-diagnostics.js +80 -0
  82. package/dist/hooks/hook-diagnostics.js.map +1 -0
  83. package/dist/hooks/hook-errors.d.ts +33 -0
  84. package/dist/hooks/hook-errors.d.ts.map +1 -1
  85. package/dist/hooks/hook-errors.js +46 -0
  86. package/dist/hooks/hook-errors.js.map +1 -1
  87. package/dist/hooks/hook-registration.d.ts +108 -0
  88. package/dist/hooks/hook-registration.d.ts.map +1 -0
  89. package/dist/hooks/hook-registration.js +69 -0
  90. package/dist/hooks/hook-registration.js.map +1 -0
  91. package/dist/hooks/hook-runner.d.ts +111 -11
  92. package/dist/hooks/hook-runner.d.ts.map +1 -1
  93. package/dist/hooks/hook-runner.js +309 -142
  94. package/dist/hooks/hook-runner.js.map +1 -1
  95. package/dist/hooks/hook-utils-factory.d.ts +19 -0
  96. package/dist/hooks/hook-utils-factory.d.ts.map +1 -0
  97. package/dist/hooks/hook-utils-factory.js +2 -0
  98. package/dist/hooks/hook-utils-factory.js.map +1 -0
  99. package/dist/hooks/hook-utils.d.ts +80 -12
  100. package/dist/hooks/hook-utils.d.ts.map +1 -1
  101. package/dist/hooks/invoke-hook.d.ts +71 -0
  102. package/dist/hooks/invoke-hook.d.ts.map +1 -0
  103. package/dist/hooks/invoke-hook.js +161 -0
  104. package/dist/hooks/invoke-hook.js.map +1 -0
  105. package/dist/hooks/load-user-hooks.d.ts +96 -0
  106. package/dist/hooks/load-user-hooks.d.ts.map +1 -0
  107. package/dist/hooks/load-user-hooks.js +432 -0
  108. package/dist/hooks/load-user-hooks.js.map +1 -0
  109. package/dist/hooks/nested-request.d.ts +21 -0
  110. package/dist/hooks/nested-request.d.ts.map +1 -0
  111. package/dist/hooks/nested-request.js +24 -0
  112. package/dist/hooks/nested-request.js.map +1 -0
  113. package/dist/hooks/overlay-args.d.ts +40 -0
  114. package/dist/hooks/overlay-args.d.ts.map +1 -0
  115. package/dist/hooks/overlay-args.js +84 -0
  116. package/dist/hooks/overlay-args.js.map +1 -0
  117. package/dist/hooks/resolve-targeting.d.ts +16 -0
  118. package/dist/hooks/resolve-targeting.d.ts.map +1 -0
  119. package/dist/hooks/resolve-targeting.js +168 -0
  120. package/dist/hooks/resolve-targeting.js.map +1 -0
  121. package/dist/hooks/run-scoped-hooks.d.ts +83 -0
  122. package/dist/hooks/run-scoped-hooks.d.ts.map +1 -0
  123. package/dist/hooks/run-scoped-hooks.js +153 -0
  124. package/dist/hooks/run-scoped-hooks.js.map +1 -0
  125. package/dist/index.d.ts +42 -19
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +152 -165
  128. package/dist/index.js.map +1 -1
  129. package/dist/request-sampler.d.ts +40 -11
  130. package/dist/request-sampler.d.ts.map +1 -1
  131. package/dist/request-sampler.js +51 -76
  132. package/dist/request-sampler.js.map +1 -1
  133. package/dist/sampler-paths.d.ts +19 -0
  134. package/dist/sampler-paths.d.ts.map +1 -0
  135. package/dist/sampler-paths.js +22 -0
  136. package/dist/sampler-paths.js.map +1 -0
  137. package/dist/selectors/nearest-paths.d.ts +14 -0
  138. package/dist/selectors/nearest-paths.d.ts.map +1 -0
  139. package/dist/selectors/nearest-paths.js +32 -0
  140. package/dist/selectors/nearest-paths.js.map +1 -0
  141. package/dist/selectors/path-glob.d.ts +94 -0
  142. package/dist/selectors/path-glob.d.ts.map +1 -0
  143. package/dist/selectors/path-glob.js +136 -0
  144. package/dist/selectors/path-glob.js.map +1 -0
  145. package/dist/selectors/selector-errors.d.ts +17 -0
  146. package/dist/selectors/selector-errors.d.ts.map +1 -0
  147. package/dist/selectors/selector-errors.js +139 -0
  148. package/dist/selectors/selector-errors.js.map +1 -0
  149. package/dist/selectors/selector.d.ts +55 -0
  150. package/dist/selectors/selector.d.ts.map +1 -0
  151. package/dist/selectors/selector.js +305 -0
  152. package/dist/selectors/selector.js.map +1 -0
  153. package/dist/selectors/transaction-catalog.d.ts +96 -0
  154. package/dist/selectors/transaction-catalog.d.ts.map +1 -0
  155. package/dist/selectors/transaction-catalog.js +193 -0
  156. package/dist/selectors/transaction-catalog.js.map +1 -0
  157. package/dist/selectors/transaction-filter.d.ts +119 -0
  158. package/dist/selectors/transaction-filter.d.ts.map +1 -0
  159. package/dist/selectors/transaction-filter.js +191 -0
  160. package/dist/selectors/transaction-filter.js.map +1 -0
  161. package/dist/ts-path.d.ts +36 -0
  162. package/dist/ts-path.d.ts.map +1 -0
  163. package/dist/ts-path.js +46 -0
  164. package/dist/ts-path.js.map +1 -0
  165. package/dist/utils.d.ts +1 -2
  166. package/dist/utils.d.ts.map +1 -1
  167. package/dist/utils.js +2 -20
  168. package/dist/utils.js.map +1 -1
  169. package/dist/validation/canonicalize.d.ts +17 -0
  170. package/dist/validation/canonicalize.d.ts.map +1 -0
  171. package/dist/validation/canonicalize.js +29 -0
  172. package/dist/validation/canonicalize.js.map +1 -0
  173. package/dist/validation/shared-compiler-host.d.ts +17 -0
  174. package/dist/validation/shared-compiler-host.d.ts.map +1 -0
  175. package/dist/validation/shared-compiler-host.js +58 -0
  176. package/dist/validation/shared-compiler-host.js.map +1 -0
  177. package/dist/validation/typecheck-hooks.d.ts +37 -0
  178. package/dist/validation/typecheck-hooks.d.ts.map +1 -0
  179. package/dist/validation/typecheck-hooks.js +169 -0
  180. package/dist/validation/typecheck-hooks.js.map +1 -0
  181. package/dist/validation/validate-sampler.d.ts +79 -0
  182. package/dist/validation/validate-sampler.d.ts.map +1 -0
  183. package/dist/validation/validate-sampler.js +89 -0
  184. package/dist/validation/validate-sampler.js.map +1 -0
  185. package/package.json +7 -11
  186. package/dist/cli/commands/sampler/generate/hook.d.ts +0 -10
  187. package/dist/cli/commands/sampler/generate/hook.d.ts.map +0 -1
  188. package/dist/cli/commands/sampler/generate/hook.js +0 -19
  189. package/dist/cli/commands/sampler/generate/hook.js.map +0 -1
  190. package/dist/cli/generate-hook.d.ts +0 -4
  191. package/dist/cli/generate-hook.d.ts.map +0 -1
  192. package/dist/cli/generate-hook.js +0 -96
  193. package/dist/cli/generate-hook.js.map +0 -1
  194. package/dist/cli/templates.d.ts +0 -4
  195. package/dist/cli/templates.d.ts.map +0 -1
  196. package/dist/cli/templates.js +0 -28
  197. package/dist/cli/templates.js.map +0 -1
  198. package/dist/constants.d.ts +0 -12
  199. package/dist/constants.d.ts.map +0 -1
  200. package/dist/constants.js +0 -16
  201. package/dist/constants.js.map +0 -1
  202. package/dist/generation/generate-samples-for-thymian-format.d.ts +0 -4
  203. package/dist/generation/generate-samples-for-thymian-format.d.ts.map +0 -1
  204. package/dist/generation/generate-samples-for-thymian-format.js +0 -18
  205. package/dist/generation/generate-samples-for-thymian-format.js.map +0 -1
  206. package/dist/generation/generate-samples.d.ts +0 -4
  207. package/dist/generation/generate-samples.d.ts.map +0 -1
  208. package/dist/generation/generate-samples.js.map +0 -1
  209. package/dist/hooks/generate-request-types.d.ts +0 -34
  210. package/dist/hooks/generate-request-types.d.ts.map +0 -1
  211. package/dist/hooks/generate-request-types.js +0 -458
  212. package/dist/hooks/generate-request-types.js.map +0 -1
  213. package/dist/hooks/hook-types.d.ts +0 -7
  214. package/dist/hooks/hook-types.d.ts.map +0 -1
  215. package/dist/hooks/hook-types.js +0 -2
  216. package/dist/hooks/hook-types.js.map +0 -1
  217. package/dist/hooks/load-hooks-from-samples.d.ts +0 -3
  218. package/dist/hooks/load-hooks-from-samples.d.ts.map +0 -1
  219. package/dist/hooks/load-hooks-from-samples.js +0 -22
  220. package/dist/hooks/load-hooks-from-samples.js.map +0 -1
  221. package/dist/hooks/ts-config.d.ts +0 -10
  222. package/dist/hooks/ts-config.d.ts.map +0 -1
  223. package/dist/hooks/ts-config.js +0 -10
  224. package/dist/hooks/ts-config.js.map +0 -1
  225. package/dist/samples-structure/file-request-sample.d.ts +0 -20
  226. package/dist/samples-structure/file-request-sample.d.ts.map +0 -1
  227. package/dist/samples-structure/file-request-sample.js +0 -5
  228. package/dist/samples-structure/file-request-sample.js.map +0 -1
  229. package/dist/samples-structure/get-path-transaction-id.d.ts +0 -3
  230. package/dist/samples-structure/get-path-transaction-id.d.ts.map +0 -1
  231. package/dist/samples-structure/get-path-transaction-id.js +0 -22
  232. package/dist/samples-structure/get-path-transaction-id.js.map +0 -1
  233. package/dist/samples-structure/merge-tree.d.ts +0 -5
  234. package/dist/samples-structure/merge-tree.d.ts.map +0 -1
  235. package/dist/samples-structure/merge-tree.js +0 -118
  236. package/dist/samples-structure/merge-tree.js.map +0 -1
  237. package/dist/samples-structure/read-samples-from-dir.d.ts +0 -13
  238. package/dist/samples-structure/read-samples-from-dir.d.ts.map +0 -1
  239. package/dist/samples-structure/read-samples-from-dir.js +0 -205
  240. package/dist/samples-structure/read-samples-from-dir.js.map +0 -1
  241. package/dist/samples-structure/samples-from-transactions.d.ts +0 -5
  242. package/dist/samples-structure/samples-from-transactions.d.ts.map +0 -1
  243. package/dist/samples-structure/samples-from-transactions.js +0 -120
  244. package/dist/samples-structure/samples-from-transactions.js.map +0 -1
  245. package/dist/samples-structure/samples-tree-structure.d.ts +0 -106
  246. package/dist/samples-structure/samples-tree-structure.d.ts.map +0 -1
  247. package/dist/samples-structure/samples-tree-structure.js +0 -26
  248. package/dist/samples-structure/samples-tree-structure.js.map +0 -1
  249. package/dist/samples-structure/structure-meta-on-disc.d.ts +0 -11
  250. package/dist/samples-structure/structure-meta-on-disc.d.ts.map +0 -1
  251. package/dist/samples-structure/structure-meta-on-disc.js +0 -2
  252. package/dist/samples-structure/structure-meta-on-disc.js.map +0 -1
  253. package/dist/samples-structure/traverse.d.ts +0 -4
  254. package/dist/samples-structure/traverse.d.ts.map +0 -1
  255. package/dist/samples-structure/traverse.js +0 -13
  256. package/dist/samples-structure/traverse.js.map +0 -1
  257. package/dist/samples-structure/write-samples-to-dir.d.ts +0 -37
  258. package/dist/samples-structure/write-samples-to-dir.d.ts.map +0 -1
  259. package/dist/samples-structure/write-samples-to-dir.js +0 -183
  260. package/dist/samples-structure/write-samples-to-dir.js.map +0 -1
  261. package/dist/validation/validate-sampler-output.d.ts +0 -38
  262. package/dist/validation/validate-sampler-output.d.ts.map +0 -1
  263. package/dist/validation/validate-sampler-output.js +0 -288
  264. package/dist/validation/validate-sampler-output.js.map +0 -1
@@ -1,20 +1,79 @@
1
1
  export type ParameterType = string | number | null | boolean;
2
2
  export type EndpointRequest = {
3
- body: unknown;
3
+ body?: unknown;
4
4
  headers?: Record<PropertyKey, string | string[] | undefined>;
5
5
  query?: Record<PropertyKey, ParameterType>;
6
6
  cookies?: Record<PropertyKey, ParameterType>;
7
7
  path?: Record<PropertyKey, ParameterType | ParameterType[] | Record<string, ParameterType | ParameterType[]>>;
8
8
  };
9
+ /**
10
+ * One declared response, as a cross-endpoint caller sees it.
11
+ *
12
+ * The same four fields the generated `TransactionResponse<T>` carries, so the
13
+ * internal signature and the one an author's editor shows are one contract.
14
+ * `mediaType` is the essence the response actually arrived with.
15
+ */
16
+ export type EndpointResponse = {
17
+ body: unknown;
18
+ mediaType: string;
19
+ statusCode: number;
20
+ headers: Record<string, unknown>;
21
+ };
9
22
  export type Endpoints = Record<string, {
10
23
  req: EndpointRequest;
11
- res: {
12
- body: unknown;
13
- statusCode: number;
14
- headers: Record<string, unknown>;
15
- };
24
+ res: EndpointResponse;
25
+ /**
26
+ * Every response the Transaction's operation declares. Generated as a
27
+ * discriminated union; here it is the untyped stand-in, because the
28
+ * internal surface is only ever instantiated with `Record<string, never>`.
29
+ */
30
+ responses: EndpointResponse;
16
31
  }>;
17
- export interface HookUtils<E extends Endpoints = Record<string, never>> {
32
+ /** Options for a cross-endpoint request. */
33
+ export type RequestOptions = {
34
+ /**
35
+ * Run the target's own `beforeEach` → `authorize` → `afterEach` pipeline, so
36
+ * a seeding call behaves like the real run. Default `true`; `false` is the
37
+ * raw-seeding escape, and the way out of a cycle.
38
+ */
39
+ runHooks?: boolean;
40
+ /**
41
+ * Force authorization on or off for this call, overriding the target's own
42
+ * `authorize` flag. Authorization still needs a registered authorize hook.
43
+ */
44
+ authorize?: boolean;
45
+ };
46
+ /**
47
+ * The typed setters.
48
+ *
49
+ * They coexist with direct mutation and do exactly the same thing: a setter is
50
+ * a place for the compiler to know the name and the value type, not a different
51
+ * mechanism. Both write into the same request object.
52
+ *
53
+ * In an `afterEach` hook the request has already been sent, so a setter there
54
+ * changes nothing observable — the surface stays uniform rather than throwing.
55
+ */
56
+ export interface HookSetters {
57
+ setHeader(name: string, value: string | string[] | undefined): void;
58
+ setQuery(name: string, value: unknown): void;
59
+ setPathParam(name: string, value: unknown): void;
60
+ setCookie(name: string, value: unknown): void;
61
+ setBody(body: unknown): void;
62
+ setAuthorize(authorize: boolean): void;
63
+ }
64
+ /**
65
+ * Reads a file next to the hook that asks for it.
66
+ *
67
+ * A relative path resolves against the **hook file's own directory**, not the
68
+ * working directory: a fixture lives beside the hook that uses it, and a hook
69
+ * must keep working when the run starts somewhere else.
70
+ */
71
+ export interface HookFileHelpers {
72
+ readFile(path: string): Buffer;
73
+ readText(path: string, encoding?: BufferEncoding): string;
74
+ readJson<T = unknown>(path: string): T;
75
+ }
76
+ export interface HookUtils<E extends Endpoints = Record<string, never>> extends HookSetters, HookFileHelpers {
18
77
  skip(message: string): never;
19
78
  fail(message: string): never;
20
79
  info(message: string): void;
@@ -26,11 +85,20 @@ export interface HookUtils<E extends Endpoints = Record<string, never>> {
26
85
  actual?: unknown;
27
86
  }): void;
28
87
  timeout(message: string, durationMs: number): void;
29
- request<R extends keyof E>(req: R, args: E[R]['req'], options?: {
30
- runHooks?: boolean;
31
- authorize?: boolean;
32
- forStatusCode?: number;
33
- }): Promise<E[R]['res']>;
88
+ /**
89
+ * Call another Transaction, addressed by its Selector.
90
+ *
91
+ * Keyed by Selector and resolved through the transaction catalog, so the keys
92
+ * the committed types carry and the strings resolved at run time are the same
93
+ * strings by construction. There is no `forStatusCode`: the Selector already
94
+ * carries the status you asked for.
95
+ *
96
+ * `args` **overlays** the generated request — parameter groups merge per key,
97
+ * the body deep-merges — and the answer is every response the operation
98
+ * declares, because initiating a Transaction is not the same as getting one.
99
+ * A status the description never declares throws `UndeclaredResponseError`.
100
+ */
101
+ request<R extends keyof E>(selector: R, args?: E[R]['req'], options?: RequestOptions): Promise<E[R]['responses']>;
34
102
  randomString(length?: number): string;
35
103
  }
36
104
  //# sourceMappingURL=hook-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hook-utils.d.ts","sourceRoot":"","sources":["../../src/hooks/hook-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;AAE7D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CACX,WAAW,EACT,aAAa,GACb,aAAa,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC,CAClD,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAC5B,MAAM,EACN;IACE,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE;QACH,IAAI,EAAE,OAAO,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC;CACH,CACF,CAAC;AAEF,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;IAE7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;IAE7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9C,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5D,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GACrE,IAAI,CAAC;IAER,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnD,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,EACvB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EACjB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAExB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvC"}
1
+ {"version":3,"file":"hook-utils.d.ts","sourceRoot":"","sources":["../../src/hooks/hook-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { type HttpTestCaseResult, type Logger, ThymianBaseError } from '@thymian/core';
2
+ import type { HookKind } from './hook-registration.js';
3
+ import type { CollectedRegistration } from './load-user-hooks.js';
4
+ /**
5
+ * Calls one user callback with the arguments its kind is given.
6
+ *
7
+ * The cast lives here and nowhere else: a registration's `callback` is stored as
8
+ * an opaque function because each kind's precise signature is the runner's
9
+ * contract and the generated `.d.ts` is what types it for the author.
10
+ *
11
+ * The return value is discarded on purpose. A hook's contract is to mutate in
12
+ * place and return nothing, and honouring a return corrupts the value for the
13
+ * most ordinary shorthand there is: `(r) => (r.headers.x = 'y')` evaluates to
14
+ * `'y'`.
15
+ */
16
+ export declare function invokeHook(entry: CollectedRegistration, args: readonly unknown[]): Promise<unknown>;
17
+ /**
18
+ * Where a hook's `utils` results go when there is no test case to attach them
19
+ * to — a run-scoped hook, or a `defineSample` that runs before any request
20
+ * exists. Logging them beats dropping them silently.
21
+ */
22
+ export declare function reportHookResults(logger: Logger, results: readonly HttpTestCaseResult[]): void;
23
+ /**
24
+ * Names the hook a sampler diagnostic came out of, without burying the
25
+ * diagnostic.
26
+ *
27
+ * A cycle error's value is the chain it prints and a setter-misuse error's is
28
+ * the sentence explaining the misuse — both live in `suggestions`, so wrapping
29
+ * the error in a "hook X threw" envelope would throw away the part worth
30
+ * reading. The location joins the suggestions instead, at the front, where it
31
+ * answers "which line do I open" before the diagnostic answers "why".
32
+ */
33
+ export declare function attributeToHook(error: ThymianBaseError, kind: string, entry: CollectedRegistration): ThymianBaseError;
34
+ /** What interpreting a hook's failure decided should happen next. */
35
+ export type HookFailure = {
36
+ rethrow?: ThymianBaseError;
37
+ report?: {
38
+ skip: string;
39
+ } | {
40
+ fail: string;
41
+ };
42
+ };
43
+ /**
44
+ * The one interpretation every hook kind's failure goes through:
45
+ * `utils.skip`/`utils.fail` and an unhandled off-spec seed answer become a
46
+ * verdict for the kinds that have a Transaction to apply it to; a diagnostic
47
+ * the sampler itself raised keeps its own message and suggestions with the
48
+ * hook's location added; anything else is a defect in the hook and gets the
49
+ * envelope that names it.
50
+ *
51
+ * Every diagnostic that leaves here carries `severity: 'warn'`, and that is
52
+ * load-bearing rather than a judgement about how bad it is. An `error`-severity
53
+ * event closes the whole run through `Thymian.run`'s error subscription, which
54
+ * is precisely the behaviour the outcome model replaces: one broken hook used
55
+ * to end the command and hide every transaction after it.
56
+ */
57
+ export declare function interpretHookFailure(e: unknown, kind: HookKind, entry: CollectedRegistration): HookFailure;
58
+ /**
59
+ * Runs one hook through the shared attribution pipeline and always throws on
60
+ * failure — for `defineSample`, `beforeAll` and `afterAll`, which have no
61
+ * Transaction to report a `skip`/`fail` verdict against. Callable only with a
62
+ * kind outside {@link TRANSACTION_SCOPED_KINDS}, which is what guarantees
63
+ * {@link interpretHookFailure} always hands back a `rethrow` here and never a
64
+ * `report` with nowhere to go.
65
+ *
66
+ * The raw return value is handed back rather than discarded: `beforeAll` is
67
+ * the one kind whose return is not mutate-and-ignore — a returned function is
68
+ * a cleanup to run at teardown.
69
+ */
70
+ export declare function invokeOrThrow(kind: Exclude<HookKind, 'beforeEach' | 'afterEach' | 'authorize'>, entry: CollectedRegistration, args: readonly unknown[]): Promise<unknown>;
71
+ //# sourceMappingURL=invoke-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/invoke-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,MAAM,EACX,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAOvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,IAAI,CAoBN;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,qBAAqB,GAC3B,gBAAgB,CAkBlB;AAED,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C,CAAC;AAgBF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,qBAAqB,GAC3B,WAAW,CAsCb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC,EACjE,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,OAAO,CAAC,OAAO,CAAC,CAkBlB"}
@@ -0,0 +1,161 @@
1
+ import { ThymianBaseError, } from '@thymian/core';
2
+ import { FailError, SkipError, UndeclaredResponseError, } from './hook-errors.js';
3
+ /**
4
+ * Calls one user callback with the arguments its kind is given.
5
+ *
6
+ * The cast lives here and nowhere else: a registration's `callback` is stored as
7
+ * an opaque function because each kind's precise signature is the runner's
8
+ * contract and the generated `.d.ts` is what types it for the author.
9
+ *
10
+ * The return value is discarded on purpose. A hook's contract is to mutate in
11
+ * place and return nothing, and honouring a return corrupts the value for the
12
+ * most ordinary shorthand there is: `(r) => (r.headers.x = 'y')` evaluates to
13
+ * `'y'`.
14
+ */
15
+ export async function invokeHook(entry, args) {
16
+ const callback = entry.registration.callback;
17
+ return await callback(...args);
18
+ }
19
+ /**
20
+ * Where a hook's `utils` results go when there is no test case to attach them
21
+ * to — a run-scoped hook, or a `defineSample` that runs before any request
22
+ * exists. Logging them beats dropping them silently.
23
+ */
24
+ export function reportHookResults(logger, results) {
25
+ for (const result of results) {
26
+ if (result.type === 'assertion-failure' || result.type === 'timeout') {
27
+ logger.error(result.message);
28
+ }
29
+ else if (result.type === 'warning' ||
30
+ // A nested request has no test case of its own, so these are the only
31
+ // place its failure is ever said out loud. At `info` a seed answered
32
+ // with a declared-but-different status was invisible at the default
33
+ // level, while every transaction that depended on it turned up
34
+ // `skipped` with nothing naming the cause — the reader saw the
35
+ // consequence and not the reason.
36
+ result.type === 'invalid-transaction' ||
37
+ result.type === 'execution-error') {
38
+ logger.warn(result.message);
39
+ }
40
+ else {
41
+ logger.info(result.message);
42
+ }
43
+ }
44
+ }
45
+ /**
46
+ * Names the hook a sampler diagnostic came out of, without burying the
47
+ * diagnostic.
48
+ *
49
+ * A cycle error's value is the chain it prints and a setter-misuse error's is
50
+ * the sentence explaining the misuse — both live in `suggestions`, so wrapping
51
+ * the error in a "hook X threw" envelope would throw away the part worth
52
+ * reading. The location joins the suggestions instead, at the front, where it
53
+ * answers "which line do I open" before the diagnostic answers "why".
54
+ */
55
+ export function attributeToHook(error, kind, entry) {
56
+ return new ThymianBaseError(error.message, {
57
+ ...error.options,
58
+ // After the spread, never before it. An `error` closes the run
59
+ // (`thymian.ts`), which is the mechanism ADR-0023 §2 names and the sentence
60
+ // above promises to prevent — and every sampler-raised error that reaches
61
+ // here defaults to `error` because none of them sets a severity of its own:
62
+ // `UnknownSelectorError` and `MalformedSelectorError` from `utils.request`,
63
+ // `RequestCycleError`, a seed's `RequestSerializationError`,
64
+ // `NoRequestToShapeError`, `NoNestedRequestError`. A typo in a seed's
65
+ // selector is the most ordinary hook fault there is, and it ended the run.
66
+ severity: 'warn',
67
+ suggestions: [
68
+ `Raised by the ${kind} hook exported as "${entry.exportName}" from "${entry.file}".`,
69
+ ...(error.options.suggestions ?? []),
70
+ ],
71
+ cause: error.cause,
72
+ });
73
+ }
74
+ /**
75
+ * The kinds that run against one Transaction, and so have somewhere for a
76
+ * `utils.skip`/`utils.fail` verdict — or an unhandled off-spec seed answer —
77
+ * to land. `defineSample` runs before any request exists and `beforeAll`/
78
+ * `afterAll` run once for the whole run rather than per Transaction, so a
79
+ * control-flow throw from one of those has no Transaction to apply to and is
80
+ * treated like any other defect in the hook.
81
+ */
82
+ const TRANSACTION_SCOPED_KINDS = new Set([
83
+ 'beforeEach',
84
+ 'afterEach',
85
+ 'authorize',
86
+ ]);
87
+ /**
88
+ * The one interpretation every hook kind's failure goes through:
89
+ * `utils.skip`/`utils.fail` and an unhandled off-spec seed answer become a
90
+ * verdict for the kinds that have a Transaction to apply it to; a diagnostic
91
+ * the sampler itself raised keeps its own message and suggestions with the
92
+ * hook's location added; anything else is a defect in the hook and gets the
93
+ * envelope that names it.
94
+ *
95
+ * Every diagnostic that leaves here carries `severity: 'warn'`, and that is
96
+ * load-bearing rather than a judgement about how bad it is. An `error`-severity
97
+ * event closes the whole run through `Thymian.run`'s error subscription, which
98
+ * is precisely the behaviour the outcome model replaces: one broken hook used
99
+ * to end the command and hide every transaction after it.
100
+ */
101
+ export function interpretHookFailure(e, kind, entry) {
102
+ const controlFlow = TRANSACTION_SCOPED_KINDS.has(kind);
103
+ if (controlFlow && e instanceof SkipError) {
104
+ return { report: { skip: e.message } };
105
+ }
106
+ if (controlFlow && e instanceof FailError) {
107
+ return { report: { fail: e.message } };
108
+ }
109
+ // An off-spec seed answer that nobody caught. Reacting to it is opt-in, so
110
+ // letting it escape is a legitimate way to write a hook: the transaction
111
+ // cannot be executed as described, which is a skip and not a defect, and the
112
+ // message already names the seed and what it was answered with.
113
+ if (controlFlow && e instanceof UndeclaredResponseError) {
114
+ return { report: { skip: e.message } };
115
+ }
116
+ if (e instanceof ThymianBaseError) {
117
+ return { rethrow: attributeToHook(e, kind, entry) };
118
+ }
119
+ return {
120
+ rethrow: new ThymianBaseError(
121
+ // Deliberately without the Transaction: every surface that prints one
122
+ // already names it (ADR-0022), and repeating it under a header that says
123
+ // it is the noise this model removes. What only this sentence knows is
124
+ // which export in which file to open.
125
+ `The ${kind} hook exported as "${entry.exportName}" from "${entry.file}" threw.`, {
126
+ cause: e,
127
+ name: 'HookError',
128
+ ref: 'https://thymian.dev/references/errors/hook-error/',
129
+ severity: 'warn',
130
+ }),
131
+ };
132
+ }
133
+ /**
134
+ * Runs one hook through the shared attribution pipeline and always throws on
135
+ * failure — for `defineSample`, `beforeAll` and `afterAll`, which have no
136
+ * Transaction to report a `skip`/`fail` verdict against. Callable only with a
137
+ * kind outside {@link TRANSACTION_SCOPED_KINDS}, which is what guarantees
138
+ * {@link interpretHookFailure} always hands back a `rethrow` here and never a
139
+ * `report` with nowhere to go.
140
+ *
141
+ * The raw return value is handed back rather than discarded: `beforeAll` is
142
+ * the one kind whose return is not mutate-and-ignore — a returned function is
143
+ * a cleanup to run at teardown.
144
+ */
145
+ export async function invokeOrThrow(kind, entry, args) {
146
+ try {
147
+ return await invokeHook(entry, args);
148
+ }
149
+ catch (e) {
150
+ const { rethrow } = interpretHookFailure(e, kind, entry);
151
+ if (!rethrow) {
152
+ // Unreachable: `kind`'s type excludes every member of
153
+ // TRANSACTION_SCOPED_KINDS, and that is the only set
154
+ // interpretHookFailure ever produces a `report` — never a `rethrow` —
155
+ // for.
156
+ throw new Error(`invariant violated: interpretHookFailure produced no rethrow for hook kind "${kind}"`);
157
+ }
158
+ throw rethrow;
159
+ }
160
+ }
161
+ //# sourceMappingURL=invoke-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-hook.js","sourceRoot":"","sources":["../../src/hooks/invoke-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import type { TransactionCatalog } from '../selectors/transaction-catalog.js';
2
+ import type { HookDiagnostic } from './hook-diagnostics.js';
3
+ import { type HookRegistration } from './hook-registration.js';
4
+ /** The specifier a hook file writes. */
5
+ export declare const HOOKS_RUNTIME_SPECIFIER = "@thymian/hooks";
6
+ /**
7
+ * Keep a file iff its name ends in one of the six module extensions and is not a
8
+ * declaration file.
9
+ *
10
+ * `.tsx`/`.jsx` are not among them: JSX needs a transform pragma this jiti
11
+ * instance is not configured for, so such a file would be scanned only to fail
12
+ * on its own syntax.
13
+ *
14
+ * The declaration-file exclusion is case-insensitive while the keep pattern is
15
+ * not. `types.D.ts` ends in `.ts` and so matched the keep pattern, but missed a
16
+ * case-sensitive `\.d\.ts$` — and a hand-written declaration file handed to jiti
17
+ * fails on its own `declare module` syntax. Widening the exclusion can only ever
18
+ * skip a file that could not have executed; widening the keep pattern the same
19
+ * way would make the scan depend on filesystem case sensitivity.
20
+ */
21
+ export declare function isHookFile(name: string): boolean;
22
+ /** The hooks that apply to one Transaction, each in registration order. */
23
+ export type TransactionHooks = {
24
+ readonly defineSample: readonly CollectedRegistration[];
25
+ readonly beforeEach: readonly CollectedRegistration[];
26
+ readonly afterEach: readonly CollectedRegistration[];
27
+ readonly authorize: readonly CollectedRegistration[];
28
+ };
29
+ /** A registration plus where it came from, which only the loader knows. */
30
+ export type CollectedRegistration = {
31
+ registration: HookRegistration;
32
+ /** Hooks-dir-relative path, `/`-normalized. */
33
+ file: string;
34
+ /** Absolute directory of the hook file, for the file helpers. */
35
+ dir: string;
36
+ exportName: string;
37
+ /**
38
+ * Position in the whole scan: file order on the outside, registration order
39
+ * inside each file.
40
+ *
41
+ * The registration's own `order` cannot serve: it is stamped when the hook
42
+ * is created, and a hook created in a shared module is created when the
43
+ * first file that imports it is evaluated, not when the file that exports
44
+ * it is. This is the one number that orders every hook in the run against
45
+ * every other, which is what run-scoped teardown needs to reverse.
46
+ */
47
+ sequence: number;
48
+ };
49
+ export type LoadUserHooksResult = {
50
+ /** Hook files found, in load order. */
51
+ files: readonly string[];
52
+ /** Per-transaction bindings, keyed by transaction id. */
53
+ byTransactionId: ReadonlyMap<string, TransactionHooks>;
54
+ /** Run-scoped registrations, in registration order. */
55
+ runScoped: {
56
+ beforeAll: CollectedRegistration[];
57
+ afterAll: CollectedRegistration[];
58
+ };
59
+ /** The global `authorize(callback)` registrations, in registration order. */
60
+ globalAuthorize: CollectedRegistration[];
61
+ /** Every hook that does not resolve. A non-empty list must fail the run. */
62
+ diagnostics: readonly HookDiagnostic[];
63
+ /**
64
+ * Hooks that resolve but cannot both apply — today, two `defineSample` hooks
65
+ * on one Transaction. Kept apart from {@link diagnostics} because the fault is
66
+ * different and so is the sentence a reader needs: the selector is fine, the
67
+ * pair of hooks is not.
68
+ */
69
+ conflicts: readonly HookDiagnostic[];
70
+ /**
71
+ * Hooks a file created and did not export, so nothing can reach them.
72
+ *
73
+ * Kept apart from {@link diagnostics} for the same reason {@link conflicts}
74
+ * is: the selector resolves and the file loaded, so a sentence about hooks
75
+ * that "do not resolve" would send the reader to the one thing that is fine.
76
+ */
77
+ unexported: readonly HookDiagnostic[];
78
+ /**
79
+ * Things the scan could not do, which are not a hook failing to resolve.
80
+ *
81
+ * Kept apart from {@link diagnostics} on purpose: an unreadable subdirectory
82
+ * is why the walk goes a level at a time, and turning it into a fatal error
83
+ * would throw away every healthy hook in the tree — the outcome the level-wise
84
+ * walk exists to avoid. These are reported as warnings and the run continues.
85
+ */
86
+ warnings: readonly string[];
87
+ };
88
+ /**
89
+ * Scan the hooks directory and bind every registration it exports to the
90
+ * Transactions it names.
91
+ *
92
+ * A hooks directory that does not exist is not an error — `sampler init` is
93
+ * optional and a project may have no hooks at all — it is an empty result.
94
+ */
95
+ export declare function loadUserHooks(hooksDir: string, catalog: TransactionCatalog): Promise<LoadUserHooksResult>;
96
+ //# sourceMappingURL=load-user-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-user-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/load-user-hooks.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,wBAAwB,CAAC;AAwBhC,wCAAwC;AACxC,eAAO,MAAM,uBAAuB,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMhD;AAED,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACrD,QAAQ,CAAC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACtD,CAAC;AAOF,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,gBAAgB,CAAC;IAC/B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,uCAAuC;IACvC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,yDAAyD;IACzD,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACvD,uDAAuD;IACvD,SAAS,EAAE;QACT,SAAS,EAAE,qBAAqB,EAAE,CAAC;QACnC,QAAQ,EAAE,qBAAqB,EAAE,CAAC;KACnC,CAAC;IACF,6EAA6E;IAC7E,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,4EAA4E;IAC5E,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC;;;;;OAKG;IACH,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC;;;;;;OAMG;IACH,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IACtC;;;;;;;OAOG;IACH,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC;AAgPF;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAgO9B"}