@pipeline-builder/api-core 3.4.126 → 4.0.2

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 (54) hide show
  1. package/README.md +2 -2
  2. package/lib/constants/ai-providers.d.ts +18 -0
  3. package/lib/constants/ai-providers.js +51 -1
  4. package/lib/helpers/access-helpers.d.ts +52 -11
  5. package/lib/helpers/access-helpers.js +63 -18
  6. package/lib/helpers/restore-helpers.d.ts +8 -5
  7. package/lib/helpers/restore-helpers.js +12 -10
  8. package/lib/index.d.ts +1 -1
  9. package/lib/index.js +2 -2
  10. package/lib/middleware/auth.d.ts +11 -13
  11. package/lib/middleware/auth.js +61 -21
  12. package/lib/openapi/routes/ask-routes.d.ts +7 -0
  13. package/lib/openapi/routes/ask-routes.js +62 -0
  14. package/lib/openapi/routes/image-registry-routes.d.ts +7 -0
  15. package/lib/openapi/routes/image-registry-routes.js +98 -0
  16. package/lib/openapi/routes/index.js +8 -1
  17. package/lib/openapi/routes/pipeline-routes.js +10 -1
  18. package/lib/openapi/routes/pipeline-template-routes.js +8 -6
  19. package/lib/openapi/schema-registry.js +4 -4
  20. package/lib/services/circuit-breaker.d.ts +45 -0
  21. package/lib/services/circuit-breaker.js +138 -0
  22. package/lib/services/durable-event-bus.d.ts +96 -0
  23. package/lib/services/durable-event-bus.js +204 -0
  24. package/lib/services/http-client.js +42 -2
  25. package/lib/services/index.d.ts +2 -0
  26. package/lib/services/index.js +3 -1
  27. package/lib/services/quota.js +8 -1
  28. package/lib/services/remote-audit-client.d.ts +1 -1
  29. package/lib/services/remote-audit-client.js +7 -1
  30. package/lib/services/sse-ticket-store.d.ts +7 -0
  31. package/lib/services/sse-ticket-store.js +10 -5
  32. package/lib/services/token-revocation.js +10 -1
  33. package/lib/types/index.d.ts +1 -0
  34. package/lib/types/index.js +2 -1
  35. package/lib/types/permissions.d.ts +1 -1
  36. package/lib/types/permissions.js +6 -3
  37. package/lib/types/pipeline.d.ts +0 -11
  38. package/lib/types/pipeline.js +1 -11
  39. package/lib/types/visibility.d.ts +20 -0
  40. package/lib/types/visibility.js +22 -0
  41. package/lib/utils/audit.js +1 -1
  42. package/lib/utils/response.js +6 -3
  43. package/lib/validation/ai-schemas.d.ts +2 -1
  44. package/lib/validation/ai-schemas.js +3 -3
  45. package/lib/validation/common-schemas.d.ts +8 -6
  46. package/lib/validation/common-schemas.js +8 -7
  47. package/lib/validation/message-schemas.d.ts +2 -1
  48. package/lib/validation/pipeline-schemas.d.ts +6 -3
  49. package/lib/validation/pipeline-schemas.js +4 -4
  50. package/lib/validation/pipeline-template-schemas.d.ts +9 -6
  51. package/lib/validation/pipeline-template-schemas.js +5 -4
  52. package/lib/validation/plugin-schemas.d.ts +8 -4
  53. package/lib/validation/plugin-schemas.js +5 -5
  54. package/package.json +2 -2
package/README.md CHANGED
@@ -19,7 +19,7 @@ Provides the cross-cutting primitives every backend service depends on: JWT auth
19
19
  | `requireAdmin`, `requireSystemAdmin` | Role gates (admin/owner; system-org admin/owner) |
20
20
  | `requireFeature` | Feature-flag gate |
21
21
  | `isSystemOrgId`, `isSystemAdmin`, `isServicePrincipal` | Authorization helpers (`isServicePrincipal` is true when `req.user.sub` starts with `service:`) |
22
- | `resolveAccessModifier` | Coerces requested `'public'` to `'private'` unless caller is admin/owner |
22
+ | `resolveVisibility` | Resolves the sharing rung: `'public'` needs the resource's `:publish` permission (clamped to `'org'` otherwise); an unspecified rung falls back per-entity |
23
23
  | `signServiceToken`, `getServiceAuthHeader` | Mint short-lived inter-service JWTs (default TTL 5 min) accepted unmodified by `requireAuth` |
24
24
 
25
25
  ### Responses & errors (`./utils`, `./errors`)
@@ -51,7 +51,7 @@ Provides the cross-cutting primitives every backend service depends on: JWT auth
51
51
  | Export | Purpose |
52
52
  | --- | --- |
53
53
  | `createLogger`, `logger` | Winston structured logger factory and default instance |
54
- | `AIGenerateBodySchema`, `AIGenerateFromUrlBodySchema`, `PluginCreateSchema`, `PipelineFilterSchema`, `MessageCreateSchema`, plus `PaginationSchema`, `UUIDSchema`, `AccessModifierSchema` | Zod request-validation schemas and shared building blocks |
54
+ | `AIGenerateBodySchema`, `AIGenerateFromUrlBodySchema`, `PluginCreateSchema`, `PipelineFilterSchema`, `MessageCreateSchema`, plus `PaginationSchema`, `UUIDSchema`, `VisibilitySchema` | Zod request-validation schemas and shared building blocks |
55
55
  | `registry`, `generateOpenApiSpec` | Shared schema registry and OpenAPI spec generation |
56
56
 
57
57
  ### AI provider catalog (`./constants`)
@@ -25,6 +25,24 @@ export declare const AI_PROVIDER_CATALOG: Record<string, AIProviderInfo>;
25
25
  * Used by backend services to initialize the provider registry.
26
26
  */
27
27
  export declare const AI_PROVIDER_ENV_VARS: Record<string, string>;
28
+ /**
29
+ * Provider id for a self-hosted, OpenAI-compatible endpoint — a Docker model image
30
+ * (Ollama, Docker Model Runner, vLLM) or any other server that speaks the OpenAI
31
+ * chat API. Unlike the fixed providers above, this one is NOT in the static catalog:
32
+ * its endpoint and model list are deployment-defined and resolved from env at
33
+ * runtime by {@link getOpenAICompatibleProvider}.
34
+ */
35
+ export declare const OPENAI_COMPATIBLE_PROVIDER_ID = "openai-compatible";
36
+ /**
37
+ * Resolve the OpenAI-compatible (local / self-hosted) provider from env, or `null`
38
+ * when no endpoint is configured. Enabled by `OPENAI_COMPATIBLE_BASE_URL`; the model
39
+ * list comes from `OPENAI_COMPATIBLE_MODELS` (comma list of `id[|Display Name]`),
40
+ * falling back to `OPENAI_COMPATIBLE_MODEL`, then a generic `local` id. The display
41
+ * name is overridable via `OPENAI_COMPATIBLE_NAME`.
42
+ *
43
+ * @returns Provider info for the configured local endpoint, or null if unset
44
+ */
45
+ export declare function getOpenAICompatibleProvider(): AIProviderInfo | null;
28
46
  /**
29
47
  * Get the model list for a given provider ID.
30
48
  *
@@ -66,6 +66,53 @@ export const AI_PROVIDER_ENV_VARS = {
66
66
  'xai': 'XAI_API_KEY',
67
67
  'amazon-bedrock': 'AWS_ACCESS_KEY_ID',
68
68
  };
69
+ /**
70
+ * Provider id for a self-hosted, OpenAI-compatible endpoint — a Docker model image
71
+ * (Ollama, Docker Model Runner, vLLM) or any other server that speaks the OpenAI
72
+ * chat API. Unlike the fixed providers above, this one is NOT in the static catalog:
73
+ * its endpoint and model list are deployment-defined and resolved from env at
74
+ * runtime by {@link getOpenAICompatibleProvider}.
75
+ */
76
+ export const OPENAI_COMPATIBLE_PROVIDER_ID = 'openai-compatible';
77
+ /**
78
+ * Parse a `id[|Display Name][,id2[|Name2]]` env string into model metadata. The
79
+ * id/name separator is `|` (NOT `:`) because model ids commonly contain colons —
80
+ * e.g. Ollama tags (`qwen2.5-coder:7b`) and Bedrock inference profiles.
81
+ */
82
+ function parseModelList(raw) {
83
+ return raw
84
+ .split(',')
85
+ .map((s) => s.trim())
86
+ .filter(Boolean)
87
+ .map((entry) => {
88
+ const idx = entry.indexOf('|');
89
+ const id = (idx === -1 ? entry : entry.slice(0, idx)).trim();
90
+ const name = (idx === -1 ? '' : entry.slice(idx + 1)).trim() || id;
91
+ return { id, name };
92
+ })
93
+ .filter((m) => m.id.length > 0);
94
+ }
95
+ /**
96
+ * Resolve the OpenAI-compatible (local / self-hosted) provider from env, or `null`
97
+ * when no endpoint is configured. Enabled by `OPENAI_COMPATIBLE_BASE_URL`; the model
98
+ * list comes from `OPENAI_COMPATIBLE_MODELS` (comma list of `id[|Display Name]`),
99
+ * falling back to `OPENAI_COMPATIBLE_MODEL`, then a generic `local` id. The display
100
+ * name is overridable via `OPENAI_COMPATIBLE_NAME`.
101
+ *
102
+ * @returns Provider info for the configured local endpoint, or null if unset
103
+ */
104
+ export function getOpenAICompatibleProvider() {
105
+ const baseURL = process.env.OPENAI_COMPATIBLE_BASE_URL;
106
+ if (!baseURL)
107
+ return null;
108
+ const raw = process.env.OPENAI_COMPATIBLE_MODELS ?? process.env.OPENAI_COMPATIBLE_MODEL ?? 'local|Local model';
109
+ const models = parseModelList(raw);
110
+ return {
111
+ id: OPENAI_COMPATIBLE_PROVIDER_ID,
112
+ name: process.env.OPENAI_COMPATIBLE_NAME || 'Local model (OpenAI-compatible)',
113
+ models: models.length > 0 ? models : [{ id: 'local', name: 'Local model' }],
114
+ };
115
+ }
69
116
  // Helpers
70
117
  /**
71
118
  * Get the model list for a given provider ID.
@@ -74,6 +121,9 @@ export const AI_PROVIDER_ENV_VARS = {
74
121
  * @returns Array of models, or empty array if the provider is unknown
75
122
  */
76
123
  export function getAIProviderModels(providerId) {
124
+ if (providerId === OPENAI_COMPATIBLE_PROVIDER_ID) {
125
+ return getOpenAICompatibleProvider()?.models ?? [];
126
+ }
77
127
  return AI_PROVIDER_CATALOG[providerId]?.models ?? [];
78
128
  }
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktcHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnN0YW50cy9haS1wcm92aWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQXNCdEMsVUFBVTtBQUVWOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBbUM7SUFDakUsV0FBVyxFQUFFO1FBQ1gsRUFBRSxFQUFFLFdBQVc7UUFDZixJQUFJLEVBQUUsV0FBVztRQUNqQixNQUFNLEVBQUU7WUFDTixFQUFFLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7WUFDbEQsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDOUMsRUFBRSxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1NBQzlEO0tBQ0Y7SUFDRCxRQUFRLEVBQUU7UUFDUixFQUFFLEVBQUUsUUFBUTtRQUNaLElBQUksRUFBRSxRQUFRO1FBQ2QsTUFBTSxFQUFFO1lBQ04sRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUU7WUFDMUMsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDOUMsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUU7U0FDN0M7S0FDRjtJQUNELFFBQVEsRUFBRTtRQUNSLEVBQUUsRUFBRSxRQUFRO1FBQ1osSUFBSSxFQUFFLFFBQVE7UUFDZCxNQUFNLEVBQUU7WUFDTixFQUFFLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDcEQsRUFBRSxFQUFFLEVBQUUsd0JBQXdCLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1NBQ3pEO0tBQ0Y7SUFDRCxLQUFLLEVBQUU7UUFDTCxFQUFFLEVBQUUsS0FBSztRQUNULElBQUksRUFBRSxZQUFZO1FBQ2xCLE1BQU0sRUFBRTtZQUNOLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3BDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3BDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1NBQ3JDO0tBQ0Y7SUFDRCxnQkFBZ0IsRUFBRTtRQUNoQixFQUFFLEVBQUUsZ0JBQWdCO1FBQ3BCLElBQUksRUFBRSxnQkFBZ0I7UUFDdEIsMkVBQTJFO1FBQzNFLDBFQUEwRTtRQUMxRSxrRUFBa0U7UUFDbEUsTUFBTSxFQUFFO1lBQ04sRUFBRSxFQUFFLEVBQUUsOENBQThDLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ2pGLEVBQUUsRUFBRSxFQUFFLHlCQUF5QixFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRTtZQUMxRCxFQUFFLEVBQUUsRUFBRSwwQkFBMEIsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7U0FDN0Q7S0FDRjtDQUNGLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBMkI7SUFDMUQsV0FBVyxFQUFFLG1CQUFtQjtJQUNoQyxRQUFRLEVBQUUsZ0JBQWdCO0lBQzFCLFFBQVEsRUFBRSw4QkFBOEI7SUFDeEMsS0FBSyxFQUFFLGFBQWE7SUFDcEIsZ0JBQWdCLEVBQUUsbUJBQW1CO0NBQ3RDLENBQUM7QUFFRixVQUFVO0FBRVY7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsVUFBa0I7SUFDcEQsT0FBTyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDO0FBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLy8gVHlwZXNcblxuLyoqIE1ldGFkYXRhIGZvciBhIHNpbmdsZSBBSSBtb2RlbC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQUlNb2RlbEluZm8ge1xuICAvKiogTW9kZWwgaWRlbnRpZmllciB1c2VkIGluIEFQSSBjYWxscyAoZS5nLiBcImNsYXVkZS1zb25uZXQtNVwiKS4gKi9cbiAgaWQ6IHN0cmluZztcbiAgLyoqIEh1bWFuLXJlYWRhYmxlIGRpc3BsYXkgbmFtZSAoZS5nLiBcIkNsYXVkZSBTb25uZXQgNVwiKS4gKi9cbiAgbmFtZTogc3RyaW5nO1xufVxuXG4vKiogTWV0YWRhdGEgZm9yIGFuIEFJIHByb3ZpZGVyIHdpdGggaXRzIGF2YWlsYWJsZSBtb2RlbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIEFJUHJvdmlkZXJJbmZvIHtcbiAgLyoqIFByb3ZpZGVyIGlkZW50aWZpZXIgKGUuZy4gXCJhbnRocm9waWNcIiwgXCJvcGVuYWlcIiwgXCJnb29nbGVcIikuICovXG4gIGlkOiBzdHJpbmc7XG4gIC8qKiBIdW1hbi1yZWFkYWJsZSBkaXNwbGF5IG5hbWUgKGUuZy4gXCJBbnRocm9waWNcIikuICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIE1vZGVscyBhdmFpbGFibGUgZm9yIHRoaXMgcHJvdmlkZXIuICovXG4gIG1vZGVsczogQUlNb2RlbEluZm9bXTtcbn1cblxuLy8gQ2F0YWxvZ1xuXG4vKipcbiAqIFN0YW5kYXJkIEFJIHByb3ZpZGVyIGNhdGFsb2cg4oCUIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIGFsbCBzdXBwb3J0ZWRcbiAqIHByb3ZpZGVycyBhbmQgdGhlaXIgbW9kZWxzLiBVc2VkIGJ5IGJvdGggYmFja2VuZCBzZXJ2aWNlcyBhbmQgZnJvbnRlbmRcbiAqIGNvbXBvbmVudHMuXG4gKi9cbmV4cG9ydCBjb25zdCBBSV9QUk9WSURFUl9DQVRBTE9HOiBSZWNvcmQ8c3RyaW5nLCBBSVByb3ZpZGVySW5mbz4gPSB7XG4gICdhbnRocm9waWMnOiB7XG4gICAgaWQ6ICdhbnRocm9waWMnLFxuICAgIG5hbWU6ICdBbnRocm9waWMnLFxuICAgIG1vZGVsczogW1xuICAgICAgeyBpZDogJ2NsYXVkZS1zb25uZXQtNScsIG5hbWU6ICdDbGF1ZGUgU29ubmV0IDUnIH0sXG4gICAgICB7IGlkOiAnY2xhdWRlLW9wdXMtNScsIG5hbWU6ICdDbGF1ZGUgT3B1cyA1JyB9LFxuICAgICAgeyBpZDogJ2NsYXVkZS1oYWlrdS00LTUtMjAyNTEwMDEnLCBuYW1lOiAnQ2xhdWRlIEhhaWt1IDQuNScgfSxcbiAgICBdLFxuICB9LFxuICAnb3BlbmFpJzoge1xuICAgIGlkOiAnb3BlbmFpJyxcbiAgICBuYW1lOiAnT3BlbkFJJyxcbiAgICBtb2RlbHM6IFtcbiAgICAgIHsgaWQ6ICdncHQtNS42LXNvbCcsIG5hbWU6ICdHUFQtNS42IFNvbCcgfSxcbiAgICAgIHsgaWQ6ICdncHQtNS42LXRlcnJhJywgbmFtZTogJ0dQVC01LjYgVGVycmEnIH0sXG4gICAgICB7IGlkOiAnZ3B0LTUuNi1sdW5hJywgbmFtZTogJ0dQVC01LjYgTHVuYScgfSxcbiAgICBdLFxuICB9LFxuICAnZ29vZ2xlJzoge1xuICAgIGlkOiAnZ29vZ2xlJyxcbiAgICBuYW1lOiAnR29vZ2xlJyxcbiAgICBtb2RlbHM6IFtcbiAgICAgIHsgaWQ6ICdnZW1pbmktMy43LWZsYXNoJywgbmFtZTogJ0dlbWluaSAzLjcgRmxhc2gnIH0sXG4gICAgICB7IGlkOiAnZ2VtaW5pLTMuMS1wcm8tcHJldmlldycsIG5hbWU6ICdHZW1pbmkgMy4xIFBybycgfSxcbiAgICBdLFxuICB9LFxuICAneGFpJzoge1xuICAgIGlkOiAneGFpJyxcbiAgICBuYW1lOiAneEFJIChHcm9rKScsXG4gICAgbW9kZWxzOiBbXG4gICAgICB7IGlkOiAnZ3Jvay00LjYnLCBuYW1lOiAnR3JvayA0LjYnIH0sXG4gICAgICB7IGlkOiAnZ3Jvay00LjUnLCBuYW1lOiAnR3JvayA0LjUnIH0sXG4gICAgICB7IGlkOiAnZ3Jvay00LjMnLCBuYW1lOiAnR3JvayA0LjMnIH0sXG4gICAgXSxcbiAgfSxcbiAgJ2FtYXpvbi1iZWRyb2NrJzoge1xuICAgIGlkOiAnYW1hem9uLWJlZHJvY2snLFxuICAgIG5hbWU6ICdBbWF6b24gQmVkcm9jaycsXG4gICAgLy8gQmVkcm9jayBpZHMgYXJlIHJlZ2lvbi1zY29wZWQgY3Jvc3MtcmVnaW9uIGluZmVyZW5jZSBwcm9maWxlczsgdGhlIGB1cy5gXG4gICAgLy8gcHJlZml4IHRhcmdldHMgVVMgcmVnaW9ucyDigJQgc3dhcCB0aGUgcHJlZml4IChldS4vYXBhYy4v4oCmKSB0byBtYXRjaCB5b3VyXG4gICAgLy8gZGVwbG95IHJlZ2lvbiwgYW5kIGNvbmZpcm0gYXZhaWxhYmlsaXR5IGluIHRoZSBCZWRyb2NrIGNvbnNvbGUuXG4gICAgbW9kZWxzOiBbXG4gICAgICB7IGlkOiAndXMuYW50aHJvcGljLmNsYXVkZS1zb25uZXQtNC01LTIwMjUwOTI5LXYxOjAnLCBuYW1lOiAnQ2xhdWRlIFNvbm5ldCA0LjUnIH0sXG4gICAgICB7IGlkOiAndXMuYW1hem9uLm5vdmEtcHJvLXYxOjAnLCBuYW1lOiAnQW1hem9uIE5vdmEgUHJvJyB9LFxuICAgICAgeyBpZDogJ3VzLmFtYXpvbi5ub3ZhLWxpdGUtdjE6MCcsIG5hbWU6ICdBbWF6b24gTm92YSBMaXRlJyB9LFxuICAgIF0sXG4gIH0sXG59O1xuXG4vKipcbiAqIEVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzIGZvciBlYWNoIEFJIHByb3ZpZGVyJ3MgQVBJIGtleS5cbiAqIFVzZWQgYnkgYmFja2VuZCBzZXJ2aWNlcyB0byBpbml0aWFsaXplIHRoZSBwcm92aWRlciByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGNvbnN0IEFJX1BST1ZJREVSX0VOVl9WQVJTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAnYW50aHJvcGljJzogJ0FOVEhST1BJQ19BUElfS0VZJyxcbiAgJ29wZW5haSc6ICdPUEVOQUlfQVBJX0tFWScsXG4gICdnb29nbGUnOiAnR09PR0xFX0dFTkVSQVRJVkVfQUlfQVBJX0tFWScsXG4gICd4YWknOiAnWEFJX0FQSV9LRVknLFxuICAnYW1hem9uLWJlZHJvY2snOiAnQVdTX0FDQ0VTU19LRVlfSUQnLFxufTtcblxuLy8gSGVscGVyc1xuXG4vKipcbiAqIEdldCB0aGUgbW9kZWwgbGlzdCBmb3IgYSBnaXZlbiBwcm92aWRlciBJRC5cbiAqXG4gKiBAcGFyYW0gcHJvdmlkZXJJZCAtIFByb3ZpZGVyIGlkZW50aWZpZXIgKGUuZy4gXCJhbnRocm9waWNcIilcbiAqIEByZXR1cm5zIEFycmF5IG9mIG1vZGVscywgb3IgZW1wdHkgYXJyYXkgaWYgdGhlIHByb3ZpZGVyIGlzIHVua25vd25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFJUHJvdmlkZXJNb2RlbHMocHJvdmlkZXJJZDogc3RyaW5nKTogQUlNb2RlbEluZm9bXSB7XG4gIHJldHVybiBBSV9QUk9WSURFUl9DQVRBTE9HW3Byb3ZpZGVySWRdPy5tb2RlbHMgPz8gW107XG59XG4iXX0=
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktcHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnN0YW50cy9haS1wcm92aWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQXNCdEMsVUFBVTtBQUVWOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBbUM7SUFDakUsV0FBVyxFQUFFO1FBQ1gsRUFBRSxFQUFFLFdBQVc7UUFDZixJQUFJLEVBQUUsV0FBVztRQUNqQixNQUFNLEVBQUU7WUFDTixFQUFFLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7WUFDbEQsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDOUMsRUFBRSxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1NBQzlEO0tBQ0Y7SUFDRCxRQUFRLEVBQUU7UUFDUixFQUFFLEVBQUUsUUFBUTtRQUNaLElBQUksRUFBRSxRQUFRO1FBQ2QsTUFBTSxFQUFFO1lBQ04sRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUU7WUFDMUMsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDOUMsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUU7U0FDN0M7S0FDRjtJQUNELFFBQVEsRUFBRTtRQUNSLEVBQUUsRUFBRSxRQUFRO1FBQ1osSUFBSSxFQUFFLFFBQVE7UUFDZCxNQUFNLEVBQUU7WUFDTixFQUFFLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDcEQsRUFBRSxFQUFFLEVBQUUsd0JBQXdCLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1NBQ3pEO0tBQ0Y7SUFDRCxLQUFLLEVBQUU7UUFDTCxFQUFFLEVBQUUsS0FBSztRQUNULElBQUksRUFBRSxZQUFZO1FBQ2xCLE1BQU0sRUFBRTtZQUNOLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3BDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3BDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1NBQ3JDO0tBQ0Y7SUFDRCxnQkFBZ0IsRUFBRTtRQUNoQixFQUFFLEVBQUUsZ0JBQWdCO1FBQ3BCLElBQUksRUFBRSxnQkFBZ0I7UUFDdEIsMkVBQTJFO1FBQzNFLDBFQUEwRTtRQUMxRSxrRUFBa0U7UUFDbEUsTUFBTSxFQUFFO1lBQ04sRUFBRSxFQUFFLEVBQUUsOENBQThDLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ2pGLEVBQUUsRUFBRSxFQUFFLHlCQUF5QixFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRTtZQUMxRCxFQUFFLEVBQUUsRUFBRSwwQkFBMEIsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7U0FDN0Q7S0FDRjtDQUNGLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBMkI7SUFDMUQsV0FBVyxFQUFFLG1CQUFtQjtJQUNoQyxRQUFRLEVBQUUsZ0JBQWdCO0lBQzFCLFFBQVEsRUFBRSw4QkFBOEI7SUFDeEMsS0FBSyxFQUFFLGFBQWE7SUFDcEIsZ0JBQWdCLEVBQUUsbUJBQW1CO0NBQ3RDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxtQkFBbUIsQ0FBQztBQUVqRTs7OztHQUlHO0FBQ0gsU0FBUyxjQUFjLENBQUMsR0FBVztJQUNqQyxPQUFPLEdBQUc7U0FDUCxLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDcEIsTUFBTSxDQUFDLE9BQU8sQ0FBQztTQUNmLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQ2IsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzdELE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQ25FLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQyxDQUFDO1NBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsMkJBQTJCO0lBQ3pDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUM7SUFDdkQsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLElBQUksQ0FBQztJQUMxQixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHdCQUF3QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLElBQUksbUJBQW1CLENBQUM7SUFDL0csTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ25DLE9BQU87UUFDTCxFQUFFLEVBQUUsNkJBQTZCO1FBQ2pDLElBQUksRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixJQUFJLGlDQUFpQztRQUM3RSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDO0tBQzVFLENBQUM7QUFDSixDQUFDO0FBRUQsVUFBVTtBQUVWOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLFVBQWtCO0lBQ3BELElBQUksVUFBVSxLQUFLLDZCQUE2QixFQUFFLENBQUM7UUFDakQsT0FBTywyQkFBMkIsRUFBRSxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFDckQsQ0FBQztJQUNELE9BQU8sbUJBQW1CLENBQUMsVUFBVSxDQUFDLEVBQUUsTUFBTSxJQUFJLEVBQUUsQ0FBQztBQUN2RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8vIFR5cGVzXG5cbi8qKiBNZXRhZGF0YSBmb3IgYSBzaW5nbGUgQUkgbW9kZWwuICovXG5leHBvcnQgaW50ZXJmYWNlIEFJTW9kZWxJbmZvIHtcbiAgLyoqIE1vZGVsIGlkZW50aWZpZXIgdXNlZCBpbiBBUEkgY2FsbHMgKGUuZy4gXCJjbGF1ZGUtc29ubmV0LTVcIikuICovXG4gIGlkOiBzdHJpbmc7XG4gIC8qKiBIdW1hbi1yZWFkYWJsZSBkaXNwbGF5IG5hbWUgKGUuZy4gXCJDbGF1ZGUgU29ubmV0IDVcIikuICovXG4gIG5hbWU6IHN0cmluZztcbn1cblxuLyoqIE1ldGFkYXRhIGZvciBhbiBBSSBwcm92aWRlciB3aXRoIGl0cyBhdmFpbGFibGUgbW9kZWxzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBSVByb3ZpZGVySW5mbyB7XG4gIC8qKiBQcm92aWRlciBpZGVudGlmaWVyIChlLmcuIFwiYW50aHJvcGljXCIsIFwib3BlbmFpXCIsIFwiZ29vZ2xlXCIpLiAqL1xuICBpZDogc3RyaW5nO1xuICAvKiogSHVtYW4tcmVhZGFibGUgZGlzcGxheSBuYW1lIChlLmcuIFwiQW50aHJvcGljXCIpLiAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKiBNb2RlbHMgYXZhaWxhYmxlIGZvciB0aGlzIHByb3ZpZGVyLiAqL1xuICBtb2RlbHM6IEFJTW9kZWxJbmZvW107XG59XG5cbi8vIENhdGFsb2dcblxuLyoqXG4gKiBTdGFuZGFyZCBBSSBwcm92aWRlciBjYXRhbG9nIOKAlCBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBhbGwgc3VwcG9ydGVkXG4gKiBwcm92aWRlcnMgYW5kIHRoZWlyIG1vZGVscy4gVXNlZCBieSBib3RoIGJhY2tlbmQgc2VydmljZXMgYW5kIGZyb250ZW5kXG4gKiBjb21wb25lbnRzLlxuICovXG5leHBvcnQgY29uc3QgQUlfUFJPVklERVJfQ0FUQUxPRzogUmVjb3JkPHN0cmluZywgQUlQcm92aWRlckluZm8+ID0ge1xuICAnYW50aHJvcGljJzoge1xuICAgIGlkOiAnYW50aHJvcGljJyxcbiAgICBuYW1lOiAnQW50aHJvcGljJyxcbiAgICBtb2RlbHM6IFtcbiAgICAgIHsgaWQ6ICdjbGF1ZGUtc29ubmV0LTUnLCBuYW1lOiAnQ2xhdWRlIFNvbm5ldCA1JyB9LFxuICAgICAgeyBpZDogJ2NsYXVkZS1vcHVzLTUnLCBuYW1lOiAnQ2xhdWRlIE9wdXMgNScgfSxcbiAgICAgIHsgaWQ6ICdjbGF1ZGUtaGFpa3UtNC01LTIwMjUxMDAxJywgbmFtZTogJ0NsYXVkZSBIYWlrdSA0LjUnIH0sXG4gICAgXSxcbiAgfSxcbiAgJ29wZW5haSc6IHtcbiAgICBpZDogJ29wZW5haScsXG4gICAgbmFtZTogJ09wZW5BSScsXG4gICAgbW9kZWxzOiBbXG4gICAgICB7IGlkOiAnZ3B0LTUuNi1zb2wnLCBuYW1lOiAnR1BULTUuNiBTb2wnIH0sXG4gICAgICB7IGlkOiAnZ3B0LTUuNi10ZXJyYScsIG5hbWU6ICdHUFQtNS42IFRlcnJhJyB9LFxuICAgICAgeyBpZDogJ2dwdC01LjYtbHVuYScsIG5hbWU6ICdHUFQtNS42IEx1bmEnIH0sXG4gICAgXSxcbiAgfSxcbiAgJ2dvb2dsZSc6IHtcbiAgICBpZDogJ2dvb2dsZScsXG4gICAgbmFtZTogJ0dvb2dsZScsXG4gICAgbW9kZWxzOiBbXG4gICAgICB7IGlkOiAnZ2VtaW5pLTMuNy1mbGFzaCcsIG5hbWU6ICdHZW1pbmkgMy43IEZsYXNoJyB9LFxuICAgICAgeyBpZDogJ2dlbWluaS0zLjEtcHJvLXByZXZpZXcnLCBuYW1lOiAnR2VtaW5pIDMuMSBQcm8nIH0sXG4gICAgXSxcbiAgfSxcbiAgJ3hhaSc6IHtcbiAgICBpZDogJ3hhaScsXG4gICAgbmFtZTogJ3hBSSAoR3JvayknLFxuICAgIG1vZGVsczogW1xuICAgICAgeyBpZDogJ2dyb2stNC42JywgbmFtZTogJ0dyb2sgNC42JyB9LFxuICAgICAgeyBpZDogJ2dyb2stNC41JywgbmFtZTogJ0dyb2sgNC41JyB9LFxuICAgICAgeyBpZDogJ2dyb2stNC4zJywgbmFtZTogJ0dyb2sgNC4zJyB9LFxuICAgIF0sXG4gIH0sXG4gICdhbWF6b24tYmVkcm9jayc6IHtcbiAgICBpZDogJ2FtYXpvbi1iZWRyb2NrJyxcbiAgICBuYW1lOiAnQW1hem9uIEJlZHJvY2snLFxuICAgIC8vIEJlZHJvY2sgaWRzIGFyZSByZWdpb24tc2NvcGVkIGNyb3NzLXJlZ2lvbiBpbmZlcmVuY2UgcHJvZmlsZXM7IHRoZSBgdXMuYFxuICAgIC8vIHByZWZpeCB0YXJnZXRzIFVTIHJlZ2lvbnMg4oCUIHN3YXAgdGhlIHByZWZpeCAoZXUuL2FwYWMuL+KApikgdG8gbWF0Y2ggeW91clxuICAgIC8vIGRlcGxveSByZWdpb24sIGFuZCBjb25maXJtIGF2YWlsYWJpbGl0eSBpbiB0aGUgQmVkcm9jayBjb25zb2xlLlxuICAgIG1vZGVsczogW1xuICAgICAgeyBpZDogJ3VzLmFudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOS12MTowJywgbmFtZTogJ0NsYXVkZSBTb25uZXQgNC41JyB9LFxuICAgICAgeyBpZDogJ3VzLmFtYXpvbi5ub3ZhLXByby12MTowJywgbmFtZTogJ0FtYXpvbiBOb3ZhIFBybycgfSxcbiAgICAgIHsgaWQ6ICd1cy5hbWF6b24ubm92YS1saXRlLXYxOjAnLCBuYW1lOiAnQW1hem9uIE5vdmEgTGl0ZScgfSxcbiAgICBdLFxuICB9LFxufTtcblxuLyoqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcyBmb3IgZWFjaCBBSSBwcm92aWRlcidzIEFQSSBrZXkuXG4gKiBVc2VkIGJ5IGJhY2tlbmQgc2VydmljZXMgdG8gaW5pdGlhbGl6ZSB0aGUgcHJvdmlkZXIgcmVnaXN0cnkuXG4gKi9cbmV4cG9ydCBjb25zdCBBSV9QUk9WSURFUl9FTlZfVkFSUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgJ2FudGhyb3BpYyc6ICdBTlRIUk9QSUNfQVBJX0tFWScsXG4gICdvcGVuYWknOiAnT1BFTkFJX0FQSV9LRVknLFxuICAnZ29vZ2xlJzogJ0dPT0dMRV9HRU5FUkFUSVZFX0FJX0FQSV9LRVknLFxuICAneGFpJzogJ1hBSV9BUElfS0VZJyxcbiAgJ2FtYXpvbi1iZWRyb2NrJzogJ0FXU19BQ0NFU1NfS0VZX0lEJyxcbn07XG5cbi8qKlxuICogUHJvdmlkZXIgaWQgZm9yIGEgc2VsZi1ob3N0ZWQsIE9wZW5BSS1jb21wYXRpYmxlIGVuZHBvaW50IOKAlCBhIERvY2tlciBtb2RlbCBpbWFnZVxuICogKE9sbGFtYSwgRG9ja2VyIE1vZGVsIFJ1bm5lciwgdkxMTSkgb3IgYW55IG90aGVyIHNlcnZlciB0aGF0IHNwZWFrcyB0aGUgT3BlbkFJXG4gKiBjaGF0IEFQSS4gVW5saWtlIHRoZSBmaXhlZCBwcm92aWRlcnMgYWJvdmUsIHRoaXMgb25lIGlzIE5PVCBpbiB0aGUgc3RhdGljIGNhdGFsb2c6XG4gKiBpdHMgZW5kcG9pbnQgYW5kIG1vZGVsIGxpc3QgYXJlIGRlcGxveW1lbnQtZGVmaW5lZCBhbmQgcmVzb2x2ZWQgZnJvbSBlbnYgYXRcbiAqIHJ1bnRpbWUgYnkge0BsaW5rIGdldE9wZW5BSUNvbXBhdGlibGVQcm92aWRlcn0uXG4gKi9cbmV4cG9ydCBjb25zdCBPUEVOQUlfQ09NUEFUSUJMRV9QUk9WSURFUl9JRCA9ICdvcGVuYWktY29tcGF0aWJsZSc7XG5cbi8qKlxuICogUGFyc2UgYSBgaWRbfERpc3BsYXkgTmFtZV1bLGlkMlt8TmFtZTJdXWAgZW52IHN0cmluZyBpbnRvIG1vZGVsIG1ldGFkYXRhLiBUaGVcbiAqIGlkL25hbWUgc2VwYXJhdG9yIGlzIGB8YCAoTk9UIGA6YCkgYmVjYXVzZSBtb2RlbCBpZHMgY29tbW9ubHkgY29udGFpbiBjb2xvbnMg4oCUXG4gKiBlLmcuIE9sbGFtYSB0YWdzIChgcXdlbjIuNS1jb2Rlcjo3YmApIGFuZCBCZWRyb2NrIGluZmVyZW5jZSBwcm9maWxlcy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VNb2RlbExpc3QocmF3OiBzdHJpbmcpOiBBSU1vZGVsSW5mb1tdIHtcbiAgcmV0dXJuIHJhd1xuICAgIC5zcGxpdCgnLCcpXG4gICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5tYXAoKGVudHJ5KSA9PiB7XG4gICAgICBjb25zdCBpZHggPSBlbnRyeS5pbmRleE9mKCd8Jyk7XG4gICAgICBjb25zdCBpZCA9IChpZHggPT09IC0xID8gZW50cnkgOiBlbnRyeS5zbGljZSgwLCBpZHgpKS50cmltKCk7XG4gICAgICBjb25zdCBuYW1lID0gKGlkeCA9PT0gLTEgPyAnJyA6IGVudHJ5LnNsaWNlKGlkeCArIDEpKS50cmltKCkgfHwgaWQ7XG4gICAgICByZXR1cm4geyBpZCwgbmFtZSB9O1xuICAgIH0pXG4gICAgLmZpbHRlcigobSkgPT4gbS5pZC5sZW5ndGggPiAwKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBPcGVuQUktY29tcGF0aWJsZSAobG9jYWwgLyBzZWxmLWhvc3RlZCkgcHJvdmlkZXIgZnJvbSBlbnYsIG9yIGBudWxsYFxuICogd2hlbiBubyBlbmRwb2ludCBpcyBjb25maWd1cmVkLiBFbmFibGVkIGJ5IGBPUEVOQUlfQ09NUEFUSUJMRV9CQVNFX1VSTGA7IHRoZSBtb2RlbFxuICogbGlzdCBjb21lcyBmcm9tIGBPUEVOQUlfQ09NUEFUSUJMRV9NT0RFTFNgIChjb21tYSBsaXN0IG9mIGBpZFt8RGlzcGxheSBOYW1lXWApLFxuICogZmFsbGluZyBiYWNrIHRvIGBPUEVOQUlfQ09NUEFUSUJMRV9NT0RFTGAsIHRoZW4gYSBnZW5lcmljIGBsb2NhbGAgaWQuIFRoZSBkaXNwbGF5XG4gKiBuYW1lIGlzIG92ZXJyaWRhYmxlIHZpYSBgT1BFTkFJX0NPTVBBVElCTEVfTkFNRWAuXG4gKlxuICogQHJldHVybnMgUHJvdmlkZXIgaW5mbyBmb3IgdGhlIGNvbmZpZ3VyZWQgbG9jYWwgZW5kcG9pbnQsIG9yIG51bGwgaWYgdW5zZXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE9wZW5BSUNvbXBhdGlibGVQcm92aWRlcigpOiBBSVByb3ZpZGVySW5mbyB8IG51bGwge1xuICBjb25zdCBiYXNlVVJMID0gcHJvY2Vzcy5lbnYuT1BFTkFJX0NPTVBBVElCTEVfQkFTRV9VUkw7XG4gIGlmICghYmFzZVVSTCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52Lk9QRU5BSV9DT01QQVRJQkxFX01PREVMUyA/PyBwcm9jZXNzLmVudi5PUEVOQUlfQ09NUEFUSUJMRV9NT0RFTCA/PyAnbG9jYWx8TG9jYWwgbW9kZWwnO1xuICBjb25zdCBtb2RlbHMgPSBwYXJzZU1vZGVsTGlzdChyYXcpO1xuICByZXR1cm4ge1xuICAgIGlkOiBPUEVOQUlfQ09NUEFUSUJMRV9QUk9WSURFUl9JRCxcbiAgICBuYW1lOiBwcm9jZXNzLmVudi5PUEVOQUlfQ09NUEFUSUJMRV9OQU1FIHx8ICdMb2NhbCBtb2RlbCAoT3BlbkFJLWNvbXBhdGlibGUpJyxcbiAgICBtb2RlbHM6IG1vZGVscy5sZW5ndGggPiAwID8gbW9kZWxzIDogW3sgaWQ6ICdsb2NhbCcsIG5hbWU6ICdMb2NhbCBtb2RlbCcgfV0sXG4gIH07XG59XG5cbi8vIEhlbHBlcnNcblxuLyoqXG4gKiBHZXQgdGhlIG1vZGVsIGxpc3QgZm9yIGEgZ2l2ZW4gcHJvdmlkZXIgSUQuXG4gKlxuICogQHBhcmFtIHByb3ZpZGVySWQgLSBQcm92aWRlciBpZGVudGlmaWVyIChlLmcuIFwiYW50aHJvcGljXCIpXG4gKiBAcmV0dXJucyBBcnJheSBvZiBtb2RlbHMsIG9yIGVtcHR5IGFycmF5IGlmIHRoZSBwcm92aWRlciBpcyB1bmtub3duXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBSVByb3ZpZGVyTW9kZWxzKHByb3ZpZGVySWQ6IHN0cmluZyk6IEFJTW9kZWxJbmZvW10ge1xuICBpZiAocHJvdmlkZXJJZCA9PT0gT1BFTkFJX0NPTVBBVElCTEVfUFJPVklERVJfSUQpIHtcbiAgICByZXR1cm4gZ2V0T3BlbkFJQ29tcGF0aWJsZVByb3ZpZGVyKCk/Lm1vZGVscyA/PyBbXTtcbiAgfVxuICByZXR1cm4gQUlfUFJPVklERVJfQ0FUQUxPR1twcm92aWRlcklkXT8ubW9kZWxzID8/IFtdO1xufVxuIl19
@@ -1,22 +1,63 @@
1
1
  import type { Request, Response } from 'express';
2
2
  import type { Permission } from '../types/permissions.js';
3
+ import type { Visibility } from '../types/visibility.js';
4
+ /** The slice of a catalog entity the write gate needs. */
5
+ export interface VisibilityWriteTarget {
6
+ /** Rung the row currently sits at — see {@link Visibility}. */
7
+ visibility?: string;
8
+ /** Author. The only non-admin who may touch a `private` row. */
9
+ createdBy?: string;
10
+ }
3
11
  /**
4
- * Check whether a non-admin user may modify a public resource.
12
+ * Check whether the caller may modify a catalog entity, per its visibility rung.
13
+ * The single write gate behind every pipeline / plugin / template mutation.
5
14
  *
6
- * Returns `true` if the request may proceed. Returns `false` and sends
7
- * a 403 response if the user lacks permission.
15
+ * - `public` a system admin, or the holder of `publishPermission` (the same
16
+ * permission that let them publish it in the first place, so whoever can
17
+ * publish can also manage what they published)
18
+ * - `org` — anyone who got this far: the resource's `:write` permission plus the
19
+ * org scoping the caller already passed IS the gate
20
+ * - `private` — the AUTHOR alone (plus system admins)
8
21
  *
9
- * @param req - Express request
10
- * @param res - Express response
11
- * @param resource - Resource with an accessModifier field
12
- * @returns `true` if access is allowed, `false` if blocked (response already sent)
22
+ * The `private` branch is load-bearing on the TOMBSTONE paths (restore / purge),
23
+ * which are org-scoped rather than visibility-scoped because soft-delete is one
24
+ * shared code path without it, any org member could resurrect someone else's
25
+ * personal draft. On the live paths the read predicate has already hidden the
26
+ * row, making this defense in depth.
27
+ *
28
+ * Returns `true` if the request may proceed; returns `false` having ALREADY sent
29
+ * a 403.
13
30
  *
14
31
  * @example
15
32
  * ```typescript
16
- * if (!requirePublicAccess(req, res, pipeline)) return;
33
+ * if (!requireVisibilityWriteAccess(req, res, pipeline, userId, 'pipelines:publish')) return;
17
34
  * await pipelineService.delete(id, orgId, userId);
18
35
  * ```
19
36
  */
20
- export declare function requirePublicAccess(req: Request, res: Response, resource: {
21
- accessModifier?: string;
22
- }, publishPermission?: Permission): boolean;
37
+ export declare function requireVisibilityWriteAccess(req: Request, res: Response, resource: VisibilityWriteTarget, userId: string, publishPermission: Permission): boolean;
38
+ /**
39
+ * Resolve the effective visibility for an entity being created or updated.
40
+ *
41
+ * `public` requires the publish capability (superadmins pass via implicit-all);
42
+ * a caller who asks for it without the permission is clamped to `org` rather
43
+ * than dropped to a personal draft — they asked to SHARE it, and `org` is the
44
+ * widest rung they are entitled to. Anything else passes through.
45
+ *
46
+ * `fallback` is the rung an UNSPECIFIED visibility lands on, and it is
47
+ * deliberately per-entity even though the ladder itself is identical everywhere:
48
+ *
49
+ * - **templates** default to `private` — draft-first is the whole point of the
50
+ * personal rung; you polish a starter before publishing it.
51
+ * - **pipelines / plugins** default to `org` — they are team assets that deploy
52
+ * shared infrastructure, so creating one must not hide it from the team. A
53
+ * personal draft stays available, but opt-in.
54
+ *
55
+ * Same ladder, same gate, different centre of gravity — expressed as an argument
56
+ * rather than a second code path.
57
+ *
58
+ * Permission-based (not coarse-role-based): a bespoke custom Role can be granted
59
+ * publish rights and is no longer forced private by its `member` label. Built-in
60
+ * Admin/Owner bundles carry the publish permissions; the built-in Member bundle
61
+ * does not, so members top out at `org`.
62
+ */
63
+ export declare function resolveVisibility(req: Request, requested: string | undefined, publishPermission: Permission, fallback?: Visibility): Visibility;
@@ -2,36 +2,81 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { isSystemAdmin, userHasPermission } from '../middleware/auth.js';
4
4
  import { ErrorCode } from '../types/error-codes.js';
5
- import { AccessModifier } from '../types/pipeline.js';
6
5
  import { sendError } from '../utils/response.js';
7
6
  /**
8
- * Check whether a non-admin user may modify a public resource.
7
+ * Check whether the caller may modify a catalog entity, per its visibility rung.
8
+ * The single write gate behind every pipeline / plugin / template mutation.
9
9
  *
10
- * Returns `true` if the request may proceed. Returns `false` and sends
11
- * a 403 response if the user lacks permission.
10
+ * - `public` a system admin, or the holder of `publishPermission` (the same
11
+ * permission that let them publish it in the first place, so whoever can
12
+ * publish can also manage what they published)
13
+ * - `org` — anyone who got this far: the resource's `:write` permission plus the
14
+ * org scoping the caller already passed IS the gate
15
+ * - `private` — the AUTHOR alone (plus system admins)
12
16
  *
13
- * @param req - Express request
14
- * @param res - Express response
15
- * @param resource - Resource with an accessModifier field
16
- * @returns `true` if access is allowed, `false` if blocked (response already sent)
17
+ * The `private` branch is load-bearing on the TOMBSTONE paths (restore / purge),
18
+ * which are org-scoped rather than visibility-scoped because soft-delete is one
19
+ * shared code path without it, any org member could resurrect someone else's
20
+ * personal draft. On the live paths the read predicate has already hidden the
21
+ * row, making this defense in depth.
22
+ *
23
+ * Returns `true` if the request may proceed; returns `false` having ALREADY sent
24
+ * a 403.
17
25
  *
18
26
  * @example
19
27
  * ```typescript
20
- * if (!requirePublicAccess(req, res, pipeline)) return;
28
+ * if (!requireVisibilityWriteAccess(req, res, pipeline, userId, 'pipelines:publish')) return;
21
29
  * await pipelineService.delete(id, orgId, userId);
22
30
  * ```
23
31
  */
24
- export function requirePublicAccess(req, res, resource, publishPermission) {
25
- // Private resources: no extra gate (org-scoping already applies). Public/non-private:
26
- // a system admin OR the holder of the matching publish permission may modify it — so
27
- // the same permission that let a non-superadmin PUBLISH it (create path) also lets
28
- // them manage it. The write itself stays pinned to the caller's org, so this never
29
- // grants cross-org reach. Without a publishPermission, it stays superadmin-only.
30
- const mayModify = isSystemAdmin(req) || (!!publishPermission && userHasPermission(req, publishPermission));
31
- if (!mayModify && resource.accessModifier !== AccessModifier.PRIVATE) {
32
+ export function requireVisibilityWriteAccess(req, res, resource, userId, publishPermission) {
33
+ if (isSystemAdmin(req))
34
+ return true;
35
+ if (resource.visibility === 'public' && !userHasPermission(req, publishPermission)) {
32
36
  sendError(res, 403, 'You lack permission to modify this public resource.', ErrorCode.INSUFFICIENT_PERMISSIONS);
33
37
  return false;
34
38
  }
39
+ // Fail closed on an anonymous/absent caller — an empty userId must never match
40
+ // an empty `createdBy` and hand over someone else's draft.
41
+ if (resource.visibility === 'private' && (!userId || resource.createdBy !== userId)) {
42
+ sendError(res, 403, 'Only the author can modify a private resource.', ErrorCode.INSUFFICIENT_PERMISSIONS);
43
+ return false;
44
+ }
35
45
  return true;
36
46
  }
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9hY2Nlc3MtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBR3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsR0FBWSxFQUNaLEdBQWEsRUFDYixRQUFxQyxFQUNyQyxpQkFBOEI7SUFFOUIsc0ZBQXNGO0lBQ3RGLHFGQUFxRjtJQUNyRixtRkFBbUY7SUFDbkYsbUZBQW1GO0lBQ25GLGlGQUFpRjtJQUNqRixNQUFNLFNBQVMsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsaUJBQWlCLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUMzRyxJQUFJLENBQUMsU0FBUyxJQUFJLFFBQVEsQ0FBQyxjQUFjLEtBQUssY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JFLFNBQVMsQ0FDUCxHQUFHLEVBQ0gsR0FBRyxFQUNILHFEQUFxRCxFQUNyRCxTQUFTLENBQUMsd0JBQXdCLENBQ25DLENBQUM7UUFDRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgaXNTeXN0ZW1BZG1pbiwgdXNlckhhc1Blcm1pc3Npb24gfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGguanMnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBQZXJtaXNzaW9uIH0gZnJvbSAnLi4vdHlwZXMvcGVybWlzc2lvbnMuanMnO1xuaW1wb3J0IHsgQWNjZXNzTW9kaWZpZXIgfSBmcm9tICcuLi90eXBlcy9waXBlbGluZS5qcyc7XG5pbXBvcnQgeyBzZW5kRXJyb3IgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBhIG5vbi1hZG1pbiB1c2VyIG1heSBtb2RpZnkgYSBwdWJsaWMgcmVzb3VyY2UuXG4gKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHJlcXVlc3QgbWF5IHByb2NlZWQuIFJldHVybnMgYGZhbHNlYCBhbmQgc2VuZHNcbiAqIGEgNDAzIHJlc3BvbnNlIGlmIHRoZSB1c2VyIGxhY2tzIHBlcm1pc3Npb24uXG4gKlxuICogQHBhcmFtIHJlcSAtIEV4cHJlc3MgcmVxdWVzdFxuICogQHBhcmFtIHJlcyAtIEV4cHJlc3MgcmVzcG9uc2VcbiAqIEBwYXJhbSByZXNvdXJjZSAtIFJlc291cmNlIHdpdGggYW4gYWNjZXNzTW9kaWZpZXIgZmllbGRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBhY2Nlc3MgaXMgYWxsb3dlZCwgYGZhbHNlYCBpZiBibG9ja2VkIChyZXNwb25zZSBhbHJlYWR5IHNlbnQpXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmICghcmVxdWlyZVB1YmxpY0FjY2VzcyhyZXEsIHJlcywgcGlwZWxpbmUpKSByZXR1cm47XG4gKiBhd2FpdCBwaXBlbGluZVNlcnZpY2UuZGVsZXRlKGlkLCBvcmdJZCwgdXNlcklkKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVB1YmxpY0FjY2VzcyhcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICByZXNvdXJjZTogeyBhY2Nlc3NNb2RpZmllcj86IHN0cmluZyB9LFxuICBwdWJsaXNoUGVybWlzc2lvbj86IFBlcm1pc3Npb24sXG4pOiBib29sZWFuIHtcbiAgLy8gUHJpdmF0ZSByZXNvdXJjZXM6IG5vIGV4dHJhIGdhdGUgKG9yZy1zY29waW5nIGFscmVhZHkgYXBwbGllcykuIFB1YmxpYy9ub24tcHJpdmF0ZTpcbiAgLy8gYSBzeXN0ZW0gYWRtaW4gT1IgdGhlIGhvbGRlciBvZiB0aGUgbWF0Y2hpbmcgcHVibGlzaCBwZXJtaXNzaW9uIG1heSBtb2RpZnkgaXQg4oCUIHNvXG4gIC8vIHRoZSBzYW1lIHBlcm1pc3Npb24gdGhhdCBsZXQgYSBub24tc3VwZXJhZG1pbiBQVUJMSVNIIGl0IChjcmVhdGUgcGF0aCkgYWxzbyBsZXRzXG4gIC8vIHRoZW0gbWFuYWdlIGl0LiBUaGUgd3JpdGUgaXRzZWxmIHN0YXlzIHBpbm5lZCB0byB0aGUgY2FsbGVyJ3Mgb3JnLCBzbyB0aGlzIG5ldmVyXG4gIC8vIGdyYW50cyBjcm9zcy1vcmcgcmVhY2guIFdpdGhvdXQgYSBwdWJsaXNoUGVybWlzc2lvbiwgaXQgc3RheXMgc3VwZXJhZG1pbi1vbmx5LlxuICBjb25zdCBtYXlNb2RpZnkgPSBpc1N5c3RlbUFkbWluKHJlcSkgfHwgKCEhcHVibGlzaFBlcm1pc3Npb24gJiYgdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwdWJsaXNoUGVybWlzc2lvbikpO1xuICBpZiAoIW1heU1vZGlmeSAmJiByZXNvdXJjZS5hY2Nlc3NNb2RpZmllciAhPT0gQWNjZXNzTW9kaWZpZXIuUFJJVkFURSkge1xuICAgIHNlbmRFcnJvcihcbiAgICAgIHJlcyxcbiAgICAgIDQwMyxcbiAgICAgICdZb3UgbGFjayBwZXJtaXNzaW9uIHRvIG1vZGlmeSB0aGlzIHB1YmxpYyByZXNvdXJjZS4nLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
47
+ /**
48
+ * Resolve the effective visibility for an entity being created or updated.
49
+ *
50
+ * `public` requires the publish capability (superadmins pass via implicit-all);
51
+ * a caller who asks for it without the permission is clamped to `org` rather
52
+ * than dropped to a personal draft — they asked to SHARE it, and `org` is the
53
+ * widest rung they are entitled to. Anything else passes through.
54
+ *
55
+ * `fallback` is the rung an UNSPECIFIED visibility lands on, and it is
56
+ * deliberately per-entity even though the ladder itself is identical everywhere:
57
+ *
58
+ * - **templates** default to `private` — draft-first is the whole point of the
59
+ * personal rung; you polish a starter before publishing it.
60
+ * - **pipelines / plugins** default to `org` — they are team assets that deploy
61
+ * shared infrastructure, so creating one must not hide it from the team. A
62
+ * personal draft stays available, but opt-in.
63
+ *
64
+ * Same ladder, same gate, different centre of gravity — expressed as an argument
65
+ * rather than a second code path.
66
+ *
67
+ * Permission-based (not coarse-role-based): a bespoke custom Role can be granted
68
+ * publish rights and is no longer forced private by its `member` label. Built-in
69
+ * Admin/Owner bundles carry the publish permissions; the built-in Member bundle
70
+ * does not, so members top out at `org`.
71
+ */
72
+ export function resolveVisibility(req, requested, publishPermission, fallback = 'private') {
73
+ if (requested === 'public') {
74
+ return userHasPermission(req, publishPermission) ? 'public' : 'org';
75
+ }
76
+ if (requested === 'org')
77
+ return 'org';
78
+ if (requested === 'private')
79
+ return 'private';
80
+ return fallback;
81
+ }
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9hY2Nlc3MtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBR3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBVWpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0gsTUFBTSxVQUFVLDRCQUE0QixDQUMxQyxHQUFZLEVBQ1osR0FBYSxFQUNiLFFBQStCLEVBQy9CLE1BQWMsRUFDZCxpQkFBNkI7SUFFN0IsSUFBSSxhQUFhLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFcEMsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7UUFDbkYsU0FBUyxDQUNQLEdBQUcsRUFDSCxHQUFHLEVBQ0gscURBQXFELEVBQ3JELFNBQVMsQ0FBQyx3QkFBd0IsQ0FDbkMsQ0FBQztRQUNGLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELCtFQUErRTtJQUMvRSwyREFBMkQ7SUFDM0QsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxTQUFTLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNwRixTQUFTLENBQ1AsR0FBRyxFQUNILEdBQUcsRUFDSCxnREFBZ0QsRUFDaEQsU0FBUyxDQUFDLHdCQUF3QixDQUNuQyxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsR0FBWSxFQUNaLFNBQTZCLEVBQzdCLGlCQUE2QixFQUM3QixRQUFRLEdBQWUsU0FBUztJQUVoQyxJQUFJLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUMzQixPQUFPLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN0RSxDQUFDO0lBQ0QsSUFBSSxTQUFTLEtBQUssS0FBSztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3RDLElBQUksU0FBUyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGlzU3lzdGVtQWRtaW4sIHVzZXJIYXNQZXJtaXNzaW9uIH0gZnJvbSAnLi4vbWlkZGxld2FyZS9hdXRoLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB0eXBlIHsgVmlzaWJpbGl0eSB9IGZyb20gJy4uL3R5cGVzL3Zpc2liaWxpdHkuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogVGhlIHNsaWNlIG9mIGEgY2F0YWxvZyBlbnRpdHkgdGhlIHdyaXRlIGdhdGUgbmVlZHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFZpc2liaWxpdHlXcml0ZVRhcmdldCB7XG4gIC8qKiBSdW5nIHRoZSByb3cgY3VycmVudGx5IHNpdHMgYXQg4oCUIHNlZSB7QGxpbmsgVmlzaWJpbGl0eX0uICovXG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIC8qKiBBdXRob3IuIFRoZSBvbmx5IG5vbi1hZG1pbiB3aG8gbWF5IHRvdWNoIGEgYHByaXZhdGVgIHJvdy4gKi9cbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIGNhbGxlciBtYXkgbW9kaWZ5IGEgY2F0YWxvZyBlbnRpdHksIHBlciBpdHMgdmlzaWJpbGl0eSBydW5nLlxuICogVGhlIHNpbmdsZSB3cml0ZSBnYXRlIGJlaGluZCBldmVyeSBwaXBlbGluZSAvIHBsdWdpbiAvIHRlbXBsYXRlIG11dGF0aW9uLlxuICpcbiAqIC0gYHB1YmxpY2Ag4oCUIGEgc3lzdGVtIGFkbWluLCBvciB0aGUgaG9sZGVyIG9mIGBwdWJsaXNoUGVybWlzc2lvbmAgKHRoZSBzYW1lXG4gKiAgIHBlcm1pc3Npb24gdGhhdCBsZXQgdGhlbSBwdWJsaXNoIGl0IGluIHRoZSBmaXJzdCBwbGFjZSwgc28gd2hvZXZlciBjYW5cbiAqICAgcHVibGlzaCBjYW4gYWxzbyBtYW5hZ2Ugd2hhdCB0aGV5IHB1Ymxpc2hlZClcbiAqIC0gYG9yZ2Ag4oCUIGFueW9uZSB3aG8gZ290IHRoaXMgZmFyOiB0aGUgcmVzb3VyY2UncyBgOndyaXRlYCBwZXJtaXNzaW9uIHBsdXMgdGhlXG4gKiAgIG9yZyBzY29waW5nIHRoZSBjYWxsZXIgYWxyZWFkeSBwYXNzZWQgSVMgdGhlIGdhdGVcbiAqIC0gYHByaXZhdGVgIOKAlCB0aGUgQVVUSE9SIGFsb25lIChwbHVzIHN5c3RlbSBhZG1pbnMpXG4gKlxuICogVGhlIGBwcml2YXRlYCBicmFuY2ggaXMgbG9hZC1iZWFyaW5nIG9uIHRoZSBUT01CU1RPTkUgcGF0aHMgKHJlc3RvcmUgLyBwdXJnZSksXG4gKiB3aGljaCBhcmUgb3JnLXNjb3BlZCByYXRoZXIgdGhhbiB2aXNpYmlsaXR5LXNjb3BlZCBiZWNhdXNlIHNvZnQtZGVsZXRlIGlzIG9uZVxuICogc2hhcmVkIGNvZGUgcGF0aCDigJQgd2l0aG91dCBpdCwgYW55IG9yZyBtZW1iZXIgY291bGQgcmVzdXJyZWN0IHNvbWVvbmUgZWxzZSdzXG4gKiBwZXJzb25hbCBkcmFmdC4gT24gdGhlIGxpdmUgcGF0aHMgdGhlIHJlYWQgcHJlZGljYXRlIGhhcyBhbHJlYWR5IGhpZGRlbiB0aGVcbiAqIHJvdywgbWFraW5nIHRoaXMgZGVmZW5zZSBpbiBkZXB0aC5cbiAqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcmVxdWVzdCBtYXkgcHJvY2VlZDsgcmV0dXJucyBgZmFsc2VgIGhhdmluZyBBTFJFQURZIHNlbnRcbiAqIGEgNDAzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoIXJlcXVpcmVWaXNpYmlsaXR5V3JpdGVBY2Nlc3MocmVxLCByZXMsIHBpcGVsaW5lLCB1c2VySWQsICdwaXBlbGluZXM6cHVibGlzaCcpKSByZXR1cm47XG4gKiBhd2FpdCBwaXBlbGluZVNlcnZpY2UuZGVsZXRlKGlkLCBvcmdJZCwgdXNlcklkKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyhcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICByZXNvdXJjZTogVmlzaWJpbGl0eVdyaXRlVGFyZ2V0LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgcHVibGlzaFBlcm1pc3Npb246IFBlcm1pc3Npb24sXG4pOiBib29sZWFuIHtcbiAgaWYgKGlzU3lzdGVtQWRtaW4ocmVxKSkgcmV0dXJuIHRydWU7XG5cbiAgaWYgKHJlc291cmNlLnZpc2liaWxpdHkgPT09ICdwdWJsaWMnICYmICF1c2VySGFzUGVybWlzc2lvbihyZXEsIHB1Ymxpc2hQZXJtaXNzaW9uKSkge1xuICAgIHNlbmRFcnJvcihcbiAgICAgIHJlcyxcbiAgICAgIDQwMyxcbiAgICAgICdZb3UgbGFjayBwZXJtaXNzaW9uIHRvIG1vZGlmeSB0aGlzIHB1YmxpYyByZXNvdXJjZS4nLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEZhaWwgY2xvc2VkIG9uIGFuIGFub255bW91cy9hYnNlbnQgY2FsbGVyIOKAlCBhbiBlbXB0eSB1c2VySWQgbXVzdCBuZXZlciBtYXRjaFxuICAvLyBhbiBlbXB0eSBgY3JlYXRlZEJ5YCBhbmQgaGFuZCBvdmVyIHNvbWVvbmUgZWxzZSdzIGRyYWZ0LlxuICBpZiAocmVzb3VyY2UudmlzaWJpbGl0eSA9PT0gJ3ByaXZhdGUnICYmICghdXNlcklkIHx8IHJlc291cmNlLmNyZWF0ZWRCeSAhPT0gdXNlcklkKSkge1xuICAgIHNlbmRFcnJvcihcbiAgICAgIHJlcyxcbiAgICAgIDQwMyxcbiAgICAgICdPbmx5IHRoZSBhdXRob3IgY2FuIG1vZGlmeSBhIHByaXZhdGUgcmVzb3VyY2UuJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlZmZlY3RpdmUgdmlzaWJpbGl0eSBmb3IgYW4gZW50aXR5IGJlaW5nIGNyZWF0ZWQgb3IgdXBkYXRlZC5cbiAqXG4gKiBgcHVibGljYCByZXF1aXJlcyB0aGUgcHVibGlzaCBjYXBhYmlsaXR5IChzdXBlcmFkbWlucyBwYXNzIHZpYSBpbXBsaWNpdC1hbGwpO1xuICogYSBjYWxsZXIgd2hvIGFza3MgZm9yIGl0IHdpdGhvdXQgdGhlIHBlcm1pc3Npb24gaXMgY2xhbXBlZCB0byBgb3JnYCByYXRoZXJcbiAqIHRoYW4gZHJvcHBlZCB0byBhIHBlcnNvbmFsIGRyYWZ0IOKAlCB0aGV5IGFza2VkIHRvIFNIQVJFIGl0LCBhbmQgYG9yZ2AgaXMgdGhlXG4gKiB3aWRlc3QgcnVuZyB0aGV5IGFyZSBlbnRpdGxlZCB0by4gQW55dGhpbmcgZWxzZSBwYXNzZXMgdGhyb3VnaC5cbiAqXG4gKiBgZmFsbGJhY2tgIGlzIHRoZSBydW5nIGFuIFVOU1BFQ0lGSUVEIHZpc2liaWxpdHkgbGFuZHMgb24sIGFuZCBpdCBpc1xuICogZGVsaWJlcmF0ZWx5IHBlci1lbnRpdHkgZXZlbiB0aG91Z2ggdGhlIGxhZGRlciBpdHNlbGYgaXMgaWRlbnRpY2FsIGV2ZXJ5d2hlcmU6XG4gKlxuICogLSAqKnRlbXBsYXRlcyoqIGRlZmF1bHQgdG8gYHByaXZhdGVgIOKAlCBkcmFmdC1maXJzdCBpcyB0aGUgd2hvbGUgcG9pbnQgb2YgdGhlXG4gKiAgIHBlcnNvbmFsIHJ1bmc7IHlvdSBwb2xpc2ggYSBzdGFydGVyIGJlZm9yZSBwdWJsaXNoaW5nIGl0LlxuICogLSAqKnBpcGVsaW5lcyAvIHBsdWdpbnMqKiBkZWZhdWx0IHRvIGBvcmdgIOKAlCB0aGV5IGFyZSB0ZWFtIGFzc2V0cyB0aGF0IGRlcGxveVxuICogICBzaGFyZWQgaW5mcmFzdHJ1Y3R1cmUsIHNvIGNyZWF0aW5nIG9uZSBtdXN0IG5vdCBoaWRlIGl0IGZyb20gdGhlIHRlYW0uIEFcbiAqICAgcGVyc29uYWwgZHJhZnQgc3RheXMgYXZhaWxhYmxlLCBidXQgb3B0LWluLlxuICpcbiAqIFNhbWUgbGFkZGVyLCBzYW1lIGdhdGUsIGRpZmZlcmVudCBjZW50cmUgb2YgZ3Jhdml0eSDigJQgZXhwcmVzc2VkIGFzIGFuIGFyZ3VtZW50XG4gKiByYXRoZXIgdGhhbiBhIHNlY29uZCBjb2RlIHBhdGguXG4gKlxuICogUGVybWlzc2lvbi1iYXNlZCAobm90IGNvYXJzZS1yb2xlLWJhc2VkKTogYSBiZXNwb2tlIGN1c3RvbSBSb2xlIGNhbiBiZSBncmFudGVkXG4gKiBwdWJsaXNoIHJpZ2h0cyBhbmQgaXMgbm8gbG9uZ2VyIGZvcmNlZCBwcml2YXRlIGJ5IGl0cyBgbWVtYmVyYCBsYWJlbC4gQnVpbHQtaW5cbiAqIEFkbWluL093bmVyIGJ1bmRsZXMgY2FycnkgdGhlIHB1Ymxpc2ggcGVybWlzc2lvbnM7IHRoZSBidWlsdC1pbiBNZW1iZXIgYnVuZGxlXG4gKiBkb2VzIG5vdCwgc28gbWVtYmVycyB0b3Agb3V0IGF0IGBvcmdgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVZpc2liaWxpdHkoXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVxdWVzdGVkOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuICBmYWxsYmFjazogVmlzaWJpbGl0eSA9ICdwcml2YXRlJyxcbik6IFZpc2liaWxpdHkge1xuICBpZiAocmVxdWVzdGVkID09PSAncHVibGljJykge1xuICAgIHJldHVybiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHB1Ymxpc2hQZXJtaXNzaW9uKSA/ICdwdWJsaWMnIDogJ29yZyc7XG4gIH1cbiAgaWYgKHJlcXVlc3RlZCA9PT0gJ29yZycpIHJldHVybiAnb3JnJztcbiAgaWYgKHJlcXVlc3RlZCA9PT0gJ3ByaXZhdGUnKSByZXR1cm4gJ3ByaXZhdGUnO1xuICByZXR1cm4gZmFsbGJhY2s7XG59XG4iXX0=
@@ -3,7 +3,10 @@ import type { Permission } from '../types/permissions.js';
3
3
  /** Minimal shape a restore route needs from the entity it restores. */
4
4
  export interface RestorableEntity {
5
5
  orgId: string;
6
- accessModifier?: string;
6
+ /** Rung the tombstone sat at — drives the restore/purge authority check. */
7
+ visibility?: string;
8
+ /** Author — the only non-admin who may restore/purge a `private` row. */
9
+ createdBy?: string;
7
10
  }
8
11
  /** The slice of a service a restore route uses (satisfied by any CrudService). */
9
12
  export interface RestorableService<T extends RestorableEntity> {
@@ -12,8 +15,8 @@ export interface RestorableService<T extends RestorableEntity> {
12
15
  }
13
16
  /**
14
17
  * Shared skeleton for a step-up-gated entity restore route: extract `:id`, load
15
- * the own-org tombstone, gate a PUBLIC entity on `publishPermission` (parity with
16
- * delete), restore, and 404 on miss. Returns `{ existing, restored }` on success,
18
+ * the own-org tombstone, gate it on the visibility ladder (parity with delete),
19
+ * restore, and 404 on miss. Returns `{ existing, restored }` on success,
17
20
  * or `null` when it has ALREADY sent a response (400/404/403) — the caller then
18
21
  * does the entity-specific audit + response. DRYs the near-identical
19
22
  * pipeline / plugin / pipeline_template restore routes (which differ only in
@@ -30,7 +33,7 @@ export interface PurgeableService<T extends RestorableEntity> {
30
33
  }
31
34
  /**
32
35
  * Shared skeleton for an entity PURGE route: extract `:id`, load the own-org
33
- * tombstone, gate a PUBLIC entity on `publishPermission` (parity with
36
+ * tombstone, gate it on the visibility ladder (parity with
34
37
  * delete/restore), then permanently hard-delete it — but ONLY when it is a
35
38
  * genuine tombstone (a live/active row loads as `null` here and 404s, so purge
36
39
  * can never hard-delete a live row). Returns `{ existing, purgedId }` on success
@@ -40,7 +43,7 @@ export interface PurgeableService<T extends RestorableEntity> {
40
43
  * frontend gates it with an explicit confirm dialog. DRYs the near-identical
41
44
  * pipeline / pipeline_template purge routes.
42
45
  */
43
- export declare function loadAndPurge<T extends RestorableEntity>(req: Request, res: Response, orgId: string, service: PurgeableService<T>, label: string, publishPermission: Permission): Promise<{
46
+ export declare function loadAndPurge<T extends RestorableEntity>(req: Request, res: Response, orgId: string, service: PurgeableService<T>, label: string, publishPermission: Permission, userId: string): Promise<{
44
47
  existing: T;
45
48
  purgedId: string;
46
49
  } | null>;
@@ -1,14 +1,14 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { requirePublicAccess } from './access-helpers.js';
3
+ import { requireVisibilityWriteAccess } from './access-helpers.js';
4
4
  import { sendEntityNotFound } from './crud-helpers.js';
5
5
  import { ErrorCode } from '../types/error-codes.js';
6
6
  import { getParam } from '../utils/params.js';
7
7
  import { sendBadRequest } from '../utils/response.js';
8
8
  /**
9
9
  * Shared skeleton for a step-up-gated entity restore route: extract `:id`, load
10
- * the own-org tombstone, gate a PUBLIC entity on `publishPermission` (parity with
11
- * delete), restore, and 404 on miss. Returns `{ existing, restored }` on success,
10
+ * the own-org tombstone, gate it on the visibility ladder (parity with delete),
11
+ * restore, and 404 on miss. Returns `{ existing, restored }` on success,
12
12
  * or `null` when it has ALREADY sent a response (400/404/403) — the caller then
13
13
  * does the entity-specific audit + response. DRYs the near-identical
14
14
  * pipeline / plugin / pipeline_template restore routes (which differ only in
@@ -26,8 +26,10 @@ export async function loadAndRestore(req, res, orgId, userId, service, label, pu
26
26
  sendEntityNotFound(res, label);
27
27
  return null;
28
28
  }
29
- // Public (shared) entities: same publish gate as delete.
30
- if (!requirePublicAccess(req, res, existing, publishPermission))
29
+ // Same ladder authority as delete: `:publish` for a public row, authorship for
30
+ // a private one. Load-bearing here — the tombstone load is org-scoped, not
31
+ // visibility-scoped, so this is what stops a colleague resurrecting a draft.
32
+ if (!requireVisibilityWriteAccess(req, res, existing, userId || '', publishPermission))
31
33
  return null;
32
34
  const restored = await service.restore(id, orgId, userId || 'system');
33
35
  if (!restored) {
@@ -38,7 +40,7 @@ export async function loadAndRestore(req, res, orgId, userId, service, label, pu
38
40
  }
39
41
  /**
40
42
  * Shared skeleton for an entity PURGE route: extract `:id`, load the own-org
41
- * tombstone, gate a PUBLIC entity on `publishPermission` (parity with
43
+ * tombstone, gate it on the visibility ladder (parity with
42
44
  * delete/restore), then permanently hard-delete it — but ONLY when it is a
43
45
  * genuine tombstone (a live/active row loads as `null` here and 404s, so purge
44
46
  * can never hard-delete a live row). Returns `{ existing, purgedId }` on success
@@ -48,7 +50,7 @@ export async function loadAndRestore(req, res, orgId, userId, service, label, pu
48
50
  * frontend gates it with an explicit confirm dialog. DRYs the near-identical
49
51
  * pipeline / pipeline_template purge routes.
50
52
  */
51
- export async function loadAndPurge(req, res, orgId, service, label, publishPermission) {
53
+ export async function loadAndPurge(req, res, orgId, service, label, publishPermission, userId) {
52
54
  const id = getParam(req.params, 'id');
53
55
  if (!id) {
54
56
  sendBadRequest(res, `${label} ID is required.`, ErrorCode.MISSING_REQUIRED_FIELD);
@@ -61,8 +63,8 @@ export async function loadAndPurge(req, res, orgId, service, label, publishPermi
61
63
  sendEntityNotFound(res, label);
62
64
  return null;
63
65
  }
64
- // Public (shared) entities: same publish gate as delete/restore.
65
- if (!requirePublicAccess(req, res, existing, publishPermission))
66
+ // Same ladder authority as delete/restore (see loadAndRestore).
67
+ if (!requireVisibilityWriteAccess(req, res, existing, userId || '', publishPermission))
66
68
  return null;
67
69
  // Reuse the retention sweep's single-id hard-delete (same tombstone match +
68
70
  // dependent-teardown hooks). Returns null on a race (already purged) → 404.
@@ -73,4 +75,4 @@ export async function loadAndPurge(req, res, orgId, service, label, publishPermi
73
75
  }
74
76
  return { existing, purgedId };
75
77
  }
76
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdG9yZS1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvcmVzdG9yZS1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFjdEQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbEMsR0FBWSxFQUNaLEdBQWEsRUFDYixLQUFhLEVBQ2IsTUFBYyxFQUNkLE9BQTZCLEVBQzdCLEtBQWEsRUFDYixpQkFBNkI7SUFFN0IsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssa0JBQWtCLEVBQUUsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ2hGLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDMUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2Qsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELHlEQUF5RDtJQUN6RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsaUJBQWlCLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUU3RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLElBQUksUUFBUSxDQUFDLENBQUM7SUFDdEUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2Qsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQVFEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZLENBQ2hDLEdBQVksRUFDWixHQUFhLEVBQ2IsS0FBYSxFQUNiLE9BQTRCLEVBQzVCLEtBQWEsRUFDYixpQkFBNkI7SUFFN0IsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssa0JBQWtCLEVBQUUsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ2hGLHdFQUF3RTtJQUN4RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxpRUFBaUU7SUFDakUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFN0UsNEVBQTRFO0lBQzVFLDRFQUE0RTtJQUM1RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3BELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ2hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgcmVxdWlyZVB1YmxpY0FjY2VzcyB9IGZyb20gJy4vYWNjZXNzLWhlbHBlcnMuanMnO1xuaW1wb3J0IHsgc2VuZEVudGl0eU5vdEZvdW5kIH0gZnJvbSAnLi9jcnVkLWhlbHBlcnMuanMnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBQZXJtaXNzaW9uIH0gZnJvbSAnLi4vdHlwZXMvcGVybWlzc2lvbnMuanMnO1xuaW1wb3J0IHsgZ2V0UGFyYW0gfSBmcm9tICcuLi91dGlscy9wYXJhbXMuanMnO1xuaW1wb3J0IHsgc2VuZEJhZFJlcXVlc3QgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbi8qKiBNaW5pbWFsIHNoYXBlIGEgcmVzdG9yZSByb3V0ZSBuZWVkcyBmcm9tIHRoZSBlbnRpdHkgaXQgcmVzdG9yZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc3RvcmFibGVFbnRpdHkge1xuICBvcmdJZDogc3RyaW5nO1xuICBhY2Nlc3NNb2RpZmllcj86IHN0cmluZztcbn1cblxuLyoqIFRoZSBzbGljZSBvZiBhIHNlcnZpY2UgYSByZXN0b3JlIHJvdXRlIHVzZXMgKHNhdGlzZmllZCBieSBhbnkgQ3J1ZFNlcnZpY2UpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXN0b3JhYmxlU2VydmljZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4ge1xuICBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPjtcbiAgcmVzdG9yZShpZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+O1xufVxuXG4vKipcbiAqIFNoYXJlZCBza2VsZXRvbiBmb3IgYSBzdGVwLXVwLWdhdGVkIGVudGl0eSByZXN0b3JlIHJvdXRlOiBleHRyYWN0IGA6aWRgLCBsb2FkXG4gKiB0aGUgb3duLW9yZyB0b21ic3RvbmUsIGdhdGUgYSBQVUJMSUMgZW50aXR5IG9uIGBwdWJsaXNoUGVybWlzc2lvbmAgKHBhcml0eSB3aXRoXG4gKiBkZWxldGUpLCByZXN0b3JlLCBhbmQgNDA0IG9uIG1pc3MuIFJldHVybnMgYHsgZXhpc3RpbmcsIHJlc3RvcmVkIH1gIG9uIHN1Y2Nlc3MsXG4gKiBvciBgbnVsbGAgd2hlbiBpdCBoYXMgQUxSRUFEWSBzZW50IGEgcmVzcG9uc2UgKDQwMC80MDQvNDAzKSDigJQgdGhlIGNhbGxlciB0aGVuXG4gKiBkb2VzIHRoZSBlbnRpdHktc3BlY2lmaWMgYXVkaXQgKyByZXNwb25zZS4gRFJZcyB0aGUgbmVhci1pZGVudGljYWxcbiAqIHBpcGVsaW5lIC8gcGx1Z2luIC8gcGlwZWxpbmVfdGVtcGxhdGUgcmVzdG9yZSByb3V0ZXMgKHdoaWNoIGRpZmZlciBvbmx5IGluXG4gKiBzZXJ2aWNlLCBhdWRpdCBhY3Rpb24sIGFuZCByZXNwb25zZSBzaGFwaW5nKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRBbmRSZXN0b3JlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PihcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBvcmdJZDogc3RyaW5nLFxuICB1c2VySWQ6IHN0cmluZyxcbiAgc2VydmljZTogUmVzdG9yYWJsZVNlcnZpY2U8VD4sXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuKTogUHJvbWlzZTx7IGV4aXN0aW5nOiBUOyByZXN0b3JlZDogVCB9IHwgbnVsbD4ge1xuICBjb25zdCBpZCA9IGdldFBhcmFtKHJlcS5wYXJhbXMsICdpZCcpO1xuICBpZiAoIWlkKSB7XG4gICAgc2VuZEJhZFJlcXVlc3QocmVzLCBgJHtsYWJlbH0gSUQgaXMgcmVxdWlyZWQuYCwgRXJyb3JDb2RlLk1JU1NJTkdfUkVRVUlSRURfRklFTEQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gTG9hZCB0aGUgVE9NQlNUT05FIChvd24tb3JnKS4gQSBsaXZlIHJvdyAvIHVua25vd24gaWQgLyBhbHJlYWR5LXB1cmdlZCDihpIgNDA0LlxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNlcnZpY2UuZmluZERlbGV0ZWRCeUlkKGlkLCBvcmdJZCk7XG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBQdWJsaWMgKHNoYXJlZCkgZW50aXRpZXM6IHNhbWUgcHVibGlzaCBnYXRlIGFzIGRlbGV0ZS5cbiAgaWYgKCFyZXF1aXJlUHVibGljQWNjZXNzKHJlcSwgcmVzLCBleGlzdGluZywgcHVibGlzaFBlcm1pc3Npb24pKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCByZXN0b3JlZCA9IGF3YWl0IHNlcnZpY2UucmVzdG9yZShpZCwgb3JnSWQsIHVzZXJJZCB8fCAnc3lzdGVtJyk7XG4gIGlmICghcmVzdG9yZWQpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4geyBleGlzdGluZywgcmVzdG9yZWQgfTtcbn1cblxuLyoqIFRoZSBzbGljZSBvZiBhIHNlcnZpY2UgYSBwdXJnZSByb3V0ZSB1c2VzIChzYXRpc2ZpZWQgYnkgYW55IENydWRTZXJ2aWNlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHVyZ2VhYmxlU2VydmljZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4ge1xuICBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPjtcbiAgcHVyZ2VCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPjtcbn1cblxuLyoqXG4gKiBTaGFyZWQgc2tlbGV0b24gZm9yIGFuIGVudGl0eSBQVVJHRSByb3V0ZTogZXh0cmFjdCBgOmlkYCwgbG9hZCB0aGUgb3duLW9yZ1xuICogdG9tYnN0b25lLCBnYXRlIGEgUFVCTElDIGVudGl0eSBvbiBgcHVibGlzaFBlcm1pc3Npb25gIChwYXJpdHkgd2l0aFxuICogZGVsZXRlL3Jlc3RvcmUpLCB0aGVuIHBlcm1hbmVudGx5IGhhcmQtZGVsZXRlIGl0IOKAlCBidXQgT05MWSB3aGVuIGl0IGlzIGFcbiAqIGdlbnVpbmUgdG9tYnN0b25lIChhIGxpdmUvYWN0aXZlIHJvdyBsb2FkcyBhcyBgbnVsbGAgaGVyZSBhbmQgNDA0cywgc28gcHVyZ2VcbiAqIGNhbiBuZXZlciBoYXJkLWRlbGV0ZSBhIGxpdmUgcm93KS4gUmV0dXJucyBgeyBleGlzdGluZywgcHVyZ2VkSWQgfWAgb24gc3VjY2Vzc1xuICogKHRoZSBjYWxsZXIgZW1pdHMgdGhlIGVudGl0eS1zcGVjaWZpYyBhdWRpdCBvZmYgYGV4aXN0aW5nYCksIG9yIGBudWxsYCB3aGVuIGl0XG4gKiBoYXMgQUxSRUFEWSBzZW50IGEgcmVzcG9uc2UgKDQwMC80MDQvNDAzKS4gUHVyZ2UgaXMgaW50ZW50aW9uYWxseSBOT1Qgc3RlcC11cFxuICogZ2F0ZWQ6IGl0IG9ubHkgZmluYWxpemVzIHdoYXQgdGhlIHJldGVudGlvbiBzd2VlcCB3b3VsZCByZW1vdmUgYW55d2F5LCBhbmQgdGhlXG4gKiBmcm9udGVuZCBnYXRlcyBpdCB3aXRoIGFuIGV4cGxpY2l0IGNvbmZpcm0gZGlhbG9nLiBEUllzIHRoZSBuZWFyLWlkZW50aWNhbFxuICogcGlwZWxpbmUgLyBwaXBlbGluZV90ZW1wbGF0ZSBwdXJnZSByb3V0ZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQW5kUHVyZ2U8VCBleHRlbmRzIFJlc3RvcmFibGVFbnRpdHk+KFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHNlcnZpY2U6IFB1cmdlYWJsZVNlcnZpY2U8VD4sXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuKTogUHJvbWlzZTx7IGV4aXN0aW5nOiBUOyBwdXJnZWRJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gIGNvbnN0IGlkID0gZ2V0UGFyYW0ocmVxLnBhcmFtcywgJ2lkJyk7XG4gIGlmICghaWQpIHtcbiAgICBzZW5kQmFkUmVxdWVzdChyZXMsIGAke2xhYmVsfSBJRCBpcyByZXF1aXJlZC5gLCBFcnJvckNvZGUuTUlTU0lOR19SRVFVSVJFRF9GSUVMRCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBMb2FkIHRoZSBUT01CU1RPTkUgKG93bi1vcmcpLiBBIGxpdmUgcm93IC8gdW5rbm93biBpZCAvIGFscmVhZHktcHVyZ2VkIOKGkiA0MDQsXG4gIC8vIHNvIGEgY3VycmVudGx5LWFjdGl2ZSBlbnRpdHkgaXMgbmV2ZXIgaGFyZC1kZWxldGVkIHRocm91Z2ggdGhpcyBwYXRoLlxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNlcnZpY2UuZmluZERlbGV0ZWRCeUlkKGlkLCBvcmdJZCk7XG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBQdWJsaWMgKHNoYXJlZCkgZW50aXRpZXM6IHNhbWUgcHVibGlzaCBnYXRlIGFzIGRlbGV0ZS9yZXN0b3JlLlxuICBpZiAoIXJlcXVpcmVQdWJsaWNBY2Nlc3MocmVxLCByZXMsIGV4aXN0aW5nLCBwdWJsaXNoUGVybWlzc2lvbikpIHJldHVybiBudWxsO1xuXG4gIC8vIFJldXNlIHRoZSByZXRlbnRpb24gc3dlZXAncyBzaW5nbGUtaWQgaGFyZC1kZWxldGUgKHNhbWUgdG9tYnN0b25lIG1hdGNoICtcbiAgLy8gZGVwZW5kZW50LXRlYXJkb3duIGhvb2tzKS4gUmV0dXJucyBudWxsIG9uIGEgcmFjZSAoYWxyZWFkeSBwdXJnZWQpIOKGkiA0MDQuXG4gIGNvbnN0IHB1cmdlZElkID0gYXdhaXQgc2VydmljZS5wdXJnZUJ5SWQoaWQsIG9yZ0lkKTtcbiAgaWYgKCFwdXJnZWRJZCkge1xuICAgIHNlbmRFbnRpdHlOb3RGb3VuZChyZXMsIGxhYmVsKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IGV4aXN0aW5nLCBwdXJnZWRJZCB9O1xufVxuIl19
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdG9yZS1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvcmVzdG9yZS1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFpQnREOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxjQUFjLENBQ2xDLEdBQVksRUFDWixHQUFhLEVBQ2IsS0FBYSxFQUNiLE1BQWMsRUFDZCxPQUE2QixFQUM3QixLQUFhLEVBQ2IsaUJBQTZCO0lBRTdCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNSLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLGtCQUFrQixFQUFFLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2xGLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGdGQUFnRjtJQUNoRixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwrRUFBK0U7SUFDL0UsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxJQUFJLENBQUMsNEJBQTRCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsTUFBTSxJQUFJLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRXBHLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sSUFBSSxRQUFRLENBQUMsQ0FBQztJQUN0RSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0IsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBUUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FDaEMsR0FBWSxFQUNaLEdBQWEsRUFDYixLQUFhLEVBQ2IsT0FBNEIsRUFDNUIsS0FBYSxFQUNiLGlCQUE2QixFQUM3QixNQUFjO0lBRWQsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssa0JBQWtCLEVBQUUsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ2hGLHdFQUF3RTtJQUN4RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsSUFBSSxDQUFDLDRCQUE0QixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sSUFBSSxFQUFFLEVBQUUsaUJBQWlCLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUVwRyw0RUFBNEU7SUFDNUUsNEVBQTRFO0lBQzVFLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2Qsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDaEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyByZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzIH0gZnJvbSAnLi9hY2Nlc3MtaGVscGVycy5qcyc7XG5pbXBvcnQgeyBzZW5kRW50aXR5Tm90Rm91bmQgfSBmcm9tICcuL2NydWQtaGVscGVycy5qcyc7XG5pbXBvcnQgeyBFcnJvckNvZGUgfSBmcm9tICcuLi90eXBlcy9lcnJvci1jb2Rlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFBlcm1pc3Npb24gfSBmcm9tICcuLi90eXBlcy9wZXJtaXNzaW9ucy5qcyc7XG5pbXBvcnQgeyBnZXRQYXJhbSB9IGZyb20gJy4uL3V0aWxzL3BhcmFtcy5qcyc7XG5pbXBvcnQgeyBzZW5kQmFkUmVxdWVzdCB9IGZyb20gJy4uL3V0aWxzL3Jlc3BvbnNlLmpzJztcblxuLyoqIE1pbmltYWwgc2hhcGUgYSByZXN0b3JlIHJvdXRlIG5lZWRzIGZyb20gdGhlIGVudGl0eSBpdCByZXN0b3Jlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdG9yYWJsZUVudGl0eSB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIC8qKiBSdW5nIHRoZSB0b21ic3RvbmUgc2F0IGF0IOKAlCBkcml2ZXMgdGhlIHJlc3RvcmUvcHVyZ2UgYXV0aG9yaXR5IGNoZWNrLiAqL1xuICB2aXNpYmlsaXR5Pzogc3RyaW5nO1xuICAvKiogQXV0aG9yIOKAlCB0aGUgb25seSBub24tYWRtaW4gd2hvIG1heSByZXN0b3JlL3B1cmdlIGEgYHByaXZhdGVgIHJvdy4gKi9cbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xufVxuXG4vKiogVGhlIHNsaWNlIG9mIGEgc2VydmljZSBhIHJlc3RvcmUgcm91dGUgdXNlcyAoc2F0aXNmaWVkIGJ5IGFueSBDcnVkU2VydmljZSkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc3RvcmFibGVTZXJ2aWNlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PiB7XG4gIGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+O1xuICByZXN0b3JlKGlkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxUIHwgbnVsbD47XG59XG5cbi8qKlxuICogU2hhcmVkIHNrZWxldG9uIGZvciBhIHN0ZXAtdXAtZ2F0ZWQgZW50aXR5IHJlc3RvcmUgcm91dGU6IGV4dHJhY3QgYDppZGAsIGxvYWRcbiAqIHRoZSBvd24tb3JnIHRvbWJzdG9uZSwgZ2F0ZSBpdCBvbiB0aGUgdmlzaWJpbGl0eSBsYWRkZXIgKHBhcml0eSB3aXRoIGRlbGV0ZSksXG4gKiByZXN0b3JlLCBhbmQgNDA0IG9uIG1pc3MuIFJldHVybnMgYHsgZXhpc3RpbmcsIHJlc3RvcmVkIH1gIG9uIHN1Y2Nlc3MsXG4gKiBvciBgbnVsbGAgd2hlbiBpdCBoYXMgQUxSRUFEWSBzZW50IGEgcmVzcG9uc2UgKDQwMC80MDQvNDAzKSDigJQgdGhlIGNhbGxlciB0aGVuXG4gKiBkb2VzIHRoZSBlbnRpdHktc3BlY2lmaWMgYXVkaXQgKyByZXNwb25zZS4gRFJZcyB0aGUgbmVhci1pZGVudGljYWxcbiAqIHBpcGVsaW5lIC8gcGx1Z2luIC8gcGlwZWxpbmVfdGVtcGxhdGUgcmVzdG9yZSByb3V0ZXMgKHdoaWNoIGRpZmZlciBvbmx5IGluXG4gKiBzZXJ2aWNlLCBhdWRpdCBhY3Rpb24sIGFuZCByZXNwb25zZSBzaGFwaW5nKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRBbmRSZXN0b3JlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PihcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBvcmdJZDogc3RyaW5nLFxuICB1c2VySWQ6IHN0cmluZyxcbiAgc2VydmljZTogUmVzdG9yYWJsZVNlcnZpY2U8VD4sXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuKTogUHJvbWlzZTx7IGV4aXN0aW5nOiBUOyByZXN0b3JlZDogVCB9IHwgbnVsbD4ge1xuICBjb25zdCBpZCA9IGdldFBhcmFtKHJlcS5wYXJhbXMsICdpZCcpO1xuICBpZiAoIWlkKSB7XG4gICAgc2VuZEJhZFJlcXVlc3QocmVzLCBgJHtsYWJlbH0gSUQgaXMgcmVxdWlyZWQuYCwgRXJyb3JDb2RlLk1JU1NJTkdfUkVRVUlSRURfRklFTEQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gTG9hZCB0aGUgVE9NQlNUT05FIChvd24tb3JnKS4gQSBsaXZlIHJvdyAvIHVua25vd24gaWQgLyBhbHJlYWR5LXB1cmdlZCDihpIgNDA0LlxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNlcnZpY2UuZmluZERlbGV0ZWRCeUlkKGlkLCBvcmdJZCk7XG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBTYW1lIGxhZGRlciBhdXRob3JpdHkgYXMgZGVsZXRlOiBgOnB1Ymxpc2hgIGZvciBhIHB1YmxpYyByb3csIGF1dGhvcnNoaXAgZm9yXG4gIC8vIGEgcHJpdmF0ZSBvbmUuIExvYWQtYmVhcmluZyBoZXJlIOKAlCB0aGUgdG9tYnN0b25lIGxvYWQgaXMgb3JnLXNjb3BlZCwgbm90XG4gIC8vIHZpc2liaWxpdHktc2NvcGVkLCBzbyB0aGlzIGlzIHdoYXQgc3RvcHMgYSBjb2xsZWFndWUgcmVzdXJyZWN0aW5nIGEgZHJhZnQuXG4gIGlmICghcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyhyZXEsIHJlcywgZXhpc3RpbmcsIHVzZXJJZCB8fCAnJywgcHVibGlzaFBlcm1pc3Npb24pKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCByZXN0b3JlZCA9IGF3YWl0IHNlcnZpY2UucmVzdG9yZShpZCwgb3JnSWQsIHVzZXJJZCB8fCAnc3lzdGVtJyk7XG4gIGlmICghcmVzdG9yZWQpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4geyBleGlzdGluZywgcmVzdG9yZWQgfTtcbn1cblxuLyoqIFRoZSBzbGljZSBvZiBhIHNlcnZpY2UgYSBwdXJnZSByb3V0ZSB1c2VzIChzYXRpc2ZpZWQgYnkgYW55IENydWRTZXJ2aWNlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHVyZ2VhYmxlU2VydmljZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4ge1xuICBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPjtcbiAgcHVyZ2VCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPjtcbn1cblxuLyoqXG4gKiBTaGFyZWQgc2tlbGV0b24gZm9yIGFuIGVudGl0eSBQVVJHRSByb3V0ZTogZXh0cmFjdCBgOmlkYCwgbG9hZCB0aGUgb3duLW9yZ1xuICogdG9tYnN0b25lLCBnYXRlIGl0IG9uIHRoZSB2aXNpYmlsaXR5IGxhZGRlciAocGFyaXR5IHdpdGhcbiAqIGRlbGV0ZS9yZXN0b3JlKSwgdGhlbiBwZXJtYW5lbnRseSBoYXJkLWRlbGV0ZSBpdCDigJQgYnV0IE9OTFkgd2hlbiBpdCBpcyBhXG4gKiBnZW51aW5lIHRvbWJzdG9uZSAoYSBsaXZlL2FjdGl2ZSByb3cgbG9hZHMgYXMgYG51bGxgIGhlcmUgYW5kIDQwNHMsIHNvIHB1cmdlXG4gKiBjYW4gbmV2ZXIgaGFyZC1kZWxldGUgYSBsaXZlIHJvdykuIFJldHVybnMgYHsgZXhpc3RpbmcsIHB1cmdlZElkIH1gIG9uIHN1Y2Nlc3NcbiAqICh0aGUgY2FsbGVyIGVtaXRzIHRoZSBlbnRpdHktc3BlY2lmaWMgYXVkaXQgb2ZmIGBleGlzdGluZ2ApLCBvciBgbnVsbGAgd2hlbiBpdFxuICogaGFzIEFMUkVBRFkgc2VudCBhIHJlc3BvbnNlICg0MDAvNDA0LzQwMykuIFB1cmdlIGlzIGludGVudGlvbmFsbHkgTk9UIHN0ZXAtdXBcbiAqIGdhdGVkOiBpdCBvbmx5IGZpbmFsaXplcyB3aGF0IHRoZSByZXRlbnRpb24gc3dlZXAgd291bGQgcmVtb3ZlIGFueXdheSwgYW5kIHRoZVxuICogZnJvbnRlbmQgZ2F0ZXMgaXQgd2l0aCBhbiBleHBsaWNpdCBjb25maXJtIGRpYWxvZy4gRFJZcyB0aGUgbmVhci1pZGVudGljYWxcbiAqIHBpcGVsaW5lIC8gcGlwZWxpbmVfdGVtcGxhdGUgcHVyZ2Ugcm91dGVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZEFuZFB1cmdlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PihcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBzZXJ2aWNlOiBQdXJnZWFibGVTZXJ2aWNlPFQ+LFxuICBsYWJlbDogc3RyaW5nLFxuICBwdWJsaXNoUGVybWlzc2lvbjogUGVybWlzc2lvbixcbiAgdXNlcklkOiBzdHJpbmcsXG4pOiBQcm9taXNlPHsgZXhpc3Rpbmc6IFQ7IHB1cmdlZElkOiBzdHJpbmcgfSB8IG51bGw+IHtcbiAgY29uc3QgaWQgPSBnZXRQYXJhbShyZXEucGFyYW1zLCAnaWQnKTtcbiAgaWYgKCFpZCkge1xuICAgIHNlbmRCYWRSZXF1ZXN0KHJlcywgYCR7bGFiZWx9IElEIGlzIHJlcXVpcmVkLmAsIEVycm9yQ29kZS5NSVNTSU5HX1JFUVVJUkVEX0ZJRUxEKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIExvYWQgdGhlIFRPTUJTVE9ORSAob3duLW9yZykuIEEgbGl2ZSByb3cgLyB1bmtub3duIGlkIC8gYWxyZWFkeS1wdXJnZWQg4oaSIDQwNCxcbiAgLy8gc28gYSBjdXJyZW50bHktYWN0aXZlIGVudGl0eSBpcyBuZXZlciBoYXJkLWRlbGV0ZWQgdGhyb3VnaCB0aGlzIHBhdGguXG4gIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc2VydmljZS5maW5kRGVsZXRlZEJ5SWQoaWQsIG9yZ0lkKTtcbiAgaWYgKCFleGlzdGluZykge1xuICAgIHNlbmRFbnRpdHlOb3RGb3VuZChyZXMsIGxhYmVsKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIFNhbWUgbGFkZGVyIGF1dGhvcml0eSBhcyBkZWxldGUvcmVzdG9yZSAoc2VlIGxvYWRBbmRSZXN0b3JlKS5cbiAgaWYgKCFyZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzKHJlcSwgcmVzLCBleGlzdGluZywgdXNlcklkIHx8ICcnLCBwdWJsaXNoUGVybWlzc2lvbikpIHJldHVybiBudWxsO1xuXG4gIC8vIFJldXNlIHRoZSByZXRlbnRpb24gc3dlZXAncyBzaW5nbGUtaWQgaGFyZC1kZWxldGUgKHNhbWUgdG9tYnN0b25lIG1hdGNoICtcbiAgLy8gZGVwZW5kZW50LXRlYXJkb3duIGhvb2tzKS4gUmV0dXJucyBudWxsIG9uIGEgcmFjZSAoYWxyZWFkeSBwdXJnZWQpIOKGkiA0MDQuXG4gIGNvbnN0IHB1cmdlZElkID0gYXdhaXQgc2VydmljZS5wdXJnZUJ5SWQoaWQsIG9yZ0lkKTtcbiAgaWYgKCFwdXJnZWRJZCkge1xuICAgIHNlbmRFbnRpdHlOb3RGb3VuZChyZXMsIGxhYmVsKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IGV4aXN0aW5nLCBwdXJnZWRJZCB9O1xufVxuIl19
package/lib/index.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * - RequestIdentity — parsed JWT identity
14
14
  * - ServiceConfig, RequestOptions — HTTP client types
15
15
  * - QuotaType, QuotaCheckResult — quota service types
16
- * - PipelineType, ComputeType, AccessModifier — pipeline domain types
16
+ * - PipelineType, ComputeType, Visibility — pipeline domain types
17
17
  * - FeatureFlags — feature flag types
18
18
  *
19
19
  * **Utilities**
package/lib/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * - RequestIdentity — parsed JWT identity
16
16
  * - ServiceConfig, RequestOptions — HTTP client types
17
17
  * - QuotaType, QuotaCheckResult — quota service types
18
- * - PipelineType, ComputeType, AccessModifier — pipeline domain types
18
+ * - PipelineType, ComputeType, Visibility — pipeline domain types
19
19
  * - FeatureFlags — feature flag types
20
20
  *
21
21
  * **Utilities**
@@ -68,4 +68,4 @@ export * from './errors/index.js';
68
68
  export * from './validation/index.js';
69
69
  // OpenAPI
70
70
  export * from './openapi/index.js';
71
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQ0c7QUFFSCxRQUFRO0FBQ1IsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyxZQUFZO0FBQ1osY0FBYyxzQkFBc0IsQ0FBQztBQUVyQyxRQUFRO0FBQ1IsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyxVQUFVO0FBQ1YsY0FBYyxvQkFBb0IsQ0FBQztBQUVuQyxXQUFXO0FBQ1gsY0FBYyxxQkFBcUIsQ0FBQztBQUVwQyxhQUFhO0FBQ2IsY0FBYyx1QkFBdUIsQ0FBQztBQUV0QyxTQUFTO0FBQ1QsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyxTQUFTO0FBQ1QsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyxhQUFhO0FBQ2IsY0FBYyx1QkFBdUIsQ0FBQztBQUV0QyxVQUFVO0FBQ1YsY0FBYyxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEBtb2R1bGUgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmVcbiAqXG4gKiBDb3JlIEFQSSB1dGlsaXRpZXMgc2hhcmVkIGFjcm9zcyBhbGwgc2VydmljZXMuXG4gKlxuICogKipNaWRkbGV3YXJlKipcbiAqIC0gcmVxdWlyZUF1dGgsIHJlcXVpcmVTeXN0ZW1BZG1pbiwgcmVxdWlyZUZlYXR1cmUg4oCUIEpXVCBhdXRoZW50aWNhdGlvblxuICogLSBpc1N5c3RlbUFkbWluLCBpc1NlcnZpY2VQcmluY2lwYWwg4oCUIGF1dGhvcml6YXRpb24gaGVscGVycyAoaXNTeXN0ZW1PcmdJZCByZW1haW5zIGFzIGEgY29udGVudC1vd25lciBjaGVjaywgbm90IGEgcHJpdmlsZWdlIGdhdGUpXG4gKiAtIHNpZ25TZXJ2aWNlVG9rZW4sIGdldFNlcnZpY2VBdXRoSGVhZGVyIOKAlCBpbnRlci1zZXJ2aWNlIEpXVCBtaW50aW5nXG4gKlxuICogKipUeXBlcyoqXG4gKiAtIEVycm9yQ29kZSwgRXJyb3JDb2RlU3RhdHVzIOKAlCBzdGFuZGFyZGl6ZWQgZXJyb3IgY29kZSBlbnVtIGFuZCBzdGF0dXMgbWFwcGluZ1xuICogLSBSZXF1ZXN0SWRlbnRpdHkg4oCUIHBhcnNlZCBKV1QgaWRlbnRpdHlcbiAqIC0gU2VydmljZUNvbmZpZywgUmVxdWVzdE9wdGlvbnMg4oCUIEhUVFAgY2xpZW50IHR5cGVzXG4gKiAtIFF1b3RhVHlwZSwgUXVvdGFDaGVja1Jlc3VsdCDigJQgcXVvdGEgc2VydmljZSB0eXBlc1xuICogLSBQaXBlbGluZVR5cGUsIENvbXB1dGVUeXBlLCBBY2Nlc3NNb2RpZmllciDigJQgcGlwZWxpbmUgZG9tYWluIHR5cGVzXG4gKiAtIEZlYXR1cmVGbGFncyDigJQgZmVhdHVyZSBmbGFnIHR5cGVzXG4gKlxuICogKipVdGlsaXRpZXMqKlxuICogLSBjcmVhdGVMb2dnZXIg4oCUIFdpbnN0b24tYmFzZWQgc3RydWN0dXJlZCBsb2dnZXIgZmFjdG9yeVxuICogLSBzZW5kU3VjY2Vzcywgc2VuZEVycm9yLCBzZW5kUGFnaW5hdGVkTmVzdGVkLCBzZW5kQmFkUmVxdWVzdCwgc2VuZEludGVybmFsRXJyb3Ig4oCUIEhUVFAgcmVzcG9uc2UgaGVscGVyc1xuICogLSBnZXRQYXJhbSwgZ2V0T3JnSWQg4oCUIHJlcXVlc3QgcGFyYW1ldGVyIGV4dHJhY3Rpb25cbiAqIC0gcGFyc2VRdWVyeUludCwgcGFyc2VRdWVyeVN0cmluZyDigJQgcXVlcnkgc3RyaW5nIHBhcnNpbmdcbiAqIC0gZ2V0SWRlbnRpdHkg4oCUIGlkZW50aXR5IGV4dHJhY3Rpb24gZnJvbSByZXF1ZXN0c1xuICogLSBlcnJvck1lc3NhZ2Ug4oCUIHNhZmUgZXJyb3ItdG8tc3RyaW5nIGNvbnZlcnNpb25cbiAqXG4gKiAqKkNvbnN0YW50cyoqXG4gKiAtIEhUVFAgc3RhdHVzIGNvZGVzLCBBSSBwcm92aWRlciBpZGVudGlmaWVycywgdGltZSBjb25zdGFudHNcbiAqXG4gKiAqKlNlcnZpY2VzKipcbiAqIC0gSW50ZXJuYWxIdHRwQ2xpZW50LCBjcmVhdGVTYWZlQ2xpZW50IOKAlCBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgSFRUUCBjbGllbnRcbiAqIC0gY3JlYXRlUXVvdGFTZXJ2aWNlIOKAlCBxdW90YSBlbmZvcmNlbWVudCBjbGllbnQgZmFjdG9yeVxuICogLSBDYWNoZVNlcnZpY2Ug4oCUIGluLW1lbW9yeSBUVEwgY2FjaGVcbiAqIC0gQ29tcGxpYW5jZUNsaWVudCDigJQgY29tcGxpYW5jZSBzZXJ2aWNlIGNsaWVudFxuICogLSBFbnRpdHlFdmVudEVtaXR0ZXIg4oCUIGRvbWFpbiBldmVudCBwdWIvc3ViXG4gKlxuICogKipFcnJvcnMqKlxuICogLSBBcHBFcnJvciwgTm90Rm91bmRFcnJvciwgRm9yYmlkZGVuRXJyb3Ig4oCUIHR5cGVkIEhUVFAgZXJyb3IgY2xhc3Nlc1xuICpcbiAqICoqVmFsaWRhdGlvbioqXG4gKiAtIFpvZC1iYXNlZCByZXF1ZXN0IHZhbGlkYXRpb24gc2NoZW1hcyBhbmQgbWlkZGxld2FyZVxuICpcbiAqICoqUm91dGVzKipcbiAqIC0gSGVhbHRoIGNoZWNrIHJvdXRlIGZhY3RvcnlcbiAqXG4gKiAqKk9wZW5BUEkqKlxuICogLSBTY2hlbWEgcmVnaXN0cnkgYW5kIHNwZWMgZ2VuZXJhdGlvblxuICovXG5cbi8vIFR5cGVzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzL2luZGV4LmpzJztcblxuLy8gQ29uc3RhbnRzXG5leHBvcnQgKiBmcm9tICcuL2NvbnN0YW50cy9pbmRleC5qcyc7XG5cbi8vIFV0aWxzXG5leHBvcnQgKiBmcm9tICcuL3V0aWxzL2luZGV4LmpzJztcblxuLy8gSGVscGVyc1xuZXhwb3J0ICogZnJvbSAnLi9oZWxwZXJzL2luZGV4LmpzJztcblxuLy8gU2VydmljZXNcbmV4cG9ydCAqIGZyb20gJy4vc2VydmljZXMvaW5kZXguanMnO1xuXG4vLyBNaWRkbGV3YXJlXG5leHBvcnQgKiBmcm9tICcuL21pZGRsZXdhcmUvaW5kZXguanMnO1xuXG4vLyBSb3V0ZXNcbmV4cG9ydCAqIGZyb20gJy4vcm91dGVzL2luZGV4LmpzJztcblxuLy8gRXJyb3JzXG5leHBvcnQgKiBmcm9tICcuL2Vycm9ycy9pbmRleC5qcyc7XG5cbi8vIFZhbGlkYXRpb25cbmV4cG9ydCAqIGZyb20gJy4vdmFsaWRhdGlvbi9pbmRleC5qcyc7XG5cbi8vIE9wZW5BUElcbmV4cG9ydCAqIGZyb20gJy4vb3BlbmFwaS9pbmRleC5qcyc7XG4iXX0=
71
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQ0c7QUFFSCxRQUFRO0FBQ1IsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyxZQUFZO0FBQ1osY0FBYyxzQkFBc0IsQ0FBQztBQUVyQyxRQUFRO0FBQ1IsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyxVQUFVO0FBQ1YsY0FBYyxvQkFBb0IsQ0FBQztBQUVuQyxXQUFXO0FBQ1gsY0FBYyxxQkFBcUIsQ0FBQztBQUVwQyxhQUFhO0FBQ2IsY0FBYyx1QkFBdUIsQ0FBQztBQUV0QyxTQUFTO0FBQ1QsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyxTQUFTO0FBQ1QsY0FBYyxtQkFBbUIsQ0FBQztBQUVsQyxhQUFhO0FBQ2IsY0FBYyx1QkFBdUIsQ0FBQztBQUV0QyxVQUFVO0FBQ1YsY0FBYyxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEBtb2R1bGUgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmVcbiAqXG4gKiBDb3JlIEFQSSB1dGlsaXRpZXMgc2hhcmVkIGFjcm9zcyBhbGwgc2VydmljZXMuXG4gKlxuICogKipNaWRkbGV3YXJlKipcbiAqIC0gcmVxdWlyZUF1dGgsIHJlcXVpcmVTeXN0ZW1BZG1pbiwgcmVxdWlyZUZlYXR1cmUg4oCUIEpXVCBhdXRoZW50aWNhdGlvblxuICogLSBpc1N5c3RlbUFkbWluLCBpc1NlcnZpY2VQcmluY2lwYWwg4oCUIGF1dGhvcml6YXRpb24gaGVscGVycyAoaXNTeXN0ZW1PcmdJZCByZW1haW5zIGFzIGEgY29udGVudC1vd25lciBjaGVjaywgbm90IGEgcHJpdmlsZWdlIGdhdGUpXG4gKiAtIHNpZ25TZXJ2aWNlVG9rZW4sIGdldFNlcnZpY2VBdXRoSGVhZGVyIOKAlCBpbnRlci1zZXJ2aWNlIEpXVCBtaW50aW5nXG4gKlxuICogKipUeXBlcyoqXG4gKiAtIEVycm9yQ29kZSwgRXJyb3JDb2RlU3RhdHVzIOKAlCBzdGFuZGFyZGl6ZWQgZXJyb3IgY29kZSBlbnVtIGFuZCBzdGF0dXMgbWFwcGluZ1xuICogLSBSZXF1ZXN0SWRlbnRpdHkg4oCUIHBhcnNlZCBKV1QgaWRlbnRpdHlcbiAqIC0gU2VydmljZUNvbmZpZywgUmVxdWVzdE9wdGlvbnMg4oCUIEhUVFAgY2xpZW50IHR5cGVzXG4gKiAtIFF1b3RhVHlwZSwgUXVvdGFDaGVja1Jlc3VsdCDigJQgcXVvdGEgc2VydmljZSB0eXBlc1xuICogLSBQaXBlbGluZVR5cGUsIENvbXB1dGVUeXBlLCBWaXNpYmlsaXR5IOKAlCBwaXBlbGluZSBkb21haW4gdHlwZXNcbiAqIC0gRmVhdHVyZUZsYWdzIOKAlCBmZWF0dXJlIGZsYWcgdHlwZXNcbiAqXG4gKiAqKlV0aWxpdGllcyoqXG4gKiAtIGNyZWF0ZUxvZ2dlciDigJQgV2luc3Rvbi1iYXNlZCBzdHJ1Y3R1cmVkIGxvZ2dlciBmYWN0b3J5XG4gKiAtIHNlbmRTdWNjZXNzLCBzZW5kRXJyb3IsIHNlbmRQYWdpbmF0ZWROZXN0ZWQsIHNlbmRCYWRSZXF1ZXN0LCBzZW5kSW50ZXJuYWxFcnJvciDigJQgSFRUUCByZXNwb25zZSBoZWxwZXJzXG4gKiAtIGdldFBhcmFtLCBnZXRPcmdJZCDigJQgcmVxdWVzdCBwYXJhbWV0ZXIgZXh0cmFjdGlvblxuICogLSBwYXJzZVF1ZXJ5SW50LCBwYXJzZVF1ZXJ5U3RyaW5nIOKAlCBxdWVyeSBzdHJpbmcgcGFyc2luZ1xuICogLSBnZXRJZGVudGl0eSDigJQgaWRlbnRpdHkgZXh0cmFjdGlvbiBmcm9tIHJlcXVlc3RzXG4gKiAtIGVycm9yTWVzc2FnZSDigJQgc2FmZSBlcnJvci10by1zdHJpbmcgY29udmVyc2lvblxuICpcbiAqICoqQ29uc3RhbnRzKipcbiAqIC0gSFRUUCBzdGF0dXMgY29kZXMsIEFJIHByb3ZpZGVyIGlkZW50aWZpZXJzLCB0aW1lIGNvbnN0YW50c1xuICpcbiAqICoqU2VydmljZXMqKlxuICogLSBJbnRlcm5hbEh0dHBDbGllbnQsIGNyZWF0ZVNhZmVDbGllbnQg4oCUIGludGVybmFsIHNlcnZpY2UtdG8tc2VydmljZSBIVFRQIGNsaWVudFxuICogLSBjcmVhdGVRdW90YVNlcnZpY2Ug4oCUIHF1b3RhIGVuZm9yY2VtZW50IGNsaWVudCBmYWN0b3J5XG4gKiAtIENhY2hlU2VydmljZSDigJQgaW4tbWVtb3J5IFRUTCBjYWNoZVxuICogLSBDb21wbGlhbmNlQ2xpZW50IOKAlCBjb21wbGlhbmNlIHNlcnZpY2UgY2xpZW50XG4gKiAtIEVudGl0eUV2ZW50RW1pdHRlciDigJQgZG9tYWluIGV2ZW50IHB1Yi9zdWJcbiAqXG4gKiAqKkVycm9ycyoqXG4gKiAtIEFwcEVycm9yLCBOb3RGb3VuZEVycm9yLCBGb3JiaWRkZW5FcnJvciDigJQgdHlwZWQgSFRUUCBlcnJvciBjbGFzc2VzXG4gKlxuICogKipWYWxpZGF0aW9uKipcbiAqIC0gWm9kLWJhc2VkIHJlcXVlc3QgdmFsaWRhdGlvbiBzY2hlbWFzIGFuZCBtaWRkbGV3YXJlXG4gKlxuICogKipSb3V0ZXMqKlxuICogLSBIZWFsdGggY2hlY2sgcm91dGUgZmFjdG9yeVxuICpcbiAqICoqT3BlbkFQSSoqXG4gKiAtIFNjaGVtYSByZWdpc3RyeSBhbmQgc3BlYyBnZW5lcmF0aW9uXG4gKi9cblxuLy8gVHlwZXNcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMvaW5kZXguanMnO1xuXG4vLyBDb25zdGFudHNcbmV4cG9ydCAqIGZyb20gJy4vY29uc3RhbnRzL2luZGV4LmpzJztcblxuLy8gVXRpbHNcbmV4cG9ydCAqIGZyb20gJy4vdXRpbHMvaW5kZXguanMnO1xuXG4vLyBIZWxwZXJzXG5leHBvcnQgKiBmcm9tICcuL2hlbHBlcnMvaW5kZXguanMnO1xuXG4vLyBTZXJ2aWNlc1xuZXhwb3J0ICogZnJvbSAnLi9zZXJ2aWNlcy9pbmRleC5qcyc7XG5cbi8vIE1pZGRsZXdhcmVcbmV4cG9ydCAqIGZyb20gJy4vbWlkZGxld2FyZS9pbmRleC5qcyc7XG5cbi8vIFJvdXRlc1xuZXhwb3J0ICogZnJvbSAnLi9yb3V0ZXMvaW5kZXguanMnO1xuXG4vLyBFcnJvcnNcbmV4cG9ydCAqIGZyb20gJy4vZXJyb3JzL2luZGV4LmpzJztcblxuLy8gVmFsaWRhdGlvblxuZXhwb3J0ICogZnJvbSAnLi92YWxpZGF0aW9uL2luZGV4LmpzJztcblxuLy8gT3BlbkFQSVxuZXhwb3J0ICogZnJvbSAnLi9vcGVuYXBpL2luZGV4LmpzJztcbiJdfQ==
@@ -156,19 +156,10 @@ export declare function requireSystemAdmin(req: Request, res: Response, next: Ne
156
156
  * Sysadmins (isSuperAdmin) bypass — they always have every feature.
157
157
  */
158
158
  export declare function requireFeature(feature: string): (req: Request, res: Response, next: NextFunction) => void;
159
- /**
160
- * Resolve the effective access modifier for an entity being created/updated.
161
- * 'public' is permitted only for a caller holding the relevant publish
162
- * capability (`pipelines:publish` / `plugins:publish`) — superadmins pass via
163
- * implicit-all. Everyone else (including callers who requested 'public' without
164
- * the permission, and service principals) gets 'private'.
165
- *
166
- * Permission-based (not coarse-role-based): a bespoke custom Role can be granted
167
- * publish rights and is no longer forced private by its `member` label. Built-in
168
- * Admin/Owner bundles carry the publish permissions, so their behavior is
169
- * unchanged; the built-in Member bundle does not, so members stay private-only.
170
- */
171
- export declare function resolveAccessModifier(req: Request, requested: string | undefined, publishPermission: Permission): 'public' | 'private';
159
+ /** Replace the service-token denylist (service names). Empty ⇒ kill-switch off. */
160
+ export declare function setServiceTokenDenylist(names: Iterable<string>): void;
161
+ /** True when `sub` is `service:<name>` and `<name>` is on the denylist. */
162
+ export declare function isServiceTokenDenied(sub: string): boolean;
172
163
  export interface ServiceTokenOptions {
173
164
  /** Calling service identifier (e.g. 'billing', 'platform'). Embedded as `sub: service:<name>`. */
174
165
  serviceName: string;
@@ -187,6 +178,13 @@ export interface ServiceTokenOptions {
187
178
  * `isAdmin` is derived from this (admin|owner → true).
188
179
  */
189
180
  role: 'owner' | 'admin' | 'member';
181
+ /**
182
+ * Optional fine-grained permission claim. Prefer this + `role: 'member'` over a
183
+ * high role when a call needs ONE specific capability (e.g. `['plugins:write']`
184
+ * to push a plugin image) — the token then satisfies that permission gate
185
+ * WITHOUT carrying `isAdmin`, so a leaked token can't perform admin actions.
186
+ */
187
+ permissions?: Permission[];
190
188
  }
191
189
  /**
192
190
  * Mint a JWT identifying the calling service. Used for inter-service HTTP calls.