@flink-app/flink 0.14.3 → 2.0.0-alpha.100

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 (280) hide show
  1. package/CHANGELOG.md +1051 -0
  2. package/SCHEMA_EXTRACTION_ANALYSIS.md +494 -0
  3. package/SIMPLE_AST_FEASIBILITY.md +570 -0
  4. package/bin/flink.ts +13 -2
  5. package/cli/build.ts +24 -44
  6. package/cli/clean.ts +13 -25
  7. package/cli/cli-utils.ts +190 -17
  8. package/cli/dev.ts +252 -0
  9. package/cli/loadEnvFiles.ts +116 -0
  10. package/cli/run.ts +45 -62
  11. package/dist/bin/flink.js +61 -2
  12. package/dist/cli/build.js +20 -25
  13. package/dist/cli/clean.js +12 -10
  14. package/dist/cli/cli-utils.d.ts +34 -3
  15. package/dist/cli/cli-utils.js +193 -12
  16. package/dist/cli/dev.d.ts +2 -0
  17. package/dist/cli/dev.js +279 -0
  18. package/dist/cli/loadEnvFiles.d.ts +30 -0
  19. package/dist/cli/loadEnvFiles.js +113 -0
  20. package/dist/cli/run.js +47 -46
  21. package/dist/src/DependencyTracker.d.ts +44 -0
  22. package/dist/src/DependencyTracker.js +239 -0
  23. package/dist/src/FlinkApp.d.ts +163 -10
  24. package/dist/src/FlinkApp.js +847 -184
  25. package/dist/src/FlinkContext.d.ts +41 -0
  26. package/dist/src/FlinkErrors.d.ts +19 -6
  27. package/dist/src/FlinkErrors.js +36 -42
  28. package/dist/src/FlinkHttpHandler.d.ts +219 -26
  29. package/dist/src/FlinkHttpHandler.js +37 -1
  30. package/dist/src/FlinkJob.d.ts +10 -0
  31. package/dist/src/FlinkLog.d.ts +82 -18
  32. package/dist/src/FlinkLog.js +165 -13
  33. package/dist/src/FlinkLogFactory.d.ts +288 -0
  34. package/dist/src/FlinkLogFactory.js +619 -0
  35. package/dist/src/FlinkRepo.d.ts +10 -2
  36. package/dist/src/FlinkRepo.js +11 -1
  37. package/dist/src/FlinkRequestContext.d.ts +63 -0
  38. package/dist/src/FlinkRequestContext.js +74 -0
  39. package/dist/src/FlinkResponse.d.ts +6 -0
  40. package/dist/src/FlinkService.d.ts +38 -0
  41. package/dist/src/FlinkService.js +46 -0
  42. package/dist/src/LeaderElection.d.ts +45 -0
  43. package/dist/src/LeaderElection.js +269 -0
  44. package/dist/src/SchemaCache.d.ts +84 -0
  45. package/dist/src/SchemaCache.js +289 -0
  46. package/dist/src/TypeScriptCompiler.d.ts +161 -51
  47. package/dist/src/TypeScriptCompiler.js +1253 -617
  48. package/dist/src/TypeScriptUtils.js +4 -0
  49. package/dist/src/ai/AgentRunner.d.ts +39 -0
  50. package/dist/src/ai/AgentRunner.js +760 -0
  51. package/dist/src/ai/ConversationAgent.d.ts +279 -0
  52. package/dist/src/ai/ConversationAgent.js +404 -0
  53. package/dist/src/ai/ConversationFlinkAgent.d.ts +278 -0
  54. package/dist/src/ai/ConversationFlinkAgent.js +404 -0
  55. package/dist/src/ai/FlinkAgent.d.ts +690 -0
  56. package/dist/src/ai/FlinkAgent.js +729 -0
  57. package/dist/src/ai/FlinkTool.d.ts +135 -0
  58. package/dist/src/ai/FlinkTool.js +2 -0
  59. package/dist/src/ai/InMemoryConversationAgent.d.ts +121 -0
  60. package/dist/src/ai/InMemoryConversationAgent.js +209 -0
  61. package/dist/src/ai/LLMAdapter.d.ts +148 -0
  62. package/dist/src/ai/LLMAdapter.js +2 -0
  63. package/dist/src/ai/PersistentFlinkAgent.d.ts +278 -0
  64. package/dist/src/ai/PersistentFlinkAgent.js +403 -0
  65. package/dist/src/ai/SubAgentExecutor.d.ts +38 -0
  66. package/dist/src/ai/SubAgentExecutor.js +223 -0
  67. package/dist/src/ai/ToolExecutor.d.ts +64 -0
  68. package/dist/src/ai/ToolExecutor.js +497 -0
  69. package/dist/src/ai/agentInstructions.d.ts +68 -0
  70. package/dist/src/ai/agentInstructions.js +286 -0
  71. package/dist/src/ai/index.d.ts +8 -0
  72. package/dist/src/ai/index.js +26 -0
  73. package/dist/src/ai/instructionFileLoader.d.ts +44 -0
  74. package/dist/src/ai/instructionFileLoader.js +179 -0
  75. package/dist/src/auth/FlinkAuthPlugin.d.ts +1 -1
  76. package/dist/src/handlers/StreamWriterFactory.d.ts +20 -0
  77. package/dist/src/handlers/StreamWriterFactory.js +83 -0
  78. package/dist/src/index.d.ts +14 -0
  79. package/dist/src/index.js +17 -0
  80. package/dist/src/loadPluginSchemas.d.ts +45 -0
  81. package/dist/src/loadPluginSchemas.js +143 -0
  82. package/dist/src/schema-extraction/ComplexTypeDetection.d.ts +40 -0
  83. package/dist/src/schema-extraction/ComplexTypeDetection.js +75 -0
  84. package/dist/src/schema-extraction/TypeScriptSourceParser.d.ts +321 -0
  85. package/dist/src/schema-extraction/TypeScriptSourceParser.js +925 -0
  86. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.d.ts +1 -0
  87. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.js +233 -0
  88. package/dist/src/schema-extraction/TypeScriptTokenizer.d.ts +57 -0
  89. package/dist/src/schema-extraction/TypeScriptTokenizer.js +177 -0
  90. package/dist/src/schema-extraction/index.d.ts +2 -0
  91. package/dist/src/schema-extraction/index.js +20 -0
  92. package/dist/src/schema-extraction/types.d.ts +31 -0
  93. package/dist/src/schema-extraction/types.js +2 -0
  94. package/dist/src/utils/loadFlinkConfig.d.ts +53 -0
  95. package/dist/src/utils/loadFlinkConfig.js +77 -0
  96. package/dist/src/utils.d.ts +30 -0
  97. package/dist/src/utils.js +52 -0
  98. package/dist/src/workers/SchemaGeneratorWorker.d.ts +1 -0
  99. package/dist/src/workers/SchemaGeneratorWorker.js +49 -0
  100. package/dist/src/workers/WorkerPool.d.ts +60 -0
  101. package/dist/src/workers/WorkerPool.js +306 -0
  102. package/examples/logging-hierarchical-example.ts +125 -0
  103. package/package.json +29 -4
  104. package/readme.md +499 -0
  105. package/spec/AgentDescendantDetection.spec.ts +335 -0
  106. package/spec/AgentDuplicateDetection.spec.ts +112 -0
  107. package/spec/AgentObserver.spec.ts +266 -0
  108. package/spec/AgentRunner.spec.ts +1062 -0
  109. package/spec/AsyncLocalStorageContext.spec.ts +223 -0
  110. package/spec/ConversationHooks.spec.ts +257 -0
  111. package/spec/FlinkAgent.spec.ts +681 -0
  112. package/spec/FlinkApp.htmlResponse.spec.ts +260 -0
  113. package/spec/FlinkApp.onError.invocation.spec.ts +151 -0
  114. package/spec/FlinkApp.onError.spec.ts +1 -2
  115. package/spec/FlinkApp.query.spec.ts +107 -0
  116. package/spec/FlinkApp.routeOrdering.spec.ts +61 -0
  117. package/spec/FlinkApp.undefinedResponse.spec.ts +123 -0
  118. package/spec/FlinkApp.validationMode.spec.ts +155 -0
  119. package/spec/FlinkJob.spec.ts +171 -0
  120. package/spec/FlinkLogFactory.spec.ts +337 -0
  121. package/spec/FlinkRepo.spec.ts +1 -1
  122. package/spec/LeaderElection.spec.ts +174 -0
  123. package/spec/StreamingIntegration.spec.ts +139 -0
  124. package/spec/ToolExecutor.spec.ts +465 -0
  125. package/spec/TypeScriptCompiler.spec.ts +1 -1
  126. package/spec/TypeScriptSourceParser.spec.ts +1215 -0
  127. package/spec/TypeScriptTokenizer.spec.ts +366 -0
  128. package/spec/ai/ContextCompaction.spec.ts +405 -0
  129. package/spec/ai/ConversationAgent.spec.ts +520 -0
  130. package/spec/ai/InMemoryConversationAgent.spec.ts +144 -0
  131. package/spec/ai/agentInstructions.spec.ts +358 -0
  132. package/spec/fixtures/agent-instructions/TestAgent.ts +24 -0
  133. package/spec/fixtures/agent-instructions/simple.md +3 -0
  134. package/spec/fixtures/agent-instructions/template.md +18 -0
  135. package/spec/fixtures/agent-instructions/yaml-format.yaml +9 -0
  136. package/spec/mock-project/dist/.tsbuildinfo +1 -0
  137. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +56 -0
  138. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +58 -0
  139. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +52 -0
  140. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +52 -0
  141. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +52 -0
  142. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +54 -0
  143. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +54 -0
  144. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +57 -0
  145. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +57 -0
  146. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler.js +53 -0
  147. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler2.js +55 -0
  148. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +57 -0
  149. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +75 -0
  150. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +57 -0
  151. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +58 -0
  152. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +58 -0
  153. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +54 -0
  154. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +55 -0
  155. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +54 -0
  156. package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +54 -0
  157. package/spec/mock-project/dist/spec/mock-project/src/index.js +83 -0
  158. package/spec/mock-project/dist/spec/mock-project/src/repos/CarRepo.js +26 -0
  159. package/spec/mock-project/dist/spec/mock-project/src/schemas/Car.js +2 -0
  160. package/spec/mock-project/dist/spec/mock-project/src/schemas/DefaultExportSchema.js +2 -0
  161. package/spec/mock-project/dist/spec/mock-project/src/schemas/FileWithTwoSchemas.js +2 -0
  162. package/spec/mock-project/dist/src/FlinkApp.js +1000 -0
  163. package/spec/mock-project/dist/src/FlinkContext.js +2 -0
  164. package/spec/mock-project/dist/src/FlinkErrors.js +143 -0
  165. package/spec/mock-project/dist/src/FlinkHttpHandler.js +47 -0
  166. package/spec/mock-project/dist/src/FlinkJob.js +2 -0
  167. package/spec/mock-project/dist/src/FlinkLog.js +119 -0
  168. package/spec/mock-project/dist/src/FlinkLogFactory.js +617 -0
  169. package/spec/mock-project/dist/src/FlinkPlugin.js +2 -0
  170. package/spec/mock-project/dist/src/FlinkRepo.js +224 -0
  171. package/spec/mock-project/dist/src/FlinkRequestContext.js +74 -0
  172. package/spec/mock-project/dist/src/FlinkResponse.js +2 -0
  173. package/spec/mock-project/dist/src/ai/AgentExecutor.js +279 -0
  174. package/spec/mock-project/dist/src/ai/AgentRunner.js +632 -0
  175. package/spec/mock-project/dist/src/ai/ConversationAgent.js +402 -0
  176. package/spec/mock-project/dist/src/ai/ConversationFlinkAgent.js +422 -0
  177. package/spec/mock-project/dist/src/ai/FlinkAgent.js +699 -0
  178. package/spec/mock-project/dist/src/ai/FlinkTool.js +2 -0
  179. package/spec/mock-project/dist/src/ai/InMemoryConversationAgent.js +209 -0
  180. package/spec/mock-project/dist/src/ai/LLMAdapter.js +2 -0
  181. package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +223 -0
  182. package/spec/mock-project/dist/src/ai/ToolExecutor.js +412 -0
  183. package/spec/mock-project/dist/src/ai/agentInstructions.js +246 -0
  184. package/spec/mock-project/dist/src/auth/FlinkAuthPlugin.js +2 -0
  185. package/spec/mock-project/dist/src/auth/FlinkAuthUser.js +2 -0
  186. package/spec/mock-project/dist/src/handlers/GetCar.js +26 -52
  187. package/spec/mock-project/dist/src/handlers/GetCar.js.map +1 -0
  188. package/spec/mock-project/dist/src/handlers/GetCar2.js +32 -54
  189. package/spec/mock-project/dist/src/handlers/GetCar2.js.map +1 -0
  190. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +26 -48
  191. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js.map +1 -0
  192. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +28 -48
  193. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js.map +1 -0
  194. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +29 -48
  195. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js.map +1 -0
  196. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +26 -50
  197. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js.map +1 -0
  198. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +28 -50
  199. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js.map +1 -0
  200. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +27 -53
  201. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js.map +1 -0
  202. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +29 -53
  203. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js.map +1 -0
  204. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +16 -49
  205. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js.map +1 -0
  206. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +25 -50
  207. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js.map +1 -0
  208. package/spec/mock-project/dist/src/handlers/PatchCar.js +27 -53
  209. package/spec/mock-project/dist/src/handlers/PatchCar.js.map +1 -0
  210. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +44 -70
  211. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js.map +1 -0
  212. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +27 -53
  213. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js.map +1 -0
  214. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +28 -54
  215. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js.map +1 -0
  216. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +28 -54
  217. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js.map +1 -0
  218. package/spec/mock-project/dist/src/handlers/PostCar.js +24 -50
  219. package/spec/mock-project/dist/src/handlers/PostCar.js.map +1 -0
  220. package/spec/mock-project/dist/src/handlers/PostLogin.js +25 -51
  221. package/spec/mock-project/dist/src/handlers/PostLogin.js.map +1 -0
  222. package/spec/mock-project/dist/src/handlers/PostLogout.js +24 -50
  223. package/spec/mock-project/dist/src/handlers/PostLogout.js.map +1 -0
  224. package/spec/mock-project/dist/src/handlers/PutCar.js +24 -50
  225. package/spec/mock-project/dist/src/handlers/PutCar.js.map +1 -0
  226. package/spec/mock-project/dist/src/handlers/StreamWriterFactory.js +83 -0
  227. package/spec/mock-project/dist/src/index.js +52 -76
  228. package/spec/mock-project/dist/src/index.js.map +1 -0
  229. package/spec/mock-project/dist/src/mock-data-generator.js +9 -0
  230. package/spec/mock-project/dist/src/repos/CarRepo.js +12 -24
  231. package/spec/mock-project/dist/src/repos/CarRepo.js.map +1 -0
  232. package/spec/mock-project/dist/src/schemas/Car.js +3 -1
  233. package/spec/mock-project/dist/src/schemas/Car.js.map +1 -0
  234. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +3 -1
  235. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js.map +1 -0
  236. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +3 -1
  237. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js.map +1 -0
  238. package/spec/mock-project/dist/src/utils.js +290 -0
  239. package/spec/mock-project/tsconfig.json +6 -1
  240. package/spec/schema-generation-nested-objects.spec.ts +97 -0
  241. package/spec/testHelpers.ts +49 -0
  242. package/spec/utils.caseConversion.spec.ts +78 -0
  243. package/spec/utils.spec.ts +13 -13
  244. package/src/DependencyTracker.ts +166 -0
  245. package/src/FlinkApp.ts +919 -155
  246. package/src/FlinkContext.ts +43 -0
  247. package/src/FlinkErrors.ts +32 -12
  248. package/src/FlinkHttpHandler.ts +246 -28
  249. package/src/FlinkJob.ts +11 -0
  250. package/src/FlinkLog.ts +119 -12
  251. package/src/FlinkLogFactory.ts +699 -0
  252. package/src/FlinkRepo.ts +10 -3
  253. package/src/FlinkRequestContext.ts +95 -0
  254. package/src/FlinkResponse.ts +6 -0
  255. package/src/FlinkService.ts +49 -0
  256. package/src/LeaderElection.ts +203 -0
  257. package/src/SchemaCache.ts +232 -0
  258. package/src/TypeScriptCompiler.ts +1347 -610
  259. package/src/TypeScriptUtils.ts +5 -0
  260. package/src/ai/AgentRunner.ts +646 -0
  261. package/src/ai/ConversationAgent.ts +413 -0
  262. package/src/ai/FlinkAgent.ts +1069 -0
  263. package/src/ai/FlinkTool.ts +165 -0
  264. package/src/ai/InMemoryConversationAgent.ts +149 -0
  265. package/src/ai/LLMAdapter.ts +126 -0
  266. package/src/ai/ToolExecutor.ts +485 -0
  267. package/src/ai/agentInstructions.ts +245 -0
  268. package/src/ai/index.ts +8 -0
  269. package/src/ai/instructionFileLoader.ts +156 -0
  270. package/src/auth/FlinkAuthPlugin.ts +2 -1
  271. package/src/handlers/StreamWriterFactory.ts +84 -0
  272. package/src/index.ts +14 -0
  273. package/src/loadPluginSchemas.ts +141 -0
  274. package/src/schema-extraction/TypeScriptSourceParser.ts +1058 -0
  275. package/src/schema-extraction/TypeScriptTokenizer.ts +205 -0
  276. package/src/schema-extraction/index.ts +2 -0
  277. package/src/schema-extraction/types.ts +34 -0
  278. package/src/utils/loadFlinkConfig.ts +89 -0
  279. package/src/utils.ts +52 -0
  280. package/tsconfig.json +6 -1
@@ -1,5 +1,7 @@
1
1
  import { FlinkAuthPlugin } from "./auth/FlinkAuthPlugin";
2
2
  import { FlinkRepo } from "./FlinkRepo";
3
+ import { FlinkAgent } from "./ai/FlinkAgent";
4
+ import { FlinkService } from "./FlinkService";
3
5
  export interface FlinkContext<P = any> {
4
6
  repos: {
5
7
  [x: string]: FlinkRepo<any, any>;
@@ -9,4 +11,43 @@ export interface FlinkContext<P = any> {
9
11
  * Type of authentication, if any.
10
12
  */
11
13
  auth?: FlinkAuthPlugin;
14
+ /**
15
+ * AI namespace containing agents
16
+ *
17
+ * Define agents directly in your context interface:
18
+ *
19
+ * @example
20
+ * interface AppCtx extends FlinkContext<PluginCtx> {
21
+ * auth: JwtAuthPlugin;
22
+ * repos: {
23
+ * carRepo: CarRepo;
24
+ * };
25
+ * agents: {
26
+ * carAgent: CarAgent;
27
+ * userAgent: UserAgent;
28
+ * };
29
+ * }
30
+ */
31
+ agents?: {
32
+ [x: string]: FlinkAgent<any>;
33
+ };
34
+ /**
35
+ * Optional services namespace for shared business logic.
36
+ *
37
+ * Define services directly in your context interface:
38
+ *
39
+ * @example
40
+ * interface AppCtx extends FlinkContext<PluginCtx> {
41
+ * repos: {
42
+ * carRepo: CarRepo;
43
+ * };
44
+ * services: {
45
+ * carService: CarService;
46
+ * orderService: OrderService;
47
+ * };
48
+ * }
49
+ */
50
+ services?: {
51
+ [x: string]: FlinkService<any>;
52
+ };
12
53
  }
@@ -6,36 +6,46 @@ export type FlinkError = undefined;
6
6
  *
7
7
  * @param detail - Optional custom error message
8
8
  * @param code - Optional custom error code
9
+ * @param meta - Optional structured payload (must be JSON-serializable)
9
10
  * @example
10
11
  * ```ts
11
12
  * if (!user) return notFound("User not found");
13
+ * if (!user) return notFound("User not found", "userNotFound", { userId });
12
14
  * ```
13
15
  */
14
- export declare function notFound(detail?: string, code?: string): FlinkResponse<FlinkError>;
16
+ export declare function notFound(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
15
17
  /**
16
18
  * Returns a 409 Conflict error response.
17
19
  * Use when a request conflicts with existing data (e.g., duplicate username/email).
18
20
  *
19
21
  * @param detail - Optional custom error message
20
22
  * @param code - Optional custom error code
23
+ * @param meta - Optional structured payload (must be JSON-serializable)
21
24
  * @example
22
25
  * ```ts
23
26
  * if (existingUser) return conflict("Email already registered");
24
27
  * ```
25
28
  */
26
- export declare function conflict(detail?: string, code?: string): FlinkResponse<FlinkError>;
29
+ export declare function conflict(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
27
30
  /**
28
31
  * Returns a 400 Bad Request error response.
29
32
  * Use when the request is malformed or contains invalid data (e.g., validation errors).
30
33
  *
31
34
  * @param detail - Optional custom error message
32
35
  * @param code - Optional custom error code
36
+ * @param meta - Optional structured payload (must be JSON-serializable).
37
+ * Useful for domain-specific context like payment decline codes,
38
+ * retry hints, or structured field errors.
33
39
  * @example
34
40
  * ```ts
35
41
  * if (!email || !password) return badRequest("Email and password are required");
42
+ * return badRequest("Payment declined", "paymentDeclined", {
43
+ * gatewayCode: "insufficient_funds",
44
+ * attemptId: "att_123",
45
+ * });
36
46
  * ```
37
47
  */
38
- export declare function badRequest(detail?: string, code?: string): FlinkResponse<FlinkError>;
48
+ export declare function badRequest(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
39
49
  /**
40
50
  * Returns a 401 Unauthorized error response.
41
51
  * Use when authentication is required but missing or invalid (e.g., no token, expired token).
@@ -43,12 +53,13 @@ export declare function badRequest(detail?: string, code?: string): FlinkRespons
43
53
  *
44
54
  * @param detail - Optional custom error message
45
55
  * @param code - Optional custom error code
56
+ * @param meta - Optional structured payload (must be JSON-serializable)
46
57
  * @example
47
58
  * ```ts
48
59
  * if (!ctx.auth?.user) return unauthorized("Authentication required");
49
60
  * ```
50
61
  */
51
- export declare function unauthorized(detail?: string, code?: string): FlinkResponse<FlinkError>;
62
+ export declare function unauthorized(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
52
63
  /**
53
64
  * Returns a 403 Forbidden error response.
54
65
  * Use when the user is authenticated but lacks permission to access the resource.
@@ -56,21 +67,23 @@ export declare function unauthorized(detail?: string, code?: string): FlinkRespo
56
67
  *
57
68
  * @param detail - Optional custom error message
58
69
  * @param code - Optional custom error code
70
+ * @param meta - Optional structured payload (must be JSON-serializable)
59
71
  * @example
60
72
  * ```ts
61
73
  * if (ctx.auth?.user?.role !== "admin") return forbidden("Admin access required");
62
74
  * ```
63
75
  */
64
- export declare function forbidden(detail?: string, code?: string): FlinkResponse<FlinkError>;
76
+ export declare function forbidden(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
65
77
  /**
66
78
  * Returns a 500 Internal Server Error response.
67
79
  * Use when an unexpected error occurs on the server side.
68
80
  *
69
81
  * @param detail - Optional custom error message
70
82
  * @param code - Optional custom error code
83
+ * @param meta - Optional structured payload (must be JSON-serializable)
71
84
  * @example
72
85
  * ```ts
73
86
  * try { ... } catch (error) { return internalServerError("Failed to process request"); }
74
87
  * ```
75
88
  */
76
- export declare function internalServerError(detail?: string, code?: string): FlinkResponse<FlinkError>;
89
+ export declare function internalServerError(detail?: string, code?: string, meta?: unknown): FlinkResponse<FlinkError>;
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  exports.notFound = notFound;
4
15
  exports.conflict = conflict;
@@ -13,20 +24,17 @@ var uuid_1 = require("uuid");
13
24
  *
14
25
  * @param detail - Optional custom error message
15
26
  * @param code - Optional custom error code
27
+ * @param meta - Optional structured payload (must be JSON-serializable)
16
28
  * @example
17
29
  * ```ts
18
30
  * if (!user) return notFound("User not found");
31
+ * if (!user) return notFound("User not found", "userNotFound", { userId });
19
32
  * ```
20
33
  */
21
- function notFound(detail, code) {
34
+ function notFound(detail, code, meta) {
22
35
  return {
23
36
  status: 404,
24
- error: {
25
- id: (0, uuid_1.v4)(),
26
- title: "Not Found",
27
- detail: detail || "The requested resource does not exist",
28
- code: code || "notFound"
29
- },
37
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Not Found", detail: detail || "The requested resource does not exist", code: code || "notFound" }, (meta !== undefined && { meta: meta })),
30
38
  };
31
39
  }
32
40
  /**
@@ -35,20 +43,16 @@ function notFound(detail, code) {
35
43
  *
36
44
  * @param detail - Optional custom error message
37
45
  * @param code - Optional custom error code
46
+ * @param meta - Optional structured payload (must be JSON-serializable)
38
47
  * @example
39
48
  * ```ts
40
49
  * if (existingUser) return conflict("Email already registered");
41
50
  * ```
42
51
  */
43
- function conflict(detail, code) {
52
+ function conflict(detail, code, meta) {
44
53
  return {
45
54
  status: 409,
46
- error: {
47
- id: (0, uuid_1.v4)(),
48
- title: "Conflict",
49
- detail: detail || "An identical entity exits",
50
- code: code || "conflict"
51
- },
55
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Conflict", detail: detail || "An identical entity exits", code: code || "conflict" }, (meta !== undefined && { meta: meta })),
52
56
  };
53
57
  }
54
58
  /**
@@ -57,20 +61,22 @@ function conflict(detail, code) {
57
61
  *
58
62
  * @param detail - Optional custom error message
59
63
  * @param code - Optional custom error code
64
+ * @param meta - Optional structured payload (must be JSON-serializable).
65
+ * Useful for domain-specific context like payment decline codes,
66
+ * retry hints, or structured field errors.
60
67
  * @example
61
68
  * ```ts
62
69
  * if (!email || !password) return badRequest("Email and password are required");
70
+ * return badRequest("Payment declined", "paymentDeclined", {
71
+ * gatewayCode: "insufficient_funds",
72
+ * attemptId: "att_123",
73
+ * });
63
74
  * ```
64
75
  */
65
- function badRequest(detail, code) {
76
+ function badRequest(detail, code, meta) {
66
77
  return {
67
78
  status: 400,
68
- error: {
69
- id: (0, uuid_1.v4)(),
70
- title: "Bad Request",
71
- detail: detail || "Invalid request",
72
- code: code || "badRequest"
73
- },
79
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Bad Request", detail: detail || "Invalid request", code: code || "badRequest" }, (meta !== undefined && { meta: meta })),
74
80
  };
75
81
  }
76
82
  /**
@@ -80,20 +86,16 @@ function badRequest(detail, code) {
80
86
  *
81
87
  * @param detail - Optional custom error message
82
88
  * @param code - Optional custom error code
89
+ * @param meta - Optional structured payload (must be JSON-serializable)
83
90
  * @example
84
91
  * ```ts
85
92
  * if (!ctx.auth?.user) return unauthorized("Authentication required");
86
93
  * ```
87
94
  */
88
- function unauthorized(detail, code) {
95
+ function unauthorized(detail, code, meta) {
89
96
  return {
90
97
  status: 401,
91
- error: {
92
- id: (0, uuid_1.v4)(),
93
- title: "Unauthorized",
94
- detail: detail || "Authentication required",
95
- code: code || "unauthorized"
96
- },
98
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Unauthorized", detail: detail || "Authentication required", code: code || "unauthorized" }, (meta !== undefined && { meta: meta })),
97
99
  };
98
100
  }
99
101
  /**
@@ -103,20 +105,16 @@ function unauthorized(detail, code) {
103
105
  *
104
106
  * @param detail - Optional custom error message
105
107
  * @param code - Optional custom error code
108
+ * @param meta - Optional structured payload (must be JSON-serializable)
106
109
  * @example
107
110
  * ```ts
108
111
  * if (ctx.auth?.user?.role !== "admin") return forbidden("Admin access required");
109
112
  * ```
110
113
  */
111
- function forbidden(detail, code) {
114
+ function forbidden(detail, code, meta) {
112
115
  return {
113
116
  status: 403,
114
- error: {
115
- id: (0, uuid_1.v4)(),
116
- title: "Forbidden",
117
- detail: detail || "You do not have permission to access this resource",
118
- code: code || "forbidden"
119
- },
117
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Forbidden", detail: detail || "You do not have permission to access this resource", code: code || "forbidden" }, (meta !== undefined && { meta: meta })),
120
118
  };
121
119
  }
122
120
  /**
@@ -125,19 +123,15 @@ function forbidden(detail, code) {
125
123
  *
126
124
  * @param detail - Optional custom error message
127
125
  * @param code - Optional custom error code
126
+ * @param meta - Optional structured payload (must be JSON-serializable)
128
127
  * @example
129
128
  * ```ts
130
129
  * try { ... } catch (error) { return internalServerError("Failed to process request"); }
131
130
  * ```
132
131
  */
133
- function internalServerError(detail, code) {
132
+ function internalServerError(detail, code, meta) {
134
133
  return {
135
134
  status: 500,
136
- error: {
137
- id: (0, uuid_1.v4)(),
138
- title: "Internal Server Error",
139
- detail: detail || "Something unexpected went wrong",
140
- code: code || "internalServerError"
141
- },
135
+ error: __assign({ id: (0, uuid_1.v4)(), title: "Internal Server Error", detail: detail || "Something unexpected went wrong", code: code || "internalServerError" }, (meta !== undefined && { meta: meta })),
142
136
  };
143
137
  }
@@ -1,5 +1,4 @@
1
1
  import { Request } from "express";
2
- import { JSONSchema } from "./FlinkApp";
3
2
  import { FlinkContext } from "./FlinkContext";
4
3
  import { FlinkError } from "./FlinkErrors";
5
4
  import { FlinkResponse } from "./FlinkResponse";
@@ -10,24 +9,102 @@ export declare enum HttpMethod {
10
9
  delete = "delete",
11
10
  patch = "patch"
12
11
  }
13
- type Params = Request["params"];
12
+ /**
13
+ * Validation mode for handler request and response schemas.
14
+ *
15
+ * Controls whether request and/or response data is validated against JSON schemas.
16
+ *
17
+ * **Security Note:** Skipping validation can introduce security risks. Only use
18
+ * SkipValidation or ValidateResponse when you have implemented custom validation
19
+ * or the endpoint is internal/trusted.
20
+ *
21
+ * - Validate: Validate both request and response (default behavior)
22
+ * - SkipValidation: Skip both request and response validation
23
+ * - ValidateRequest: Validate only request, skip response validation
24
+ * - ValidateResponse: Validate only response, skip request validation
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Skip validation for webhook with custom signature verification
29
+ * export const Route: RouteProps = {
30
+ * path: "/webhook",
31
+ * validation: ValidationMode.SkipValidation
32
+ * };
33
+ *
34
+ * // Validate request but allow flexible response during development
35
+ * export const Route: RouteProps = {
36
+ * path: "/api/data",
37
+ * validation: ValidationMode.ValidateRequest
38
+ * };
39
+ * ```
40
+ */
41
+ export declare enum ValidationMode {
42
+ Validate = "Validate",
43
+ SkipValidation = "SkipValidation",
44
+ ValidateRequest = "ValidateRequest",
45
+ ValidateResponse = "ValidateResponse"
46
+ }
47
+ type Params = Record<string, string>;
14
48
  /**
15
49
  * Query type for request query parameters.
16
- * Does currently not allow nested objects, although
17
- * underlying express Request does allow it.
18
50
  *
19
- * Uses index signature to allow both Record types and interface types
20
- * to be assignable to Query without requiring explicit index signatures.
51
+ * All query parameter values are normalized to strings or string arrays:
52
+ * - Single values: string (e.g., ?name=John becomes { name: "John" })
53
+ * - Multiple values: string[] (e.g., ?tag=a&tag=b becomes { tag: ["a", "b"] })
54
+ *
55
+ * Does not allow nested objects, although underlying Express Request does allow it.
21
56
  */
22
- type Query = {
23
- [x: string]: string | string[] | undefined;
24
- };
57
+ type Query = Record<string, string | string[]>;
58
+ /**
59
+ * Stream format for streaming handlers.
60
+ * - sse: Server-Sent Events (text/event-stream)
61
+ * - ndjson: Newline-Delimited JSON (application/x-ndjson)
62
+ */
63
+ export type StreamFormat = "sse" | "ndjson";
25
64
  /**
26
- * Flink request extends express Request but adds reqId and user object.
65
+ * Stream writer interface for SSE/NDJSON streaming.
66
+ *
67
+ * Provides methods to write data chunks, handle errors, and manage the stream lifecycle.
68
+ * Only available in handlers where streamFormat is specified in RouteProps.
69
+ */
70
+ export interface StreamWriter<T = any> {
71
+ /**
72
+ * Write data to the stream.
73
+ * Data is automatically JSON-stringified and formatted according to streamFormat.
74
+ */
75
+ write(data: T): void;
76
+ /**
77
+ * Send error to client and close the stream.
78
+ */
79
+ error(error: Error | string): void;
80
+ /**
81
+ * Close the stream gracefully.
82
+ */
83
+ end(): void;
84
+ /**
85
+ * Check if stream is still open (client connected).
86
+ * Returns false if client has disconnected.
87
+ */
88
+ isOpen(): boolean;
89
+ }
90
+ /**
91
+ * Flink request extends express Request but adds reqId, user object, and userPermissions.
92
+ *
93
+ * userPermissions is populated by auth plugins during authentication and contains
94
+ * the resolved permissions array based on the plugin's configuration (roles, dynamic
95
+ * roles, custom permissions, etc.)
96
+ *
97
+ * token / rawToken are populated by auth plugins that have a token concept (e.g. JWT).
98
+ * `token` is the decoded, signature-verified payload; `rawToken` is the original token
99
+ * string that authenticated the request (Bearer header or custom tokenExtractor output).
100
+ * Both are optional and only set once authentication succeeds.
27
101
  */
28
102
  export type FlinkRequest<T = any, P = Params, Q = Query> = Request<P, any, T, Q> & {
29
103
  reqId: string;
30
104
  user?: any;
105
+ userPermissions?: string[];
106
+ token?: any;
107
+ rawToken?: string;
31
108
  };
32
109
  /**
33
110
  * Route props to control routing.
@@ -59,6 +136,27 @@ export interface RouteProps {
59
136
  mockApi?: boolean;
60
137
  /**
61
138
  * Set permissions needed to access route if route requires authentication.
139
+ *
140
+ * When an array is provided, the user must have **ALL** permissions in the array (AND logic).
141
+ * To require any one of multiple permissions (OR logic), implement custom permission
142
+ * checking in the handler using the `user.permissions` array.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * // Single permission
147
+ * permissions: "car:create"
148
+ *
149
+ * // Multiple permissions (user must have ALL)
150
+ * permissions: ["car:create", "car:premium"]
151
+ *
152
+ * // OR logic requires custom implementation
153
+ * const handler = async ({ ctx, user }) => {
154
+ * if (!user.permissions.includes("car:admin") && !user.permissions.includes("car:moderator")) {
155
+ * throw forbidden("Need admin or moderator permission");
156
+ * }
157
+ * // ... handler logic
158
+ * };
159
+ * ```
62
160
  */
63
161
  permissions?: string | string[];
64
162
  /**
@@ -82,15 +180,124 @@ export interface RouteProps {
82
180
  * to avoid conflicts you can set a negative order.
83
181
  */
84
182
  order?: number;
183
+ /**
184
+ * Validation mode for request and response schemas.
185
+ *
186
+ * Controls schema validation behavior for this handler. Use with caution as
187
+ * skipping validation can introduce security vulnerabilities.
188
+ *
189
+ * **Options:**
190
+ * - Validate: Validate both request and response (default)
191
+ * - SkipValidation: Skip both request and response validation
192
+ * - ValidateRequest: Validate only request, skip response validation
193
+ * - ValidateResponse: Validate only response, skip request validation
194
+ *
195
+ * **When to skip validation:**
196
+ * - Webhook handlers with custom signature verification
197
+ * - Performance-critical internal endpoints
198
+ * - Handlers using alternative validation methods (e.g., Zod, Joi)
199
+ *
200
+ * @default ValidationMode.Validate
201
+ */
202
+ validation?: ValidationMode;
203
+ /**
204
+ * Stream format for streaming handlers (SSE or NDJSON).
205
+ *
206
+ * When specified, the handler becomes a streaming handler and receives a `stream`
207
+ * parameter for writing data chunks. Response validation is automatically skipped
208
+ * for streaming handlers (chunks are progressive, not a final JSON response).
209
+ *
210
+ * **Formats:**
211
+ * - sse: Server-Sent Events (text/event-stream) - ideal for browser EventSource API
212
+ * - ndjson: Newline-Delimited JSON (application/x-ndjson) - ideal for LLM text streaming
213
+ *
214
+ * **Example:**
215
+ * ```typescript
216
+ * export const Route: RouteProps = {
217
+ * path: "/ai/stream",
218
+ * streamFormat: "sse"
219
+ * };
220
+ *
221
+ * const handler: GetHandler<{}, void> = async ({ ctx, stream }) => {
222
+ * if (!stream) throw new Error("Stream not available");
223
+ * stream.write({ message: "Hello" });
224
+ * stream.end();
225
+ * };
226
+ * ```
227
+ */
228
+ streamFormat?: StreamFormat;
229
+ /**
230
+ * When set, the handler's `data` field is sent as a raw response with the
231
+ * given content type instead of the standard JSON envelope. Response schema
232
+ * validation is automatically skipped.
233
+ *
234
+ * Accepts Express shorthand names (`"html"`, `"csv"`, `"text"`, `"xml"`)
235
+ * or any full MIME type string (`"application/pdf"`, etc.).
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * export const Route: RouteProps = {
240
+ * path: "/dashboard",
241
+ * responseType: "html",
242
+ * };
243
+ *
244
+ * const handler: GetHandler<AppContext, void> = async ({ ctx }) => {
245
+ * return { data: `<h1>Hello</h1>` };
246
+ * };
247
+ * ```
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * export const Route: RouteProps = {
252
+ * path: "/export",
253
+ * responseType: "csv",
254
+ * };
255
+ *
256
+ * const handler: GetHandler<AppContext, void> = async ({ ctx }) => {
257
+ * return { data: `id,name\n1,Alice` };
258
+ * };
259
+ * ```
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * export const Route: RouteProps = {
264
+ * path: "/logo",
265
+ * responseType: "image/png",
266
+ * };
267
+ *
268
+ * const handler: GetHandler<AppContext, Buffer> = async ({ ctx }) => {
269
+ * const imageBuffer = await fs.promises.readFile("./logo.png");
270
+ * return { data: imageBuffer };
271
+ * };
272
+ * ```
273
+ */
274
+ responseType?: "html" | "csv" | "text" | "xml" | "image/png" | "image/jpeg" | "image/gif" | "image/svg+xml" | "image/webp" | "application/pdf" | "application/octet-stream" | (string & {});
275
+ /**
276
+ * Direct JSON Schema for request body validation.
277
+ * When set, bypasses manifest lookup for request schema.
278
+ * Useful for plugin handlers that have their own compiled schemas.
279
+ */
280
+ reqSchema?: object;
281
+ /**
282
+ * Direct JSON Schema for response body validation.
283
+ * When set, bypasses manifest lookup for response schema.
284
+ * Useful for plugin handlers that have their own compiled schemas.
285
+ */
286
+ resSchema?: object;
85
287
  }
86
288
  /**
87
289
  * Http handler function that handlers implements in order to
88
290
  * handle HTTP requests and return a JSON response.
291
+ *
292
+ * For streaming handlers (when streamFormat is specified in RouteProps),
293
+ * the stream parameter is available. Streaming handlers should still return
294
+ * a FlinkResponse (can be empty), but it will be ignored by the framework.
89
295
  */
90
296
  export type Handler<Ctx extends FlinkContext, ReqSchema = any, ResSchema = any, P extends Params = Params, Q extends Query = Query> = (props: {
91
297
  req: FlinkRequest<ReqSchema, P, Q>;
92
298
  ctx: Ctx;
93
299
  origin?: string;
300
+ stream?: StreamWriter;
94
301
  }) => Promise<FlinkResponse<ResSchema | FlinkError>>;
95
302
  /**
96
303
  * Http handler function specifically for GET requests as those does
@@ -109,24 +316,10 @@ export type HandlerFile = {
109
316
  default: Handler<any, any, any, any, any>;
110
317
  Route?: RouteProps;
111
318
  /**
112
- * Name of schemas, is set at compile time by Flink compiler.
113
- */
114
- __schemas?: {
115
- reqSchema?: JSONSchema;
116
- resSchema?: JSONSchema;
117
- };
118
- /**
119
- * Typescript source file name, is set at compile time by Flink compiler.
319
+ * Typescript source file path (relative to project root), set at compile time by Flink compiler.
320
+ * Used to look up handler metadata from schema-manifest.json at runtime.
120
321
  */
121
322
  __file?: string;
122
- /**
123
- * Description of query params, is set at compile time by Flink compiler.
124
- */
125
- __query?: QueryParamMetadata[];
126
- /**
127
- * Description of path params, is set at compile time by Flink compiler.
128
- */
129
- __params?: QueryParamMetadata[];
130
323
  };
131
324
  export type QueryParamMetadata = {
132
325
  name: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpMethod = void 0;
3
+ exports.ValidationMode = exports.HttpMethod = void 0;
4
4
  var HttpMethod;
5
5
  (function (HttpMethod) {
6
6
  HttpMethod["get"] = "get";
@@ -9,3 +9,39 @@ var HttpMethod;
9
9
  HttpMethod["delete"] = "delete";
10
10
  HttpMethod["patch"] = "patch";
11
11
  })(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
12
+ /**
13
+ * Validation mode for handler request and response schemas.
14
+ *
15
+ * Controls whether request and/or response data is validated against JSON schemas.
16
+ *
17
+ * **Security Note:** Skipping validation can introduce security risks. Only use
18
+ * SkipValidation or ValidateResponse when you have implemented custom validation
19
+ * or the endpoint is internal/trusted.
20
+ *
21
+ * - Validate: Validate both request and response (default behavior)
22
+ * - SkipValidation: Skip both request and response validation
23
+ * - ValidateRequest: Validate only request, skip response validation
24
+ * - ValidateResponse: Validate only response, skip request validation
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Skip validation for webhook with custom signature verification
29
+ * export const Route: RouteProps = {
30
+ * path: "/webhook",
31
+ * validation: ValidationMode.SkipValidation
32
+ * };
33
+ *
34
+ * // Validate request but allow flexible response during development
35
+ * export const Route: RouteProps = {
36
+ * path: "/api/data",
37
+ * validation: ValidationMode.ValidateRequest
38
+ * };
39
+ * ```
40
+ */
41
+ var ValidationMode;
42
+ (function (ValidationMode) {
43
+ ValidationMode["Validate"] = "Validate";
44
+ ValidationMode["SkipValidation"] = "SkipValidation";
45
+ ValidationMode["ValidateRequest"] = "ValidateRequest";
46
+ ValidationMode["ValidateResponse"] = "ValidateResponse";
47
+ })(ValidationMode || (exports.ValidationMode = ValidationMode = {}));
@@ -31,6 +31,16 @@ export type FlinkJobProps = {
31
31
  * retried after the next interval.
32
32
  */
33
33
  singleton?: boolean;
34
+ /**
35
+ * If true, this job will run on all instances regardless of leader election.
36
+ *
37
+ * By default, when leader election is enabled, jobs only run on the leader instance.
38
+ * Set this to true for jobs that should run on every instance, such as
39
+ * local cache cleanup or instance-specific health checks.
40
+ *
41
+ * Has no effect when leader election is not enabled.
42
+ */
43
+ runOnAllInstances?: boolean;
34
44
  };
35
45
  /**
36
46
  * Type for Flink job function. This function should be default exported from