@pipeline-builder/api-core 0.0.1

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 (184) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +98 -0
  3. package/lib/constants/ai-providers.d.ts +52 -0
  4. package/lib/constants/ai-providers.js +129 -0
  5. package/lib/constants/http-status.d.ts +20 -0
  6. package/lib/constants/http-status.js +26 -0
  7. package/lib/constants/index.d.ts +3 -0
  8. package/lib/constants/index.js +6 -0
  9. package/lib/constants/time.d.ts +10 -0
  10. package/lib/constants/time.js +13 -0
  11. package/lib/errors/app-errors.d.ts +30 -0
  12. package/lib/errors/app-errors.js +53 -0
  13. package/lib/errors/index.d.ts +1 -0
  14. package/lib/errors/index.js +4 -0
  15. package/lib/helpers/access-helpers.d.ts +63 -0
  16. package/lib/helpers/access-helpers.js +82 -0
  17. package/lib/helpers/crud-helpers.d.ts +9 -0
  18. package/lib/helpers/crud-helpers.js +23 -0
  19. package/lib/helpers/index.d.ts +6 -0
  20. package/lib/helpers/index.js +9 -0
  21. package/lib/helpers/org-hierarchy-http.d.ts +74 -0
  22. package/lib/helpers/org-hierarchy-http.js +144 -0
  23. package/lib/helpers/org-hierarchy.d.ts +57 -0
  24. package/lib/helpers/org-hierarchy.js +110 -0
  25. package/lib/helpers/restore-helpers.d.ts +49 -0
  26. package/lib/helpers/restore-helpers.js +78 -0
  27. package/lib/helpers/sse-helpers.d.ts +20 -0
  28. package/lib/helpers/sse-helpers.js +45 -0
  29. package/lib/index.d.ts +58 -0
  30. package/lib/index.js +71 -0
  31. package/lib/middleware/auth.d.ts +208 -0
  32. package/lib/middleware/auth.js +588 -0
  33. package/lib/middleware/index.d.ts +3 -0
  34. package/lib/middleware/index.js +6 -0
  35. package/lib/middleware/mongo-sanitize.d.ts +32 -0
  36. package/lib/middleware/mongo-sanitize.js +100 -0
  37. package/lib/middleware/step-up.d.ts +45 -0
  38. package/lib/middleware/step-up.js +138 -0
  39. package/lib/openapi/extend-zod.d.ts +1 -0
  40. package/lib/openapi/extend-zod.js +6 -0
  41. package/lib/openapi/index.d.ts +2 -0
  42. package/lib/openapi/index.js +5 -0
  43. package/lib/openapi/registry.d.ts +17 -0
  44. package/lib/openapi/registry.js +38 -0
  45. package/lib/openapi/routes/ask-routes.d.ts +7 -0
  46. package/lib/openapi/routes/ask-routes.js +62 -0
  47. package/lib/openapi/routes/billing-routes.d.ts +1 -0
  48. package/lib/openapi/routes/billing-routes.js +66 -0
  49. package/lib/openapi/routes/image-registry-routes.d.ts +7 -0
  50. package/lib/openapi/routes/image-registry-routes.js +98 -0
  51. package/lib/openapi/routes/index.d.ts +5 -0
  52. package/lib/openapi/routes/index.js +28 -0
  53. package/lib/openapi/routes/message-routes.d.ts +1 -0
  54. package/lib/openapi/routes/message-routes.js +105 -0
  55. package/lib/openapi/routes/pipeline-routes.d.ts +1 -0
  56. package/lib/openapi/routes/pipeline-routes.js +105 -0
  57. package/lib/openapi/routes/pipeline-template-routes.d.ts +1 -0
  58. package/lib/openapi/routes/pipeline-template-routes.js +61 -0
  59. package/lib/openapi/routes/plugin-routes.d.ts +1 -0
  60. package/lib/openapi/routes/plugin-routes.js +96 -0
  61. package/lib/openapi/routes/quota-routes.d.ts +1 -0
  62. package/lib/openapi/routes/quota-routes.js +62 -0
  63. package/lib/openapi/schema-registry.d.ts +25 -0
  64. package/lib/openapi/schema-registry.js +91 -0
  65. package/lib/routes/health.d.ts +41 -0
  66. package/lib/routes/health.js +82 -0
  67. package/lib/routes/index.d.ts +1 -0
  68. package/lib/routes/index.js +4 -0
  69. package/lib/services/audit-spool.d.ts +80 -0
  70. package/lib/services/audit-spool.js +172 -0
  71. package/lib/services/cache-service.d.ts +124 -0
  72. package/lib/services/cache-service.js +276 -0
  73. package/lib/services/circuit-breaker.d.ts +45 -0
  74. package/lib/services/circuit-breaker.js +138 -0
  75. package/lib/services/compliance-client.d.ts +46 -0
  76. package/lib/services/compliance-client.js +128 -0
  77. package/lib/services/compliance-event-subscriber.d.ts +16 -0
  78. package/lib/services/compliance-event-subscriber.js +72 -0
  79. package/lib/services/durable-event-bus.d.ts +96 -0
  80. package/lib/services/durable-event-bus.js +204 -0
  81. package/lib/services/entity-events.d.ts +48 -0
  82. package/lib/services/entity-events.js +79 -0
  83. package/lib/services/env-redis.d.ts +44 -0
  84. package/lib/services/env-redis.js +94 -0
  85. package/lib/services/http-client.d.ts +143 -0
  86. package/lib/services/http-client.js +335 -0
  87. package/lib/services/index.d.ts +18 -0
  88. package/lib/services/index.js +20 -0
  89. package/lib/services/leader-lock.d.ts +45 -0
  90. package/lib/services/leader-lock.js +85 -0
  91. package/lib/services/quota.d.ts +130 -0
  92. package/lib/services/quota.js +264 -0
  93. package/lib/services/remote-audit-client.d.ts +160 -0
  94. package/lib/services/remote-audit-client.js +390 -0
  95. package/lib/services/retry-strategy.d.ts +74 -0
  96. package/lib/services/retry-strategy.js +118 -0
  97. package/lib/services/scheduler.d.ts +41 -0
  98. package/lib/services/scheduler.js +86 -0
  99. package/lib/services/service-boot.d.ts +20 -0
  100. package/lib/services/service-boot.js +28 -0
  101. package/lib/services/sse-ticket-store.d.ts +51 -0
  102. package/lib/services/sse-ticket-store.js +130 -0
  103. package/lib/services/token-revocation.d.ts +52 -0
  104. package/lib/services/token-revocation.js +120 -0
  105. package/lib/testing/tier-mock.d.ts +44 -0
  106. package/lib/testing/tier-mock.js +65 -0
  107. package/lib/types/audit-events.d.ts +69 -0
  108. package/lib/types/audit-events.js +4 -0
  109. package/lib/types/catalog-metadata.d.ts +36 -0
  110. package/lib/types/catalog-metadata.js +21 -0
  111. package/lib/types/common.d.ts +255 -0
  112. package/lib/types/common.js +41 -0
  113. package/lib/types/error-codes.d.ts +54 -0
  114. package/lib/types/error-codes.js +107 -0
  115. package/lib/types/feature-flags.d.ts +36 -0
  116. package/lib/types/feature-flags.js +128 -0
  117. package/lib/types/http.d.ts +27 -0
  118. package/lib/types/http.js +4 -0
  119. package/lib/types/index.d.ts +11 -0
  120. package/lib/types/index.js +14 -0
  121. package/lib/types/permissions.d.ts +65 -0
  122. package/lib/types/permissions.js +131 -0
  123. package/lib/types/pipeline-template.d.ts +30 -0
  124. package/lib/types/pipeline-template.js +13 -0
  125. package/lib/types/pipeline.d.ts +59 -0
  126. package/lib/types/pipeline.js +31 -0
  127. package/lib/types/quota-tiers.d.ts +79 -0
  128. package/lib/types/quota-tiers.js +221 -0
  129. package/lib/types/visibility.d.ts +20 -0
  130. package/lib/types/visibility.js +22 -0
  131. package/lib/utils/alias-resolver.d.ts +37 -0
  132. package/lib/utils/alias-resolver.js +68 -0
  133. package/lib/utils/audit.d.ts +15 -0
  134. package/lib/utils/audit.js +39 -0
  135. package/lib/utils/aws-scrub.d.ts +11 -0
  136. package/lib/utils/aws-scrub.js +67 -0
  137. package/lib/utils/compliance-attributes.d.ts +6 -0
  138. package/lib/utils/compliance-attributes.js +69 -0
  139. package/lib/utils/concurrency.d.ts +9 -0
  140. package/lib/utils/concurrency.js +29 -0
  141. package/lib/utils/crash-handlers.d.ts +18 -0
  142. package/lib/utils/crash-handlers.js +36 -0
  143. package/lib/utils/env.d.ts +28 -0
  144. package/lib/utils/env.js +54 -0
  145. package/lib/utils/headers.d.ts +18 -0
  146. package/lib/utils/headers.js +21 -0
  147. package/lib/utils/identity.d.ts +40 -0
  148. package/lib/utils/identity.js +51 -0
  149. package/lib/utils/index.d.ts +17 -0
  150. package/lib/utils/index.js +20 -0
  151. package/lib/utils/logger.d.ts +38 -0
  152. package/lib/utils/logger.js +174 -0
  153. package/lib/utils/metric-emitter.d.ts +36 -0
  154. package/lib/utils/metric-emitter.js +32 -0
  155. package/lib/utils/object.d.ts +13 -0
  156. package/lib/utils/object.js +18 -0
  157. package/lib/utils/params.d.ts +150 -0
  158. package/lib/utils/params.js +206 -0
  159. package/lib/utils/response.d.ts +117 -0
  160. package/lib/utils/response.js +223 -0
  161. package/lib/utils/safe-require.d.ts +13 -0
  162. package/lib/utils/safe-require.js +19 -0
  163. package/lib/utils/secret-encryption.d.ts +176 -0
  164. package/lib/utils/secret-encryption.js +374 -0
  165. package/lib/utils/ssrf.d.ts +30 -0
  166. package/lib/utils/ssrf.js +106 -0
  167. package/lib/validation/ai-schemas.d.ts +56 -0
  168. package/lib/validation/ai-schemas.js +78 -0
  169. package/lib/validation/common-schemas.d.ts +133 -0
  170. package/lib/validation/common-schemas.js +94 -0
  171. package/lib/validation/index.d.ts +7 -0
  172. package/lib/validation/index.js +10 -0
  173. package/lib/validation/message-schemas.d.ts +160 -0
  174. package/lib/validation/message-schemas.js +156 -0
  175. package/lib/validation/middleware.d.ts +72 -0
  176. package/lib/validation/middleware.js +65 -0
  177. package/lib/validation/pipeline-schemas.d.ts +181 -0
  178. package/lib/validation/pipeline-schemas.js +101 -0
  179. package/lib/validation/pipeline-template-schemas.d.ts +155 -0
  180. package/lib/validation/pipeline-template-schemas.js +66 -0
  181. package/lib/validation/plugin-schemas.d.ts +171 -0
  182. package/lib/validation/plugin-schemas.js +81 -0
  183. package/openapi.yaml +292 -0
  184. package/package.json +167 -0
@@ -0,0 +1,62 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { registry } from '../registry.js';
4
+ const tags = ['Quotas'];
5
+ const auth = [{ bearerAuth: [] }];
6
+ export function registerQuotaRoutes() {
7
+ registry.registerPath({
8
+ method: 'get',
9
+ path: '/quotas',
10
+ summary: 'Get own quotas',
11
+ description: 'Get quota usage and limits for the current organization (from JWT).',
12
+ tags,
13
+ security: auth,
14
+ responses: { 200: { description: 'Organization quota details' } },
15
+ });
16
+ registry.registerPath({
17
+ method: 'get',
18
+ path: '/quotas/all',
19
+ summary: 'Get all org quotas',
20
+ description: 'Get quotas for all organizations. System admin only.',
21
+ tags,
22
+ security: auth,
23
+ responses: { 200: { description: 'All organization quotas' }, 403: { description: 'Admin required' } },
24
+ });
25
+ registry.registerPath({
26
+ method: 'get',
27
+ path: '/quotas/{orgId}',
28
+ summary: 'Get org quotas',
29
+ description: 'Get quota usage and limits for a specific organization.',
30
+ tags,
31
+ security: auth,
32
+ responses: { 200: { description: 'Organization quota details' }, 404: { description: 'Organization not found' } },
33
+ });
34
+ registry.registerPath({
35
+ method: 'get',
36
+ path: '/quotas/{orgId}/{quotaType}',
37
+ summary: 'Get specific quota',
38
+ description: 'Get a specific quota type for an organization.',
39
+ tags,
40
+ security: auth,
41
+ responses: { 200: { description: 'Quota type details' } },
42
+ });
43
+ registry.registerPath({
44
+ method: 'put',
45
+ path: '/quotas/{orgId}',
46
+ summary: 'Update org quotas',
47
+ description: 'Update quota limits for an organization. System admin only.',
48
+ tags,
49
+ security: auth,
50
+ responses: { 200: { description: 'Quotas updated' }, 403: { description: 'Admin required' } },
51
+ });
52
+ registry.registerPath({
53
+ method: 'post',
54
+ path: '/quotas/{orgId}/reset',
55
+ summary: 'Reset quota usage',
56
+ description: 'Reset usage counters for an organization. Admin only.',
57
+ tags,
58
+ security: auth,
59
+ responses: { 200: { description: 'Quota usage reset' }, 403: { description: 'Admin required' } },
60
+ });
61
+ }
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEtcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29wZW5hcGkvcm91dGVzL3F1b3RhLXJvdXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUxQyxNQUFNLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3hCLE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUVsQyxNQUFNLFVBQVUsbUJBQW1CO0lBQ2pDLFFBQVEsQ0FBQyxZQUFZLENBQUM7UUFDcEIsTUFBTSxFQUFFLEtBQUs7UUFDYixJQUFJLEVBQUUsU0FBUztRQUNmLE9BQU8sRUFBRSxnQkFBZ0I7UUFDekIsV0FBVyxFQUFFLHFFQUFxRTtRQUNsRixJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsNEJBQTRCLEVBQUUsRUFBRTtLQUNsRSxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxDQUFDO1FBQ3BCLE1BQU0sRUFBRSxLQUFLO1FBQ2IsSUFBSSxFQUFFLGFBQWE7UUFDbkIsT0FBTyxFQUFFLG9CQUFvQjtRQUM3QixXQUFXLEVBQUUsc0RBQXNEO1FBQ25FLElBQUk7UUFDSixRQUFRLEVBQUUsSUFBSTtRQUNkLFNBQVMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxFQUFFO0tBQ3ZHLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLENBQUM7UUFDcEIsTUFBTSxFQUFFLEtBQUs7UUFDYixJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLE9BQU8sRUFBRSxnQkFBZ0I7UUFDekIsV0FBVyxFQUFFLHlEQUF5RDtRQUN0RSxJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsNEJBQTRCLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsd0JBQXdCLEVBQUUsRUFBRTtLQUNsSCxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxDQUFDO1FBQ3BCLE1BQU0sRUFBRSxLQUFLO1FBQ2IsSUFBSSxFQUFFLDZCQUE2QjtRQUNuQyxPQUFPLEVBQUUsb0JBQW9CO1FBQzdCLFdBQVcsRUFBRSxnREFBZ0Q7UUFDN0QsSUFBSTtRQUNKLFFBQVEsRUFBRSxJQUFJO1FBQ2QsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLG9CQUFvQixFQUFFLEVBQUU7S0FDMUQsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLElBQUksRUFBRSxpQkFBaUI7UUFDdkIsT0FBTyxFQUFFLG1CQUFtQjtRQUM1QixXQUFXLEVBQUUsNkRBQTZEO1FBQzFFLElBQUk7UUFDSixRQUFRLEVBQUUsSUFBSTtRQUNkLFNBQVMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxFQUFFO0tBQzlGLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLENBQUM7UUFDcEIsTUFBTSxFQUFFLE1BQU07UUFDZCxJQUFJLEVBQUUsdUJBQXVCO1FBQzdCLE9BQU8sRUFBRSxtQkFBbUI7UUFDNUIsV0FBVyxFQUFFLHVEQUF1RDtRQUNwRSxJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRTtLQUNqRyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJlZ2lzdHJ5IH0gZnJvbSAnLi4vcmVnaXN0cnkuanMnO1xuXG5jb25zdCB0YWdzID0gWydRdW90YXMnXTtcbmNvbnN0IGF1dGggPSBbeyBiZWFyZXJBdXRoOiBbXSB9XTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyUXVvdGFSb3V0ZXMoKTogdm9pZCB7XG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyUGF0aCh7XG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBwYXRoOiAnL3F1b3RhcycsXG4gICAgc3VtbWFyeTogJ0dldCBvd24gcXVvdGFzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCBxdW90YSB1c2FnZSBhbmQgbGltaXRzIGZvciB0aGUgY3VycmVudCBvcmdhbml6YXRpb24gKGZyb20gSldUKS4nLFxuICAgIHRhZ3MsXG4gICAgc2VjdXJpdHk6IGF1dGgsXG4gICAgcmVzcG9uc2VzOiB7IDIwMDogeyBkZXNjcmlwdGlvbjogJ09yZ2FuaXphdGlvbiBxdW90YSBkZXRhaWxzJyB9IH0sXG4gIH0pO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyUGF0aCh7XG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBwYXRoOiAnL3F1b3Rhcy9hbGwnLFxuICAgIHN1bW1hcnk6ICdHZXQgYWxsIG9yZyBxdW90YXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IHF1b3RhcyBmb3IgYWxsIG9yZ2FuaXphdGlvbnMuIFN5c3RlbSBhZG1pbiBvbmx5LicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHsgMjAwOiB7IGRlc2NyaXB0aW9uOiAnQWxsIG9yZ2FuaXphdGlvbiBxdW90YXMnIH0sIDQwMzogeyBkZXNjcmlwdGlvbjogJ0FkbWluIHJlcXVpcmVkJyB9IH0sXG4gIH0pO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyUGF0aCh7XG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBwYXRoOiAnL3F1b3Rhcy97b3JnSWR9JyxcbiAgICBzdW1tYXJ5OiAnR2V0IG9yZyBxdW90YXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IHF1b3RhIHVzYWdlIGFuZCBsaW1pdHMgZm9yIGEgc3BlY2lmaWMgb3JnYW5pemF0aW9uLicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHsgMjAwOiB7IGRlc2NyaXB0aW9uOiAnT3JnYW5pemF0aW9uIHF1b3RhIGRldGFpbHMnIH0sIDQwNDogeyBkZXNjcmlwdGlvbjogJ09yZ2FuaXphdGlvbiBub3QgZm91bmQnIH0gfSxcbiAgfSk7XG5cbiAgcmVnaXN0cnkucmVnaXN0ZXJQYXRoKHtcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIHBhdGg6ICcvcXVvdGFzL3tvcmdJZH0ve3F1b3RhVHlwZX0nLFxuICAgIHN1bW1hcnk6ICdHZXQgc3BlY2lmaWMgcXVvdGEnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IGEgc3BlY2lmaWMgcXVvdGEgdHlwZSBmb3IgYW4gb3JnYW5pemF0aW9uLicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHsgMjAwOiB7IGRlc2NyaXB0aW9uOiAnUXVvdGEgdHlwZSBkZXRhaWxzJyB9IH0sXG4gIH0pO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyUGF0aCh7XG4gICAgbWV0aG9kOiAncHV0JyxcbiAgICBwYXRoOiAnL3F1b3Rhcy97b3JnSWR9JyxcbiAgICBzdW1tYXJ5OiAnVXBkYXRlIG9yZyBxdW90YXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnVXBkYXRlIHF1b3RhIGxpbWl0cyBmb3IgYW4gb3JnYW5pemF0aW9uLiBTeXN0ZW0gYWRtaW4gb25seS4nLFxuICAgIHRhZ3MsXG4gICAgc2VjdXJpdHk6IGF1dGgsXG4gICAgcmVzcG9uc2VzOiB7IDIwMDogeyBkZXNjcmlwdGlvbjogJ1F1b3RhcyB1cGRhdGVkJyB9LCA0MDM6IHsgZGVzY3JpcHRpb246ICdBZG1pbiByZXF1aXJlZCcgfSB9LFxuICB9KTtcblxuICByZWdpc3RyeS5yZWdpc3RlclBhdGgoe1xuICAgIG1ldGhvZDogJ3Bvc3QnLFxuICAgIHBhdGg6ICcvcXVvdGFzL3tvcmdJZH0vcmVzZXQnLFxuICAgIHN1bW1hcnk6ICdSZXNldCBxdW90YSB1c2FnZScsXG4gICAgZGVzY3JpcHRpb246ICdSZXNldCB1c2FnZSBjb3VudGVycyBmb3IgYW4gb3JnYW5pemF0aW9uLiBBZG1pbiBvbmx5LicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHsgMjAwOiB7IGRlc2NyaXB0aW9uOiAnUXVvdGEgdXNhZ2UgcmVzZXQnIH0sIDQwMzogeyBkZXNjcmlwdGlvbjogJ0FkbWluIHJlcXVpcmVkJyB9IH0sXG4gIH0pO1xufVxuIl19
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ export declare const SuccessResponseSchema: z.ZodObject<{
3
+ success: z.ZodLiteral<true>;
4
+ statusCode: z.ZodNumber;
5
+ data: z.ZodOptional<z.ZodUnknown>;
6
+ message: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>;
8
+ export declare const ErrorResponseSchema: z.ZodObject<{
9
+ success: z.ZodLiteral<false>;
10
+ statusCode: z.ZodNumber;
11
+ message: z.ZodString;
12
+ code: z.ZodOptional<z.ZodString>;
13
+ details: z.ZodOptional<z.ZodUnknown>;
14
+ }, z.core.$strip>;
15
+ export declare const PaginatedResponseSchema: z.ZodObject<{
16
+ success: z.ZodLiteral<true>;
17
+ statusCode: z.ZodNumber;
18
+ data: z.ZodArray<z.ZodUnknown>;
19
+ count: z.ZodNumber;
20
+ limit: z.ZodNumber;
21
+ offset: z.ZodNumber;
22
+ total: z.ZodOptional<z.ZodNumber>;
23
+ message: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>;
25
+ export declare function registerSchemas(): void;
@@ -0,0 +1,91 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { z } from 'zod';
4
+ import { registry } from './registry.js';
5
+ import { AIGenerateBodySchema, PluginDeployGeneratedSchema, } from '../validation/ai-schemas.js';
6
+ import { VisibilitySchema, PaginationSchema, BaseFilterSchema, } from '../validation/common-schemas.js';
7
+ import { MessageFilterSchema, MessageCreateSchema, MessageReplySchema, } from '../validation/message-schemas.js';
8
+ import { PipelineFilterSchema, PipelineCreateSchema, PipelineUpdateSchema, } from '../validation/pipeline-schemas.js';
9
+ import { PluginFilterSchema, PluginCreateSchema, PluginUpdateSchema, PluginUploadBodySchema, } from '../validation/plugin-schemas.js';
10
+ // Response schemas (exported for type usage)
11
+ export const SuccessResponseSchema = z.object({
12
+ success: z.literal(true),
13
+ statusCode: z.number(),
14
+ data: z.unknown().optional(),
15
+ message: z.string().optional(),
16
+ });
17
+ export const ErrorResponseSchema = z.object({
18
+ success: z.literal(false),
19
+ statusCode: z.number(),
20
+ message: z.string(),
21
+ code: z.string().optional(),
22
+ details: z.unknown().optional(),
23
+ });
24
+ export const PaginatedResponseSchema = z.object({
25
+ success: z.literal(true),
26
+ statusCode: z.number(),
27
+ data: z.array(z.unknown()),
28
+ count: z.number(),
29
+ limit: z.number(),
30
+ offset: z.number(),
31
+ total: z.number().optional(),
32
+ message: z.string().optional(),
33
+ });
34
+ export function registerSchemas() {
35
+ // Common schemas
36
+ registry.register('Visibility', VisibilitySchema.openapi({
37
+ description: 'Sharing rung: "private" (author only), "org" (everyone in the owning organization), or "public" (the org, its teams, and — from the system org — every org)',
38
+ example: 'private',
39
+ }));
40
+ registry.register('PaginationParams', PaginationSchema.openapi({
41
+ description: 'Standard pagination and sorting parameters',
42
+ }));
43
+ registry.register('BaseFilter', BaseFilterSchema.openapi({
44
+ description: 'Common filter fields shared by all entity queries',
45
+ }));
46
+ // Pipeline schemas
47
+ registry.register('PipelineFilter', PipelineFilterSchema.openapi({
48
+ description: 'Query filters for listing pipelines',
49
+ }));
50
+ registry.register('PipelineCreate', PipelineCreateSchema.openapi({
51
+ description: 'Request body for creating a new pipeline',
52
+ }));
53
+ registry.register('PipelineUpdate', PipelineUpdateSchema.openapi({
54
+ description: 'Request body for updating an existing pipeline',
55
+ }));
56
+ // Plugin schemas
57
+ registry.register('PluginFilter', PluginFilterSchema.openapi({
58
+ description: 'Query filters for listing plugins',
59
+ }));
60
+ registry.register('PluginCreate', PluginCreateSchema.openapi({
61
+ description: 'Request body for creating a new plugin',
62
+ }));
63
+ registry.register('PluginUpdate', PluginUpdateSchema.openapi({
64
+ description: 'Request body for updating an existing plugin',
65
+ }));
66
+ registry.register('PluginUploadBody', PluginUploadBodySchema.openapi({
67
+ description: 'Metadata for plugin ZIP upload (multipart form-data)',
68
+ }));
69
+ // Message schemas
70
+ registry.register('MessageFilter', MessageFilterSchema.openapi({
71
+ description: 'Query filters for listing messages',
72
+ }));
73
+ registry.register('MessageCreate', MessageCreateSchema.openapi({
74
+ description: 'Request body for creating a new message or announcement',
75
+ }));
76
+ registry.register('MessageReply', MessageReplySchema.openapi({
77
+ description: 'Request body for replying to a message thread',
78
+ }));
79
+ // AI schemas
80
+ registry.register('AIGenerateBody', AIGenerateBodySchema.openapi({
81
+ description: 'Request body for AI-powered generation (pipeline or plugin)',
82
+ }));
83
+ registry.register('PluginDeployGenerated', PluginDeployGeneratedSchema.openapi({
84
+ description: 'Request body for deploying an AI-generated plugin',
85
+ }));
86
+ // Response schemas
87
+ registry.register('SuccessResponse', SuccessResponseSchema.openapi('SuccessResponse'));
88
+ registry.register('ErrorResponse', ErrorResponseSchema.openapi('ErrorResponse'));
89
+ registry.register('PaginatedResponse', PaginatedResponseSchema.openapi('PaginatedResponse'));
90
+ }
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZW5hcGkvc2NoZW1hLXJlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsMkJBQTJCLEdBQzVCLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEdBQ2pCLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIsa0JBQWtCLEdBQ25CLE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsb0JBQW9CLEdBQ3JCLE1BQU0sbUNBQW1DLENBQUM7QUFDM0MsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLHNCQUFzQixHQUN2QixNQUFNLGlDQUFpQyxDQUFDO0FBRXpDLDZDQUE2QztBQUM3QyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzVDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QixVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUN0QixJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM1QixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUMvQixDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN6QixVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUN0QixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUNuQixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMzQixPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUNoQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzlDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QixVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUN0QixJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDMUIsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDakIsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDakIsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUU7SUFDbEIsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDNUIsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDL0IsQ0FBQyxDQUFDO0FBRUgsTUFBTSxVQUFVLGVBQWU7SUFDN0IsaUJBQWlCO0lBQ2pCLFFBQVEsQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUN2RCxXQUFXLEVBQUUsNkpBQTZKO1FBQzFLLE9BQU8sRUFBRSxTQUFTO0tBQ25CLENBQUMsQ0FBQyxDQUFDO0lBRUosUUFBUSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUM7UUFDN0QsV0FBVyxFQUFFLDRDQUE0QztLQUMxRCxDQUFDLENBQUMsQ0FBQztJQUVKLFFBQVEsQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUN2RCxXQUFXLEVBQUUsbURBQW1EO0tBQ2pFLENBQUMsQ0FBQyxDQUFDO0lBRUosbUJBQW1CO0lBQ25CLFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsb0JBQW9CLENBQUMsT0FBTyxDQUFDO1FBQy9ELFdBQVcsRUFBRSxxQ0FBcUM7S0FDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSixRQUFRLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLG9CQUFvQixDQUFDLE9BQU8sQ0FBQztRQUMvRCxXQUFXLEVBQUUsMENBQTBDO0tBQ3hELENBQUMsQ0FBQyxDQUFDO0lBRUosUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxvQkFBb0IsQ0FBQyxPQUFPLENBQUM7UUFDL0QsV0FBVyxFQUFFLGdEQUFnRDtLQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVKLGlCQUFpQjtJQUNqQixRQUFRLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7UUFDM0QsV0FBVyxFQUFFLG1DQUFtQztLQUNqRCxDQUFDLENBQUMsQ0FBQztJQUVKLFFBQVEsQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLGtCQUFrQixDQUFDLE9BQU8sQ0FBQztRQUMzRCxXQUFXLEVBQUUsd0NBQXdDO0tBQ3RELENBQUMsQ0FBQyxDQUFDO0lBRUosUUFBUSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsa0JBQWtCLENBQUMsT0FBTyxDQUFDO1FBQzNELFdBQVcsRUFBRSw4Q0FBOEM7S0FDNUQsQ0FBQyxDQUFDLENBQUM7SUFFSixRQUFRLENBQUMsUUFBUSxDQUFDLGtCQUFrQixFQUFFLHNCQUFzQixDQUFDLE9BQU8sQ0FBQztRQUNuRSxXQUFXLEVBQUUsc0RBQXNEO0tBQ3BFLENBQUMsQ0FBQyxDQUFDO0lBRUosa0JBQWtCO0lBQ2xCLFFBQVEsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLG1CQUFtQixDQUFDLE9BQU8sQ0FBQztRQUM3RCxXQUFXLEVBQUUsb0NBQW9DO0tBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUosUUFBUSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxDQUFDO1FBQzdELFdBQVcsRUFBRSx5REFBeUQ7S0FDdkUsQ0FBQyxDQUFDLENBQUM7SUFFSixRQUFRLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7UUFDM0QsV0FBVyxFQUFFLCtDQUErQztLQUM3RCxDQUFDLENBQUMsQ0FBQztJQUVKLGFBQWE7SUFDYixRQUFRLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLG9CQUFvQixDQUFDLE9BQU8sQ0FBQztRQUMvRCxXQUFXLEVBQUUsNkRBQTZEO0tBQzNFLENBQUMsQ0FBQyxDQUFDO0lBRUosUUFBUSxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSwyQkFBMkIsQ0FBQyxPQUFPLENBQUM7UUFDN0UsV0FBVyxFQUFFLG1EQUFtRDtLQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVKLG1CQUFtQjtJQUNuQixRQUFRLENBQUMsUUFBUSxDQUFDLGlCQUFpQixFQUFFLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDdkYsUUFBUSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDakYsUUFBUSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO0FBQy9GLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZCc7XG5cbmltcG9ydCB7IHJlZ2lzdHJ5IH0gZnJvbSAnLi9yZWdpc3RyeS5qcyc7XG5pbXBvcnQge1xuICBBSUdlbmVyYXRlQm9keVNjaGVtYSxcbiAgUGx1Z2luRGVwbG95R2VuZXJhdGVkU2NoZW1hLFxufSBmcm9tICcuLi92YWxpZGF0aW9uL2FpLXNjaGVtYXMuanMnO1xuaW1wb3J0IHtcbiAgVmlzaWJpbGl0eVNjaGVtYSxcbiAgUGFnaW5hdGlvblNjaGVtYSxcbiAgQmFzZUZpbHRlclNjaGVtYSxcbn0gZnJvbSAnLi4vdmFsaWRhdGlvbi9jb21tb24tc2NoZW1hcy5qcyc7XG5pbXBvcnQge1xuICBNZXNzYWdlRmlsdGVyU2NoZW1hLFxuICBNZXNzYWdlQ3JlYXRlU2NoZW1hLFxuICBNZXNzYWdlUmVwbHlTY2hlbWEsXG59IGZyb20gJy4uL3ZhbGlkYXRpb24vbWVzc2FnZS1zY2hlbWFzLmpzJztcbmltcG9ydCB7XG4gIFBpcGVsaW5lRmlsdGVyU2NoZW1hLFxuICBQaXBlbGluZUNyZWF0ZVNjaGVtYSxcbiAgUGlwZWxpbmVVcGRhdGVTY2hlbWEsXG59IGZyb20gJy4uL3ZhbGlkYXRpb24vcGlwZWxpbmUtc2NoZW1hcy5qcyc7XG5pbXBvcnQge1xuICBQbHVnaW5GaWx0ZXJTY2hlbWEsXG4gIFBsdWdpbkNyZWF0ZVNjaGVtYSxcbiAgUGx1Z2luVXBkYXRlU2NoZW1hLFxuICBQbHVnaW5VcGxvYWRCb2R5U2NoZW1hLFxufSBmcm9tICcuLi92YWxpZGF0aW9uL3BsdWdpbi1zY2hlbWFzLmpzJztcblxuLy8gUmVzcG9uc2Ugc2NoZW1hcyAoZXhwb3J0ZWQgZm9yIHR5cGUgdXNhZ2UpXG5leHBvcnQgY29uc3QgU3VjY2Vzc1Jlc3BvbnNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBzdWNjZXNzOiB6LmxpdGVyYWwodHJ1ZSksXG4gIHN0YXR1c0NvZGU6IHoubnVtYmVyKCksXG4gIGRhdGE6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gIG1lc3NhZ2U6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRXJyb3JSZXNwb25zZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgc3VjY2Vzczogei5saXRlcmFsKGZhbHNlKSxcbiAgc3RhdHVzQ29kZTogei5udW1iZXIoKSxcbiAgbWVzc2FnZTogei5zdHJpbmcoKSxcbiAgY29kZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBkZXRhaWxzOiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBQYWdpbmF0ZWRSZXNwb25zZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgc3VjY2Vzczogei5saXRlcmFsKHRydWUpLFxuICBzdGF0dXNDb2RlOiB6Lm51bWJlcigpLFxuICBkYXRhOiB6LmFycmF5KHoudW5rbm93bigpKSxcbiAgY291bnQ6IHoubnVtYmVyKCksXG4gIGxpbWl0OiB6Lm51bWJlcigpLFxuICBvZmZzZXQ6IHoubnVtYmVyKCksXG4gIHRvdGFsOiB6Lm51bWJlcigpLm9wdGlvbmFsKCksXG4gIG1lc3NhZ2U6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJTY2hlbWFzKCk6IHZvaWQge1xuICAvLyBDb21tb24gc2NoZW1hc1xuICByZWdpc3RyeS5yZWdpc3RlcignVmlzaWJpbGl0eScsIFZpc2liaWxpdHlTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdTaGFyaW5nIHJ1bmc6IFwicHJpdmF0ZVwiIChhdXRob3Igb25seSksIFwib3JnXCIgKGV2ZXJ5b25lIGluIHRoZSBvd25pbmcgb3JnYW5pemF0aW9uKSwgb3IgXCJwdWJsaWNcIiAodGhlIG9yZywgaXRzIHRlYW1zLCBhbmQg4oCUIGZyb20gdGhlIHN5c3RlbSBvcmcg4oCUIGV2ZXJ5IG9yZyknLFxuICAgIGV4YW1wbGU6ICdwcml2YXRlJyxcbiAgfSkpO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdQYWdpbmF0aW9uUGFyYW1zJywgUGFnaW5hdGlvblNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1N0YW5kYXJkIHBhZ2luYXRpb24gYW5kIHNvcnRpbmcgcGFyYW1ldGVycycsXG4gIH0pKTtcblxuICByZWdpc3RyeS5yZWdpc3RlcignQmFzZUZpbHRlcicsIEJhc2VGaWx0ZXJTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdDb21tb24gZmlsdGVyIGZpZWxkcyBzaGFyZWQgYnkgYWxsIGVudGl0eSBxdWVyaWVzJyxcbiAgfSkpO1xuXG4gIC8vIFBpcGVsaW5lIHNjaGVtYXNcbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ1BpcGVsaW5lRmlsdGVyJywgUGlwZWxpbmVGaWx0ZXJTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdRdWVyeSBmaWx0ZXJzIGZvciBsaXN0aW5nIHBpcGVsaW5lcycsXG4gIH0pKTtcblxuICByZWdpc3RyeS5yZWdpc3RlcignUGlwZWxpbmVDcmVhdGUnLCBQaXBlbGluZUNyZWF0ZVNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVlc3QgYm9keSBmb3IgY3JlYXRpbmcgYSBuZXcgcGlwZWxpbmUnLFxuICB9KSk7XG5cbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ1BpcGVsaW5lVXBkYXRlJywgUGlwZWxpbmVVcGRhdGVTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdSZXF1ZXN0IGJvZHkgZm9yIHVwZGF0aW5nIGFuIGV4aXN0aW5nIHBpcGVsaW5lJyxcbiAgfSkpO1xuXG4gIC8vIFBsdWdpbiBzY2hlbWFzXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdQbHVnaW5GaWx0ZXInLCBQbHVnaW5GaWx0ZXJTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdRdWVyeSBmaWx0ZXJzIGZvciBsaXN0aW5nIHBsdWdpbnMnLFxuICB9KSk7XG5cbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ1BsdWdpbkNyZWF0ZScsIFBsdWdpbkNyZWF0ZVNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVlc3QgYm9keSBmb3IgY3JlYXRpbmcgYSBuZXcgcGx1Z2luJyxcbiAgfSkpO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdQbHVnaW5VcGRhdGUnLCBQbHVnaW5VcGRhdGVTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdSZXF1ZXN0IGJvZHkgZm9yIHVwZGF0aW5nIGFuIGV4aXN0aW5nIHBsdWdpbicsXG4gIH0pKTtcblxuICByZWdpc3RyeS5yZWdpc3RlcignUGx1Z2luVXBsb2FkQm9keScsIFBsdWdpblVwbG9hZEJvZHlTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdNZXRhZGF0YSBmb3IgcGx1Z2luIFpJUCB1cGxvYWQgKG11bHRpcGFydCBmb3JtLWRhdGEpJyxcbiAgfSkpO1xuXG4gIC8vIE1lc3NhZ2Ugc2NoZW1hc1xuICByZWdpc3RyeS5yZWdpc3RlcignTWVzc2FnZUZpbHRlcicsIE1lc3NhZ2VGaWx0ZXJTY2hlbWEub3BlbmFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdRdWVyeSBmaWx0ZXJzIGZvciBsaXN0aW5nIG1lc3NhZ2VzJyxcbiAgfSkpO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdNZXNzYWdlQ3JlYXRlJywgTWVzc2FnZUNyZWF0ZVNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVlc3QgYm9keSBmb3IgY3JlYXRpbmcgYSBuZXcgbWVzc2FnZSBvciBhbm5vdW5jZW1lbnQnLFxuICB9KSk7XG5cbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ01lc3NhZ2VSZXBseScsIE1lc3NhZ2VSZXBseVNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVlc3QgYm9keSBmb3IgcmVwbHlpbmcgdG8gYSBtZXNzYWdlIHRocmVhZCcsXG4gIH0pKTtcblxuICAvLyBBSSBzY2hlbWFzXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdBSUdlbmVyYXRlQm9keScsIEFJR2VuZXJhdGVCb2R5U2NoZW1hLm9wZW5hcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnUmVxdWVzdCBib2R5IGZvciBBSS1wb3dlcmVkIGdlbmVyYXRpb24gKHBpcGVsaW5lIG9yIHBsdWdpbiknLFxuICB9KSk7XG5cbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ1BsdWdpbkRlcGxveUdlbmVyYXRlZCcsIFBsdWdpbkRlcGxveUdlbmVyYXRlZFNjaGVtYS5vcGVuYXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1JlcXVlc3QgYm9keSBmb3IgZGVwbG95aW5nIGFuIEFJLWdlbmVyYXRlZCBwbHVnaW4nLFxuICB9KSk7XG5cbiAgLy8gUmVzcG9uc2Ugc2NoZW1hc1xuICByZWdpc3RyeS5yZWdpc3RlcignU3VjY2Vzc1Jlc3BvbnNlJywgU3VjY2Vzc1Jlc3BvbnNlU2NoZW1hLm9wZW5hcGkoJ1N1Y2Nlc3NSZXNwb25zZScpKTtcbiAgcmVnaXN0cnkucmVnaXN0ZXIoJ0Vycm9yUmVzcG9uc2UnLCBFcnJvclJlc3BvbnNlU2NoZW1hLm9wZW5hcGkoJ0Vycm9yUmVzcG9uc2UnKSk7XG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyKCdQYWdpbmF0ZWRSZXNwb25zZScsIFBhZ2luYXRlZFJlc3BvbnNlU2NoZW1hLm9wZW5hcGkoJ1BhZ2luYXRlZFJlc3BvbnNlJykpO1xufVxuIl19
@@ -0,0 +1,41 @@
1
+ import { Router, type Request, type Response } from 'express';
2
+ /**
3
+ * Options for health check endpoint.
4
+ */
5
+ export interface HealthCheckOptions {
6
+ /** Service name */
7
+ serviceName: string;
8
+ /** Service version (optional) */
9
+ version?: string;
10
+ /** Custom health check function for dependencies */
11
+ checkDependencies?: () => Promise<Record<string, 'connected' | 'disconnected' | 'unknown'>>;
12
+ }
13
+ /**
14
+ * Liveness handler — returns 200 as long as the process is alive enough to
15
+ * respond. Dependency status is reported in the body as informational, but a
16
+ * disconnected dependency does NOT fail the probe (use /ready for that).
17
+ *
18
+ * Use as the Kubernetes / ECS LIVENESS probe — it should only fail when the
19
+ * process is genuinely stuck and needs to be restarted.
20
+ */
21
+ export declare function createHealthCheck(options: HealthCheckOptions): (_req: Request, res: Response) => Promise<void>;
22
+ /**
23
+ * Readiness handler — returns 503 if any dependency is `disconnected` (or
24
+ * the dependency check itself threw). Returns 200 only when the service is
25
+ * fully ready to serve traffic.
26
+ *
27
+ * Use as the Kubernetes / ECS READINESS probe — when this fails, the
28
+ * orchestrator stops routing traffic to this pod but does NOT restart it.
29
+ */
30
+ export declare function createReadinessCheck(options: HealthCheckOptions): (_req: Request, res: Response) => Promise<void>;
31
+ /**
32
+ * Create a health/readiness router exposing:
33
+ * - GET /health — liveness (always 200 unless process is dead)
34
+ * - GET /ready — readiness (503 if dependencies are disconnected)
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * app.use(createHealthRouter({ serviceName: 'plugin' }));
39
+ * ```
40
+ */
41
+ export declare function createHealthRouter(options: HealthCheckOptions): Router;
@@ -0,0 +1,82 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { Router } from 'express';
4
+ import { sendSuccess, sendError } from '../utils/response.js';
5
+ const startTime = Date.now();
6
+ /**
7
+ * Build a HealthCheckResponse + collect dependency status.
8
+ * Shared between /health (liveness) and /ready (readiness).
9
+ */
10
+ async function buildHealthResponse(options) {
11
+ const { serviceName, version, checkDependencies } = options;
12
+ const response = {
13
+ status: 'healthy',
14
+ service: serviceName,
15
+ timestamp: new Date().toISOString(),
16
+ uptime: Math.floor((Date.now() - startTime) / 1000),
17
+ };
18
+ if (version)
19
+ response.version = version;
20
+ if (!checkDependencies) {
21
+ return { response, hasDisconnected: false, checkFailed: false };
22
+ }
23
+ try {
24
+ response.dependencies = await checkDependencies();
25
+ const hasDisconnected = Object.values(response.dependencies).some((status) => status === 'disconnected');
26
+ return { response, hasDisconnected, checkFailed: false };
27
+ }
28
+ catch {
29
+ response.dependencies = { check: 'disconnected' };
30
+ return { response, hasDisconnected: true, checkFailed: true };
31
+ }
32
+ }
33
+ /**
34
+ * Liveness handler — returns 200 as long as the process is alive enough to
35
+ * respond. Dependency status is reported in the body as informational, but a
36
+ * disconnected dependency does NOT fail the probe (use /ready for that).
37
+ *
38
+ * Use as the Kubernetes / ECS LIVENESS probe — it should only fail when the
39
+ * process is genuinely stuck and needs to be restarted.
40
+ */
41
+ export function createHealthCheck(options) {
42
+ return async (_req, res) => {
43
+ const { response } = await buildHealthResponse(options);
44
+ sendSuccess(res, 200, response);
45
+ };
46
+ }
47
+ /**
48
+ * Readiness handler — returns 503 if any dependency is `disconnected` (or
49
+ * the dependency check itself threw). Returns 200 only when the service is
50
+ * fully ready to serve traffic.
51
+ *
52
+ * Use as the Kubernetes / ECS READINESS probe — when this fails, the
53
+ * orchestrator stops routing traffic to this pod but does NOT restart it.
54
+ */
55
+ export function createReadinessCheck(options) {
56
+ return async (_req, res) => {
57
+ const { response, hasDisconnected } = await buildHealthResponse(options);
58
+ if (hasDisconnected) {
59
+ response.status = 'unhealthy';
60
+ sendError(res, 503, 'Service not ready', undefined, response);
61
+ return;
62
+ }
63
+ sendSuccess(res, 200, response);
64
+ };
65
+ }
66
+ /**
67
+ * Create a health/readiness router exposing:
68
+ * - GET /health — liveness (always 200 unless process is dead)
69
+ * - GET /ready — readiness (503 if dependencies are disconnected)
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * app.use(createHealthRouter({ serviceName: 'plugin' }));
74
+ * ```
75
+ */
76
+ export function createHealthRouter(options) {
77
+ const router = Router();
78
+ router.get('/health', createHealthCheck(options));
79
+ router.get('/ready', createReadinessCheck(options));
80
+ return router;
81
+ }
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhbHRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JvdXRlcy9oZWFsdGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsTUFBTSxFQUErQixNQUFNLFNBQVMsQ0FBQztBQUU5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTlELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQWM3Qjs7O0dBR0c7QUFDSCxLQUFLLFVBQVUsbUJBQW1CLENBQUMsT0FBMkI7SUFLNUQsTUFBTSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDNUQsTUFBTSxRQUFRLEdBQXdCO1FBQ3BDLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE9BQU8sRUFBRSxXQUFXO1FBQ3BCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtRQUNuQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUM7S0FDcEQsQ0FBQztJQUNGLElBQUksT0FBTztRQUFFLFFBQVEsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBRXhDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDbEUsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILFFBQVEsQ0FBQyxZQUFZLEdBQUcsTUFBTSxpQkFBaUIsRUFBRSxDQUFDO1FBQ2xELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FDL0QsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sS0FBSyxjQUFjLENBQ3RDLENBQUM7UUFDRixPQUFPLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDM0QsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLFFBQVEsQ0FBQyxZQUFZLEdBQUcsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLENBQUM7UUFDbEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNoRSxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsT0FBMkI7SUFDM0QsT0FBTyxLQUFLLEVBQUUsSUFBYSxFQUFFLEdBQWEsRUFBaUIsRUFBRTtRQUMzRCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4RCxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxPQUEyQjtJQUM5RCxPQUFPLEtBQUssRUFBRSxJQUFhLEVBQUUsR0FBYSxFQUFpQixFQUFFO1FBQzNELE1BQU0sRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6RSxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ3BCLFFBQVEsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO1lBQzlCLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLG1CQUFtQixFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM5RCxPQUFPO1FBQ1QsQ0FBQztRQUNELFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsT0FBMkI7SUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUM7SUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNsRCxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3BELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgUm91dGVyLCB0eXBlIFJlcXVlc3QsIHR5cGUgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB0eXBlIHsgSGVhbHRoQ2hlY2tSZXNwb25zZSB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBzZW5kU3VjY2Vzcywgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGhlYWx0aCBjaGVjayBlbmRwb2ludC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja09wdGlvbnMge1xuICAvKiogU2VydmljZSBuYW1lICovXG4gIHNlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIC8qKiBTZXJ2aWNlIHZlcnNpb24gKG9wdGlvbmFsKSAqL1xuICB2ZXJzaW9uPzogc3RyaW5nO1xuICAvKiogQ3VzdG9tIGhlYWx0aCBjaGVjayBmdW5jdGlvbiBmb3IgZGVwZW5kZW5jaWVzICovXG4gIGNoZWNrRGVwZW5kZW5jaWVzPzogKCkgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCAnY29ubmVjdGVkJyB8ICdkaXNjb25uZWN0ZWQnIHwgJ3Vua25vd24nPj47XG59XG5cbi8qKlxuICogQnVpbGQgYSBIZWFsdGhDaGVja1Jlc3BvbnNlICsgY29sbGVjdCBkZXBlbmRlbmN5IHN0YXR1cy5cbiAqIFNoYXJlZCBiZXR3ZWVuIC9oZWFsdGggKGxpdmVuZXNzKSBhbmQgL3JlYWR5IChyZWFkaW5lc3MpLlxuICovXG5hc3luYyBmdW5jdGlvbiBidWlsZEhlYWx0aFJlc3BvbnNlKG9wdGlvbnM6IEhlYWx0aENoZWNrT3B0aW9ucyk6IFByb21pc2U8e1xuICByZXNwb25zZTogSGVhbHRoQ2hlY2tSZXNwb25zZTtcbiAgaGFzRGlzY29ubmVjdGVkOiBib29sZWFuO1xuICBjaGVja0ZhaWxlZDogYm9vbGVhbjtcbn0+IHtcbiAgY29uc3QgeyBzZXJ2aWNlTmFtZSwgdmVyc2lvbiwgY2hlY2tEZXBlbmRlbmNpZXMgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHJlc3BvbnNlOiBIZWFsdGhDaGVja1Jlc3BvbnNlID0ge1xuICAgIHN0YXR1czogJ2hlYWx0aHknLFxuICAgIHNlcnZpY2U6IHNlcnZpY2VOYW1lLFxuICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIHVwdGltZTogTWF0aC5mbG9vcigoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgfTtcbiAgaWYgKHZlcnNpb24pIHJlc3BvbnNlLnZlcnNpb24gPSB2ZXJzaW9uO1xuXG4gIGlmICghY2hlY2tEZXBlbmRlbmNpZXMpIHtcbiAgICByZXR1cm4geyByZXNwb25zZSwgaGFzRGlzY29ubmVjdGVkOiBmYWxzZSwgY2hlY2tGYWlsZWQ6IGZhbHNlIH07XG4gIH1cblxuICB0cnkge1xuICAgIHJlc3BvbnNlLmRlcGVuZGVuY2llcyA9IGF3YWl0IGNoZWNrRGVwZW5kZW5jaWVzKCk7XG4gICAgY29uc3QgaGFzRGlzY29ubmVjdGVkID0gT2JqZWN0LnZhbHVlcyhyZXNwb25zZS5kZXBlbmRlbmNpZXMpLnNvbWUoXG4gICAgICAoc3RhdHVzKSA9PiBzdGF0dXMgPT09ICdkaXNjb25uZWN0ZWQnLFxuICAgICk7XG4gICAgcmV0dXJuIHsgcmVzcG9uc2UsIGhhc0Rpc2Nvbm5lY3RlZCwgY2hlY2tGYWlsZWQ6IGZhbHNlIH07XG4gIH0gY2F0Y2gge1xuICAgIHJlc3BvbnNlLmRlcGVuZGVuY2llcyA9IHsgY2hlY2s6ICdkaXNjb25uZWN0ZWQnIH07XG4gICAgcmV0dXJuIHsgcmVzcG9uc2UsIGhhc0Rpc2Nvbm5lY3RlZDogdHJ1ZSwgY2hlY2tGYWlsZWQ6IHRydWUgfTtcbiAgfVxufVxuXG4vKipcbiAqIExpdmVuZXNzIGhhbmRsZXIg4oCUIHJldHVybnMgMjAwIGFzIGxvbmcgYXMgdGhlIHByb2Nlc3MgaXMgYWxpdmUgZW5vdWdoIHRvXG4gKiByZXNwb25kLiBEZXBlbmRlbmN5IHN0YXR1cyBpcyByZXBvcnRlZCBpbiB0aGUgYm9keSBhcyBpbmZvcm1hdGlvbmFsLCBidXQgYVxuICogZGlzY29ubmVjdGVkIGRlcGVuZGVuY3kgZG9lcyBOT1QgZmFpbCB0aGUgcHJvYmUgKHVzZSAvcmVhZHkgZm9yIHRoYXQpLlxuICpcbiAqIFVzZSBhcyB0aGUgS3ViZXJuZXRlcyAvIEVDUyBMSVZFTkVTUyBwcm9iZSDigJQgaXQgc2hvdWxkIG9ubHkgZmFpbCB3aGVuIHRoZVxuICogcHJvY2VzcyBpcyBnZW51aW5lbHkgc3R1Y2sgYW5kIG5lZWRzIHRvIGJlIHJlc3RhcnRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhlYWx0aENoZWNrKG9wdGlvbnM6IEhlYWx0aENoZWNrT3B0aW9ucykge1xuICByZXR1cm4gYXN5bmMgKF9yZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBjb25zdCB7IHJlc3BvbnNlIH0gPSBhd2FpdCBidWlsZEhlYWx0aFJlc3BvbnNlKG9wdGlvbnMpO1xuICAgIHNlbmRTdWNjZXNzKHJlcywgMjAwLCByZXNwb25zZSk7XG4gIH07XG59XG5cbi8qKlxuICogUmVhZGluZXNzIGhhbmRsZXIg4oCUIHJldHVybnMgNTAzIGlmIGFueSBkZXBlbmRlbmN5IGlzIGBkaXNjb25uZWN0ZWRgIChvclxuICogdGhlIGRlcGVuZGVuY3kgY2hlY2sgaXRzZWxmIHRocmV3KS4gUmV0dXJucyAyMDAgb25seSB3aGVuIHRoZSBzZXJ2aWNlIGlzXG4gKiBmdWxseSByZWFkeSB0byBzZXJ2ZSB0cmFmZmljLlxuICpcbiAqIFVzZSBhcyB0aGUgS3ViZXJuZXRlcyAvIEVDUyBSRUFESU5FU1MgcHJvYmUg4oCUIHdoZW4gdGhpcyBmYWlscywgdGhlXG4gKiBvcmNoZXN0cmF0b3Igc3RvcHMgcm91dGluZyB0cmFmZmljIHRvIHRoaXMgcG9kIGJ1dCBkb2VzIE5PVCByZXN0YXJ0IGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVhZGluZXNzQ2hlY2sob3B0aW9uczogSGVhbHRoQ2hlY2tPcHRpb25zKSB7XG4gIHJldHVybiBhc3luYyAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHsgcmVzcG9uc2UsIGhhc0Rpc2Nvbm5lY3RlZCB9ID0gYXdhaXQgYnVpbGRIZWFsdGhSZXNwb25zZShvcHRpb25zKTtcbiAgICBpZiAoaGFzRGlzY29ubmVjdGVkKSB7XG4gICAgICByZXNwb25zZS5zdGF0dXMgPSAndW5oZWFsdGh5JztcbiAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ1NlcnZpY2Ugbm90IHJlYWR5JywgdW5kZWZpbmVkLCByZXNwb25zZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHNlbmRTdWNjZXNzKHJlcywgMjAwLCByZXNwb25zZSk7XG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgaGVhbHRoL3JlYWRpbmVzcyByb3V0ZXIgZXhwb3Npbmc6XG4gKiAtIEdFVCAvaGVhbHRoIOKAlCBsaXZlbmVzcyAoYWx3YXlzIDIwMCB1bmxlc3MgcHJvY2VzcyBpcyBkZWFkKVxuICogLSBHRVQgL3JlYWR5ICDigJQgcmVhZGluZXNzICg1MDMgaWYgZGVwZW5kZW5jaWVzIGFyZSBkaXNjb25uZWN0ZWQpXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGFwcC51c2UoY3JlYXRlSGVhbHRoUm91dGVyKHsgc2VydmljZU5hbWU6ICdwbHVnaW4nIH0pKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGVhbHRoUm91dGVyKG9wdGlvbnM6IEhlYWx0aENoZWNrT3B0aW9ucyk6IFJvdXRlciB7XG4gIGNvbnN0IHJvdXRlciA9IFJvdXRlcigpO1xuICByb3V0ZXIuZ2V0KCcvaGVhbHRoJywgY3JlYXRlSGVhbHRoQ2hlY2sob3B0aW9ucykpO1xuICByb3V0ZXIuZ2V0KCcvcmVhZHknLCBjcmVhdGVSZWFkaW5lc3NDaGVjayhvcHRpb25zKSk7XG4gIHJldHVybiByb3V0ZXI7XG59XG4iXX0=
@@ -0,0 +1 @@
1
+ export * from './health.js';
@@ -0,0 +1,4 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export * from './health.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcm91dGVzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsY0FBYyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuZXhwb3J0ICogZnJvbSAnLi9oZWFsdGguanMnO1xuIl19
@@ -0,0 +1,80 @@
1
+ import type { RemoteAuditEvent } from './remote-audit-client.js';
2
+ /** A buffered emission: the event plus which service must re-deliver it. */
3
+ export interface AuditSpoolEntry {
4
+ event: RemoteAuditEvent;
5
+ serviceName: string;
6
+ }
7
+ /**
8
+ * Durable buffer for audit events that failed LIVE delivery to the platform
9
+ * (retries exhausted during a sustained outage). Without this, the audit trail —
10
+ * a security log — is silently lost the moment the platform is down for longer
11
+ * than the client's small retry budget.
12
+ *
13
+ * Contract:
14
+ * - BOUNDED. A security log must degrade to "dropped the oldest, loudly" (a
15
+ * metric) rather than grow without limit and OOM the emitter.
16
+ * - FAIL-SAFE. Every method swallows its own errors — a broken/unreachable spool
17
+ * must never break or block the audit emission path (which is itself
18
+ * fire-and-forget). A spool problem degrades to the pre-spool behavior.
19
+ * - Ordering is best-effort. Re-delivered events chain at re-delivery time
20
+ * (that's when the platform inserts them), so each event also carries an
21
+ * `occurredAt` stamped at emission for reviewers — see RemoteAuditEvent.
22
+ */
23
+ export interface AuditSpool {
24
+ /** Buffer an event that failed live delivery. */
25
+ enqueue(entry: AuditSpoolEntry): Promise<void>;
26
+ /**
27
+ * Atomically MOVE up to `max` buffered entries onto an in-progress list and
28
+ * return them. Because the entries are moved (not popped-and-dropped), a crash
29
+ * mid-drain leaves them recoverable on the in-progress list — see `recover`.
30
+ * Each taken entry MUST be resolved with exactly one of `ack` (delivered) or
31
+ * `requeue` (still failing), or it lingers on the in-progress list until the
32
+ * next `recover`.
33
+ */
34
+ take(max: number): Promise<AuditSpoolEntry[]>;
35
+ /** Acknowledge successfully re-delivered entries — removes them from the
36
+ * in-progress list so they are not recovered again. */
37
+ ack(entries: AuditSpoolEntry[]): Promise<void>;
38
+ /** Return entries whose re-delivery failed to the HEAD of the buffer (retried
39
+ * first) and clear them from the in-progress list. Best-effort. */
40
+ requeue(entries: AuditSpoolEntry[]): Promise<void>;
41
+ /** Reclaim any entries stranded on the in-progress list by a prior crash,
42
+ * moving them back to the head of the main buffer. Call once at startup.
43
+ * Returns the number reclaimed. */
44
+ recover(): Promise<number>;
45
+ /** Approximate current depth (for metrics / drain decisions). */
46
+ depth(): Promise<number>;
47
+ }
48
+ /** Minimal Redis LIST surface the spool needs (a subset of ioredis). */
49
+ interface RedisListClient {
50
+ rpush(key: string, ...values: string[]): Promise<number>;
51
+ lpush(key: string, ...values: string[]): Promise<number>;
52
+ lpop(key: string, count: number): Promise<string[] | null>;
53
+ ltrim(key: string, start: number, stop: number): Promise<unknown>;
54
+ llen(key: string): Promise<number>;
55
+ /** Atomically pop from one list end and push to another (Redis ≥ 6.2). */
56
+ lmove(source: string, destination: string, from: 'LEFT' | 'RIGHT', to: 'LEFT' | 'RIGHT'): Promise<string | null>;
57
+ /** Remove `count` occurrences of `value` from a list. */
58
+ lrem(key: string, count: number, value: string): Promise<number>;
59
+ }
60
+ /**
61
+ * Redis-LIST-backed spool. Durable across process restarts (unlike an in-memory
62
+ * or per-pod-disk buffer), shared by all replicas of a service, and bounded via
63
+ * a trim-to-tail on overflow (drops the OLDEST, emitting `audit_spool_dropped_total`).
64
+ */
65
+ export declare function createRedisAuditSpool(redis: RedisListClient, opts?: {
66
+ maxDepth?: number;
67
+ key?: string;
68
+ }): AuditSpool;
69
+ /**
70
+ * Build a Redis-backed audit spool from the ambient `REDIS_URL` / `REDIS_HOST`
71
+ * env via the shared `createEnvRedisClient`. Returns `null` when Redis is not
72
+ * configured or the client can't be constructed — the caller then runs without a
73
+ * spool (pre-spool best-effort behavior), never crashing. The shared helper loads
74
+ * ioredis via `createRequire`, so this stays importable where Redis isn't present.
75
+ */
76
+ export declare function createEnvRedisAuditSpool(opts?: {
77
+ maxDepth?: number;
78
+ key?: string;
79
+ }): AuditSpool | null;
80
+ export {};