@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.
- package/LICENSE +202 -0
- package/README.md +98 -0
- package/lib/constants/ai-providers.d.ts +52 -0
- package/lib/constants/ai-providers.js +129 -0
- package/lib/constants/http-status.d.ts +20 -0
- package/lib/constants/http-status.js +26 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.js +6 -0
- package/lib/constants/time.d.ts +10 -0
- package/lib/constants/time.js +13 -0
- package/lib/errors/app-errors.d.ts +30 -0
- package/lib/errors/app-errors.js +53 -0
- package/lib/errors/index.d.ts +1 -0
- package/lib/errors/index.js +4 -0
- package/lib/helpers/access-helpers.d.ts +63 -0
- package/lib/helpers/access-helpers.js +82 -0
- package/lib/helpers/crud-helpers.d.ts +9 -0
- package/lib/helpers/crud-helpers.js +23 -0
- package/lib/helpers/index.d.ts +6 -0
- package/lib/helpers/index.js +9 -0
- package/lib/helpers/org-hierarchy-http.d.ts +74 -0
- package/lib/helpers/org-hierarchy-http.js +144 -0
- package/lib/helpers/org-hierarchy.d.ts +57 -0
- package/lib/helpers/org-hierarchy.js +110 -0
- package/lib/helpers/restore-helpers.d.ts +49 -0
- package/lib/helpers/restore-helpers.js +78 -0
- package/lib/helpers/sse-helpers.d.ts +20 -0
- package/lib/helpers/sse-helpers.js +45 -0
- package/lib/index.d.ts +58 -0
- package/lib/index.js +71 -0
- package/lib/middleware/auth.d.ts +208 -0
- package/lib/middleware/auth.js +588 -0
- package/lib/middleware/index.d.ts +3 -0
- package/lib/middleware/index.js +6 -0
- package/lib/middleware/mongo-sanitize.d.ts +32 -0
- package/lib/middleware/mongo-sanitize.js +100 -0
- package/lib/middleware/step-up.d.ts +45 -0
- package/lib/middleware/step-up.js +138 -0
- package/lib/openapi/extend-zod.d.ts +1 -0
- package/lib/openapi/extend-zod.js +6 -0
- package/lib/openapi/index.d.ts +2 -0
- package/lib/openapi/index.js +5 -0
- package/lib/openapi/registry.d.ts +17 -0
- package/lib/openapi/registry.js +38 -0
- package/lib/openapi/routes/ask-routes.d.ts +7 -0
- package/lib/openapi/routes/ask-routes.js +62 -0
- package/lib/openapi/routes/billing-routes.d.ts +1 -0
- package/lib/openapi/routes/billing-routes.js +66 -0
- package/lib/openapi/routes/image-registry-routes.d.ts +7 -0
- package/lib/openapi/routes/image-registry-routes.js +98 -0
- package/lib/openapi/routes/index.d.ts +5 -0
- package/lib/openapi/routes/index.js +28 -0
- package/lib/openapi/routes/message-routes.d.ts +1 -0
- package/lib/openapi/routes/message-routes.js +105 -0
- package/lib/openapi/routes/pipeline-routes.d.ts +1 -0
- package/lib/openapi/routes/pipeline-routes.js +105 -0
- package/lib/openapi/routes/pipeline-template-routes.d.ts +1 -0
- package/lib/openapi/routes/pipeline-template-routes.js +61 -0
- package/lib/openapi/routes/plugin-routes.d.ts +1 -0
- package/lib/openapi/routes/plugin-routes.js +96 -0
- package/lib/openapi/routes/quota-routes.d.ts +1 -0
- package/lib/openapi/routes/quota-routes.js +62 -0
- package/lib/openapi/schema-registry.d.ts +25 -0
- package/lib/openapi/schema-registry.js +91 -0
- package/lib/routes/health.d.ts +41 -0
- package/lib/routes/health.js +82 -0
- package/lib/routes/index.d.ts +1 -0
- package/lib/routes/index.js +4 -0
- package/lib/services/audit-spool.d.ts +80 -0
- package/lib/services/audit-spool.js +172 -0
- package/lib/services/cache-service.d.ts +124 -0
- package/lib/services/cache-service.js +276 -0
- package/lib/services/circuit-breaker.d.ts +45 -0
- package/lib/services/circuit-breaker.js +138 -0
- package/lib/services/compliance-client.d.ts +46 -0
- package/lib/services/compliance-client.js +128 -0
- package/lib/services/compliance-event-subscriber.d.ts +16 -0
- package/lib/services/compliance-event-subscriber.js +72 -0
- package/lib/services/durable-event-bus.d.ts +96 -0
- package/lib/services/durable-event-bus.js +204 -0
- package/lib/services/entity-events.d.ts +48 -0
- package/lib/services/entity-events.js +79 -0
- package/lib/services/env-redis.d.ts +44 -0
- package/lib/services/env-redis.js +94 -0
- package/lib/services/http-client.d.ts +143 -0
- package/lib/services/http-client.js +335 -0
- package/lib/services/index.d.ts +18 -0
- package/lib/services/index.js +20 -0
- package/lib/services/leader-lock.d.ts +45 -0
- package/lib/services/leader-lock.js +85 -0
- package/lib/services/quota.d.ts +130 -0
- package/lib/services/quota.js +264 -0
- package/lib/services/remote-audit-client.d.ts +160 -0
- package/lib/services/remote-audit-client.js +390 -0
- package/lib/services/retry-strategy.d.ts +74 -0
- package/lib/services/retry-strategy.js +118 -0
- package/lib/services/scheduler.d.ts +41 -0
- package/lib/services/scheduler.js +86 -0
- package/lib/services/service-boot.d.ts +20 -0
- package/lib/services/service-boot.js +28 -0
- package/lib/services/sse-ticket-store.d.ts +51 -0
- package/lib/services/sse-ticket-store.js +130 -0
- package/lib/services/token-revocation.d.ts +52 -0
- package/lib/services/token-revocation.js +120 -0
- package/lib/testing/tier-mock.d.ts +44 -0
- package/lib/testing/tier-mock.js +65 -0
- package/lib/types/audit-events.d.ts +69 -0
- package/lib/types/audit-events.js +4 -0
- package/lib/types/catalog-metadata.d.ts +36 -0
- package/lib/types/catalog-metadata.js +21 -0
- package/lib/types/common.d.ts +255 -0
- package/lib/types/common.js +41 -0
- package/lib/types/error-codes.d.ts +54 -0
- package/lib/types/error-codes.js +107 -0
- package/lib/types/feature-flags.d.ts +36 -0
- package/lib/types/feature-flags.js +128 -0
- package/lib/types/http.d.ts +27 -0
- package/lib/types/http.js +4 -0
- package/lib/types/index.d.ts +11 -0
- package/lib/types/index.js +14 -0
- package/lib/types/permissions.d.ts +65 -0
- package/lib/types/permissions.js +131 -0
- package/lib/types/pipeline-template.d.ts +30 -0
- package/lib/types/pipeline-template.js +13 -0
- package/lib/types/pipeline.d.ts +59 -0
- package/lib/types/pipeline.js +31 -0
- package/lib/types/quota-tiers.d.ts +79 -0
- package/lib/types/quota-tiers.js +221 -0
- package/lib/types/visibility.d.ts +20 -0
- package/lib/types/visibility.js +22 -0
- package/lib/utils/alias-resolver.d.ts +37 -0
- package/lib/utils/alias-resolver.js +68 -0
- package/lib/utils/audit.d.ts +15 -0
- package/lib/utils/audit.js +39 -0
- package/lib/utils/aws-scrub.d.ts +11 -0
- package/lib/utils/aws-scrub.js +67 -0
- package/lib/utils/compliance-attributes.d.ts +6 -0
- package/lib/utils/compliance-attributes.js +69 -0
- package/lib/utils/concurrency.d.ts +9 -0
- package/lib/utils/concurrency.js +29 -0
- package/lib/utils/crash-handlers.d.ts +18 -0
- package/lib/utils/crash-handlers.js +36 -0
- package/lib/utils/env.d.ts +28 -0
- package/lib/utils/env.js +54 -0
- package/lib/utils/headers.d.ts +18 -0
- package/lib/utils/headers.js +21 -0
- package/lib/utils/identity.d.ts +40 -0
- package/lib/utils/identity.js +51 -0
- package/lib/utils/index.d.ts +17 -0
- package/lib/utils/index.js +20 -0
- package/lib/utils/logger.d.ts +38 -0
- package/lib/utils/logger.js +174 -0
- package/lib/utils/metric-emitter.d.ts +36 -0
- package/lib/utils/metric-emitter.js +32 -0
- package/lib/utils/object.d.ts +13 -0
- package/lib/utils/object.js +18 -0
- package/lib/utils/params.d.ts +150 -0
- package/lib/utils/params.js +206 -0
- package/lib/utils/response.d.ts +117 -0
- package/lib/utils/response.js +223 -0
- package/lib/utils/safe-require.d.ts +13 -0
- package/lib/utils/safe-require.js +19 -0
- package/lib/utils/secret-encryption.d.ts +176 -0
- package/lib/utils/secret-encryption.js +374 -0
- package/lib/utils/ssrf.d.ts +30 -0
- package/lib/utils/ssrf.js +106 -0
- package/lib/validation/ai-schemas.d.ts +56 -0
- package/lib/validation/ai-schemas.js +78 -0
- package/lib/validation/common-schemas.d.ts +133 -0
- package/lib/validation/common-schemas.js +94 -0
- package/lib/validation/index.d.ts +7 -0
- package/lib/validation/index.js +10 -0
- package/lib/validation/message-schemas.d.ts +160 -0
- package/lib/validation/message-schemas.js +156 -0
- package/lib/validation/middleware.d.ts +72 -0
- package/lib/validation/middleware.js +65 -0
- package/lib/validation/pipeline-schemas.d.ts +181 -0
- package/lib/validation/pipeline-schemas.js +101 -0
- package/lib/validation/pipeline-template-schemas.d.ts +155 -0
- package/lib/validation/pipeline-template-schemas.js +66 -0
- package/lib/validation/plugin-schemas.d.ts +171 -0
- package/lib/validation/plugin-schemas.js +81 -0
- package/openapi.yaml +292 -0
- package/package.json +167 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import type { Permission } from './permissions.js';
|
|
2
|
+
import type { QuotaTier } from './quota-tiers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Capability scope catalog for machine/automation tokens. A scoped token carries
|
|
5
|
+
* exactly one of these instead of role-based permissions; endpoints that accept a
|
|
6
|
+
* scoped identity check it via `hasScope`. Kept a closed union (mirroring
|
|
7
|
+
* {@link Permission}) so a typo on either the mint or the check side is a compile
|
|
8
|
+
* error. Add a value here when introducing a new scoped-token surface.
|
|
9
|
+
*/
|
|
10
|
+
export type TokenScope = 'reporting:ingest';
|
|
11
|
+
/**
|
|
12
|
+
* Quota type identifiers.
|
|
13
|
+
*
|
|
14
|
+
* - `plugins` / `pipelines` — count of created entities
|
|
15
|
+
* - `apiCalls` — generic API call count (read-heavy paths)
|
|
16
|
+
* - `aiCalls` — AI provider invocations (counted separately because each call
|
|
17
|
+
* has external dollar cost; sized smaller than apiCalls per tier)
|
|
18
|
+
* - `storageBytes` — registry storage budget per org. Unlike the others
|
|
19
|
+
* (which count discrete events), this is a measured total recomputed
|
|
20
|
+
* on demand. Incremented by the image-registry's push-gate before
|
|
21
|
+
* issuing a token whose scope includes `push`; the GC scheduler
|
|
22
|
+
* eventually frees the bytes, then the next push-gate check reads
|
|
23
|
+
* the lower value. NOT a counter-style quota in the sense of
|
|
24
|
+
* `incrementUsage` — the registry pushes the measured total via
|
|
25
|
+
* `updateLimits`/`resetUsage` flows. Tier limits are bytes.
|
|
26
|
+
* - `dashboards` / `alertRules` / `alertDestinations` / `idpConfigs` —
|
|
27
|
+
* resource-count quotas added to close per-org DoS surfaces in the
|
|
28
|
+
* user-editable feature tables. Without these caps a single org could
|
|
29
|
+
* spam thousands of dashboards / rules and bloat the shared Postgres /
|
|
30
|
+
* Mongo working sets. Counted at create time; decremented on delete.
|
|
31
|
+
*/
|
|
32
|
+
export type QuotaType = 'plugins' | 'pipelines' | 'apiCalls' | 'aiCalls' | 'storageBytes' | 'dashboards' | 'alertRules' | 'alertDestinations' | 'idpConfigs';
|
|
33
|
+
/**
|
|
34
|
+
* Valid quota type values.
|
|
35
|
+
*/
|
|
36
|
+
export declare const VALID_QUOTA_TYPES: readonly ['plugins', 'pipelines', 'apiCalls', 'aiCalls', 'storageBytes', 'dashboards', 'alertRules', 'alertDestinations', 'idpConfigs'];
|
|
37
|
+
/**
|
|
38
|
+
* Type guard to check if a value is a valid QuotaType.
|
|
39
|
+
*
|
|
40
|
+
* @param value - Value to check
|
|
41
|
+
* @returns True if value is a valid QuotaType
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* if (isValidQuotaType(req.body.quotaType)) {
|
|
46
|
+
* // quotaType is guaranteed to be QuotaType
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function isValidQuotaType(value: unknown): value is QuotaType;
|
|
51
|
+
/**
|
|
52
|
+
* Result from quota check operation.
|
|
53
|
+
*/
|
|
54
|
+
export interface QuotaCheckResult {
|
|
55
|
+
/** Whether the request is allowed */
|
|
56
|
+
allowed: boolean;
|
|
57
|
+
/** Maximum quota limit (-1 for unlimited) */
|
|
58
|
+
limit: number;
|
|
59
|
+
/** Current usage count */
|
|
60
|
+
used: number;
|
|
61
|
+
/** Remaining quota (-1 for unlimited) */
|
|
62
|
+
remaining: number;
|
|
63
|
+
/** ISO timestamp when quota resets */
|
|
64
|
+
resetAt: string;
|
|
65
|
+
/** Whether quota is unlimited */
|
|
66
|
+
unlimited: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* True ONLY when this result is the fail-open sentinel returned because the
|
|
69
|
+
* quota service was unreachable / returned non-ok (not a real quota reading).
|
|
70
|
+
* Lets fail-closed callers (e.g. the registry storage push-gate) distinguish
|
|
71
|
+
* an outage from a genuine `limit: -1` (unlimited) org. Absent on real results.
|
|
72
|
+
*/
|
|
73
|
+
failOpen?: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Quota information for error responses.
|
|
77
|
+
*/
|
|
78
|
+
export interface QuotaInfo {
|
|
79
|
+
type: QuotaType;
|
|
80
|
+
limit: number;
|
|
81
|
+
used: number;
|
|
82
|
+
remaining: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Standard API success response.
|
|
86
|
+
*/
|
|
87
|
+
export interface ApiSuccessResponse<T = unknown> {
|
|
88
|
+
success: true;
|
|
89
|
+
statusCode: number;
|
|
90
|
+
data?: T;
|
|
91
|
+
message?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Standard API error response.
|
|
95
|
+
*/
|
|
96
|
+
export interface ApiErrorResponse {
|
|
97
|
+
success: false;
|
|
98
|
+
statusCode: number;
|
|
99
|
+
message: string;
|
|
100
|
+
code?: string;
|
|
101
|
+
details?: unknown;
|
|
102
|
+
quota?: QuotaInfo;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Combined API response type.
|
|
106
|
+
*/
|
|
107
|
+
export type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;
|
|
108
|
+
/**
|
|
109
|
+
* JWT payload from access tokens.
|
|
110
|
+
*
|
|
111
|
+
* Users can belong to multiple organizations. The token is scoped to one
|
|
112
|
+
* active organization at a time. The `role` field is the user's per-org
|
|
113
|
+
* role in that organization (from the UserOrganization junction collection),
|
|
114
|
+
* and `isAdmin` is derived as `role === 'admin' || role === 'owner'`.
|
|
115
|
+
*
|
|
116
|
+
* Use `POST /auth/switch-org` to change the active organization, which
|
|
117
|
+
* re-issues tokens with the new org's role and context.
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* Coarse per-org membership label, DERIVED from the Roles a user is assigned
|
|
121
|
+
* (the highest `grantsRole` among them; `owner` is set only by ownership
|
|
122
|
+
* transfer). It is a display/authority label — driving `isAdmin`, ownership,
|
|
123
|
+
* and seat accounting — NOT a permission source. Effective permissions come
|
|
124
|
+
* solely from the user's assigned Roles (see `resolveUserPermissions`). Not a
|
|
125
|
+
* global role.
|
|
126
|
+
*/
|
|
127
|
+
export type OrgRole = 'owner' | 'admin' | 'member';
|
|
128
|
+
export interface JwtPayload {
|
|
129
|
+
/** User ID (subject) */
|
|
130
|
+
sub: string;
|
|
131
|
+
/** Username */
|
|
132
|
+
username: string;
|
|
133
|
+
/** User email */
|
|
134
|
+
email: string;
|
|
135
|
+
/** Per-org role in the active organization ('owner' | 'admin' | 'member'). Not a global role. */
|
|
136
|
+
role: OrgRole;
|
|
137
|
+
/** Derived: true when role is 'admin' or 'owner' in the active organization */
|
|
138
|
+
isAdmin?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Resolved fine-grained permissions for the active org/team — the union of
|
|
141
|
+
* the permissions carried by every Role the user is assigned (see
|
|
142
|
+
* `resolveUserPermissions`). Absent on machine/scoped tokens. Superadmins are
|
|
143
|
+
* granted all permissions implicitly and may omit this. Endpoints enforce via
|
|
144
|
+
* `requirePermission(...)`.
|
|
145
|
+
*/
|
|
146
|
+
permissions?: Permission[];
|
|
147
|
+
/**
|
|
148
|
+
* Global super-admin flag (cross-org). When `true`, the user is treated
|
|
149
|
+
* as a system administrator regardless of which org they're currently
|
|
150
|
+
* acting under. This is the SOLE signal for sysadmin authority — the old path
|
|
151
|
+
* (membership in the well-known "system" org with role admin/owner) has been
|
|
152
|
+
* removed because it conflated "Pipeline Builder operator" with "real customer
|
|
153
|
+
* tenant" in the data model. Grant sysadmin only via `isSuperAdmin`.
|
|
154
|
+
*/
|
|
155
|
+
isSuperAdmin?: boolean;
|
|
156
|
+
/** Organization's quota tier. */
|
|
157
|
+
tier?: QuotaTier;
|
|
158
|
+
/** Resolved feature flags for this user/org */
|
|
159
|
+
features?: string[];
|
|
160
|
+
/**
|
|
161
|
+
* Narrow capability scope for machine/automation tokens (e.g.
|
|
162
|
+
* `'reporting:ingest'`). Absent on normal interactive user tokens. Endpoints
|
|
163
|
+
* that accept a scoped identity check this (see `hasScope`) instead of role;
|
|
164
|
+
* a scoped token is minted with minimal role for least-privilege.
|
|
165
|
+
*/
|
|
166
|
+
scope?: TokenScope;
|
|
167
|
+
/** Active organization ID (from UserOrganization membership) */
|
|
168
|
+
organizationId?: string;
|
|
169
|
+
/** Active organization name */
|
|
170
|
+
organizationName?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Org → team hierarchy (org-team-hierarchy proposal, phase 1).
|
|
173
|
+
* `parentOrganizationId` is the active org's direct parent; `rootOrganizationId`
|
|
174
|
+
* is the top of its ancestry chain. Both are **omitted for flat (root) orgs** —
|
|
175
|
+
* consumers should treat the effective root as `rootOrganizationId ?? organizationId`
|
|
176
|
+
* (use the shared {@link effectiveRootOrgId} accessor rather than coalescing inline).
|
|
177
|
+
* Currently every org is flat, so these are absent on all tokens today.
|
|
178
|
+
*/
|
|
179
|
+
parentOrganizationId?: string;
|
|
180
|
+
/** Root organization ID of the active org's ancestry chain (see `parentOrganizationId`). */
|
|
181
|
+
rootOrganizationId?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Set on tokens issued by the sysadmin impersonation flow
|
|
184
|
+
* (`POST /admin/impersonate/:userId`). Carries the original sysadmin's
|
|
185
|
+
* user id so audit events still attribute actions correctly.
|
|
186
|
+
*/
|
|
187
|
+
impersonatorId?: string;
|
|
188
|
+
/**
|
|
189
|
+
* When true, the token is read-only — any non-GET request is rejected
|
|
190
|
+
* upstream by the platform's read-only impersonation gate. Lets
|
|
191
|
+
* sysadmins "view as user X" without risking a destructive action.
|
|
192
|
+
*/
|
|
193
|
+
impersonationReadOnly?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* The user's `tokenVersion` at the moment this token was issued. Every
|
|
196
|
+
* privilege change (deactivate / role or tier downgrade / membership or
|
|
197
|
+
* ownership change / password change / logout-all) increments the user's
|
|
198
|
+
* server-side `tokenVersion`, so a token whose embedded version is behind the
|
|
199
|
+
* current one has been REVOKED. Platform validates this against Mongo; the
|
|
200
|
+
* stateless services validate it against a Redis-published current-version
|
|
201
|
+
* store (see `setTokenRevocationStore`). Absent on machine/service tokens.
|
|
202
|
+
*/
|
|
203
|
+
tokenVersion?: number;
|
|
204
|
+
/** Token type */
|
|
205
|
+
type: 'access' | 'refresh';
|
|
206
|
+
/** Issued at timestamp */
|
|
207
|
+
iat?: number;
|
|
208
|
+
/** Expiration timestamp */
|
|
209
|
+
exp?: number;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The account boundary (root org) for a token's active org.
|
|
213
|
+
*
|
|
214
|
+
* The account root is `rootOrganizationId ?? organizationId`: a flat (root) org
|
|
215
|
+
* omits `rootOrganizationId`, so it IS its own root; a team (child) org carries
|
|
216
|
+
* the top of its ancestry chain. Every account-scoped read (quota/seat/billing
|
|
217
|
+
* pooling) must resolve through this coalesce rather than reading
|
|
218
|
+
* `organizationId` directly — the latter silently works today (all orgs flat)
|
|
219
|
+
* but would bind to the team instead of the account once teams exist.
|
|
220
|
+
*
|
|
221
|
+
* @returns the effective root org id, or `undefined` when neither field is set.
|
|
222
|
+
*/
|
|
223
|
+
export declare function effectiveRootOrgId(payload: Pick<JwtPayload, 'organizationId' | 'rootOrganizationId'>): string | undefined;
|
|
224
|
+
/**
|
|
225
|
+
* Extended Express Request with user property.
|
|
226
|
+
*/
|
|
227
|
+
declare global {
|
|
228
|
+
namespace Express {
|
|
229
|
+
interface Request {
|
|
230
|
+
user?: JwtPayload;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Service configuration for internal HTTP client.
|
|
236
|
+
*/
|
|
237
|
+
export interface ServiceConfig {
|
|
238
|
+
/** Service hostname */
|
|
239
|
+
host: string;
|
|
240
|
+
/** Service port */
|
|
241
|
+
port: number;
|
|
242
|
+
/** Request timeout in milliseconds */
|
|
243
|
+
timeout?: number;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Health check response.
|
|
247
|
+
*/
|
|
248
|
+
export interface HealthCheckResponse {
|
|
249
|
+
status: 'healthy' | 'unhealthy';
|
|
250
|
+
service: string;
|
|
251
|
+
timestamp: string;
|
|
252
|
+
uptime: number;
|
|
253
|
+
version?: string;
|
|
254
|
+
dependencies?: Record<string, 'connected' | 'disconnected' | 'unknown'>;
|
|
255
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Valid quota type values.
|
|
5
|
+
*/
|
|
6
|
+
export const VALID_QUOTA_TYPES = [
|
|
7
|
+
'plugins', 'pipelines', 'apiCalls', 'aiCalls', 'storageBytes',
|
|
8
|
+
'dashboards', 'alertRules', 'alertDestinations', 'idpConfigs',
|
|
9
|
+
];
|
|
10
|
+
/**
|
|
11
|
+
* Type guard to check if a value is a valid QuotaType.
|
|
12
|
+
*
|
|
13
|
+
* @param value - Value to check
|
|
14
|
+
* @returns True if value is a valid QuotaType
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* if (isValidQuotaType(req.body.quotaType)) {
|
|
19
|
+
* // quotaType is guaranteed to be QuotaType
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function isValidQuotaType(value) {
|
|
24
|
+
return typeof value === 'string' && VALID_QUOTA_TYPES.includes(value);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The account boundary (root org) for a token's active org.
|
|
28
|
+
*
|
|
29
|
+
* The account root is `rootOrganizationId ?? organizationId`: a flat (root) org
|
|
30
|
+
* omits `rootOrganizationId`, so it IS its own root; a team (child) org carries
|
|
31
|
+
* the top of its ancestry chain. Every account-scoped read (quota/seat/billing
|
|
32
|
+
* pooling) must resolve through this coalesce rather than reading
|
|
33
|
+
* `organizationId` directly — the latter silently works today (all orgs flat)
|
|
34
|
+
* but would bind to the team instead of the account once teams exist.
|
|
35
|
+
*
|
|
36
|
+
* @returns the effective root org id, or `undefined` when neither field is set.
|
|
37
|
+
*/
|
|
38
|
+
export function effectiveRootOrgId(payload) {
|
|
39
|
+
return payload.rootOrganizationId ?? payload.organizationId;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBMEN0Qzs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHO0lBQy9CLFNBQVMsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxjQUFjO0lBQzdELFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsWUFBWTtDQUNyRCxDQUFDO0FBRVg7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWM7SUFDN0MsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksaUJBQWlCLENBQUMsUUFBUSxDQUFDLEtBQWtCLENBQUMsQ0FBQztBQUNyRixDQUFDO0FBeUtEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxPQUFrRTtJQUVsRSxPQUFPLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDO0FBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBQZXJtaXNzaW9uIH0gZnJvbSAnLi9wZXJtaXNzaW9ucy5qcyc7XG5pbXBvcnQgdHlwZSB7IFF1b3RhVGllciB9IGZyb20gJy4vcXVvdGEtdGllcnMuanMnO1xuXG4vKipcbiAqIENhcGFiaWxpdHkgc2NvcGUgY2F0YWxvZyBmb3IgbWFjaGluZS9hdXRvbWF0aW9uIHRva2Vucy4gQSBzY29wZWQgdG9rZW4gY2Fycmllc1xuICogZXhhY3RseSBvbmUgb2YgdGhlc2UgaW5zdGVhZCBvZiByb2xlLWJhc2VkIHBlcm1pc3Npb25zOyBlbmRwb2ludHMgdGhhdCBhY2NlcHQgYVxuICogc2NvcGVkIGlkZW50aXR5IGNoZWNrIGl0IHZpYSBgaGFzU2NvcGVgLiBLZXB0IGEgY2xvc2VkIHVuaW9uIChtaXJyb3JpbmdcbiAqIHtAbGluayBQZXJtaXNzaW9ufSkgc28gYSB0eXBvIG9uIGVpdGhlciB0aGUgbWludCBvciB0aGUgY2hlY2sgc2lkZSBpcyBhIGNvbXBpbGVcbiAqIGVycm9yLiBBZGQgYSB2YWx1ZSBoZXJlIHdoZW4gaW50cm9kdWNpbmcgYSBuZXcgc2NvcGVkLXRva2VuIHN1cmZhY2UuXG4gKi9cbmV4cG9ydCB0eXBlIFRva2VuU2NvcGUgPSAncmVwb3J0aW5nOmluZ2VzdCc7XG5cbi8qKlxuICogUXVvdGEgdHlwZSBpZGVudGlmaWVycy5cbiAqXG4gKiAtIGBwbHVnaW5zYCAvIGBwaXBlbGluZXNgIOKAlCBjb3VudCBvZiBjcmVhdGVkIGVudGl0aWVzXG4gKiAtIGBhcGlDYWxsc2Ag4oCUIGdlbmVyaWMgQVBJIGNhbGwgY291bnQgKHJlYWQtaGVhdnkgcGF0aHMpXG4gKiAtIGBhaUNhbGxzYCDigJQgQUkgcHJvdmlkZXIgaW52b2NhdGlvbnMgKGNvdW50ZWQgc2VwYXJhdGVseSBiZWNhdXNlIGVhY2ggY2FsbFxuICogICBoYXMgZXh0ZXJuYWwgZG9sbGFyIGNvc3Q7IHNpemVkIHNtYWxsZXIgdGhhbiBhcGlDYWxscyBwZXIgdGllcilcbiAqIC0gYHN0b3JhZ2VCeXRlc2Ag4oCUIHJlZ2lzdHJ5IHN0b3JhZ2UgYnVkZ2V0IHBlciBvcmcuIFVubGlrZSB0aGUgb3RoZXJzXG4gKiAgICh3aGljaCBjb3VudCBkaXNjcmV0ZSBldmVudHMpLCB0aGlzIGlzIGEgbWVhc3VyZWQgdG90YWwgcmVjb21wdXRlZFxuICogICBvbiBkZW1hbmQuIEluY3JlbWVudGVkIGJ5IHRoZSBpbWFnZS1yZWdpc3RyeSdzIHB1c2gtZ2F0ZSBiZWZvcmVcbiAqICAgaXNzdWluZyBhIHRva2VuIHdob3NlIHNjb3BlIGluY2x1ZGVzIGBwdXNoYDsgdGhlIEdDIHNjaGVkdWxlclxuICogICBldmVudHVhbGx5IGZyZWVzIHRoZSBieXRlcywgdGhlbiB0aGUgbmV4dCBwdXNoLWdhdGUgY2hlY2sgcmVhZHNcbiAqICAgdGhlIGxvd2VyIHZhbHVlLiBOT1QgYSBjb3VudGVyLXN0eWxlIHF1b3RhIGluIHRoZSBzZW5zZSBvZlxuICogICBgaW5jcmVtZW50VXNhZ2VgIOKAlCB0aGUgcmVnaXN0cnkgcHVzaGVzIHRoZSBtZWFzdXJlZCB0b3RhbCB2aWFcbiAqICAgYHVwZGF0ZUxpbWl0c2AvYHJlc2V0VXNhZ2VgIGZsb3dzLiBUaWVyIGxpbWl0cyBhcmUgYnl0ZXMuXG4gKiAtIGBkYXNoYm9hcmRzYCAvIGBhbGVydFJ1bGVzYCAvIGBhbGVydERlc3RpbmF0aW9uc2AgLyBgaWRwQ29uZmlnc2Ag4oCUXG4gKiAgIHJlc291cmNlLWNvdW50IHF1b3RhcyBhZGRlZCB0byBjbG9zZSBwZXItb3JnIERvUyBzdXJmYWNlcyBpbiB0aGVcbiAqICAgdXNlci1lZGl0YWJsZSBmZWF0dXJlIHRhYmxlcy4gV2l0aG91dCB0aGVzZSBjYXBzIGEgc2luZ2xlIG9yZyBjb3VsZFxuICogICBzcGFtIHRob3VzYW5kcyBvZiBkYXNoYm9hcmRzIC8gcnVsZXMgYW5kIGJsb2F0IHRoZSBzaGFyZWQgUG9zdGdyZXMgL1xuICogICBNb25nbyB3b3JraW5nIHNldHMuIENvdW50ZWQgYXQgY3JlYXRlIHRpbWU7IGRlY3JlbWVudGVkIG9uIGRlbGV0ZS5cbiAqL1xuLy8gTk9URTogYHNlYXRzYCBpcyBpbnRlbnRpb25hbGx5IE5PVCBoZXJlLiBJdCdzIGEgdGllciBsaW1pdCAoUXVvdGFUaWVyTGltaXRzKVxuLy8gZW5mb3JjZWQgYnkgY29tcGFyaW5nIHRoZSBvcmcncyBMSVZFIG1lbWJlciBjb3VudCBhdCBpbnZpdGUgdGltZSDigJQgbm90IGFuXG4vLyBpbmNyZW1lbnRpbmcgcGVyLXBlcmlvZCBjb3VudGVyIGxpa2UgdGhlIGNvbnN1bWFibGUgcXVvdGFzIGJlbG93LlxuZXhwb3J0IHR5cGUgUXVvdGFUeXBlID1cbiAgfCAncGx1Z2lucycgfCAncGlwZWxpbmVzJyB8ICdhcGlDYWxscycgfCAnYWlDYWxscycgfCAnc3RvcmFnZUJ5dGVzJ1xuICB8ICdkYXNoYm9hcmRzJyB8ICdhbGVydFJ1bGVzJyB8ICdhbGVydERlc3RpbmF0aW9ucycgfCAnaWRwQ29uZmlncyc7XG5cbi8qKlxuICogVmFsaWQgcXVvdGEgdHlwZSB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBWQUxJRF9RVU9UQV9UWVBFUyA9IFtcbiAgJ3BsdWdpbnMnLCAncGlwZWxpbmVzJywgJ2FwaUNhbGxzJywgJ2FpQ2FsbHMnLCAnc3RvcmFnZUJ5dGVzJyxcbiAgJ2Rhc2hib2FyZHMnLCAnYWxlcnRSdWxlcycsICdhbGVydERlc3RpbmF0aW9ucycsICdpZHBDb25maWdzJyxcbl0gYXMgY29uc3Q7XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgUXVvdGFUeXBlLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHZhbHVlIGlzIGEgdmFsaWQgUXVvdGFUeXBlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmIChpc1ZhbGlkUXVvdGFUeXBlKHJlcS5ib2R5LnF1b3RhVHlwZSkpIHtcbiAqICAgLy8gcXVvdGFUeXBlIGlzIGd1YXJhbnRlZWQgdG8gYmUgUXVvdGFUeXBlXG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRRdW90YVR5cGUodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBRdW90YVR5cGUge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiBWQUxJRF9RVU9UQV9UWVBFUy5pbmNsdWRlcyh2YWx1ZSBhcyBRdW90YVR5cGUpO1xufVxuXG4vKipcbiAqIFJlc3VsdCBmcm9tIHF1b3RhIGNoZWNrIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YUNoZWNrUmVzdWx0IHtcbiAgLyoqIFdoZXRoZXIgdGhlIHJlcXVlc3QgaXMgYWxsb3dlZCAqL1xuICBhbGxvd2VkOiBib29sZWFuO1xuICAvKiogTWF4aW11bSBxdW90YSBsaW1pdCAoLTEgZm9yIHVubGltaXRlZCkgKi9cbiAgbGltaXQ6IG51bWJlcjtcbiAgLyoqIEN1cnJlbnQgdXNhZ2UgY291bnQgKi9cbiAgdXNlZDogbnVtYmVyO1xuICAvKiogUmVtYWluaW5nIHF1b3RhICgtMSBmb3IgdW5saW1pdGVkKSAqL1xuICByZW1haW5pbmc6IG51bWJlcjtcbiAgLyoqIElTTyB0aW1lc3RhbXAgd2hlbiBxdW90YSByZXNldHMgKi9cbiAgcmVzZXRBdDogc3RyaW5nO1xuICAvKiogV2hldGhlciBxdW90YSBpcyB1bmxpbWl0ZWQgKi9cbiAgdW5saW1pdGVkOiBib29sZWFuO1xuICAvKipcbiAgICogVHJ1ZSBPTkxZIHdoZW4gdGhpcyByZXN1bHQgaXMgdGhlIGZhaWwtb3BlbiBzZW50aW5lbCByZXR1cm5lZCBiZWNhdXNlIHRoZVxuICAgKiBxdW90YSBzZXJ2aWNlIHdhcyB1bnJlYWNoYWJsZSAvIHJldHVybmVkIG5vbi1vayAobm90IGEgcmVhbCBxdW90YSByZWFkaW5nKS5cbiAgICogTGV0cyBmYWlsLWNsb3NlZCBjYWxsZXJzIChlLmcuIHRoZSByZWdpc3RyeSBzdG9yYWdlIHB1c2gtZ2F0ZSkgZGlzdGluZ3Vpc2hcbiAgICogYW4gb3V0YWdlIGZyb20gYSBnZW51aW5lIGBsaW1pdDogLTFgICh1bmxpbWl0ZWQpIG9yZy4gQWJzZW50IG9uIHJlYWwgcmVzdWx0cy5cbiAgICovXG4gIGZhaWxPcGVuPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBRdW90YSBpbmZvcm1hdGlvbiBmb3IgZXJyb3IgcmVzcG9uc2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1b3RhSW5mbyB7XG4gIHR5cGU6IFF1b3RhVHlwZTtcbiAgbGltaXQ6IG51bWJlcjtcbiAgdXNlZDogbnVtYmVyO1xuICByZW1haW5pbmc6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBBUEkgc3VjY2VzcyByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcGlTdWNjZXNzUmVzcG9uc2U8VCA9IHVua25vd24+IHtcbiAgc3VjY2VzczogdHJ1ZTtcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xuICBkYXRhPzogVDtcbiAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBBUEkgZXJyb3IgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBpRXJyb3JSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGZhbHNlO1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgY29kZT86IHN0cmluZztcbiAgZGV0YWlscz86IHVua25vd247XG4gIHF1b3RhPzogUXVvdGFJbmZvO1xufVxuXG4vKipcbiAqIENvbWJpbmVkIEFQSSByZXNwb25zZSB0eXBlLlxuICovXG5leHBvcnQgdHlwZSBBcGlSZXNwb25zZTxUID0gdW5rbm93bj4gPSBBcGlTdWNjZXNzUmVzcG9uc2U8VD4gfCBBcGlFcnJvclJlc3BvbnNlO1xuXG4vKipcbiAqIEpXVCBwYXlsb2FkIGZyb20gYWNjZXNzIHRva2Vucy5cbiAqXG4gKiBVc2VycyBjYW4gYmVsb25nIHRvIG11bHRpcGxlIG9yZ2FuaXphdGlvbnMuIFRoZSB0b2tlbiBpcyBzY29wZWQgdG8gb25lXG4gKiBhY3RpdmUgb3JnYW5pemF0aW9uIGF0IGEgdGltZS4gVGhlIGByb2xlYCBmaWVsZCBpcyB0aGUgdXNlcidzIHBlci1vcmdcbiAqIHJvbGUgaW4gdGhhdCBvcmdhbml6YXRpb24gKGZyb20gdGhlIFVzZXJPcmdhbml6YXRpb24ganVuY3Rpb24gY29sbGVjdGlvbiksXG4gKiBhbmQgYGlzQWRtaW5gIGlzIGRlcml2ZWQgYXMgYHJvbGUgPT09ICdhZG1pbicgfHwgcm9sZSA9PT0gJ293bmVyJ2AuXG4gKlxuICogVXNlIGBQT1NUIC9hdXRoL3N3aXRjaC1vcmdgIHRvIGNoYW5nZSB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbiwgd2hpY2hcbiAqIHJlLWlzc3VlcyB0b2tlbnMgd2l0aCB0aGUgbmV3IG9yZydzIHJvbGUgYW5kIGNvbnRleHQuXG4gKi9cbi8qKlxuICogQ29hcnNlIHBlci1vcmcgbWVtYmVyc2hpcCBsYWJlbCwgREVSSVZFRCBmcm9tIHRoZSBSb2xlcyBhIHVzZXIgaXMgYXNzaWduZWRcbiAqICh0aGUgaGlnaGVzdCBgZ3JhbnRzUm9sZWAgYW1vbmcgdGhlbTsgYG93bmVyYCBpcyBzZXQgb25seSBieSBvd25lcnNoaXBcbiAqIHRyYW5zZmVyKS4gSXQgaXMgYSBkaXNwbGF5L2F1dGhvcml0eSBsYWJlbCDigJQgZHJpdmluZyBgaXNBZG1pbmAsIG93bmVyc2hpcCxcbiAqIGFuZCBzZWF0IGFjY291bnRpbmcg4oCUIE5PVCBhIHBlcm1pc3Npb24gc291cmNlLiBFZmZlY3RpdmUgcGVybWlzc2lvbnMgY29tZVxuICogc29sZWx5IGZyb20gdGhlIHVzZXIncyBhc3NpZ25lZCBSb2xlcyAoc2VlIGByZXNvbHZlVXNlclBlcm1pc3Npb25zYCkuIE5vdCBhXG4gKiBnbG9iYWwgcm9sZS5cbiAqL1xuZXhwb3J0IHR5cGUgT3JnUm9sZSA9ICdvd25lcicgfCAnYWRtaW4nIHwgJ21lbWJlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnd0UGF5bG9hZCB7XG4gIC8qKiBVc2VyIElEIChzdWJqZWN0KSAqL1xuICBzdWI6IHN0cmluZztcbiAgLyoqIFVzZXJuYW1lICovXG4gIHVzZXJuYW1lOiBzdHJpbmc7XG4gIC8qKiBVc2VyIGVtYWlsICovXG4gIGVtYWlsOiBzdHJpbmc7XG4gIC8qKiBQZXItb3JnIHJvbGUgaW4gdGhlIGFjdGl2ZSBvcmdhbml6YXRpb24gKCdvd25lcicgfCAnYWRtaW4nIHwgJ21lbWJlcicpLiBOb3QgYSBnbG9iYWwgcm9sZS4gKi9cbiAgcm9sZTogT3JnUm9sZTtcbiAgLyoqIERlcml2ZWQ6IHRydWUgd2hlbiByb2xlIGlzICdhZG1pbicgb3IgJ293bmVyJyBpbiB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbiAqL1xuICBpc0FkbWluPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFJlc29sdmVkIGZpbmUtZ3JhaW5lZCBwZXJtaXNzaW9ucyBmb3IgdGhlIGFjdGl2ZSBvcmcvdGVhbSDigJQgdGhlIHVuaW9uIG9mXG4gICAqIHRoZSBwZXJtaXNzaW9ucyBjYXJyaWVkIGJ5IGV2ZXJ5IFJvbGUgdGhlIHVzZXIgaXMgYXNzaWduZWQgKHNlZVxuICAgKiBgcmVzb2x2ZVVzZXJQZXJtaXNzaW9uc2ApLiBBYnNlbnQgb24gbWFjaGluZS9zY29wZWQgdG9rZW5zLiBTdXBlcmFkbWlucyBhcmVcbiAgICogZ3JhbnRlZCBhbGwgcGVybWlzc2lvbnMgaW1wbGljaXRseSBhbmQgbWF5IG9taXQgdGhpcy4gRW5kcG9pbnRzIGVuZm9yY2UgdmlhXG4gICAqIGByZXF1aXJlUGVybWlzc2lvbiguLi4pYC5cbiAgICovXG4gIHBlcm1pc3Npb25zPzogUGVybWlzc2lvbltdO1xuICAvKipcbiAgICogR2xvYmFsIHN1cGVyLWFkbWluIGZsYWcgKGNyb3NzLW9yZykuIFdoZW4gYHRydWVgLCB0aGUgdXNlciBpcyB0cmVhdGVkXG4gICAqIGFzIGEgc3lzdGVtIGFkbWluaXN0cmF0b3IgcmVnYXJkbGVzcyBvZiB3aGljaCBvcmcgdGhleSdyZSBjdXJyZW50bHlcbiAgICogYWN0aW5nIHVuZGVyLiBUaGlzIGlzIHRoZSBTT0xFIHNpZ25hbCBmb3Igc3lzYWRtaW4gYXV0aG9yaXR5IOKAlCB0aGUgb2xkIHBhdGhcbiAgICogKG1lbWJlcnNoaXAgaW4gdGhlIHdlbGwta25vd24gXCJzeXN0ZW1cIiBvcmcgd2l0aCByb2xlIGFkbWluL293bmVyKSBoYXMgYmVlblxuICAgKiByZW1vdmVkIGJlY2F1c2UgaXQgY29uZmxhdGVkIFwiUGlwZWxpbmUgQnVpbGRlciBvcGVyYXRvclwiIHdpdGggXCJyZWFsIGN1c3RvbWVyXG4gICAqIHRlbmFudFwiIGluIHRoZSBkYXRhIG1vZGVsLiBHcmFudCBzeXNhZG1pbiBvbmx5IHZpYSBgaXNTdXBlckFkbWluYC5cbiAgICovXG4gIGlzU3VwZXJBZG1pbj86IGJvb2xlYW47XG4gIC8qKiBPcmdhbml6YXRpb24ncyBxdW90YSB0aWVyLiAqL1xuICB0aWVyPzogUXVvdGFUaWVyO1xuICAvKiogUmVzb2x2ZWQgZmVhdHVyZSBmbGFncyBmb3IgdGhpcyB1c2VyL29yZyAqL1xuICBmZWF0dXJlcz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogTmFycm93IGNhcGFiaWxpdHkgc2NvcGUgZm9yIG1hY2hpbmUvYXV0b21hdGlvbiB0b2tlbnMgKGUuZy5cbiAgICogYCdyZXBvcnRpbmc6aW5nZXN0J2ApLiBBYnNlbnQgb24gbm9ybWFsIGludGVyYWN0aXZlIHVzZXIgdG9rZW5zLiBFbmRwb2ludHNcbiAgICogdGhhdCBhY2NlcHQgYSBzY29wZWQgaWRlbnRpdHkgY2hlY2sgdGhpcyAoc2VlIGBoYXNTY29wZWApIGluc3RlYWQgb2Ygcm9sZTtcbiAgICogYSBzY29wZWQgdG9rZW4gaXMgbWludGVkIHdpdGggbWluaW1hbCByb2xlIGZvciBsZWFzdC1wcml2aWxlZ2UuXG4gICAqL1xuICBzY29wZT86IFRva2VuU2NvcGU7XG4gIC8qKiBBY3RpdmUgb3JnYW5pemF0aW9uIElEIChmcm9tIFVzZXJPcmdhbml6YXRpb24gbWVtYmVyc2hpcCkgKi9cbiAgb3JnYW5pemF0aW9uSWQ/OiBzdHJpbmc7XG4gIC8qKiBBY3RpdmUgb3JnYW5pemF0aW9uIG5hbWUgKi9cbiAgb3JnYW5pemF0aW9uTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIE9yZyDihpIgdGVhbSBoaWVyYXJjaHkgKG9yZy10ZWFtLWhpZXJhcmNoeSBwcm9wb3NhbCwgcGhhc2UgMSkuXG4gICAqIGBwYXJlbnRPcmdhbml6YXRpb25JZGAgaXMgdGhlIGFjdGl2ZSBvcmcncyBkaXJlY3QgcGFyZW50OyBgcm9vdE9yZ2FuaXphdGlvbklkYFxuICAgKiBpcyB0aGUgdG9wIG9mIGl0cyBhbmNlc3RyeSBjaGFpbi4gQm90aCBhcmUgKipvbWl0dGVkIGZvciBmbGF0IChyb290KSBvcmdzKiog4oCUXG4gICAqIGNvbnN1bWVycyBzaG91bGQgdHJlYXQgdGhlIGVmZmVjdGl2ZSByb290IGFzIGByb290T3JnYW5pemF0aW9uSWQgPz8gb3JnYW5pemF0aW9uSWRgXG4gICAqICh1c2UgdGhlIHNoYXJlZCB7QGxpbmsgZWZmZWN0aXZlUm9vdE9yZ0lkfSBhY2Nlc3NvciByYXRoZXIgdGhhbiBjb2FsZXNjaW5nIGlubGluZSkuXG4gICAqIEN1cnJlbnRseSBldmVyeSBvcmcgaXMgZmxhdCwgc28gdGhlc2UgYXJlIGFic2VudCBvbiBhbGwgdG9rZW5zIHRvZGF5LlxuICAgKi9cbiAgcGFyZW50T3JnYW5pemF0aW9uSWQ/OiBzdHJpbmc7XG4gIC8qKiBSb290IG9yZ2FuaXphdGlvbiBJRCBvZiB0aGUgYWN0aXZlIG9yZydzIGFuY2VzdHJ5IGNoYWluIChzZWUgYHBhcmVudE9yZ2FuaXphdGlvbklkYCkuICovXG4gIHJvb3RPcmdhbml6YXRpb25JZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFNldCBvbiB0b2tlbnMgaXNzdWVkIGJ5IHRoZSBzeXNhZG1pbiBpbXBlcnNvbmF0aW9uIGZsb3dcbiAgICogKGBQT1NUIC9hZG1pbi9pbXBlcnNvbmF0ZS86dXNlcklkYCkuIENhcnJpZXMgdGhlIG9yaWdpbmFsIHN5c2FkbWluJ3NcbiAgICogdXNlciBpZCBzbyBhdWRpdCBldmVudHMgc3RpbGwgYXR0cmlidXRlIGFjdGlvbnMgY29ycmVjdGx5LlxuICAgKi9cbiAgaW1wZXJzb25hdG9ySWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHRoZSB0b2tlbiBpcyByZWFkLW9ubHkg4oCUIGFueSBub24tR0VUIHJlcXVlc3QgaXMgcmVqZWN0ZWRcbiAgICogdXBzdHJlYW0gYnkgdGhlIHBsYXRmb3JtJ3MgcmVhZC1vbmx5IGltcGVyc29uYXRpb24gZ2F0ZS4gTGV0c1xuICAgKiBzeXNhZG1pbnMgXCJ2aWV3IGFzIHVzZXIgWFwiIHdpdGhvdXQgcmlza2luZyBhIGRlc3RydWN0aXZlIGFjdGlvbi5cbiAgICovXG4gIGltcGVyc29uYXRpb25SZWFkT25seT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUaGUgdXNlcidzIGB0b2tlblZlcnNpb25gIGF0IHRoZSBtb21lbnQgdGhpcyB0b2tlbiB3YXMgaXNzdWVkLiBFdmVyeVxuICAgKiBwcml2aWxlZ2UgY2hhbmdlIChkZWFjdGl2YXRlIC8gcm9sZSBvciB0aWVyIGRvd25ncmFkZSAvIG1lbWJlcnNoaXAgb3JcbiAgICogb3duZXJzaGlwIGNoYW5nZSAvIHBhc3N3b3JkIGNoYW5nZSAvIGxvZ291dC1hbGwpIGluY3JlbWVudHMgdGhlIHVzZXInc1xuICAgKiBzZXJ2ZXItc2lkZSBgdG9rZW5WZXJzaW9uYCwgc28gYSB0b2tlbiB3aG9zZSBlbWJlZGRlZCB2ZXJzaW9uIGlzIGJlaGluZCB0aGVcbiAgICogY3VycmVudCBvbmUgaGFzIGJlZW4gUkVWT0tFRC4gUGxhdGZvcm0gdmFsaWRhdGVzIHRoaXMgYWdhaW5zdCBNb25nbzsgdGhlXG4gICAqIHN0YXRlbGVzcyBzZXJ2aWNlcyB2YWxpZGF0ZSBpdCBhZ2FpbnN0IGEgUmVkaXMtcHVibGlzaGVkIGN1cnJlbnQtdmVyc2lvblxuICAgKiBzdG9yZSAoc2VlIGBzZXRUb2tlblJldm9jYXRpb25TdG9yZWApLiBBYnNlbnQgb24gbWFjaGluZS9zZXJ2aWNlIHRva2Vucy5cbiAgICovXG4gIHRva2VuVmVyc2lvbj86IG51bWJlcjtcbiAgLyoqIFRva2VuIHR5cGUgKi9cbiAgdHlwZTogJ2FjY2VzcycgfCAncmVmcmVzaCc7XG4gIC8qKiBJc3N1ZWQgYXQgdGltZXN0YW1wICovXG4gIGlhdD86IG51bWJlcjtcbiAgLyoqIEV4cGlyYXRpb24gdGltZXN0YW1wICovXG4gIGV4cD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgYWNjb3VudCBib3VuZGFyeSAocm9vdCBvcmcpIGZvciBhIHRva2VuJ3MgYWN0aXZlIG9yZy5cbiAqXG4gKiBUaGUgYWNjb3VudCByb290IGlzIGByb290T3JnYW5pemF0aW9uSWQgPz8gb3JnYW5pemF0aW9uSWRgOiBhIGZsYXQgKHJvb3QpIG9yZ1xuICogb21pdHMgYHJvb3RPcmdhbml6YXRpb25JZGAsIHNvIGl0IElTIGl0cyBvd24gcm9vdDsgYSB0ZWFtIChjaGlsZCkgb3JnIGNhcnJpZXNcbiAqIHRoZSB0b3Agb2YgaXRzIGFuY2VzdHJ5IGNoYWluLiBFdmVyeSBhY2NvdW50LXNjb3BlZCByZWFkIChxdW90YS9zZWF0L2JpbGxpbmdcbiAqIHBvb2xpbmcpIG11c3QgcmVzb2x2ZSB0aHJvdWdoIHRoaXMgY29hbGVzY2UgcmF0aGVyIHRoYW4gcmVhZGluZ1xuICogYG9yZ2FuaXphdGlvbklkYCBkaXJlY3RseSDigJQgdGhlIGxhdHRlciBzaWxlbnRseSB3b3JrcyB0b2RheSAoYWxsIG9yZ3MgZmxhdClcbiAqIGJ1dCB3b3VsZCBiaW5kIHRvIHRoZSB0ZWFtIGluc3RlYWQgb2YgdGhlIGFjY291bnQgb25jZSB0ZWFtcyBleGlzdC5cbiAqXG4gKiBAcmV0dXJucyB0aGUgZWZmZWN0aXZlIHJvb3Qgb3JnIGlkLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5laXRoZXIgZmllbGQgaXMgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWZmZWN0aXZlUm9vdE9yZ0lkKFxuICBwYXlsb2FkOiBQaWNrPEp3dFBheWxvYWQsICdvcmdhbml6YXRpb25JZCcgfCAncm9vdE9yZ2FuaXphdGlvbklkJz4sXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gcGF5bG9hZC5yb290T3JnYW5pemF0aW9uSWQgPz8gcGF5bG9hZC5vcmdhbml6YXRpb25JZDtcbn1cblxuLyoqXG4gKiBFeHRlbmRlZCBFeHByZXNzIFJlcXVlc3Qgd2l0aCB1c2VyIHByb3BlcnR5LlxuICovXG5kZWNsYXJlIGdsb2JhbCB7XG4gIG5hbWVzcGFjZSBFeHByZXNzIHtcbiAgICBpbnRlcmZhY2UgUmVxdWVzdCB7XG4gICAgICB1c2VyPzogSnd0UGF5bG9hZDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZm9yIGludGVybmFsIEhUVFAgY2xpZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZpY2VDb25maWcge1xuICAvKiogU2VydmljZSBob3N0bmFtZSAqL1xuICBob3N0OiBzdHJpbmc7XG4gIC8qKiBTZXJ2aWNlIHBvcnQgKi9cbiAgcG9ydDogbnVtYmVyO1xuICAvKiogUmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEhlYWx0aCBjaGVjayByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja1Jlc3BvbnNlIHtcbiAgc3RhdHVzOiAnaGVhbHRoeScgfCAndW5oZWFsdGh5JztcbiAgc2VydmljZTogc3RyaW5nO1xuICB0aW1lc3RhbXA6IHN0cmluZztcbiAgdXB0aW1lOiBudW1iZXI7XG4gIHZlcnNpb24/OiBzdHJpbmc7XG4gIGRlcGVuZGVuY2llcz86IFJlY29yZDxzdHJpbmcsICdjb25uZWN0ZWQnIHwgJ2Rpc2Nvbm5lY3RlZCcgfCAndW5rbm93bic+O1xufVxuIl19
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized error codes used across all API microservices.
|
|
3
|
+
* Use these codes in error responses for consistent client handling.
|
|
4
|
+
*
|
|
5
|
+
* Each HTTP status category has one primary code. Use the `details`
|
|
6
|
+
* field in error responses for sub-type information (e.g. which quota
|
|
7
|
+
* was exceeded, which field failed validation).
|
|
8
|
+
*/
|
|
9
|
+
export declare enum ErrorCode {
|
|
10
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
11
|
+
TOKEN_EXPIRED = "TOKEN_EXPIRED",
|
|
12
|
+
TOKEN_INVALID = "TOKEN_INVALID",
|
|
13
|
+
TOKEN_MISSING = "TOKEN_MISSING",
|
|
14
|
+
TOKEN_REVOKED = "TOKEN_REVOKED",
|
|
15
|
+
INSUFFICIENT_PERMISSIONS = "INSUFFICIENT_PERMISSIONS",
|
|
16
|
+
ORG_MISMATCH = "ORG_MISMATCH",
|
|
17
|
+
COMPLIANCE_VIOLATION = "COMPLIANCE_VIOLATION",
|
|
18
|
+
NOT_FOUND = "NOT_FOUND",
|
|
19
|
+
ORG_NOT_FOUND = "ORG_NOT_FOUND",
|
|
20
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
21
|
+
MISSING_REQUIRED_FIELD = "MISSING_REQUIRED_FIELD",
|
|
22
|
+
TEMPLATE_UNKNOWN_PATH = "TEMPLATE_UNKNOWN_PATH",
|
|
23
|
+
TEMPLATE_CYCLE = "TEMPLATE_CYCLE",
|
|
24
|
+
TEMPLATE_PARSE_ERROR = "TEMPLATE_PARSE_ERROR",
|
|
25
|
+
TEMPLATE_TYPE_MISMATCH = "TEMPLATE_TYPE_MISMATCH",
|
|
26
|
+
TEMPLATE_SECRETS_RESERVED = "TEMPLATE_SECRETS_RESERVED",
|
|
27
|
+
TEMPLATE_CONTRACT_VIOLATION = "TEMPLATE_CONTRACT_VIOLATION",
|
|
28
|
+
TEMPLATE_SIZE_EXCEEDED = "TEMPLATE_SIZE_EXCEEDED",
|
|
29
|
+
TEMPLATE_VALIDATION_FAILED = "TEMPLATE_VALIDATION_FAILED",
|
|
30
|
+
QUOTA_EXCEEDED = "QUOTA_EXCEEDED",
|
|
31
|
+
RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED",
|
|
32
|
+
PAYLOAD_TOO_LARGE = "PAYLOAD_TOO_LARGE",
|
|
33
|
+
CONFLICT = "CONFLICT",
|
|
34
|
+
DUPLICATE_ENTRY = "DUPLICATE_ENTRY",
|
|
35
|
+
SCAN_CONFLICT = "SCAN_CONFLICT",
|
|
36
|
+
PAYMENT_METHOD_REQUIRED = "PAYMENT_METHOD_REQUIRED",// 402
|
|
37
|
+
DISCOUNT_CEILING_EXCEEDED = "DISCOUNT_CEILING_EXCEEDED",// 400
|
|
38
|
+
DISCOUNT_NOT_FOUND = "DISCOUNT_NOT_FOUND",// 404
|
|
39
|
+
DISCOUNT_INACTIVE = "DISCOUNT_INACTIVE",// 409
|
|
40
|
+
PLAN_OVER_CAP = "PLAN_OVER_CAP",// 409
|
|
41
|
+
ADDON_OVER_CAP = "ADDON_OVER_CAP",// 409
|
|
42
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
43
|
+
DATABASE_ERROR = "DATABASE_ERROR",
|
|
44
|
+
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",
|
|
45
|
+
COMPLIANCE_SERVICE_UNAVAILABLE = "COMPLIANCE_SERVICE_UNAVAILABLE"
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Maps error codes to their default HTTP status codes.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ErrorCodeStatus: Record<ErrorCode, number>;
|
|
51
|
+
/**
|
|
52
|
+
* Get the HTTP status code for an error code.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getStatusForErrorCode(code: ErrorCode): number;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Standardized error codes used across all API microservices.
|
|
5
|
+
* Use these codes in error responses for consistent client handling.
|
|
6
|
+
*
|
|
7
|
+
* Each HTTP status category has one primary code. Use the `details`
|
|
8
|
+
* field in error responses for sub-type information (e.g. which quota
|
|
9
|
+
* was exceeded, which field failed validation).
|
|
10
|
+
*/
|
|
11
|
+
export var ErrorCode;
|
|
12
|
+
(function (ErrorCode) {
|
|
13
|
+
// Authentication errors (401)
|
|
14
|
+
ErrorCode["UNAUTHORIZED"] = "UNAUTHORIZED";
|
|
15
|
+
ErrorCode["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
|
|
16
|
+
ErrorCode["TOKEN_INVALID"] = "TOKEN_INVALID";
|
|
17
|
+
ErrorCode["TOKEN_MISSING"] = "TOKEN_MISSING";
|
|
18
|
+
ErrorCode["TOKEN_REVOKED"] = "TOKEN_REVOKED";
|
|
19
|
+
// Authorization errors (403)
|
|
20
|
+
ErrorCode["INSUFFICIENT_PERMISSIONS"] = "INSUFFICIENT_PERMISSIONS";
|
|
21
|
+
ErrorCode["ORG_MISMATCH"] = "ORG_MISMATCH";
|
|
22
|
+
ErrorCode["COMPLIANCE_VIOLATION"] = "COMPLIANCE_VIOLATION";
|
|
23
|
+
// Not found errors (404)
|
|
24
|
+
ErrorCode["NOT_FOUND"] = "NOT_FOUND";
|
|
25
|
+
ErrorCode["ORG_NOT_FOUND"] = "ORG_NOT_FOUND";
|
|
26
|
+
// Validation errors (400)
|
|
27
|
+
ErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR";
|
|
28
|
+
ErrorCode["MISSING_REQUIRED_FIELD"] = "MISSING_REQUIRED_FIELD";
|
|
29
|
+
ErrorCode["TEMPLATE_UNKNOWN_PATH"] = "TEMPLATE_UNKNOWN_PATH";
|
|
30
|
+
ErrorCode["TEMPLATE_CYCLE"] = "TEMPLATE_CYCLE";
|
|
31
|
+
ErrorCode["TEMPLATE_PARSE_ERROR"] = "TEMPLATE_PARSE_ERROR";
|
|
32
|
+
ErrorCode["TEMPLATE_TYPE_MISMATCH"] = "TEMPLATE_TYPE_MISMATCH";
|
|
33
|
+
ErrorCode["TEMPLATE_SECRETS_RESERVED"] = "TEMPLATE_SECRETS_RESERVED";
|
|
34
|
+
ErrorCode["TEMPLATE_CONTRACT_VIOLATION"] = "TEMPLATE_CONTRACT_VIOLATION";
|
|
35
|
+
ErrorCode["TEMPLATE_SIZE_EXCEEDED"] = "TEMPLATE_SIZE_EXCEEDED";
|
|
36
|
+
ErrorCode["TEMPLATE_VALIDATION_FAILED"] = "TEMPLATE_VALIDATION_FAILED";
|
|
37
|
+
// Quota/Rate limit errors (429)
|
|
38
|
+
ErrorCode["QUOTA_EXCEEDED"] = "QUOTA_EXCEEDED";
|
|
39
|
+
ErrorCode["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED";
|
|
40
|
+
// Payload errors (413)
|
|
41
|
+
ErrorCode["PAYLOAD_TOO_LARGE"] = "PAYLOAD_TOO_LARGE";
|
|
42
|
+
// Conflict errors (409)
|
|
43
|
+
ErrorCode["CONFLICT"] = "CONFLICT";
|
|
44
|
+
ErrorCode["DUPLICATE_ENTRY"] = "DUPLICATE_ENTRY";
|
|
45
|
+
ErrorCode["SCAN_CONFLICT"] = "SCAN_CONFLICT";
|
|
46
|
+
// Billing errors
|
|
47
|
+
ErrorCode["PAYMENT_METHOD_REQUIRED"] = "PAYMENT_METHOD_REQUIRED";
|
|
48
|
+
ErrorCode["DISCOUNT_CEILING_EXCEEDED"] = "DISCOUNT_CEILING_EXCEEDED";
|
|
49
|
+
ErrorCode["DISCOUNT_NOT_FOUND"] = "DISCOUNT_NOT_FOUND";
|
|
50
|
+
ErrorCode["DISCOUNT_INACTIVE"] = "DISCOUNT_INACTIVE";
|
|
51
|
+
ErrorCode["PLAN_OVER_CAP"] = "PLAN_OVER_CAP";
|
|
52
|
+
ErrorCode["ADDON_OVER_CAP"] = "ADDON_OVER_CAP";
|
|
53
|
+
// Server errors (500)
|
|
54
|
+
ErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
55
|
+
ErrorCode["DATABASE_ERROR"] = "DATABASE_ERROR";
|
|
56
|
+
// Service unavailable (503)
|
|
57
|
+
ErrorCode["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
|
58
|
+
ErrorCode["COMPLIANCE_SERVICE_UNAVAILABLE"] = "COMPLIANCE_SERVICE_UNAVAILABLE";
|
|
59
|
+
})(ErrorCode || (ErrorCode = {}));
|
|
60
|
+
/**
|
|
61
|
+
* Maps error codes to their default HTTP status codes.
|
|
62
|
+
*/
|
|
63
|
+
export const ErrorCodeStatus = {
|
|
64
|
+
[ErrorCode.UNAUTHORIZED]: 401,
|
|
65
|
+
[ErrorCode.TOKEN_EXPIRED]: 401,
|
|
66
|
+
[ErrorCode.TOKEN_INVALID]: 401,
|
|
67
|
+
[ErrorCode.TOKEN_MISSING]: 401,
|
|
68
|
+
[ErrorCode.TOKEN_REVOKED]: 401,
|
|
69
|
+
[ErrorCode.INSUFFICIENT_PERMISSIONS]: 403,
|
|
70
|
+
[ErrorCode.ORG_MISMATCH]: 403,
|
|
71
|
+
[ErrorCode.COMPLIANCE_VIOLATION]: 403,
|
|
72
|
+
[ErrorCode.NOT_FOUND]: 404,
|
|
73
|
+
[ErrorCode.ORG_NOT_FOUND]: 404,
|
|
74
|
+
[ErrorCode.VALIDATION_ERROR]: 400,
|
|
75
|
+
[ErrorCode.MISSING_REQUIRED_FIELD]: 400,
|
|
76
|
+
[ErrorCode.TEMPLATE_UNKNOWN_PATH]: 400,
|
|
77
|
+
[ErrorCode.TEMPLATE_CYCLE]: 400,
|
|
78
|
+
[ErrorCode.TEMPLATE_PARSE_ERROR]: 400,
|
|
79
|
+
[ErrorCode.TEMPLATE_TYPE_MISMATCH]: 400,
|
|
80
|
+
[ErrorCode.TEMPLATE_SECRETS_RESERVED]: 400,
|
|
81
|
+
[ErrorCode.TEMPLATE_CONTRACT_VIOLATION]: 400,
|
|
82
|
+
[ErrorCode.TEMPLATE_SIZE_EXCEEDED]: 400,
|
|
83
|
+
[ErrorCode.TEMPLATE_VALIDATION_FAILED]: 400,
|
|
84
|
+
[ErrorCode.QUOTA_EXCEEDED]: 429,
|
|
85
|
+
[ErrorCode.RATE_LIMIT_EXCEEDED]: 429,
|
|
86
|
+
[ErrorCode.PAYLOAD_TOO_LARGE]: 413,
|
|
87
|
+
[ErrorCode.CONFLICT]: 409,
|
|
88
|
+
[ErrorCode.DUPLICATE_ENTRY]: 409,
|
|
89
|
+
[ErrorCode.SCAN_CONFLICT]: 409,
|
|
90
|
+
[ErrorCode.PAYMENT_METHOD_REQUIRED]: 402,
|
|
91
|
+
[ErrorCode.DISCOUNT_CEILING_EXCEEDED]: 400,
|
|
92
|
+
[ErrorCode.DISCOUNT_NOT_FOUND]: 404,
|
|
93
|
+
[ErrorCode.DISCOUNT_INACTIVE]: 409,
|
|
94
|
+
[ErrorCode.PLAN_OVER_CAP]: 409,
|
|
95
|
+
[ErrorCode.ADDON_OVER_CAP]: 409,
|
|
96
|
+
[ErrorCode.INTERNAL_ERROR]: 500,
|
|
97
|
+
[ErrorCode.DATABASE_ERROR]: 500,
|
|
98
|
+
[ErrorCode.SERVICE_UNAVAILABLE]: 503,
|
|
99
|
+
[ErrorCode.COMPLIANCE_SERVICE_UNAVAILABLE]: 503,
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Get the HTTP status code for an error code.
|
|
103
|
+
*/
|
|
104
|
+
export function getStatusForErrorCode(code) {
|
|
105
|
+
return ErrorCodeStatus[code] ?? 500;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3ItY29kZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvZXJyb3ItY29kZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFOLElBQVksU0F3RFg7QUF4REQsV0FBWSxTQUFTO0lBQ25CLDhCQUE4QjtJQUM5QiwwQ0FBNkIsQ0FBQTtJQUM3Qiw0Q0FBK0IsQ0FBQTtJQUMvQiw0Q0FBK0IsQ0FBQTtJQUMvQiw0Q0FBK0IsQ0FBQTtJQUMvQiw0Q0FBK0IsQ0FBQTtJQUUvQiw2QkFBNkI7SUFDN0Isa0VBQXFELENBQUE7SUFDckQsMENBQTZCLENBQUE7SUFDN0IsMERBQTZDLENBQUE7SUFFN0MseUJBQXlCO0lBQ3pCLG9DQUF1QixDQUFBO0lBQ3ZCLDRDQUErQixDQUFBO0lBRS9CLDBCQUEwQjtJQUMxQixrREFBcUMsQ0FBQTtJQUNyQyw4REFBaUQsQ0FBQTtJQUNqRCw0REFBK0MsQ0FBQTtJQUMvQyw4Q0FBaUMsQ0FBQTtJQUNqQywwREFBNkMsQ0FBQTtJQUM3Qyw4REFBaUQsQ0FBQTtJQUNqRCxvRUFBdUQsQ0FBQTtJQUN2RCx3RUFBMkQsQ0FBQTtJQUMzRCw4REFBaUQsQ0FBQTtJQUNqRCxzRUFBeUQsQ0FBQTtJQUV6RCxnQ0FBZ0M7SUFDaEMsOENBQWlDLENBQUE7SUFDakMsd0RBQTJDLENBQUE7SUFFM0MsdUJBQXVCO0lBQ3ZCLG9EQUF1QyxDQUFBO0lBRXZDLHdCQUF3QjtJQUN4QixrQ0FBcUIsQ0FBQTtJQUNyQixnREFBbUMsQ0FBQTtJQUNuQyw0Q0FBK0IsQ0FBQTtJQUUvQixpQkFBaUI7SUFDakIsZ0VBQW1ELENBQUE7SUFDbkQsb0VBQXVELENBQUE7SUFDdkQsc0RBQXlDLENBQUE7SUFDekMsb0RBQXVDLENBQUE7SUFDdkMsNENBQStCLENBQUE7SUFDL0IsOENBQWlDLENBQUE7SUFFakMsc0JBQXNCO0lBQ3RCLDhDQUFpQyxDQUFBO0lBQ2pDLDhDQUFpQyxDQUFBO0lBRWpDLDRCQUE0QjtJQUM1Qix3REFBMkMsQ0FBQTtJQUMzQyw4RUFBaUUsQ0FBQTtBQUNuRSxDQUFDLEVBeERXLFNBQVMsS0FBVCxTQUFTLFFBd0RwQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE4QjtJQUN4RCxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHO0lBQzdCLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUc7SUFDOUIsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRztJQUM5QixDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxHQUFHO0lBQzlCLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUc7SUFDOUIsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsRUFBRSxHQUFHO0lBQ3pDLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxFQUFFLEdBQUc7SUFDN0IsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsRUFBRSxHQUFHO0lBQ3JDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUc7SUFDMUIsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRztJQUM5QixDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEdBQUc7SUFDakMsQ0FBQyxTQUFTLENBQUMsc0JBQXNCLENBQUMsRUFBRSxHQUFHO0lBQ3ZDLENBQUMsU0FBUyxDQUFDLHFCQUFxQixDQUFDLEVBQUUsR0FBRztJQUN0QyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxHQUFHO0lBQy9CLENBQUMsU0FBUyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsR0FBRztJQUNyQyxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLEdBQUc7SUFDdkMsQ0FBQyxTQUFTLENBQUMseUJBQXlCLENBQUMsRUFBRSxHQUFHO0lBQzFDLENBQUMsU0FBUyxDQUFDLDJCQUEyQixDQUFDLEVBQUUsR0FBRztJQUM1QyxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLEdBQUc7SUFDdkMsQ0FBQyxTQUFTLENBQUMsMEJBQTBCLENBQUMsRUFBRSxHQUFHO0lBQzNDLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUc7SUFDL0IsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUMsRUFBRSxHQUFHO0lBQ3BDLENBQUMsU0FBUyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsR0FBRztJQUNsQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHO0lBQ3pCLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLEdBQUc7SUFDaEMsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRztJQUM5QixDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLEdBQUc7SUFDeEMsQ0FBQyxTQUFTLENBQUMseUJBQXlCLENBQUMsRUFBRSxHQUFHO0lBQzFDLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsR0FBRztJQUNuQyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEdBQUc7SUFDbEMsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRztJQUM5QixDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxHQUFHO0lBQy9CLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUc7SUFDL0IsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRztJQUMvQixDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLEdBQUc7SUFDcEMsQ0FBQyxTQUFTLENBQUMsOEJBQThCLENBQUMsRUFBRSxHQUFHO0NBQ2hELENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxJQUFlO0lBQ25ELE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQztBQUN0QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogU3RhbmRhcmRpemVkIGVycm9yIGNvZGVzIHVzZWQgYWNyb3NzIGFsbCBBUEkgbWljcm9zZXJ2aWNlcy5cbiAqIFVzZSB0aGVzZSBjb2RlcyBpbiBlcnJvciByZXNwb25zZXMgZm9yIGNvbnNpc3RlbnQgY2xpZW50IGhhbmRsaW5nLlxuICpcbiAqIEVhY2ggSFRUUCBzdGF0dXMgY2F0ZWdvcnkgaGFzIG9uZSBwcmltYXJ5IGNvZGUuIFVzZSB0aGUgYGRldGFpbHNgXG4gKiBmaWVsZCBpbiBlcnJvciByZXNwb25zZXMgZm9yIHN1Yi10eXBlIGluZm9ybWF0aW9uIChlLmcuIHdoaWNoIHF1b3RhXG4gKiB3YXMgZXhjZWVkZWQsIHdoaWNoIGZpZWxkIGZhaWxlZCB2YWxpZGF0aW9uKS5cbiAqL1xuZXhwb3J0IGVudW0gRXJyb3JDb2RlIHtcbiAgLy8gQXV0aGVudGljYXRpb24gZXJyb3JzICg0MDEpXG4gIFVOQVVUSE9SSVpFRCA9ICdVTkFVVEhPUklaRUQnLFxuICBUT0tFTl9FWFBJUkVEID0gJ1RPS0VOX0VYUElSRUQnLFxuICBUT0tFTl9JTlZBTElEID0gJ1RPS0VOX0lOVkFMSUQnLFxuICBUT0tFTl9NSVNTSU5HID0gJ1RPS0VOX01JU1NJTkcnLFxuICBUT0tFTl9SRVZPS0VEID0gJ1RPS0VOX1JFVk9LRUQnLFxuXG4gIC8vIEF1dGhvcml6YXRpb24gZXJyb3JzICg0MDMpXG4gIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyA9ICdJTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMnLFxuICBPUkdfTUlTTUFUQ0ggPSAnT1JHX01JU01BVENIJyxcbiAgQ09NUExJQU5DRV9WSU9MQVRJT04gPSAnQ09NUExJQU5DRV9WSU9MQVRJT04nLFxuXG4gIC8vIE5vdCBmb3VuZCBlcnJvcnMgKDQwNClcbiAgTk9UX0ZPVU5EID0gJ05PVF9GT1VORCcsXG4gIE9SR19OT1RfRk9VTkQgPSAnT1JHX05PVF9GT1VORCcsXG5cbiAgLy8gVmFsaWRhdGlvbiBlcnJvcnMgKDQwMClcbiAgVkFMSURBVElPTl9FUlJPUiA9ICdWQUxJREFUSU9OX0VSUk9SJyxcbiAgTUlTU0lOR19SRVFVSVJFRF9GSUVMRCA9ICdNSVNTSU5HX1JFUVVJUkVEX0ZJRUxEJyxcbiAgVEVNUExBVEVfVU5LTk9XTl9QQVRIID0gJ1RFTVBMQVRFX1VOS05PV05fUEFUSCcsXG4gIFRFTVBMQVRFX0NZQ0xFID0gJ1RFTVBMQVRFX0NZQ0xFJyxcbiAgVEVNUExBVEVfUEFSU0VfRVJST1IgPSAnVEVNUExBVEVfUEFSU0VfRVJST1InLFxuICBURU1QTEFURV9UWVBFX01JU01BVENIID0gJ1RFTVBMQVRFX1RZUEVfTUlTTUFUQ0gnLFxuICBURU1QTEFURV9TRUNSRVRTX1JFU0VSVkVEID0gJ1RFTVBMQVRFX1NFQ1JFVFNfUkVTRVJWRUQnLFxuICBURU1QTEFURV9DT05UUkFDVF9WSU9MQVRJT04gPSAnVEVNUExBVEVfQ09OVFJBQ1RfVklPTEFUSU9OJyxcbiAgVEVNUExBVEVfU0laRV9FWENFRURFRCA9ICdURU1QTEFURV9TSVpFX0VYQ0VFREVEJyxcbiAgVEVNUExBVEVfVkFMSURBVElPTl9GQUlMRUQgPSAnVEVNUExBVEVfVkFMSURBVElPTl9GQUlMRUQnLFxuXG4gIC8vIFF1b3RhL1JhdGUgbGltaXQgZXJyb3JzICg0MjkpXG4gIFFVT1RBX0VYQ0VFREVEID0gJ1FVT1RBX0VYQ0VFREVEJyxcbiAgUkFURV9MSU1JVF9FWENFRURFRCA9ICdSQVRFX0xJTUlUX0VYQ0VFREVEJyxcblxuICAvLyBQYXlsb2FkIGVycm9ycyAoNDEzKVxuICBQQVlMT0FEX1RPT19MQVJHRSA9ICdQQVlMT0FEX1RPT19MQVJHRScsXG5cbiAgLy8gQ29uZmxpY3QgZXJyb3JzICg0MDkpXG4gIENPTkZMSUNUID0gJ0NPTkZMSUNUJyxcbiAgRFVQTElDQVRFX0VOVFJZID0gJ0RVUExJQ0FURV9FTlRSWScsXG4gIFNDQU5fQ09ORkxJQ1QgPSAnU0NBTl9DT05GTElDVCcsXG5cbiAgLy8gQmlsbGluZyBlcnJvcnNcbiAgUEFZTUVOVF9NRVRIT0RfUkVRVUlSRUQgPSAnUEFZTUVOVF9NRVRIT0RfUkVRVUlSRUQnLCAvLyA0MDJcbiAgRElTQ09VTlRfQ0VJTElOR19FWENFRURFRCA9ICdESVNDT1VOVF9DRUlMSU5HX0VYQ0VFREVEJywgLy8gNDAwXG4gIERJU0NPVU5UX05PVF9GT1VORCA9ICdESVNDT1VOVF9OT1RfRk9VTkQnLCAvLyA0MDRcbiAgRElTQ09VTlRfSU5BQ1RJVkUgPSAnRElTQ09VTlRfSU5BQ1RJVkUnLCAvLyA0MDlcbiAgUExBTl9PVkVSX0NBUCA9ICdQTEFOX09WRVJfQ0FQJywgLy8gNDA5XG4gIEFERE9OX09WRVJfQ0FQID0gJ0FERE9OX09WRVJfQ0FQJywgLy8gNDA5XG5cbiAgLy8gU2VydmVyIGVycm9ycyAoNTAwKVxuICBJTlRFUk5BTF9FUlJPUiA9ICdJTlRFUk5BTF9FUlJPUicsXG4gIERBVEFCQVNFX0VSUk9SID0gJ0RBVEFCQVNFX0VSUk9SJyxcblxuICAvLyBTZXJ2aWNlIHVuYXZhaWxhYmxlICg1MDMpXG4gIFNFUlZJQ0VfVU5BVkFJTEFCTEUgPSAnU0VSVklDRV9VTkFWQUlMQUJMRScsXG4gIENPTVBMSUFOQ0VfU0VSVklDRV9VTkFWQUlMQUJMRSA9ICdDT01QTElBTkNFX1NFUlZJQ0VfVU5BVkFJTEFCTEUnLFxufVxuXG4vKipcbiAqIE1hcHMgZXJyb3IgY29kZXMgdG8gdGhlaXIgZGVmYXVsdCBIVFRQIHN0YXR1cyBjb2Rlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IEVycm9yQ29kZVN0YXR1czogUmVjb3JkPEVycm9yQ29kZSwgbnVtYmVyPiA9IHtcbiAgW0Vycm9yQ29kZS5VTkFVVEhPUklaRURdOiA0MDEsXG4gIFtFcnJvckNvZGUuVE9LRU5fRVhQSVJFRF06IDQwMSxcbiAgW0Vycm9yQ29kZS5UT0tFTl9JTlZBTElEXTogNDAxLFxuICBbRXJyb3JDb2RlLlRPS0VOX01JU1NJTkddOiA0MDEsXG4gIFtFcnJvckNvZGUuVE9LRU5fUkVWT0tFRF06IDQwMSxcbiAgW0Vycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlNdOiA0MDMsXG4gIFtFcnJvckNvZGUuT1JHX01JU01BVENIXTogNDAzLFxuICBbRXJyb3JDb2RlLkNPTVBMSUFOQ0VfVklPTEFUSU9OXTogNDAzLFxuICBbRXJyb3JDb2RlLk5PVF9GT1VORF06IDQwNCxcbiAgW0Vycm9yQ29kZS5PUkdfTk9UX0ZPVU5EXTogNDA0LFxuICBbRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1JdOiA0MDAsXG4gIFtFcnJvckNvZGUuTUlTU0lOR19SRVFVSVJFRF9GSUVMRF06IDQwMCxcbiAgW0Vycm9yQ29kZS5URU1QTEFURV9VTktOT1dOX1BBVEhdOiA0MDAsXG4gIFtFcnJvckNvZGUuVEVNUExBVEVfQ1lDTEVdOiA0MDAsXG4gIFtFcnJvckNvZGUuVEVNUExBVEVfUEFSU0VfRVJST1JdOiA0MDAsXG4gIFtFcnJvckNvZGUuVEVNUExBVEVfVFlQRV9NSVNNQVRDSF06IDQwMCxcbiAgW0Vycm9yQ29kZS5URU1QTEFURV9TRUNSRVRTX1JFU0VSVkVEXTogNDAwLFxuICBbRXJyb3JDb2RlLlRFTVBMQVRFX0NPTlRSQUNUX1ZJT0xBVElPTl06IDQwMCxcbiAgW0Vycm9yQ29kZS5URU1QTEFURV9TSVpFX0VYQ0VFREVEXTogNDAwLFxuICBbRXJyb3JDb2RlLlRFTVBMQVRFX1ZBTElEQVRJT05fRkFJTEVEXTogNDAwLFxuICBbRXJyb3JDb2RlLlFVT1RBX0VYQ0VFREVEXTogNDI5LFxuICBbRXJyb3JDb2RlLlJBVEVfTElNSVRfRVhDRUVERURdOiA0MjksXG4gIFtFcnJvckNvZGUuUEFZTE9BRF9UT09fTEFSR0VdOiA0MTMsXG4gIFtFcnJvckNvZGUuQ09ORkxJQ1RdOiA0MDksXG4gIFtFcnJvckNvZGUuRFVQTElDQVRFX0VOVFJZXTogNDA5LFxuICBbRXJyb3JDb2RlLlNDQU5fQ09ORkxJQ1RdOiA0MDksXG4gIFtFcnJvckNvZGUuUEFZTUVOVF9NRVRIT0RfUkVRVUlSRURdOiA0MDIsXG4gIFtFcnJvckNvZGUuRElTQ09VTlRfQ0VJTElOR19FWENFRURFRF06IDQwMCxcbiAgW0Vycm9yQ29kZS5ESVNDT1VOVF9OT1RfRk9VTkRdOiA0MDQsXG4gIFtFcnJvckNvZGUuRElTQ09VTlRfSU5BQ1RJVkVdOiA0MDksXG4gIFtFcnJvckNvZGUuUExBTl9PVkVSX0NBUF06IDQwOSxcbiAgW0Vycm9yQ29kZS5BRERPTl9PVkVSX0NBUF06IDQwOSxcbiAgW0Vycm9yQ29kZS5JTlRFUk5BTF9FUlJPUl06IDUwMCxcbiAgW0Vycm9yQ29kZS5EQVRBQkFTRV9FUlJPUl06IDUwMCxcbiAgW0Vycm9yQ29kZS5TRVJWSUNFX1VOQVZBSUxBQkxFXTogNTAzLFxuICBbRXJyb3JDb2RlLkNPTVBMSUFOQ0VfU0VSVklDRV9VTkFWQUlMQUJMRV06IDUwMyxcbn07XG5cbi8qKlxuICogR2V0IHRoZSBIVFRQIHN0YXR1cyBjb2RlIGZvciBhbiBlcnJvciBjb2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdHVzRm9yRXJyb3JDb2RlKGNvZGU6IEVycm9yQ29kZSk6IG51bWJlciB7XG4gIHJldHVybiBFcnJvckNvZGVTdGF0dXNbY29kZV0gPz8gNTAwO1xufVxuIl19
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { QuotaTier } from './quota-tiers.js';
|
|
2
|
+
/** Canonical feature flag identifiers. */
|
|
3
|
+
export type FeatureFlag = 'priority_support' | 'custom_integrations' | 'ai_generation' | 'bulk_operations' | 'audit_log' | 'sso' | 'advanced_reporting' | 'team_usage_analytics' | 'compliance_standard' | 'compliance_advanced';
|
|
4
|
+
/** All valid feature flags (order determines display order). */
|
|
5
|
+
export declare const ALL_FEATURE_FLAGS: readonly FeatureFlag[];
|
|
6
|
+
/** Check whether a string is a valid FeatureFlag. */
|
|
7
|
+
export declare function isValidFeatureFlag(value: string): value is FeatureFlag;
|
|
8
|
+
/** Features enabled by default for each tier. */
|
|
9
|
+
export declare const TIER_FEATURES: Record<QuotaTier, readonly FeatureFlag[]>;
|
|
10
|
+
/** Human-readable metadata for each feature flag. */
|
|
11
|
+
export declare const FEATURE_METADATA: Record<FeatureFlag, {
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a user's effective feature set.
|
|
17
|
+
*
|
|
18
|
+
* 1. Sysadmins (isSuperAdmin) always get ALL features.
|
|
19
|
+
* 2. Start with the tier's default features.
|
|
20
|
+
* 3. Apply per-user overrides: `true` adds a feature, `false` removes it.
|
|
21
|
+
* 4. Invalid override keys are silently ignored.
|
|
22
|
+
*
|
|
23
|
+
* @param tier - The organization's quota tier
|
|
24
|
+
* @param opts - Resolution options:
|
|
25
|
+
* - `overrides`: per-user overrides (key = feature flag, value = enabled)
|
|
26
|
+
* - `isSuperAdmin`: whether the user has the global super-admin flag
|
|
27
|
+
* - `accountFeatures`: account-level entitlements (e.g. purchased add-on
|
|
28
|
+
* bundles). A NAMED field so it can never be silently dropped by a caller
|
|
29
|
+
* that omits a trailing positional arg.
|
|
30
|
+
* @returns Sorted array of enabled feature flags
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveUserFeatures(tier: QuotaTier, opts?: {
|
|
33
|
+
overrides?: Record<string, boolean> | null;
|
|
34
|
+
isSuperAdmin?: boolean;
|
|
35
|
+
accountFeatures?: readonly string[] | null;
|
|
36
|
+
}): FeatureFlag[];
|