@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,128 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /** All valid feature flags (order determines display order). */
4
+ export const ALL_FEATURE_FLAGS = [
5
+ 'priority_support',
6
+ 'ai_generation',
7
+ 'bulk_operations',
8
+ 'custom_integrations',
9
+ 'audit_log',
10
+ 'sso',
11
+ 'advanced_reporting',
12
+ 'team_usage_analytics',
13
+ 'compliance_standard',
14
+ 'compliance_advanced',
15
+ ];
16
+ /** Check whether a string is a valid FeatureFlag. */
17
+ export function isValidFeatureFlag(value) {
18
+ return ALL_FEATURE_FLAGS.includes(value);
19
+ }
20
+ // Tier-to-feature mapping
21
+ /** Features enabled by default for each tier. */
22
+ export const TIER_FEATURES = {
23
+ developer: [],
24
+ pro: ['priority_support', 'ai_generation', 'bulk_operations'],
25
+ // Team adds audit_log (collaboration/governance) and sso (SSO/IdP is INCLUDED
26
+ // in Team, not an add-on). advanced_reporting (DORA) is NOT a Team tier feature —
27
+ // it's INCLUDED only in Enterprise and sold as an add-on bundle to every other
28
+ // tier (see billing-config `advanced_reporting`). Enterprise unlocks all.
29
+ team: ['priority_support', 'ai_generation', 'bulk_operations', 'audit_log', 'sso'],
30
+ enterprise: [...ALL_FEATURE_FLAGS],
31
+ // Unlimited includes every feature / add-on bundle (billing-disabled default).
32
+ unlimited: [...ALL_FEATURE_FLAGS],
33
+ };
34
+ // Feature metadata (for display)
35
+ /** Human-readable metadata for each feature flag. */
36
+ export const FEATURE_METADATA = {
37
+ priority_support: {
38
+ label: 'Priority Support',
39
+ description: 'Faster response times and dedicated support channels',
40
+ },
41
+ ai_generation: {
42
+ label: 'AI Generation',
43
+ description: 'AI-powered pipeline and plugin generation',
44
+ },
45
+ bulk_operations: {
46
+ label: 'Bulk Operations',
47
+ description: 'Batch create, update, and delete for pipelines and plugins',
48
+ },
49
+ custom_integrations: {
50
+ label: 'Custom Integrations',
51
+ description: 'Connect to external services and custom webhook endpoints',
52
+ },
53
+ audit_log: {
54
+ label: 'Audit Log',
55
+ description: 'Detailed audit trail of all user and system actions',
56
+ },
57
+ sso: {
58
+ label: 'SSO / IdP',
59
+ description: 'Single sign-on and external identity-provider configurations',
60
+ },
61
+ advanced_reporting: {
62
+ label: 'Advanced Reporting',
63
+ description: 'DORA / advanced delivery analytics',
64
+ },
65
+ team_usage_analytics: {
66
+ label: 'Team Usage Analytics',
67
+ description: 'Per-team usage breakdown across the org → team subtree',
68
+ },
69
+ compliance_standard: {
70
+ label: 'Standard Compliance',
71
+ description: 'Curated CI/CD best-practice compliance rule library',
72
+ },
73
+ compliance_advanced: {
74
+ label: 'Advanced Compliance',
75
+ description: 'Curated framework compliance libraries (SOC2 / PCI-DSS / CIS)',
76
+ },
77
+ };
78
+ // Resolution logic
79
+ /**
80
+ * Resolve a user's effective feature set.
81
+ *
82
+ * 1. Sysadmins (isSuperAdmin) always get ALL features.
83
+ * 2. Start with the tier's default features.
84
+ * 3. Apply per-user overrides: `true` adds a feature, `false` removes it.
85
+ * 4. Invalid override keys are silently ignored.
86
+ *
87
+ * @param tier - The organization's quota tier
88
+ * @param opts - Resolution options:
89
+ * - `overrides`: per-user overrides (key = feature flag, value = enabled)
90
+ * - `isSuperAdmin`: whether the user has the global super-admin flag
91
+ * - `accountFeatures`: account-level entitlements (e.g. purchased add-on
92
+ * bundles). A NAMED field so it can never be silently dropped by a caller
93
+ * that omits a trailing positional arg.
94
+ * @returns Sorted array of enabled feature flags
95
+ */
96
+ export function resolveUserFeatures(tier, opts) {
97
+ const { overrides: featureOverrides, isSuperAdmin, accountFeatures } = opts ?? {};
98
+ // Sysadmins get everything regardless of tier.
99
+ if (isSuperAdmin)
100
+ return [...ALL_FEATURE_FLAGS];
101
+ // Start with tier defaults
102
+ const features = new Set(TIER_FEATURES[tier] ?? []);
103
+ // Account-level entitlements (purchased feature bundles — e.g. audit_log, sso,
104
+ // advanced_reporting, team_usage_analytics, compliance_standard/advanced).
105
+ // Applied before per-user overrides so an explicit user override still wins.
106
+ if (accountFeatures) {
107
+ for (const key of accountFeatures) {
108
+ if (isValidFeatureFlag(key))
109
+ features.add(key);
110
+ }
111
+ }
112
+ // Apply per-user overrides
113
+ if (featureOverrides) {
114
+ for (const [key, enabled] of Object.entries(featureOverrides)) {
115
+ if (!isValidFeatureFlag(key))
116
+ continue;
117
+ if (enabled) {
118
+ features.add(key);
119
+ }
120
+ else {
121
+ features.delete(key);
122
+ }
123
+ }
124
+ }
125
+ // Return in canonical order
126
+ return ALL_FEATURE_FLAGS.filter(f => features.has(f));
127
+ }
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1mbGFncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9mZWF0dXJlLWZsYWdzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFtQ3RDLGdFQUFnRTtBQUNoRSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBMkI7SUFDdkQsa0JBQWtCO0lBQ2xCLGVBQWU7SUFDZixpQkFBaUI7SUFDakIscUJBQXFCO0lBQ3JCLFdBQVc7SUFDWCxLQUFLO0lBQ0wsb0JBQW9CO0lBQ3BCLHNCQUFzQjtJQUN0QixxQkFBcUI7SUFDckIscUJBQXFCO0NBQ3RCLENBQUM7QUFFRixxREFBcUQ7QUFDckQsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWE7SUFDOUMsT0FBUSxpQkFBdUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVELDBCQUEwQjtBQUUxQixpREFBaUQ7QUFDakQsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUE4QztJQUN0RSxTQUFTLEVBQUUsRUFBRTtJQUNiLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQztJQUM3RCw4RUFBOEU7SUFDOUUsa0ZBQWtGO0lBQ2xGLCtFQUErRTtJQUMvRSwwRUFBMEU7SUFDMUUsSUFBSSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxLQUFLLENBQUM7SUFDbEYsVUFBVSxFQUFFLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztJQUNsQywrRUFBK0U7SUFDL0UsU0FBUyxFQUFFLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztDQUNsQyxDQUFDO0FBRUYsaUNBQWlDO0FBRWpDLHFEQUFxRDtBQUNyRCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBZ0U7SUFDM0YsZ0JBQWdCLEVBQUU7UUFDaEIsS0FBSyxFQUFFLGtCQUFrQjtRQUN6QixXQUFXLEVBQUUsc0RBQXNEO0tBQ3BFO0lBQ0QsYUFBYSxFQUFFO1FBQ2IsS0FBSyxFQUFFLGVBQWU7UUFDdEIsV0FBVyxFQUFFLDJDQUEyQztLQUN6RDtJQUNELGVBQWUsRUFBRTtRQUNmLEtBQUssRUFBRSxpQkFBaUI7UUFDeEIsV0FBVyxFQUFFLDREQUE0RDtLQUMxRTtJQUNELG1CQUFtQixFQUFFO1FBQ25CLEtBQUssRUFBRSxxQkFBcUI7UUFDNUIsV0FBVyxFQUFFLDJEQUEyRDtLQUN6RTtJQUNELFNBQVMsRUFBRTtRQUNULEtBQUssRUFBRSxXQUFXO1FBQ2xCLFdBQVcsRUFBRSxxREFBcUQ7S0FDbkU7SUFDRCxHQUFHLEVBQUU7UUFDSCxLQUFLLEVBQUUsV0FBVztRQUNsQixXQUFXLEVBQUUsOERBQThEO0tBQzVFO0lBQ0Qsa0JBQWtCLEVBQUU7UUFDbEIsS0FBSyxFQUFFLG9CQUFvQjtRQUMzQixXQUFXLEVBQUUsb0NBQW9DO0tBQ2xEO0lBQ0Qsb0JBQW9CLEVBQUU7UUFDcEIsS0FBSyxFQUFFLHNCQUFzQjtRQUM3QixXQUFXLEVBQUUsd0RBQXdEO0tBQ3RFO0lBQ0QsbUJBQW1CLEVBQUU7UUFDbkIsS0FBSyxFQUFFLHFCQUFxQjtRQUM1QixXQUFXLEVBQUUscURBQXFEO0tBQ25FO0lBQ0QsbUJBQW1CLEVBQUU7UUFDbkIsS0FBSyxFQUFFLHFCQUFxQjtRQUM1QixXQUFXLEVBQUUsK0RBQStEO0tBQzdFO0NBQ0YsQ0FBQztBQUVGLG1CQUFtQjtBQUVuQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsSUFBZSxFQUNmLElBSUM7SUFFRCxNQUFNLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO0lBRWxGLCtDQUErQztJQUMvQyxJQUFJLFlBQVk7UUFBRSxPQUFPLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDO0lBRWhELDJCQUEyQjtJQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBYyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFFakUsK0VBQStFO0lBQy9FLDJFQUEyRTtJQUMzRSw2RUFBNkU7SUFDN0UsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNwQixLQUFLLE1BQU0sR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ2xDLElBQUksa0JBQWtCLENBQUMsR0FBRyxDQUFDO2dCQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakQsQ0FBQztJQUNILENBQUM7SUFFRCwyQkFBMkI7SUFDM0IsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3JCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUM5RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDO2dCQUFFLFNBQVM7WUFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELDRCQUE0QjtJQUM1QixPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUXVvdGFUaWVyIH0gZnJvbSAnLi9xdW90YS10aWVycy5qcyc7XG5cbi8vIEZlYXR1cmUgZmxhZyBpZGVudGlmaWVyc1xuXG4vKiogQ2Fub25pY2FsIGZlYXR1cmUgZmxhZyBpZGVudGlmaWVycy4gKi9cbmV4cG9ydCB0eXBlIEZlYXR1cmVGbGFnID1cbiAgLy8gYHByaW9yaXR5X3N1cHBvcnRgIGFuZCBgY3VzdG9tX2ludGVncmF0aW9uc2AgYXJlIEVOVEVSUFJJU0UtRVhDTFVTSVZFXG4gIC8vIG1hcmtldGluZy9lbnRpdGxlbWVudCBmbGFnczogZ3JhbnRlZCBvbmx5IGJ5IHRoZSBlbnRlcnByaXNlIHRpZXIgKG5vIGFkZC1vblxuICAvLyBidW5kbGUgc2VsbHMgdGhlbSB0byBhIGxvd2VyIHRpZXIg4oCUIGludGVudGlvbmFsLCB0aGV5IGFuY2hvciB0aGUgRW50ZXJwcmlzZVxuICAvLyBwbGFuKSBhbmQgbm90IGN1cnJlbnRseSBgcmVxdWlyZUZlYXR1cmVgLWdhdGVkIG9uIGFueSByb3V0ZSAodGhleSBzdXJmYWNlIGluXG4gIC8vIHBsYW4gbWFya2V0aW5nICsgdGhlIGVudGl0bGVtZW50IHNldDsgZW5mb3JjZW1lbnQgaXMgYSBmdXR1cmUgaG9vaykuIFRoaXMgaXNcbiAgLy8gYnkgZGVzaWduLCBub3QgZGVhZCBjb2RlIOKAlCBkbyBub3QgXCJmaXhcIiBieSB3aXJpbmcgYSBidW5kbGUgd2l0aG91dCBhIHByaWNpbmdcbiAgLy8gZGVjaXNpb24uIENvbnRyYXN0IGBhdWRpdF9sb2dgL2Bzc29gL2BhZHZhbmNlZF9yZXBvcnRpbmdgLCB3aGljaCBBUkUgc29sZCBhc1xuICAvLyBhZGQtb24gYnVuZGxlcyBhbmQgZ2F0ZWQgKHNlZSBiaWxsaW5nLWNvbmZpZyBgbG9hZEJ1bmRsZXNgICsgYHJlcXVpcmVGZWF0dXJlYCkuXG4gIHwgJ3ByaW9yaXR5X3N1cHBvcnQnXG4gIHwgJ2N1c3RvbV9pbnRlZ3JhdGlvbnMnXG4gIHwgJ2FpX2dlbmVyYXRpb24nXG4gIHwgJ2J1bGtfb3BlcmF0aW9ucydcbiAgfCAnYXVkaXRfbG9nJ1xuICB8ICdzc28nXG4gIC8vIERPUkEgLyBhZHZhbmNlZCBkZWxpdmVyeSBhbmFseXRpY3MgKHBhaWQgdGllcnMgb25seSkuXG4gIHwgJ2FkdmFuY2VkX3JlcG9ydGluZydcbiAgLy8gUGVyLXRlYW0gdXNhZ2UgYnJlYWtkb3duIGFjcm9zcyB0aGUgb3Jn4oaSdGVhbSBzdWJ0cmVlLiBJTkNMVURFRCBpbiBFbnRlcnByaXNlO1xuICAvLyBzb2xkIGFzIGFuIGFkZC1vbiBidW5kbGUgdG8gUHJvL1RlYW0gKHNlZSBiaWxsaW5nLWNvbmZpZyBgdGVhbV91c2FnZV9hbmFseXRpY3NgKS5cbiAgfCAndGVhbV91c2FnZV9hbmFseXRpY3MnXG4gIC8vIEN1cmF0ZWQgY29tcGxpYW5jZSBydWxlIGxpYnJhcmllcyBzb2xkIGFzIGFkZC1vbiBidW5kbGVzLiBgY29tcGxpYW5jZV9zdGFuZGFyZGBcbiAgLy8gPSBDSS9DRCBiZXN0LXByYWN0aWNlIHNldDsgYGNvbXBsaWFuY2VfYWR2YW5jZWRgID0gU09DMi9QQ0kvQ0lTIGZyYW1ld29ya1xuICAvLyBsaWJyYXJpZXMgKHJlcXVpcmVzIFN0YW5kYXJkKS4gVGhlc2UgZ2F0ZSBTVUJTQ1JJQklORyB0byB0aGUgc2V0J3Mgc3lzdGVtLW9yZ1xuICAvLyBwdWJsaXNoZWQgcnVsZXM7IElOQ0xVREVEIGluIEVudGVycHJpc2UvVW5saW1pdGVkICh2aWEgQUxMX0ZFQVRVUkVfRkxBR1MpLFxuICAvLyBzb2xkIHRvIERldmVsb3Blci9Qcm8vVGVhbSAoc2VlIGJpbGxpbmctY29uZmlnIGBjb21wbGlhbmNlX3N0YW5kYXJkL2FkdmFuY2VkYCkuXG4gIHwgJ2NvbXBsaWFuY2Vfc3RhbmRhcmQnXG4gIHwgJ2NvbXBsaWFuY2VfYWR2YW5jZWQnO1xuXG4vKiogQWxsIHZhbGlkIGZlYXR1cmUgZmxhZ3MgKG9yZGVyIGRldGVybWluZXMgZGlzcGxheSBvcmRlcikuICovXG5leHBvcnQgY29uc3QgQUxMX0ZFQVRVUkVfRkxBR1M6IHJlYWRvbmx5IEZlYXR1cmVGbGFnW10gPSBbXG4gICdwcmlvcml0eV9zdXBwb3J0JyxcbiAgJ2FpX2dlbmVyYXRpb24nLFxuICAnYnVsa19vcGVyYXRpb25zJyxcbiAgJ2N1c3RvbV9pbnRlZ3JhdGlvbnMnLFxuICAnYXVkaXRfbG9nJyxcbiAgJ3NzbycsXG4gICdhZHZhbmNlZF9yZXBvcnRpbmcnLFxuICAndGVhbV91c2FnZV9hbmFseXRpY3MnLFxuICAnY29tcGxpYW5jZV9zdGFuZGFyZCcsXG4gICdjb21wbGlhbmNlX2FkdmFuY2VkJyxcbl07XG5cbi8qKiBDaGVjayB3aGV0aGVyIGEgc3RyaW5nIGlzIGEgdmFsaWQgRmVhdHVyZUZsYWcuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEZlYXR1cmVGbGFnKHZhbHVlOiBzdHJpbmcpOiB2YWx1ZSBpcyBGZWF0dXJlRmxhZyB7XG4gIHJldHVybiAoQUxMX0ZFQVRVUkVfRkxBR1MgYXMgcmVhZG9ubHkgc3RyaW5nW10pLmluY2x1ZGVzKHZhbHVlKTtcbn1cblxuLy8gVGllci10by1mZWF0dXJlIG1hcHBpbmdcblxuLyoqIEZlYXR1cmVzIGVuYWJsZWQgYnkgZGVmYXVsdCBmb3IgZWFjaCB0aWVyLiAqL1xuZXhwb3J0IGNvbnN0IFRJRVJfRkVBVFVSRVM6IFJlY29yZDxRdW90YVRpZXIsIHJlYWRvbmx5IEZlYXR1cmVGbGFnW10+ID0ge1xuICBkZXZlbG9wZXI6IFtdLFxuICBwcm86IFsncHJpb3JpdHlfc3VwcG9ydCcsICdhaV9nZW5lcmF0aW9uJywgJ2J1bGtfb3BlcmF0aW9ucyddLFxuICAvLyBUZWFtIGFkZHMgYXVkaXRfbG9nIChjb2xsYWJvcmF0aW9uL2dvdmVybmFuY2UpIGFuZCBzc28gKFNTTy9JZFAgaXMgSU5DTFVERURcbiAgLy8gaW4gVGVhbSwgbm90IGFuIGFkZC1vbikuIGFkdmFuY2VkX3JlcG9ydGluZyAoRE9SQSkgaXMgTk9UIGEgVGVhbSB0aWVyIGZlYXR1cmUg4oCUXG4gIC8vIGl0J3MgSU5DTFVERUQgb25seSBpbiBFbnRlcnByaXNlIGFuZCBzb2xkIGFzIGFuIGFkZC1vbiBidW5kbGUgdG8gZXZlcnkgb3RoZXJcbiAgLy8gdGllciAoc2VlIGJpbGxpbmctY29uZmlnIGBhZHZhbmNlZF9yZXBvcnRpbmdgKS4gRW50ZXJwcmlzZSB1bmxvY2tzIGFsbC5cbiAgdGVhbTogWydwcmlvcml0eV9zdXBwb3J0JywgJ2FpX2dlbmVyYXRpb24nLCAnYnVsa19vcGVyYXRpb25zJywgJ2F1ZGl0X2xvZycsICdzc28nXSxcbiAgZW50ZXJwcmlzZTogWy4uLkFMTF9GRUFUVVJFX0ZMQUdTXSxcbiAgLy8gVW5saW1pdGVkIGluY2x1ZGVzIGV2ZXJ5IGZlYXR1cmUgLyBhZGQtb24gYnVuZGxlIChiaWxsaW5nLWRpc2FibGVkIGRlZmF1bHQpLlxuICB1bmxpbWl0ZWQ6IFsuLi5BTExfRkVBVFVSRV9GTEFHU10sXG59O1xuXG4vLyBGZWF0dXJlIG1ldGFkYXRhIChmb3IgZGlzcGxheSlcblxuLyoqIEh1bWFuLXJlYWRhYmxlIG1ldGFkYXRhIGZvciBlYWNoIGZlYXR1cmUgZmxhZy4gKi9cbmV4cG9ydCBjb25zdCBGRUFUVVJFX01FVEFEQVRBOiBSZWNvcmQ8RmVhdHVyZUZsYWcsIHsgbGFiZWw6IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZyB9PiA9IHtcbiAgcHJpb3JpdHlfc3VwcG9ydDoge1xuICAgIGxhYmVsOiAnUHJpb3JpdHkgU3VwcG9ydCcsXG4gICAgZGVzY3JpcHRpb246ICdGYXN0ZXIgcmVzcG9uc2UgdGltZXMgYW5kIGRlZGljYXRlZCBzdXBwb3J0IGNoYW5uZWxzJyxcbiAgfSxcbiAgYWlfZ2VuZXJhdGlvbjoge1xuICAgIGxhYmVsOiAnQUkgR2VuZXJhdGlvbicsXG4gICAgZGVzY3JpcHRpb246ICdBSS1wb3dlcmVkIHBpcGVsaW5lIGFuZCBwbHVnaW4gZ2VuZXJhdGlvbicsXG4gIH0sXG4gIGJ1bGtfb3BlcmF0aW9uczoge1xuICAgIGxhYmVsOiAnQnVsayBPcGVyYXRpb25zJyxcbiAgICBkZXNjcmlwdGlvbjogJ0JhdGNoIGNyZWF0ZSwgdXBkYXRlLCBhbmQgZGVsZXRlIGZvciBwaXBlbGluZXMgYW5kIHBsdWdpbnMnLFxuICB9LFxuICBjdXN0b21faW50ZWdyYXRpb25zOiB7XG4gICAgbGFiZWw6ICdDdXN0b20gSW50ZWdyYXRpb25zJyxcbiAgICBkZXNjcmlwdGlvbjogJ0Nvbm5lY3QgdG8gZXh0ZXJuYWwgc2VydmljZXMgYW5kIGN1c3RvbSB3ZWJob29rIGVuZHBvaW50cycsXG4gIH0sXG4gIGF1ZGl0X2xvZzoge1xuICAgIGxhYmVsOiAnQXVkaXQgTG9nJyxcbiAgICBkZXNjcmlwdGlvbjogJ0RldGFpbGVkIGF1ZGl0IHRyYWlsIG9mIGFsbCB1c2VyIGFuZCBzeXN0ZW0gYWN0aW9ucycsXG4gIH0sXG4gIHNzbzoge1xuICAgIGxhYmVsOiAnU1NPIC8gSWRQJyxcbiAgICBkZXNjcmlwdGlvbjogJ1NpbmdsZSBzaWduLW9uIGFuZCBleHRlcm5hbCBpZGVudGl0eS1wcm92aWRlciBjb25maWd1cmF0aW9ucycsXG4gIH0sXG4gIGFkdmFuY2VkX3JlcG9ydGluZzoge1xuICAgIGxhYmVsOiAnQWR2YW5jZWQgUmVwb3J0aW5nJyxcbiAgICBkZXNjcmlwdGlvbjogJ0RPUkEgLyBhZHZhbmNlZCBkZWxpdmVyeSBhbmFseXRpY3MnLFxuICB9LFxuICB0ZWFtX3VzYWdlX2FuYWx5dGljczoge1xuICAgIGxhYmVsOiAnVGVhbSBVc2FnZSBBbmFseXRpY3MnLFxuICAgIGRlc2NyaXB0aW9uOiAnUGVyLXRlYW0gdXNhZ2UgYnJlYWtkb3duIGFjcm9zcyB0aGUgb3JnIOKGkiB0ZWFtIHN1YnRyZWUnLFxuICB9LFxuICBjb21wbGlhbmNlX3N0YW5kYXJkOiB7XG4gICAgbGFiZWw6ICdTdGFuZGFyZCBDb21wbGlhbmNlJyxcbiAgICBkZXNjcmlwdGlvbjogJ0N1cmF0ZWQgQ0kvQ0QgYmVzdC1wcmFjdGljZSBjb21wbGlhbmNlIHJ1bGUgbGlicmFyeScsXG4gIH0sXG4gIGNvbXBsaWFuY2VfYWR2YW5jZWQ6IHtcbiAgICBsYWJlbDogJ0FkdmFuY2VkIENvbXBsaWFuY2UnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ3VyYXRlZCBmcmFtZXdvcmsgY29tcGxpYW5jZSBsaWJyYXJpZXMgKFNPQzIgLyBQQ0ktRFNTIC8gQ0lTKScsXG4gIH0sXG59O1xuXG4vLyBSZXNvbHV0aW9uIGxvZ2ljXG5cbi8qKlxuICogUmVzb2x2ZSBhIHVzZXIncyBlZmZlY3RpdmUgZmVhdHVyZSBzZXQuXG4gKlxuICogMS4gU3lzYWRtaW5zIChpc1N1cGVyQWRtaW4pIGFsd2F5cyBnZXQgQUxMIGZlYXR1cmVzLlxuICogMi4gU3RhcnQgd2l0aCB0aGUgdGllcidzIGRlZmF1bHQgZmVhdHVyZXMuXG4gKiAzLiBBcHBseSBwZXItdXNlciBvdmVycmlkZXM6IGB0cnVlYCBhZGRzIGEgZmVhdHVyZSwgYGZhbHNlYCByZW1vdmVzIGl0LlxuICogNC4gSW52YWxpZCBvdmVycmlkZSBrZXlzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICpcbiAqIEBwYXJhbSB0aWVyIC0gVGhlIG9yZ2FuaXphdGlvbidzIHF1b3RhIHRpZXJcbiAqIEBwYXJhbSBvcHRzIC0gUmVzb2x1dGlvbiBvcHRpb25zOlxuICogICAtIGBvdmVycmlkZXNgOiBwZXItdXNlciBvdmVycmlkZXMgKGtleSA9IGZlYXR1cmUgZmxhZywgdmFsdWUgPSBlbmFibGVkKVxuICogICAtIGBpc1N1cGVyQWRtaW5gOiB3aGV0aGVyIHRoZSB1c2VyIGhhcyB0aGUgZ2xvYmFsIHN1cGVyLWFkbWluIGZsYWdcbiAqICAgLSBgYWNjb3VudEZlYXR1cmVzYDogYWNjb3VudC1sZXZlbCBlbnRpdGxlbWVudHMgKGUuZy4gcHVyY2hhc2VkIGFkZC1vblxuICogICAgIGJ1bmRsZXMpLiBBIE5BTUVEIGZpZWxkIHNvIGl0IGNhbiBuZXZlciBiZSBzaWxlbnRseSBkcm9wcGVkIGJ5IGEgY2FsbGVyXG4gKiAgICAgdGhhdCBvbWl0cyBhIHRyYWlsaW5nIHBvc2l0aW9uYWwgYXJnLlxuICogQHJldHVybnMgU29ydGVkIGFycmF5IG9mIGVuYWJsZWQgZmVhdHVyZSBmbGFnc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVVzZXJGZWF0dXJlcyhcbiAgdGllcjogUXVvdGFUaWVyLFxuICBvcHRzPzoge1xuICAgIG92ZXJyaWRlcz86IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+IHwgbnVsbDtcbiAgICBpc1N1cGVyQWRtaW4/OiBib29sZWFuO1xuICAgIGFjY291bnRGZWF0dXJlcz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbDtcbiAgfSxcbik6IEZlYXR1cmVGbGFnW10ge1xuICBjb25zdCB7IG92ZXJyaWRlczogZmVhdHVyZU92ZXJyaWRlcywgaXNTdXBlckFkbWluLCBhY2NvdW50RmVhdHVyZXMgfSA9IG9wdHMgPz8ge307XG5cbiAgLy8gU3lzYWRtaW5zIGdldCBldmVyeXRoaW5nIHJlZ2FyZGxlc3Mgb2YgdGllci5cbiAgaWYgKGlzU3VwZXJBZG1pbikgcmV0dXJuIFsuLi5BTExfRkVBVFVSRV9GTEFHU107XG5cbiAgLy8gU3RhcnQgd2l0aCB0aWVyIGRlZmF1bHRzXG4gIGNvbnN0IGZlYXR1cmVzID0gbmV3IFNldDxGZWF0dXJlRmxhZz4oVElFUl9GRUFUVVJFU1t0aWVyXSA/PyBbXSk7XG5cbiAgLy8gQWNjb3VudC1sZXZlbCBlbnRpdGxlbWVudHMgKHB1cmNoYXNlZCBmZWF0dXJlIGJ1bmRsZXMg4oCUIGUuZy4gYXVkaXRfbG9nLCBzc28sXG4gIC8vIGFkdmFuY2VkX3JlcG9ydGluZywgdGVhbV91c2FnZV9hbmFseXRpY3MsIGNvbXBsaWFuY2Vfc3RhbmRhcmQvYWR2YW5jZWQpLlxuICAvLyBBcHBsaWVkIGJlZm9yZSBwZXItdXNlciBvdmVycmlkZXMgc28gYW4gZXhwbGljaXQgdXNlciBvdmVycmlkZSBzdGlsbCB3aW5zLlxuICBpZiAoYWNjb3VudEZlYXR1cmVzKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudEZlYXR1cmVzKSB7XG4gICAgICBpZiAoaXNWYWxpZEZlYXR1cmVGbGFnKGtleSkpIGZlYXR1cmVzLmFkZChrZXkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFwcGx5IHBlci11c2VyIG92ZXJyaWRlc1xuICBpZiAoZmVhdHVyZU92ZXJyaWRlcykge1xuICAgIGZvciAoY29uc3QgW2tleSwgZW5hYmxlZF0gb2YgT2JqZWN0LmVudHJpZXMoZmVhdHVyZU92ZXJyaWRlcykpIHtcbiAgICAgIGlmICghaXNWYWxpZEZlYXR1cmVGbGFnKGtleSkpIGNvbnRpbnVlO1xuICAgICAgaWYgKGVuYWJsZWQpIHtcbiAgICAgICAgZmVhdHVyZXMuYWRkKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmZWF0dXJlcy5kZWxldGUoa2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm4gaW4gY2Fub25pY2FsIG9yZGVyXG4gIHJldHVybiBBTExfRkVBVFVSRV9GTEFHUy5maWx0ZXIoZiA9PiBmZWF0dXJlcy5oYXMoZikpO1xufVxuIl19
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Generic HTTP headers representation.
3
+ */
4
+ export interface HttpHeaders {
5
+ [key: string]: string | string[] | undefined;
6
+ }
7
+ /**
8
+ * Generic HTTP request interface.
9
+ * Represents the minimal request shape needed by api-core utilities.
10
+ */
11
+ export interface HttpRequest {
12
+ /** Request headers */
13
+ headers: HttpHeaders;
14
+ /** Route parameters */
15
+ params: Record<string, string | string[] | undefined>;
16
+ /** Query parameters */
17
+ query: Record<string, unknown>;
18
+ /** Authenticated user (if present). `sub` is the OIDC-standard subject
19
+ * (= user id); higher-level layers may attach additional fields, hence
20
+ * the index signature. */
21
+ user?: {
22
+ sub?: string;
23
+ organizationId?: string;
24
+ role?: string;
25
+ [key: string]: unknown;
26
+ };
27
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export {};
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBHZW5lcmljIEhUVFAgaGVhZGVycyByZXByZXNlbnRhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwSGVhZGVycyB7XG4gIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgSFRUUCByZXF1ZXN0IGludGVyZmFjZS5cbiAqIFJlcHJlc2VudHMgdGhlIG1pbmltYWwgcmVxdWVzdCBzaGFwZSBuZWVkZWQgYnkgYXBpLWNvcmUgdXRpbGl0aWVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBSZXF1ZXN0IHtcbiAgLyoqIFJlcXVlc3QgaGVhZGVycyAqL1xuICBoZWFkZXJzOiBIdHRwSGVhZGVycztcbiAgLyoqIFJvdXRlIHBhcmFtZXRlcnMgKi9cbiAgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZD47XG4gIC8qKiBRdWVyeSBwYXJhbWV0ZXJzICovXG4gIHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgLyoqIEF1dGhlbnRpY2F0ZWQgdXNlciAoaWYgcHJlc2VudCkuIGBzdWJgIGlzIHRoZSBPSURDLXN0YW5kYXJkIHN1YmplY3RcbiAgICogICg9IHVzZXIgaWQpOyBoaWdoZXItbGV2ZWwgbGF5ZXJzIG1heSBhdHRhY2ggYWRkaXRpb25hbCBmaWVsZHMsIGhlbmNlXG4gICAqICB0aGUgaW5kZXggc2lnbmF0dXJlLiAqL1xuICB1c2VyPzoge1xuICAgIHN1Yj86IHN0cmluZztcbiAgICBvcmdhbml6YXRpb25JZD86IHN0cmluZztcbiAgICByb2xlPzogc3RyaW5nO1xuICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gIH07XG59XG5cbiJdfQ==
@@ -0,0 +1,11 @@
1
+ export * from './error-codes.js';
2
+ export * from './common.js';
3
+ export * from './pipeline.js';
4
+ export * from './catalog-metadata.js';
5
+ export * from './pipeline-template.js';
6
+ export * from './visibility.js';
7
+ export * from './http.js';
8
+ export * from './quota-tiers.js';
9
+ export * from './feature-flags.js';
10
+ export * from './permissions.js';
11
+ export * from './audit-events.js';
@@ -0,0 +1,14 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export * from './error-codes.js';
4
+ export * from './common.js';
5
+ export * from './pipeline.js';
6
+ export * from './catalog-metadata.js';
7
+ export * from './pipeline-template.js';
8
+ export * from './visibility.js';
9
+ export * from './http.js';
10
+ export * from './quota-tiers.js';
11
+ export * from './feature-flags.js';
12
+ export * from './permissions.js';
13
+ export * from './audit-events.js';
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsbUJBQW1CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuZXhwb3J0ICogZnJvbSAnLi9lcnJvci1jb2Rlcy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2NvbW1vbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY2F0YWxvZy1tZXRhZGF0YS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lLXRlbXBsYXRlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdmlzaWJpbGl0eS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2h0dHAuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9xdW90YS10aWVycy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2ZlYXR1cmUtZmxhZ3MuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9wZXJtaXNzaW9ucy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2F1ZGl0LWV2ZW50cy5qcyc7XG4iXX0=
@@ -0,0 +1,65 @@
1
+ import type { OrgRole } from './common.js';
2
+ /**
3
+ * Canonical fine-grained permission identifiers, in `resource:action` form.
4
+ *
5
+ * These are the ORG-SCOPED capabilities a Role can grant (RBAC). Coarse by
6
+ * design — `:write` covers create/update/delete for a resource — so the catalog
7
+ * and permission-picker UI stay small; split a `:write` into `:create`/`:delete`
8
+ * later if a resource needs it.
9
+ *
10
+ * NOT modeled here (intentionally): platform-operator actions (org delete, tier/
11
+ * quota override, user admin, impersonation, platform settings) stay behind the
12
+ * global `isSuperAdmin` flag, not a per-org permission; and `requireStepUp`
13
+ * (MFA) / `requireFeature` (plan entitlements) remain orthogonal gates.
14
+ */
15
+ export type Permission = 'pipelines:read' | 'pipelines:write' | 'pipelines:publish' | 'templates:read' | 'templates:write' | 'templates:publish' | 'plugins:read' | 'plugins:write' | 'plugins:publish' | 'compliance:read' | 'compliance:write' | 'members:manage' | 'roles:manage' | 'invitations:manage' | 'dashboards:read' | 'dashboards:write' | 'observability:read' | 'observability:write' | 'reports:read' | 'reports:rollup' | 'messages:read' | 'messages:write' | 'billing:read' | 'billing:manage' | 'quotas:read' | 'registry:read' | 'registry:write' | 'org:settings' | 'org:idp' | 'org:kms';
16
+ /** All valid permissions (order determines display order in the picker). */
17
+ export declare const ALL_PERMISSIONS: readonly Permission[];
18
+ /** Check whether a string is a valid Permission. */
19
+ export declare function isValidPermission(value: string): value is Permission;
20
+ /**
21
+ * Permissions that must NEVER be grantable through a user-authored CUSTOM Role —
22
+ * they gate platform-operator surfaces (the shared image registry), so allowing
23
+ * an org admin to mint a Role carrying them would be a latent privilege
24
+ * escalation. They are NOT seeded into ANY built-in Role bundle (neither
25
+ * `member` nor `admin`), so the only holder is a superadmin (implicit-all) —
26
+ * which is what makes the image-registry gates that require them effectively
27
+ * superadmin-only. This list ALSO blocks custom-Role authoring from requesting
28
+ * them (see platform `sanitizePermissions`).
29
+ */
30
+ export declare const SUPERADMIN_ONLY_PERMISSIONS: readonly Permission[];
31
+ /**
32
+ * Permissions an org may assign via a CUSTOM Role — every permission except the
33
+ * {@link SUPERADMIN_ONLY_PERMISSIONS}. Custom-Role create/update validates the
34
+ * requested permission set against this (see platform roles-service).
35
+ */
36
+ export declare const ORG_ASSIGNABLE_PERMISSIONS: readonly Permission[];
37
+ /** Whether `permission` may be granted through a user-authored custom Role. */
38
+ export declare function isOrgAssignablePermission(permission: Permission): boolean;
39
+ /**
40
+ * Seed bundle for each built-in Role, keyed by the coarse role it grants.
41
+ * Consumed by the Role seeder + the startup backfill to populate a built-in
42
+ * Role's `permissions[]`. NOT consulted at request time — see
43
+ * {@link resolveUserPermissions}.
44
+ */
45
+ export declare const ROLE_PERMISSIONS: Record<OrgRole, readonly Permission[]>;
46
+ /**
47
+ * Resolve a user's effective org permissions from the Roles assigned to them.
48
+ *
49
+ * Single-source model: a user's abilities are EXACTLY the union of the
50
+ * permissions carried by the Roles they hold (a Role = a named permission set;
51
+ * built-in Roles carry their bundle explicitly, seeded from
52
+ * {@link ROLE_PERMISSIONS}). There is no separate role-derived baseline — the
53
+ * coarse `role` label no longer grants anything on its own.
54
+ *
55
+ * 1. Platform superadmins (`isSuperAdmin`) always get ALL permissions.
56
+ * 2. Otherwise, union every permission granted by the user's assigned Roles.
57
+ * 3. Invalid/unknown permission strings are silently ignored.
58
+ *
59
+ * @param assignedPermissions - Flattened permissions from every Role the user holds
60
+ * @param isSuperAdmin - Whether the user has the global super-admin flag
61
+ * @returns Effective permissions in canonical order
62
+ */
63
+ export declare function resolveUserPermissions(assignedPermissions?: readonly string[] | null, isSuperAdmin?: boolean): Permission[];
64
+ /** Whether a resolved permission list grants `permission` (superadmin ⇒ always). */
65
+ export declare function hasPermission(granted: readonly string[] | null | undefined, permission: Permission, isSuperAdmin?: boolean): boolean;
@@ -0,0 +1,131 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /** All valid permissions (order determines display order in the picker). */
4
+ export const ALL_PERMISSIONS = [
5
+ 'pipelines:read', 'pipelines:write', 'pipelines:publish',
6
+ 'templates:read', 'templates:write', 'templates:publish',
7
+ 'plugins:read', 'plugins:write', 'plugins:publish',
8
+ 'compliance:read', 'compliance:write',
9
+ 'members:manage', 'roles:manage', 'invitations:manage',
10
+ 'dashboards:read', 'dashboards:write',
11
+ 'observability:read', 'observability:write',
12
+ 'reports:read', 'reports:rollup',
13
+ 'messages:read', 'messages:write',
14
+ 'billing:read', 'billing:manage',
15
+ 'quotas:read',
16
+ 'registry:read', 'registry:write',
17
+ 'org:settings', 'org:idp', 'org:kms',
18
+ ];
19
+ /** Check whether a string is a valid Permission. */
20
+ export function isValidPermission(value) {
21
+ return ALL_PERMISSIONS.includes(value);
22
+ }
23
+ /**
24
+ * Permissions that must NEVER be grantable through a user-authored CUSTOM Role —
25
+ * they gate platform-operator surfaces (the shared image registry), so allowing
26
+ * an org admin to mint a Role carrying them would be a latent privilege
27
+ * escalation. They are NOT seeded into ANY built-in Role bundle (neither
28
+ * `member` nor `admin`), so the only holder is a superadmin (implicit-all) —
29
+ * which is what makes the image-registry gates that require them effectively
30
+ * superadmin-only. This list ALSO blocks custom-Role authoring from requesting
31
+ * them (see platform `sanitizePermissions`).
32
+ */
33
+ export const SUPERADMIN_ONLY_PERMISSIONS = [
34
+ 'registry:read',
35
+ 'registry:write',
36
+ ];
37
+ /**
38
+ * Permissions an org may assign via a CUSTOM Role — every permission except the
39
+ * {@link SUPERADMIN_ONLY_PERMISSIONS}. Custom-Role create/update validates the
40
+ * requested permission set against this (see platform roles-service).
41
+ */
42
+ export const ORG_ASSIGNABLE_PERMISSIONS = ALL_PERMISSIONS.filter((p) => !SUPERADMIN_ONLY_PERMISSIONS.includes(p));
43
+ /** Whether `permission` may be granted through a user-authored custom Role. */
44
+ export function isOrgAssignablePermission(permission) {
45
+ return !SUPERADMIN_ONLY_PERMISSIONS.includes(permission);
46
+ }
47
+ // =============================================================================
48
+ // Built-in Role seed bundles
49
+ // =============================================================================
50
+ /**
51
+ * Permission bundles used to SEED the built-in Roles ("Admin", "Member").
52
+ *
53
+ * This is the single definition of what those built-in Roles grant — it is used
54
+ * when a Role record is created (and by the startup backfill) to populate that
55
+ * Role's own `permissions[]`. It is NOT a runtime permission source: a user's
56
+ * effective permissions come ONLY from the Roles assigned to them (see
57
+ * {@link resolveUserPermissions}). The coarse `role` label (owner/admin/member)
58
+ * survives only for `isAdmin`/ownership/display, never to grant permissions.
59
+ *
60
+ * - `member` — day-to-day builder: read + write on pipelines/templates/plugins,
61
+ * read elsewhere. No member/role/billing management, no compliance/alert
62
+ * authoring, and no `:publish` on any catalog.
63
+ * - `admin` — full org administration: every ORG-ASSIGNABLE permission (i.e.
64
+ * ALL_PERMISSIONS minus the {@link SUPERADMIN_ONLY_PERMISSIONS}, so `registry:*`
65
+ * stay superadmin-implicit-only and are NOT granted to org admins).
66
+ * - `owner` — same as admin (ownership itself — transfer/delete — is gated
67
+ * separately, not via a permission).
68
+ */
69
+ const MEMBER_PERMISSIONS = [
70
+ 'pipelines:read', 'pipelines:write',
71
+ 'templates:read', 'templates:write',
72
+ 'plugins:read', 'plugins:write',
73
+ 'compliance:read',
74
+ 'dashboards:read',
75
+ 'observability:read',
76
+ 'reports:read',
77
+ 'messages:read', 'messages:write',
78
+ 'billing:read',
79
+ 'quotas:read',
80
+ ];
81
+ const ADMIN_PERMISSIONS = [...ORG_ASSIGNABLE_PERMISSIONS];
82
+ /**
83
+ * Seed bundle for each built-in Role, keyed by the coarse role it grants.
84
+ * Consumed by the Role seeder + the startup backfill to populate a built-in
85
+ * Role's `permissions[]`. NOT consulted at request time — see
86
+ * {@link resolveUserPermissions}.
87
+ */
88
+ export const ROLE_PERMISSIONS = {
89
+ member: MEMBER_PERMISSIONS,
90
+ admin: ADMIN_PERMISSIONS,
91
+ owner: ADMIN_PERMISSIONS,
92
+ };
93
+ // =============================================================================
94
+ // Resolution
95
+ // =============================================================================
96
+ /**
97
+ * Resolve a user's effective org permissions from the Roles assigned to them.
98
+ *
99
+ * Single-source model: a user's abilities are EXACTLY the union of the
100
+ * permissions carried by the Roles they hold (a Role = a named permission set;
101
+ * built-in Roles carry their bundle explicitly, seeded from
102
+ * {@link ROLE_PERMISSIONS}). There is no separate role-derived baseline — the
103
+ * coarse `role` label no longer grants anything on its own.
104
+ *
105
+ * 1. Platform superadmins (`isSuperAdmin`) always get ALL permissions.
106
+ * 2. Otherwise, union every permission granted by the user's assigned Roles.
107
+ * 3. Invalid/unknown permission strings are silently ignored.
108
+ *
109
+ * @param assignedPermissions - Flattened permissions from every Role the user holds
110
+ * @param isSuperAdmin - Whether the user has the global super-admin flag
111
+ * @returns Effective permissions in canonical order
112
+ */
113
+ export function resolveUserPermissions(assignedPermissions, isSuperAdmin) {
114
+ if (isSuperAdmin)
115
+ return [...ALL_PERMISSIONS];
116
+ const perms = new Set();
117
+ if (assignedPermissions) {
118
+ for (const p of assignedPermissions) {
119
+ if (isValidPermission(p))
120
+ perms.add(p);
121
+ }
122
+ }
123
+ return ALL_PERMISSIONS.filter(p => perms.has(p));
124
+ }
125
+ /** Whether a resolved permission list grants `permission` (superadmin ⇒ always). */
126
+ export function hasPermission(granted, permission, isSuperAdmin) {
127
+ if (isSuperAdmin)
128
+ return true;
129
+ return !!granted && granted.includes(permission);
130
+ }
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGVybWlzc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQTJFdEMsNEVBQTRFO0FBQzVFLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBMEI7SUFDcEQsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CO0lBQ3hELGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQjtJQUN4RCxjQUFjLEVBQUUsZUFBZSxFQUFFLGlCQUFpQjtJQUNsRCxpQkFBaUIsRUFBRSxrQkFBa0I7SUFDckMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLG9CQUFvQjtJQUN0RCxpQkFBaUIsRUFBRSxrQkFBa0I7SUFDckMsb0JBQW9CLEVBQUUscUJBQXFCO0lBQzNDLGNBQWMsRUFBRSxnQkFBZ0I7SUFDaEMsZUFBZSxFQUFFLGdCQUFnQjtJQUNqQyxjQUFjLEVBQUUsZ0JBQWdCO0lBQ2hDLGFBQWE7SUFDYixlQUFlLEVBQUUsZ0JBQWdCO0lBQ2pDLGNBQWMsRUFBRSxTQUFTLEVBQUUsU0FBUztDQUNyQyxDQUFDO0FBRUYsb0RBQW9EO0FBQ3BELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxLQUFhO0lBQzdDLE9BQVEsZUFBcUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUEwQjtJQUNoRSxlQUFlO0lBQ2YsZ0JBQWdCO0NBQ2pCLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQ3JDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsMkJBQTJCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFMUUsK0VBQStFO0FBQy9FLE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxVQUFzQjtJQUM5RCxPQUFPLENBQUMsMkJBQTJCLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsNkJBQTZCO0FBQzdCLGdGQUFnRjtBQUVoRjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBMEI7SUFDaEQsZ0JBQWdCLEVBQUUsaUJBQWlCO0lBQ25DLGdCQUFnQixFQUFFLGlCQUFpQjtJQUNuQyxjQUFjLEVBQUUsZUFBZTtJQUMvQixpQkFBaUI7SUFDakIsaUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixjQUFjO0lBQ2QsZUFBZSxFQUFFLGdCQUFnQjtJQUNqQyxjQUFjO0lBQ2QsYUFBYTtDQUNkLENBQUM7QUFFRixNQUFNLGlCQUFpQixHQUEwQixDQUFDLEdBQUcsMEJBQTBCLENBQUMsQ0FBQztBQUVqRjs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUEyQztJQUN0RSxNQUFNLEVBQUUsa0JBQWtCO0lBQzFCLEtBQUssRUFBRSxpQkFBaUI7SUFDeEIsS0FBSyxFQUFFLGlCQUFpQjtDQUN6QixDQUFDO0FBRUYsZ0ZBQWdGO0FBQ2hGLGFBQWE7QUFDYixnRkFBZ0Y7QUFFaEY7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQ3BDLG1CQUE4QyxFQUM5QyxZQUFzQjtJQUV0QixJQUFJLFlBQVk7UUFBRSxPQUFPLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQztJQUU5QyxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBYyxDQUFDO0lBQ3BDLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUN4QixLQUFLLE1BQU0sQ0FBQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7WUFDcEMsSUFBSSxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7Z0JBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsb0ZBQW9GO0FBQ3BGLE1BQU0sVUFBVSxhQUFhLENBQzNCLE9BQTZDLEVBQzdDLFVBQXNCLEVBQ3RCLFlBQXNCO0lBRXRCLElBQUksWUFBWTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBPcmdSb2xlIH0gZnJvbSAnLi9jb21tb24uanMnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUGVybWlzc2lvbiBpZGVudGlmaWVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYW5vbmljYWwgZmluZS1ncmFpbmVkIHBlcm1pc3Npb24gaWRlbnRpZmllcnMsIGluIGByZXNvdXJjZTphY3Rpb25gIGZvcm0uXG4gKlxuICogVGhlc2UgYXJlIHRoZSBPUkctU0NPUEVEIGNhcGFiaWxpdGllcyBhIFJvbGUgY2FuIGdyYW50IChSQkFDKS4gQ29hcnNlIGJ5XG4gKiBkZXNpZ24g4oCUIGA6d3JpdGVgIGNvdmVycyBjcmVhdGUvdXBkYXRlL2RlbGV0ZSBmb3IgYSByZXNvdXJjZSDigJQgc28gdGhlIGNhdGFsb2dcbiAqIGFuZCBwZXJtaXNzaW9uLXBpY2tlciBVSSBzdGF5IHNtYWxsOyBzcGxpdCBhIGA6d3JpdGVgIGludG8gYDpjcmVhdGVgL2A6ZGVsZXRlYFxuICogbGF0ZXIgaWYgYSByZXNvdXJjZSBuZWVkcyBpdC5cbiAqXG4gKiBOT1QgbW9kZWxlZCBoZXJlIChpbnRlbnRpb25hbGx5KTogcGxhdGZvcm0tb3BlcmF0b3IgYWN0aW9ucyAob3JnIGRlbGV0ZSwgdGllci9cbiAqIHF1b3RhIG92ZXJyaWRlLCB1c2VyIGFkbWluLCBpbXBlcnNvbmF0aW9uLCBwbGF0Zm9ybSBzZXR0aW5ncykgc3RheSBiZWhpbmQgdGhlXG4gKiBnbG9iYWwgYGlzU3VwZXJBZG1pbmAgZmxhZywgbm90IGEgcGVyLW9yZyBwZXJtaXNzaW9uOyBhbmQgYHJlcXVpcmVTdGVwVXBgXG4gKiAoTUZBKSAvIGByZXF1aXJlRmVhdHVyZWAgKHBsYW4gZW50aXRsZW1lbnRzKSByZW1haW4gb3J0aG9nb25hbCBnYXRlcy5cbiAqL1xuZXhwb3J0IHR5cGUgUGVybWlzc2lvbiA9XG4gIC8vIFBpcGVsaW5lc1xuICB8ICdwaXBlbGluZXM6cmVhZCdcbiAgfCAncGlwZWxpbmVzOndyaXRlJ1xuICB8ICdwaXBlbGluZXM6cHVibGlzaCdcbiAgLy8gR29sZGVuLXBhdGggcGlwZWxpbmUgdGVtcGxhdGVzLiBTcGxpdCBvdXQgb2YgYHBpcGVsaW5lczoqYCBzbyBhIHBsYXRmb3JtXG4gIC8vIHRlYW0gY2FuIGN1cmF0ZSB0aGUgc3RhcnRlciBjYXRhbG9nIFdJVEhPVVQgd3JpdGUgYWNjZXNzIHRvIGV2ZXJ5IHBpcGVsaW5lXG4gIC8vIChhbmQgdmljZSB2ZXJzYSkg4oCUIHRoZSB0d28gdXNlZCB0byBzaGFyZSBvbmUgZ2F0ZS4gYDpwdWJsaXNoYCBtYXBzIHRvIHRoZVxuICAvLyB0ZW1wbGF0ZSBsYWRkZXIncyBgcHVibGljYCBydW5nOyBgb3JnYCBhbmQgYHByaXZhdGVgIG5lZWQgb25seSBgOndyaXRlYC5cbiAgfCAndGVtcGxhdGVzOnJlYWQnXG4gIHwgJ3RlbXBsYXRlczp3cml0ZSdcbiAgfCAndGVtcGxhdGVzOnB1Ymxpc2gnXG4gIC8vIFBsdWdpbnNcbiAgfCAncGx1Z2luczpyZWFkJ1xuICB8ICdwbHVnaW5zOndyaXRlJ1xuICB8ICdwbHVnaW5zOnB1Ymxpc2gnXG4gIC8vIENvbXBsaWFuY2VcbiAgfCAnY29tcGxpYW5jZTpyZWFkJ1xuICB8ICdjb21wbGlhbmNlOndyaXRlJ1xuICAvLyBNZW1iZXJzICYgYWNjZXNzXG4gIHwgJ21lbWJlcnM6bWFuYWdlJ1xuICB8ICdyb2xlczptYW5hZ2UnXG4gIHwgJ2ludml0YXRpb25zOm1hbmFnZSdcbiAgLy8gT2JzZXJ2YWJpbGl0eVxuICB8ICdkYXNoYm9hcmRzOnJlYWQnXG4gIHwgJ2Rhc2hib2FyZHM6d3JpdGUnXG4gIHwgJ29ic2VydmFiaWxpdHk6cmVhZCdcbiAgfCAnb2JzZXJ2YWJpbGl0eTp3cml0ZSdcbiAgLy8gSW5zaWdodHNcbiAgfCAncmVwb3J0czpyZWFkJ1xuICB8ICdyZXBvcnRzOnJvbGx1cCdcbiAgLy8gTWVzc2FnaW5nXG4gIHwgJ21lc3NhZ2VzOnJlYWQnXG4gIHwgJ21lc3NhZ2VzOndyaXRlJ1xuICAvLyBCaWxsaW5nICYgcXVvdGFzXG4gIHwgJ2JpbGxpbmc6cmVhZCdcbiAgfCAnYmlsbGluZzptYW5hZ2UnXG4gIHwgJ3F1b3RhczpyZWFkJ1xuICAvLyBSZWdpc3RyeVxuICB8ICdyZWdpc3RyeTpyZWFkJ1xuICB8ICdyZWdpc3RyeTp3cml0ZSdcbiAgLy8gT3JnYW5pemF0aW9uIHNldHRpbmdzLlxuICAvLyAgLSBgb3JnOnNldHRpbmdzYCDigJQgZ2VuZXJhbCBvcmcgc2V0dGluZ3MgKyBBSSBjb25maWcuXG4gIC8vICAtIGBvcmc6aWRwYCAgICAgIOKAlCBTU08gLyBJZFAgY29uZmlndXJhdGlvbiAoc2Vuc2l0aXZlOiBjb250cm9scyBsb2dpbikuXG4gIC8vICAtIGBvcmc6a21zYCAgICAgIOKAlCBjdXN0b21lci1tYW5hZ2VkIEtNUyBrZXkgY29uZmlndXJhdGlvbiAoc2Vuc2l0aXZlOlxuICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzIGVuY3J5cHRpb24gb2Ygb3JnIGRhdGEpLlxuICAvLyBgb3JnOmlkcGAvYG9yZzprbXNgIHdlcmUgc3BsaXQgT1VUIG9mIGBvcmc6c2V0dGluZ3NgIHNvIGEgY3VzdG9tIHJvbGUgY2FuXG4gIC8vIGdyYW50IGdlbmVyYWwgc2V0dGluZ3MgV0lUSE9VVCB0aGUgdHdvIHNlbnNpdGl2ZSBzdXJmYWNlcy4gQm90aCByZW1haW5cbiAgLy8gb3JnLWFzc2lnbmFibGUgYW5kIGFyZSBzZWVkZWQgaW50byB0aGUgYWRtaW4vb3duZXIgYnVuZGxlcyAodmlhXG4gIC8vIE9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TKSBzbyBleGlzdGluZyBhZG1pbnMga2VlcCBmdWxsIGFjY2Vzcy5cbiAgfCAnb3JnOnNldHRpbmdzJ1xuICB8ICdvcmc6aWRwJ1xuICB8ICdvcmc6a21zJztcblxuLyoqIEFsbCB2YWxpZCBwZXJtaXNzaW9ucyAob3JkZXIgZGV0ZXJtaW5lcyBkaXNwbGF5IG9yZGVyIGluIHRoZSBwaWNrZXIpLiAqL1xuZXhwb3J0IGNvbnN0IEFMTF9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncGlwZWxpbmVzOnJlYWQnLCAncGlwZWxpbmVzOndyaXRlJywgJ3BpcGVsaW5lczpwdWJsaXNoJyxcbiAgJ3RlbXBsYXRlczpyZWFkJywgJ3RlbXBsYXRlczp3cml0ZScsICd0ZW1wbGF0ZXM6cHVibGlzaCcsXG4gICdwbHVnaW5zOnJlYWQnLCAncGx1Z2luczp3cml0ZScsICdwbHVnaW5zOnB1Ymxpc2gnLFxuICAnY29tcGxpYW5jZTpyZWFkJywgJ2NvbXBsaWFuY2U6d3JpdGUnLFxuICAnbWVtYmVyczptYW5hZ2UnLCAncm9sZXM6bWFuYWdlJywgJ2ludml0YXRpb25zOm1hbmFnZScsXG4gICdkYXNoYm9hcmRzOnJlYWQnLCAnZGFzaGJvYXJkczp3cml0ZScsXG4gICdvYnNlcnZhYmlsaXR5OnJlYWQnLCAnb2JzZXJ2YWJpbGl0eTp3cml0ZScsXG4gICdyZXBvcnRzOnJlYWQnLCAncmVwb3J0czpyb2xsdXAnLFxuICAnbWVzc2FnZXM6cmVhZCcsICdtZXNzYWdlczp3cml0ZScsXG4gICdiaWxsaW5nOnJlYWQnLCAnYmlsbGluZzptYW5hZ2UnLFxuICAncXVvdGFzOnJlYWQnLFxuICAncmVnaXN0cnk6cmVhZCcsICdyZWdpc3RyeTp3cml0ZScsXG4gICdvcmc6c2V0dGluZ3MnLCAnb3JnOmlkcCcsICdvcmc6a21zJyxcbl07XG5cbi8qKiBDaGVjayB3aGV0aGVyIGEgc3RyaW5nIGlzIGEgdmFsaWQgUGVybWlzc2lvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUGVybWlzc2lvbih2YWx1ZTogc3RyaW5nKTogdmFsdWUgaXMgUGVybWlzc2lvbiB7XG4gIHJldHVybiAoQUxMX1BFUk1JU1NJT05TIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyh2YWx1ZSk7XG59XG5cbi8qKlxuICogUGVybWlzc2lvbnMgdGhhdCBtdXN0IE5FVkVSIGJlIGdyYW50YWJsZSB0aHJvdWdoIGEgdXNlci1hdXRob3JlZCBDVVNUT00gUm9sZSDigJRcbiAqIHRoZXkgZ2F0ZSBwbGF0Zm9ybS1vcGVyYXRvciBzdXJmYWNlcyAodGhlIHNoYXJlZCBpbWFnZSByZWdpc3RyeSksIHNvIGFsbG93aW5nXG4gKiBhbiBvcmcgYWRtaW4gdG8gbWludCBhIFJvbGUgY2FycnlpbmcgdGhlbSB3b3VsZCBiZSBhIGxhdGVudCBwcml2aWxlZ2VcbiAqIGVzY2FsYXRpb24uIFRoZXkgYXJlIE5PVCBzZWVkZWQgaW50byBBTlkgYnVpbHQtaW4gUm9sZSBidW5kbGUgKG5laXRoZXJcbiAqIGBtZW1iZXJgIG5vciBgYWRtaW5gKSwgc28gdGhlIG9ubHkgaG9sZGVyIGlzIGEgc3VwZXJhZG1pbiAoaW1wbGljaXQtYWxsKSDigJRcbiAqIHdoaWNoIGlzIHdoYXQgbWFrZXMgdGhlIGltYWdlLXJlZ2lzdHJ5IGdhdGVzIHRoYXQgcmVxdWlyZSB0aGVtIGVmZmVjdGl2ZWx5XG4gKiBzdXBlcmFkbWluLW9ubHkuIFRoaXMgbGlzdCBBTFNPIGJsb2NrcyBjdXN0b20tUm9sZSBhdXRob3JpbmcgZnJvbSByZXF1ZXN0aW5nXG4gKiB0aGVtIChzZWUgcGxhdGZvcm0gYHNhbml0aXplUGVybWlzc2lvbnNgKS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncmVnaXN0cnk6cmVhZCcsXG4gICdyZWdpc3RyeTp3cml0ZScsXG5dO1xuXG4vKipcbiAqIFBlcm1pc3Npb25zIGFuIG9yZyBtYXkgYXNzaWduIHZpYSBhIENVU1RPTSBSb2xlIOKAlCBldmVyeSBwZXJtaXNzaW9uIGV4Y2VwdCB0aGVcbiAqIHtAbGluayBTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlN9LiBDdXN0b20tUm9sZSBjcmVhdGUvdXBkYXRlIHZhbGlkYXRlcyB0aGVcbiAqIHJlcXVlc3RlZCBwZXJtaXNzaW9uIHNldCBhZ2FpbnN0IHRoaXMgKHNlZSBwbGF0Zm9ybSByb2xlcy1zZXJ2aWNlKS5cbiAqL1xuZXhwb3J0IGNvbnN0IE9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TOiByZWFkb25seSBQZXJtaXNzaW9uW10gPVxuICBBTExfUEVSTUlTU0lPTlMuZmlsdGVyKChwKSA9PiAhU1VQRVJBRE1JTl9PTkxZX1BFUk1JU1NJT05TLmluY2x1ZGVzKHApKTtcblxuLyoqIFdoZXRoZXIgYHBlcm1pc3Npb25gIG1heSBiZSBncmFudGVkIHRocm91Z2ggYSB1c2VyLWF1dGhvcmVkIGN1c3RvbSBSb2xlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3JnQXNzaWduYWJsZVBlcm1pc3Npb24ocGVybWlzc2lvbjogUGVybWlzc2lvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gIVNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OUy5pbmNsdWRlcyhwZXJtaXNzaW9uKTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEJ1aWx0LWluIFJvbGUgc2VlZCBidW5kbGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFBlcm1pc3Npb24gYnVuZGxlcyB1c2VkIHRvIFNFRUQgdGhlIGJ1aWx0LWluIFJvbGVzIChcIkFkbWluXCIsIFwiTWVtYmVyXCIpLlxuICpcbiAqIFRoaXMgaXMgdGhlIHNpbmdsZSBkZWZpbml0aW9uIG9mIHdoYXQgdGhvc2UgYnVpbHQtaW4gUm9sZXMgZ3JhbnQg4oCUIGl0IGlzIHVzZWRcbiAqIHdoZW4gYSBSb2xlIHJlY29yZCBpcyBjcmVhdGVkIChhbmQgYnkgdGhlIHN0YXJ0dXAgYmFja2ZpbGwpIHRvIHBvcHVsYXRlIHRoYXRcbiAqIFJvbGUncyBvd24gYHBlcm1pc3Npb25zW11gLiBJdCBpcyBOT1QgYSBydW50aW1lIHBlcm1pc3Npb24gc291cmNlOiBhIHVzZXInc1xuICogZWZmZWN0aXZlIHBlcm1pc3Npb25zIGNvbWUgT05MWSBmcm9tIHRoZSBSb2xlcyBhc3NpZ25lZCB0byB0aGVtIChzZWVcbiAqIHtAbGluayByZXNvbHZlVXNlclBlcm1pc3Npb25zfSkuIFRoZSBjb2Fyc2UgYHJvbGVgIGxhYmVsIChvd25lci9hZG1pbi9tZW1iZXIpXG4gKiBzdXJ2aXZlcyBvbmx5IGZvciBgaXNBZG1pbmAvb3duZXJzaGlwL2Rpc3BsYXksIG5ldmVyIHRvIGdyYW50IHBlcm1pc3Npb25zLlxuICpcbiAqIC0gYG1lbWJlcmAgIOKAlCBkYXktdG8tZGF5IGJ1aWxkZXI6IHJlYWQgKyB3cml0ZSBvbiBwaXBlbGluZXMvdGVtcGxhdGVzL3BsdWdpbnMsXG4gKiAgIHJlYWQgZWxzZXdoZXJlLiBObyBtZW1iZXIvcm9sZS9iaWxsaW5nIG1hbmFnZW1lbnQsIG5vIGNvbXBsaWFuY2UvYWxlcnRcbiAqICAgYXV0aG9yaW5nLCBhbmQgbm8gYDpwdWJsaXNoYCBvbiBhbnkgY2F0YWxvZy5cbiAqIC0gYGFkbWluYCAgIOKAlCBmdWxsIG9yZyBhZG1pbmlzdHJhdGlvbjogZXZlcnkgT1JHLUFTU0lHTkFCTEUgcGVybWlzc2lvbiAoaS5lLlxuICogICBBTExfUEVSTUlTU0lPTlMgbWludXMgdGhlIHtAbGluayBTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlN9LCBzbyBgcmVnaXN0cnk6KmBcbiAqICAgc3RheSBzdXBlcmFkbWluLWltcGxpY2l0LW9ubHkgYW5kIGFyZSBOT1QgZ3JhbnRlZCB0byBvcmcgYWRtaW5zKS5cbiAqIC0gYG93bmVyYCAgIOKAlCBzYW1lIGFzIGFkbWluIChvd25lcnNoaXAgaXRzZWxmIOKAlCB0cmFuc2Zlci9kZWxldGUg4oCUIGlzIGdhdGVkXG4gKiAgIHNlcGFyYXRlbHksIG5vdCB2aWEgYSBwZXJtaXNzaW9uKS5cbiAqL1xuY29uc3QgTUVNQkVSX1BFUk1JU1NJT05TOiByZWFkb25seSBQZXJtaXNzaW9uW10gPSBbXG4gICdwaXBlbGluZXM6cmVhZCcsICdwaXBlbGluZXM6d3JpdGUnLFxuICAndGVtcGxhdGVzOnJlYWQnLCAndGVtcGxhdGVzOndyaXRlJyxcbiAgJ3BsdWdpbnM6cmVhZCcsICdwbHVnaW5zOndyaXRlJyxcbiAgJ2NvbXBsaWFuY2U6cmVhZCcsXG4gICdkYXNoYm9hcmRzOnJlYWQnLFxuICAnb2JzZXJ2YWJpbGl0eTpyZWFkJyxcbiAgJ3JlcG9ydHM6cmVhZCcsXG4gICdtZXNzYWdlczpyZWFkJywgJ21lc3NhZ2VzOndyaXRlJyxcbiAgJ2JpbGxpbmc6cmVhZCcsXG4gICdxdW90YXM6cmVhZCcsXG5dO1xuXG5jb25zdCBBRE1JTl9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gWy4uLk9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TXTtcblxuLyoqXG4gKiBTZWVkIGJ1bmRsZSBmb3IgZWFjaCBidWlsdC1pbiBSb2xlLCBrZXllZCBieSB0aGUgY29hcnNlIHJvbGUgaXQgZ3JhbnRzLlxuICogQ29uc3VtZWQgYnkgdGhlIFJvbGUgc2VlZGVyICsgdGhlIHN0YXJ0dXAgYmFja2ZpbGwgdG8gcG9wdWxhdGUgYSBidWlsdC1pblxuICogUm9sZSdzIGBwZXJtaXNzaW9uc1tdYC4gTk9UIGNvbnN1bHRlZCBhdCByZXF1ZXN0IHRpbWUg4oCUIHNlZVxuICoge0BsaW5rIHJlc29sdmVVc2VyUGVybWlzc2lvbnN9LlxuICovXG5leHBvcnQgY29uc3QgUk9MRV9QRVJNSVNTSU9OUzogUmVjb3JkPE9yZ1JvbGUsIHJlYWRvbmx5IFBlcm1pc3Npb25bXT4gPSB7XG4gIG1lbWJlcjogTUVNQkVSX1BFUk1JU1NJT05TLFxuICBhZG1pbjogQURNSU5fUEVSTUlTU0lPTlMsXG4gIG93bmVyOiBBRE1JTl9QRVJNSVNTSU9OUyxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBSZXNvbHV0aW9uXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFJlc29sdmUgYSB1c2VyJ3MgZWZmZWN0aXZlIG9yZyBwZXJtaXNzaW9ucyBmcm9tIHRoZSBSb2xlcyBhc3NpZ25lZCB0byB0aGVtLlxuICpcbiAqIFNpbmdsZS1zb3VyY2UgbW9kZWw6IGEgdXNlcidzIGFiaWxpdGllcyBhcmUgRVhBQ1RMWSB0aGUgdW5pb24gb2YgdGhlXG4gKiBwZXJtaXNzaW9ucyBjYXJyaWVkIGJ5IHRoZSBSb2xlcyB0aGV5IGhvbGQgKGEgUm9sZSA9IGEgbmFtZWQgcGVybWlzc2lvbiBzZXQ7XG4gKiBidWlsdC1pbiBSb2xlcyBjYXJyeSB0aGVpciBidW5kbGUgZXhwbGljaXRseSwgc2VlZGVkIGZyb21cbiAqIHtAbGluayBST0xFX1BFUk1JU1NJT05TfSkuIFRoZXJlIGlzIG5vIHNlcGFyYXRlIHJvbGUtZGVyaXZlZCBiYXNlbGluZSDigJQgdGhlXG4gKiBjb2Fyc2UgYHJvbGVgIGxhYmVsIG5vIGxvbmdlciBncmFudHMgYW55dGhpbmcgb24gaXRzIG93bi5cbiAqXG4gKiAxLiBQbGF0Zm9ybSBzdXBlcmFkbWlucyAoYGlzU3VwZXJBZG1pbmApIGFsd2F5cyBnZXQgQUxMIHBlcm1pc3Npb25zLlxuICogMi4gT3RoZXJ3aXNlLCB1bmlvbiBldmVyeSBwZXJtaXNzaW9uIGdyYW50ZWQgYnkgdGhlIHVzZXIncyBhc3NpZ25lZCBSb2xlcy5cbiAqIDMuIEludmFsaWQvdW5rbm93biBwZXJtaXNzaW9uIHN0cmluZ3MgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIGFzc2lnbmVkUGVybWlzc2lvbnMgLSBGbGF0dGVuZWQgcGVybWlzc2lvbnMgZnJvbSBldmVyeSBSb2xlIHRoZSB1c2VyIGhvbGRzXG4gKiBAcGFyYW0gaXNTdXBlckFkbWluIC0gV2hldGhlciB0aGUgdXNlciBoYXMgdGhlIGdsb2JhbCBzdXBlci1hZG1pbiBmbGFnXG4gKiBAcmV0dXJucyBFZmZlY3RpdmUgcGVybWlzc2lvbnMgaW4gY2Fub25pY2FsIG9yZGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlVXNlclBlcm1pc3Npb25zKFxuICBhc3NpZ25lZFBlcm1pc3Npb25zPzogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsLFxuICBpc1N1cGVyQWRtaW4/OiBib29sZWFuLFxuKTogUGVybWlzc2lvbltdIHtcbiAgaWYgKGlzU3VwZXJBZG1pbikgcmV0dXJuIFsuLi5BTExfUEVSTUlTU0lPTlNdO1xuXG4gIGNvbnN0IHBlcm1zID0gbmV3IFNldDxQZXJtaXNzaW9uPigpO1xuICBpZiAoYXNzaWduZWRQZXJtaXNzaW9ucykge1xuICAgIGZvciAoY29uc3QgcCBvZiBhc3NpZ25lZFBlcm1pc3Npb25zKSB7XG4gICAgICBpZiAoaXNWYWxpZFBlcm1pc3Npb24ocCkpIHBlcm1zLmFkZChwKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFMTF9QRVJNSVNTSU9OUy5maWx0ZXIocCA9PiBwZXJtcy5oYXMocCkpO1xufVxuXG4vKiogV2hldGhlciBhIHJlc29sdmVkIHBlcm1pc3Npb24gbGlzdCBncmFudHMgYHBlcm1pc3Npb25gIChzdXBlcmFkbWluIOKHkiBhbHdheXMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1Blcm1pc3Npb24oXG4gIGdyYW50ZWQ6IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgcGVybWlzc2lvbjogUGVybWlzc2lvbixcbiAgaXNTdXBlckFkbWluPzogYm9vbGVhbixcbik6IGJvb2xlYW4ge1xuICBpZiAoaXNTdXBlckFkbWluKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEhZ3JhbnRlZCAmJiBncmFudGVkLmluY2x1ZGVzKHBlcm1pc3Npb24pO1xufVxuIl19
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Golden-path pipeline templates: a parameterized starter a developer
3
+ * instantiates (fills inputs) to create a new pipeline. The template body is a
4
+ * BuilderProps with `{{ vars.* }}` placeholders; each declared input maps to a
5
+ * `vars.<name>` value. Instantiation bakes the supplied inputs into the new
6
+ * pipeline's `props.vars` — the placeholders resolve at synth time like any
7
+ * other pipeline var (no separate template runtime).
8
+ */
9
+ /** Scalar types a template input can carry. */
10
+ export declare const TEMPLATE_INPUT_TYPES: readonly ['string', 'number', 'boolean'];
11
+ export type TemplateInputType = (typeof TEMPLATE_INPUT_TYPES)[number];
12
+ /**
13
+ * One declared input of a pipeline template. `name` is the `vars.<name>` key the
14
+ * template body references. This is the template's counterpart to a plugin's
15
+ * `requiredVars` contract.
16
+ */
17
+ export interface TemplateInput {
18
+ /** Variable key — referenced in the template body as `{{ vars.<name> }}`. */
19
+ readonly name: string;
20
+ /** Human label for the instantiate form (falls back to `name`). */
21
+ readonly label?: string;
22
+ readonly description?: string;
23
+ readonly type: TemplateInputType;
24
+ /** When true, instantiation fails if no value (and no default) is supplied. */
25
+ readonly required?: boolean;
26
+ /** Default applied when the user leaves the input blank. */
27
+ readonly default?: string | number | boolean;
28
+ /** Optional fixed choice set (renders as a select in the UI). */
29
+ readonly options?: string[];
30
+ }
@@ -0,0 +1,13 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Golden-path pipeline templates: a parameterized starter a developer
5
+ * instantiates (fills inputs) to create a new pipeline. The template body is a
6
+ * BuilderProps with `{{ vars.* }}` placeholders; each declared input maps to a
7
+ * `vars.<name>` value. Instantiation bakes the supplied inputs into the new
8
+ * pipeline's `props.vars` — the placeholders resolve at synth time like any
9
+ * other pipeline var (no separate template runtime).
10
+ */
11
+ /** Scalar types a template input can carry. */
12
+ export const TEMPLATE_INPUT_TYPES = ['string', 'number', 'boolean'];
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlwZWxpbmUtdGVtcGxhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGlwZWxpbmUtdGVtcGxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7OztHQU9HO0FBRUgsK0NBQStDO0FBQy9DLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQVUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEdvbGRlbi1wYXRoIHBpcGVsaW5lIHRlbXBsYXRlczogYSBwYXJhbWV0ZXJpemVkIHN0YXJ0ZXIgYSBkZXZlbG9wZXJcbiAqIGluc3RhbnRpYXRlcyAoZmlsbHMgaW5wdXRzKSB0byBjcmVhdGUgYSBuZXcgcGlwZWxpbmUuIFRoZSB0ZW1wbGF0ZSBib2R5IGlzIGFcbiAqIEJ1aWxkZXJQcm9wcyB3aXRoIGB7eyB2YXJzLiogfX1gIHBsYWNlaG9sZGVyczsgZWFjaCBkZWNsYXJlZCBpbnB1dCBtYXBzIHRvIGFcbiAqIGB2YXJzLjxuYW1lPmAgdmFsdWUuIEluc3RhbnRpYXRpb24gYmFrZXMgdGhlIHN1cHBsaWVkIGlucHV0cyBpbnRvIHRoZSBuZXdcbiAqIHBpcGVsaW5lJ3MgYHByb3BzLnZhcnNgIOKAlCB0aGUgcGxhY2Vob2xkZXJzIHJlc29sdmUgYXQgc3ludGggdGltZSBsaWtlIGFueVxuICogb3RoZXIgcGlwZWxpbmUgdmFyIChubyBzZXBhcmF0ZSB0ZW1wbGF0ZSBydW50aW1lKS5cbiAqL1xuXG4vKiogU2NhbGFyIHR5cGVzIGEgdGVtcGxhdGUgaW5wdXQgY2FuIGNhcnJ5LiAqL1xuZXhwb3J0IGNvbnN0IFRFTVBMQVRFX0lOUFVUX1RZUEVTID0gWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIFRlbXBsYXRlSW5wdXRUeXBlID0gKHR5cGVvZiBURU1QTEFURV9JTlBVVF9UWVBFUylbbnVtYmVyXTtcblxuLyoqXG4gKiBPbmUgZGVjbGFyZWQgaW5wdXQgb2YgYSBwaXBlbGluZSB0ZW1wbGF0ZS4gYG5hbWVgIGlzIHRoZSBgdmFycy48bmFtZT5gIGtleSB0aGVcbiAqIHRlbXBsYXRlIGJvZHkgcmVmZXJlbmNlcy4gVGhpcyBpcyB0aGUgdGVtcGxhdGUncyBjb3VudGVycGFydCB0byBhIHBsdWdpbidzXG4gKiBgcmVxdWlyZWRWYXJzYCBjb250cmFjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUlucHV0IHtcbiAgLyoqIFZhcmlhYmxlIGtleSDigJQgcmVmZXJlbmNlZCBpbiB0aGUgdGVtcGxhdGUgYm9keSBhcyBge3sgdmFycy48bmFtZT4gfX1gLiAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8qKiBIdW1hbiBsYWJlbCBmb3IgdGhlIGluc3RhbnRpYXRlIGZvcm0gKGZhbGxzIGJhY2sgdG8gYG5hbWVgKS4gKi9cbiAgcmVhZG9ubHkgbGFiZWw/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICByZWFkb25seSB0eXBlOiBUZW1wbGF0ZUlucHV0VHlwZTtcbiAgLyoqIFdoZW4gdHJ1ZSwgaW5zdGFudGlhdGlvbiBmYWlscyBpZiBubyB2YWx1ZSAoYW5kIG5vIGRlZmF1bHQpIGlzIHN1cHBsaWVkLiAqL1xuICByZWFkb25seSByZXF1aXJlZD86IGJvb2xlYW47XG4gIC8qKiBEZWZhdWx0IGFwcGxpZWQgd2hlbiB0aGUgdXNlciBsZWF2ZXMgdGhlIGlucHV0IGJsYW5rLiAqL1xuICByZWFkb25seSBkZWZhdWx0Pzogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbjtcbiAgLyoqIE9wdGlvbmFsIGZpeGVkIGNob2ljZSBzZXQgKHJlbmRlcnMgYXMgYSBzZWxlY3QgaW4gdGhlIFVJKS4gKi9cbiAgcmVhZG9ubHkgb3B0aW9ucz86IHN0cmluZ1tdO1xufVxuIl19
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared pipeline types used by both pipeline-core and pipeline-data
3
+ */
4
+ /**
5
+ * Utility type to extract the union of all values from an object type
6
+ */
7
+ type ValueOf<T> = T[keyof T];
8
+ /**
9
+ * AWS CodeBuild compute resource sizes
10
+ *
11
+ * @property SMALL - 3 GB memory, 2 vCPUs
12
+ * @property MEDIUM - 7 GB memory, 4 vCPUs
13
+ * @property LARGE - 15 GB memory, 8 vCPUs
14
+ * @property X2_LARGE - 145 GB memory, 72 vCPUs
15
+ *
16
+ * @see https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-compute-types.html
17
+ */
18
+ export declare const ComputeType: {
19
+ readonly SMALL: 'SMALL';
20
+ readonly MEDIUM: 'MEDIUM';
21
+ readonly LARGE: 'LARGE';
22
+ readonly X2_LARGE: 'X2_LARGE';
23
+ };
24
+ export type ComputeType = ValueOf<typeof ComputeType>;
25
+ /**
26
+ * Types of pipeline steps that can be created by plugins
27
+ *
28
+ * @property CODE_BUILD_STEP - Full CodeBuild step with custom build environment
29
+ * @property SHELL_STEP - Simple shell step without custom build environment
30
+ * @property MANUAL_APPROVAL_STEP - Native CDK approval gate (no Docker image, no commands)
31
+ */
32
+ export declare const PluginType: {
33
+ readonly CODE_BUILD_STEP: 'CodeBuildStep';
34
+ readonly SHELL_STEP: 'ShellStep';
35
+ readonly MANUAL_APPROVAL_STEP: 'ManualApprovalStep';
36
+ };
37
+ export type PluginType = ValueOf<typeof PluginType>;
38
+ /**
39
+ * Metadata type for storing configuration and custom properties
40
+ *
41
+ * Supports:
42
+ * - Standard key-value pairs (string, boolean, number)
43
+ * - Custom AWS CDK keys with the pattern `aws:cdk:{namespace}:{key}`
44
+ * (all lowercase — matches the format produced by `getCustomKey`)
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const metadata: MetaDataType = {
49
+ * BUILD_ENV: 'production',
50
+ * NODE_VERSION: '18',
51
+ * ENABLE_CACHE: true,
52
+ * MAX_RETRIES: 3
53
+ * };
54
+ * ```
55
+ */
56
+ export type MetaDataType = Record<string, string | boolean | number> & {
57
+ [K in `aws:cdk:${string}`]?: unknown;
58
+ };
59
+ export {};
@@ -0,0 +1,31 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * AWS CodeBuild compute resource sizes
5
+ *
6
+ * @property SMALL - 3 GB memory, 2 vCPUs
7
+ * @property MEDIUM - 7 GB memory, 4 vCPUs
8
+ * @property LARGE - 15 GB memory, 8 vCPUs
9
+ * @property X2_LARGE - 145 GB memory, 72 vCPUs
10
+ *
11
+ * @see https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-compute-types.html
12
+ */
13
+ export const ComputeType = {
14
+ SMALL: 'SMALL',
15
+ MEDIUM: 'MEDIUM',
16
+ LARGE: 'LARGE',
17
+ X2_LARGE: 'X2_LARGE',
18
+ };
19
+ /**
20
+ * Types of pipeline steps that can be created by plugins
21
+ *
22
+ * @property CODE_BUILD_STEP - Full CodeBuild step with custom build environment
23
+ * @property SHELL_STEP - Simple shell step without custom build environment
24
+ * @property MANUAL_APPROVAL_STEP - Native CDK approval gate (no Docker image, no commands)
25
+ */
26
+ export const PluginType = {
27
+ CODE_BUILD_STEP: 'CodeBuildStep',
28
+ SHELL_STEP: 'ShellStep',
29
+ MANUAL_APPROVAL_STEP: 'ManualApprovalStep',
30
+ };
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlwZWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGlwZWxpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQVd0Qzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUc7SUFDekIsS0FBSyxFQUFFLE9BQU87SUFDZCxNQUFNLEVBQUUsUUFBUTtJQUNoQixLQUFLLEVBQUUsT0FBTztJQUNkLFFBQVEsRUFBRSxVQUFVO0NBQ1osQ0FBQztBQUdYOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixlQUFlLEVBQUUsZUFBZTtJQUNoQyxVQUFVLEVBQUUsV0FBVztJQUN2QixvQkFBb0IsRUFBRSxvQkFBb0I7Q0FDbEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFNoYXJlZCBwaXBlbGluZSB0eXBlcyB1c2VkIGJ5IGJvdGggcGlwZWxpbmUtY29yZSBhbmQgcGlwZWxpbmUtZGF0YVxuICovXG5cbi8qKlxuICogVXRpbGl0eSB0eXBlIHRvIGV4dHJhY3QgdGhlIHVuaW9uIG9mIGFsbCB2YWx1ZXMgZnJvbSBhbiBvYmplY3QgdHlwZVxuICovXG50eXBlIFZhbHVlT2Y8VD4gPSBUW2tleW9mIFRdO1xuXG4vKipcbiAqIEFXUyBDb2RlQnVpbGQgY29tcHV0ZSByZXNvdXJjZSBzaXplc1xuICpcbiAqIEBwcm9wZXJ0eSBTTUFMTCAtIDMgR0IgbWVtb3J5LCAyIHZDUFVzXG4gKiBAcHJvcGVydHkgTUVESVVNIC0gNyBHQiBtZW1vcnksIDQgdkNQVXNcbiAqIEBwcm9wZXJ0eSBMQVJHRSAtIDE1IEdCIG1lbW9yeSwgOCB2Q1BVc1xuICogQHByb3BlcnR5IFgyX0xBUkdFIC0gMTQ1IEdCIG1lbW9yeSwgNzIgdkNQVXNcbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jb2RlYnVpbGQvbGF0ZXN0L3VzZXJndWlkZS9idWlsZC1lbnYtcmVmLWNvbXB1dGUtdHlwZXMuaHRtbFxuICovXG5leHBvcnQgY29uc3QgQ29tcHV0ZVR5cGUgPSB7XG4gIFNNQUxMOiAnU01BTEwnLFxuICBNRURJVU06ICdNRURJVU0nLFxuICBMQVJHRTogJ0xBUkdFJyxcbiAgWDJfTEFSR0U6ICdYMl9MQVJHRScsXG59IGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgQ29tcHV0ZVR5cGUgPSBWYWx1ZU9mPHR5cGVvZiBDb21wdXRlVHlwZT47XG5cbi8qKlxuICogVHlwZXMgb2YgcGlwZWxpbmUgc3RlcHMgdGhhdCBjYW4gYmUgY3JlYXRlZCBieSBwbHVnaW5zXG4gKlxuICogQHByb3BlcnR5IENPREVfQlVJTERfU1RFUCAtIEZ1bGwgQ29kZUJ1aWxkIHN0ZXAgd2l0aCBjdXN0b20gYnVpbGQgZW52aXJvbm1lbnRcbiAqIEBwcm9wZXJ0eSBTSEVMTF9TVEVQIC0gU2ltcGxlIHNoZWxsIHN0ZXAgd2l0aG91dCBjdXN0b20gYnVpbGQgZW52aXJvbm1lbnRcbiAqIEBwcm9wZXJ0eSBNQU5VQUxfQVBQUk9WQUxfU1RFUCAtIE5hdGl2ZSBDREsgYXBwcm92YWwgZ2F0ZSAobm8gRG9ja2VyIGltYWdlLCBubyBjb21tYW5kcylcbiAqL1xuZXhwb3J0IGNvbnN0IFBsdWdpblR5cGUgPSB7XG4gIENPREVfQlVJTERfU1RFUDogJ0NvZGVCdWlsZFN0ZXAnLFxuICBTSEVMTF9TVEVQOiAnU2hlbGxTdGVwJyxcbiAgTUFOVUFMX0FQUFJPVkFMX1NURVA6ICdNYW51YWxBcHByb3ZhbFN0ZXAnLFxufSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIFBsdWdpblR5cGUgPSBWYWx1ZU9mPHR5cGVvZiBQbHVnaW5UeXBlPjtcblxuLyoqXG4gKiBNZXRhZGF0YSB0eXBlIGZvciBzdG9yaW5nIGNvbmZpZ3VyYXRpb24gYW5kIGN1c3RvbSBwcm9wZXJ0aWVzXG4gKlxuICogU3VwcG9ydHM6XG4gKiAtIFN0YW5kYXJkIGtleS12YWx1ZSBwYWlycyAoc3RyaW5nLCBib29sZWFuLCBudW1iZXIpXG4gKiAtIEN1c3RvbSBBV1MgQ0RLIGtleXMgd2l0aCB0aGUgcGF0dGVybiBgYXdzOmNkazp7bmFtZXNwYWNlfTp7a2V5fWBcbiAqICAgKGFsbCBsb3dlcmNhc2Ug4oCUIG1hdGNoZXMgdGhlIGZvcm1hdCBwcm9kdWNlZCBieSBgZ2V0Q3VzdG9tS2V5YClcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbWV0YWRhdGE6IE1ldGFEYXRhVHlwZSA9IHtcbiAqICAgQlVJTERfRU5WOiAncHJvZHVjdGlvbicsXG4gKiAgIE5PREVfVkVSU0lPTjogJzE4JyxcbiAqICAgRU5BQkxFX0NBQ0hFOiB0cnVlLFxuICogICBNQVhfUkVUUklFUzogM1xuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgdHlwZSBNZXRhRGF0YVR5cGUgPVxuICBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyPiAmXG4gIHsgW0sgaW4gYGF3czpjZGs6JHtzdHJpbmd9YF0/OiB1bmtub3duIH07XG4iXX0=