@pipeline-builder/api-core 3.4.35 → 3.4.37
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/README.md +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +3 -3
- package/lib/middleware/auth.d.ts +9 -4
- package/lib/middleware/auth.js +16 -13
- package/lib/services/http-client.d.ts +5 -0
- package/lib/services/http-client.js +14 -1
- package/lib/services/index.d.ts +1 -0
- package/lib/services/index.js +2 -1
- package/lib/services/quota.d.ts +65 -1
- package/lib/services/quota.js +99 -3
- package/lib/services/remote-audit-client.d.ts +63 -0
- package/lib/services/remote-audit-client.js +67 -0
- package/lib/types/common.d.ts +37 -2
- package/lib/types/common.js +5 -2
- package/lib/types/feature-flags.d.ts +5 -5
- package/lib/types/feature-flags.js +9 -9
- package/lib/types/http.d.ts +4 -14
- package/lib/types/http.js +1 -1
- package/lib/types/quota-tiers.d.ts +13 -7
- package/lib/types/quota-tiers.js +54 -5
- package/lib/utils/identity.js +6 -6
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.js +4 -1
- package/lib/utils/metric-emitter.d.ts +36 -0
- package/lib/utils/metric-emitter.js +37 -0
- package/lib/utils/org-aws-credentials.d.ts +154 -0
- package/lib/utils/org-aws-credentials.js +159 -0
- package/lib/utils/secret-encryption.d.ts +205 -0
- package/lib/utils/secret-encryption.js +388 -0
- package/package.json +8 -5
package/lib/services/quota.js
CHANGED
|
@@ -4,9 +4,13 @@
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.createQuotaService = createQuotaService;
|
|
6
6
|
exports.incrementQuota = incrementQuota;
|
|
7
|
+
exports.reserveQuota = reserveQuota;
|
|
8
|
+
exports.decrementQuota = decrementQuota;
|
|
7
9
|
const http_client_1 = require("./http-client");
|
|
10
|
+
const quota_tiers_1 = require("../types/quota-tiers");
|
|
8
11
|
const logger_1 = require("../utils/logger");
|
|
9
|
-
|
|
12
|
+
const metric_emitter_1 = require("../utils/metric-emitter");
|
|
13
|
+
/** Retry options for quota calls fail fast since quota is fail-open. */
|
|
10
14
|
const QUOTA_REQUEST_OPTIONS = {
|
|
11
15
|
maxRateLimitRetries: 1,
|
|
12
16
|
maxRetries: 1,
|
|
@@ -49,7 +53,7 @@ function buildHeaders(orgId, authHeader, requestId) {
|
|
|
49
53
|
* // Check quota before processing
|
|
50
54
|
* const quota = await quotaService.check(orgId, 'apiCalls', authHeader);
|
|
51
55
|
* if (!quota.allowed) {
|
|
52
|
-
*
|
|
56
|
+
* return res.status(429).json({ error: 'Quota exceeded' });
|
|
53
57
|
* }
|
|
54
58
|
*
|
|
55
59
|
* // Increment quota after success
|
|
@@ -69,12 +73,14 @@ function createQuotaService(config = {}) {
|
|
|
69
73
|
const response = await client.get(path, { headers: buildHeaders(orgId, authHeader, requestId), ...QUOTA_REQUEST_OPTIONS });
|
|
70
74
|
if (!response) {
|
|
71
75
|
logger.warn('QUOTA_FAIL_OPEN: Quota service unreachable, allowing request', { orgId, quotaType });
|
|
76
|
+
(0, metric_emitter_1.emitCounter)('quota_fail_open_total', { operation: 'check', reason: 'unreachable', quotaType });
|
|
72
77
|
return createFailOpenResult();
|
|
73
78
|
}
|
|
74
79
|
if (response.statusCode !== 200 || !response.body.success || !response.body.data?.status) {
|
|
75
80
|
logger.warn('QUOTA_FAIL_OPEN: Quota check returned non-ok, allowing request', {
|
|
76
81
|
orgId, quotaType, statusCode: response.statusCode, message: response.body.message,
|
|
77
82
|
});
|
|
83
|
+
(0, metric_emitter_1.emitCounter)('quota_fail_open_total', { operation: 'check', reason: 'non-ok', quotaType });
|
|
78
84
|
return createFailOpenResult();
|
|
79
85
|
}
|
|
80
86
|
return response.body.data.status;
|
|
@@ -92,6 +98,52 @@ function createQuotaService(config = {}) {
|
|
|
92
98
|
logger.debug('Quota incremented', { orgId, quotaType, amount });
|
|
93
99
|
}
|
|
94
100
|
},
|
|
101
|
+
async reserve(orgId, quotaType, authHeader, amount = 1, requestId) {
|
|
102
|
+
const path = `/quotas/${encodeURIComponent(orgId)}/increment`;
|
|
103
|
+
// 200 carries `data.quota`; 429 (QUOTA_EXCEEDED) carries `details.quota`.
|
|
104
|
+
// Both shapes are normalized into QuotaReserveResult.
|
|
105
|
+
const response = await client.post(path, { quotaType, amount }, { headers: buildHeaders(orgId, authHeader, requestId), ...QUOTA_REQUEST_OPTIONS });
|
|
106
|
+
if (!response) {
|
|
107
|
+
logger.warn('QUOTA_FAIL_OPEN: Quota service unreachable on reserve, allowing request', { orgId, quotaType });
|
|
108
|
+
(0, metric_emitter_1.emitCounter)('quota_fail_open_total', { operation: 'reserve', reason: 'unreachable', quotaType });
|
|
109
|
+
return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
|
|
110
|
+
}
|
|
111
|
+
if (response.statusCode === 429) {
|
|
112
|
+
const q = response.body.details?.quota;
|
|
113
|
+
return {
|
|
114
|
+
exceeded: true,
|
|
115
|
+
quota: q ?? { type: quotaType, limit: 0, used: 0, remaining: 0 },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (response.statusCode !== 200 || !response.body.success) {
|
|
119
|
+
logger.warn('QUOTA_FAIL_OPEN: Quota reserve returned non-ok, allowing request', {
|
|
120
|
+
orgId, quotaType, statusCode: response.statusCode,
|
|
121
|
+
});
|
|
122
|
+
(0, metric_emitter_1.emitCounter)('quota_fail_open_total', { operation: 'reserve', reason: 'non-ok', quotaType });
|
|
123
|
+
return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
|
|
124
|
+
}
|
|
125
|
+
const q = response.body.data?.quota;
|
|
126
|
+
return {
|
|
127
|
+
exceeded: false,
|
|
128
|
+
quota: q ?? { type: quotaType, limit: -1, used: 0, remaining: -1 },
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
async decrement(orgId, quotaType, authHeader, amount = 1, requestId) {
|
|
132
|
+
const path = `/quotas/${encodeURIComponent(orgId)}/decrement`;
|
|
133
|
+
const response = await client
|
|
134
|
+
.post(path, { quotaType, amount }, { headers: buildHeaders(orgId, authHeader, requestId), ...QUOTA_REQUEST_OPTIONS });
|
|
135
|
+
if (!response || response.statusCode !== 200) {
|
|
136
|
+
// Rollback failure is logged but never propagated the action's own
|
|
137
|
+
// failure has already been surfaced to the caller; a stuck counter
|
|
138
|
+
// resolves on the next period reset.
|
|
139
|
+
logger.warn('Failed to decrement quota (slot will reset on next period)', {
|
|
140
|
+
orgId, quotaType, amount, statusCode: response?.statusCode,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
logger.debug('Quota decremented', { orgId, quotaType, amount });
|
|
145
|
+
}
|
|
146
|
+
},
|
|
95
147
|
async updateLimits(orgId, limits, authHeader, requestId) {
|
|
96
148
|
const path = `/quotas/${encodeURIComponent(orgId)}`;
|
|
97
149
|
const response = await client.put(path, limits, { headers: buildHeaders(orgId, authHeader, requestId) });
|
|
@@ -104,6 +156,19 @@ function createQuotaService(config = {}) {
|
|
|
104
156
|
logger.info('Quota limits updated', { orgId, limits });
|
|
105
157
|
return true;
|
|
106
158
|
},
|
|
159
|
+
async getTier(orgId, authHeader, requestId) {
|
|
160
|
+
const path = `/quotas/${encodeURIComponent(orgId)}`;
|
|
161
|
+
const response = await client.get(path, { headers: buildHeaders(orgId, authHeader, requestId), ...QUOTA_REQUEST_OPTIONS });
|
|
162
|
+
if (!response || response.statusCode !== 200 || !response.body.success) {
|
|
163
|
+
logger.warn('QUOTA_FAIL_OPEN: tier lookup failed, defaulting to developer tier', {
|
|
164
|
+
orgId, statusCode: response?.statusCode,
|
|
165
|
+
});
|
|
166
|
+
(0, metric_emitter_1.emitCounter)('quota_fail_open_total', { operation: 'tier', reason: response ? 'non-ok' : 'unreachable', quotaType: 'tier' });
|
|
167
|
+
return quota_tiers_1.DEFAULT_TIER;
|
|
168
|
+
}
|
|
169
|
+
const tier = response.body.data?.quota?.tier;
|
|
170
|
+
return tier && (0, quota_tiers_1.isValidTier)(tier) ? tier : quota_tiers_1.DEFAULT_TIER;
|
|
171
|
+
},
|
|
107
172
|
async reset(orgId, quotaType, authHeader, requestId) {
|
|
108
173
|
const path = `/quotas/${encodeURIComponent(orgId)}/reset`;
|
|
109
174
|
const body = quotaType ? { quotaType } : {};
|
|
@@ -134,4 +199,35 @@ function createQuotaService(config = {}) {
|
|
|
134
199
|
function incrementQuota(quotaService, orgId, quotaType, authHeader, logWarn) {
|
|
135
200
|
quotaService.increment(orgId, quotaType, authHeader).catch((err) => logWarn('Quota increment failed', { error: err instanceof Error ? err.message : String(err) }));
|
|
136
201
|
}
|
|
137
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvcXVvdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7O0FBb0Z0QyxnREF1RkM7QUFjRCx3Q0FVQztBQWpNRCwrQ0FBaUU7QUFFakUsNENBQStDO0FBRS9DLDBFQUEwRTtBQUMxRSxNQUFNLHFCQUFxQixHQUErRDtJQUN4RixtQkFBbUIsRUFBRSxDQUFDO0lBQ3RCLFVBQVUsRUFBRSxDQUFDO0NBQ2QsQ0FBQztBQUVGLE1BQU0sTUFBTSxHQUFHLElBQUEscUJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQztBQTRCckM7O0dBRUc7QUFDSCxTQUFTLG9CQUFvQjtJQUMzQixPQUFPO1FBQ0wsT0FBTyxFQUFFLElBQUk7UUFDYixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ1QsSUFBSSxFQUFFLENBQUM7UUFDUCxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2IsT0FBTyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1FBQ2pDLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxLQUFhLEVBQUUsVUFBbUIsRUFBRSxTQUFrQjtJQUMxRSxNQUFNLE9BQU8sR0FBMkIsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDOUQsSUFBSSxVQUFVO1FBQUUsT0FBTyxDQUFDLGFBQWEsR0FBRyxVQUFVLENBQUM7SUFDbkQsSUFBSSxTQUFTO1FBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUNuRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxTQUE2QixFQUFFO0lBQ2hFLE1BQU0sYUFBYSxHQUFrQjtRQUNuQyxJQUFJLEVBQUUs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LEVBQUU7b0JBQ25DLEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxVQUFVO2lCQUNuRCxDQUFDLENBQUM7Z0JBQ0gsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixjQUFjLENBQzVCLFlBQTBCLEVBQzFCLEtBQWEsRUFDYixTQUFvQixFQUNwQixVQUFrQixFQUNsQixPQUFrRDtJQUVsRCxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBWSxFQUFFLEVBQUUsQ0FDMUUsT0FBTyxDQUFDLHdCQUF3QixFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQy9GLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZVNhZmVDbGllbnQsIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9odHRwLWNsaWVudCc7XG5pbXBvcnQgeyBRdW90YVR5cGUsIFF1b3RhQ2hlY2tSZXN1bHQsIFNlcnZpY2VDb25maWcgfSBmcm9tICcuLi90eXBlcy9jb21tb24nO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyJztcblxuLyoqIFJldHJ5IG9wdGlvbnMgZm9yIHF1b3RhIGNhbGxzIOKAlCBmYWlsIGZhc3Qgc2luY2UgcXVvdGEgaXMgZmFpbC1vcGVuLiAqL1xuY29uc3QgUVVPVEFfUkVRVUVTVF9PUFRJT05TOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAnbWF4UmF0ZUxpbWl0UmV0cmllcycgfCAnbWF4UmV0cmllcyc+ID0ge1xuICBtYXhSYXRlTGltaXRSZXRyaWVzOiAxLFxuICBtYXhSZXRyaWVzOiAxLFxufTtcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdxdW90YScpO1xuXG4vKipcbiAqIFF1b3RhIHNlcnZpY2UgY2xpZW50IGludGVyZmFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YVNlcnZpY2Uge1xuICAvKiogQ2hlY2sgaWYgcXVvdGEgaXMgYXZhaWxhYmxlIChmYWlsLW9wZW4gb24gZXJyb3IpLiAqL1xuICBjaGVjayhvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhQ2hlY2tSZXN1bHQ+O1xuICAvKiogSW5jcmVtZW50IHF1b3RhIHVzYWdlLiBSZXR1cm5zIGEgcHJvbWlzZSBzbyBjYWxsZXJzIGNhbiBvcHRpb25hbGx5IGhhbmRsZSBlcnJvcnMuICovXG4gIGluY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ/OiBudW1iZXIsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIC8qKiBVcGRhdGUgcXVvdGEgbGltaXRzLiBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4gKi9cbiAgdXBkYXRlTGltaXRzKG9yZ0lkOiBzdHJpbmcsIGxpbWl0czogUGFydGlhbDxSZWNvcmQ8UXVvdGFUeXBlLCBudW1iZXI+PiwgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAvKiogUmVzZXQgcXVvdGEgdXNhZ2UuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLiAqL1xuICByZXNldChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU/OiBRdW90YVR5cGUsIGF1dGhIZWFkZXI/OiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj47XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgcXVvdGEgc2VydmljZSBjbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFTZXJ2aWNlQ29uZmlnIHtcbiAgLyoqIFF1b3RhIHNlcnZpY2UgaG9zdCAoZGVmYXVsdDogZW52IFFVT1RBX1NFUlZJQ0VfSE9TVCBvciAncXVvdGEnKSAqL1xuICBob3N0Pzogc3RyaW5nO1xuICAvKiogUXVvdGEgc2VydmljZSBwb3J0IChkZWZhdWx0OiBlbnYgUVVPVEFfU0VSVklDRV9QT1JUIG9yIDMwMDApICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChkZWZhdWx0OiA1MDAwKSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGZhaWwtb3BlbiBxdW90YSByZXN1bHQgKGFsbG93cyB0aGUgcmVxdWVzdCkuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk6IFF1b3RhQ2hlY2tSZXN1bHQge1xuICByZXR1cm4ge1xuICAgIGFsbG93ZWQ6IHRydWUsXG4gICAgbGltaXQ6IC0xLFxuICAgIHVzZWQ6IDAsXG4gICAgcmVtYWluaW5nOiAtMSxcbiAgICByZXNldEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgdW5saW1pdGVkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGNvbW1vbiByZXF1ZXN0IGhlYWRlcnMgd2l0aCBvcHRpb25hbCByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nLlxuICovXG5mdW5jdGlvbiBidWlsZEhlYWRlcnMob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7ICd4LW9yZy1pZCc6IG9yZ0lkIH07XG4gIGlmIChhdXRoSGVhZGVyKSBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBhdXRoSGVhZGVyO1xuICBpZiAocmVxdWVzdElkKSBoZWFkZXJzWydYLVJlcXVlc3QtSWQnXSA9IHJlcXVlc3RJZDtcbiAgcmV0dXJuIGhlYWRlcnM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgcXVvdGEgc2VydmljZSBjbGllbnQuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIHNlcnZpY2UgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgUXVvdGEgc2VydmljZSBjbGllbnRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcXVvdGFTZXJ2aWNlID0gY3JlYXRlUXVvdGFTZXJ2aWNlKCk7XG4gKlxuICogLy8gQ2hlY2sgcXVvdGEgYmVmb3JlIHByb2Nlc3NpbmdcbiAqIGNvbnN0IHF1b3RhID0gYXdhaXQgcXVvdGFTZXJ2aWNlLmNoZWNrKG9yZ0lkLCAnYXBpQ2FsbHMnLCBhdXRoSGVhZGVyKTtcbiAqIGlmICghcXVvdGEuYWxsb3dlZCkge1xuICogICByZXR1cm4gcmVzLnN0YXR1cyg0MjkpLmpzb24oeyBlcnJvcjogJ1F1b3RhIGV4Y2VlZGVkJyB9KTtcbiAqIH1cbiAqXG4gKiAvLyBJbmNyZW1lbnQgcXVvdGEgYWZ0ZXIgc3VjY2Vzc1xuICogcXVvdGFTZXJ2aWNlLmluY3JlbWVudChvcmdJZCwgJ2FwaUNhbGxzJywgYXV0aEhlYWRlcikuY2F0Y2goZXJyID0+IGxvZ2dlci53YXJuKCdRdW90YSBpbmNyZW1lbnQgZmFpbGVkJywgeyBlcnJvcjogZXJyIH0pKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUXVvdGFTZXJ2aWNlKGNvbmZpZzogUXVvdGFTZXJ2aWNlQ29uZmlnID0ge30pOiBRdW90YVNlcnZpY2Uge1xuICBjb25zdCBzZXJ2aWNlQ29uZmlnOiBTZXJ2aWNlQ29uZmlnID0ge1xuICAgIGhvc3Q6IGNvbmZpZy5ob3N0ID8/IHByb2Nlc3MuZW52LlFVT1RBX1NFUlZJQ0VfSE9TVCA/PyAncXVvdGEnLFxuICAgIHBvcnQ6IGNvbmZpZy5wb3J0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlFVT1RBX1NFUlZJQ0VfUE9SVCA/PyAnMzAwMCcsIDEwKSxcbiAgICB0aW1lb3V0OiBjb25maWcudGltZW91dCA/PyA1MDAwLFxuICB9O1xuXG4gIGNvbnN0IGNsaWVudCA9IGNyZWF0ZVNhZmVDbGllbnQoc2VydmljZUNvbmZpZyk7XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBjaGVjayhvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhQ2hlY2tSZXN1bHQ+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KHF1b3RhVHlwZSl9YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZ2V0PHtcbiAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgZGF0YT86IHsgcXVvdGFUeXBlOiBzdHJpbmc7IHN0YXR1czogUXVvdGFDaGVja1Jlc3VsdCB9O1xuICAgICAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgICAgfT4ocGF0aCwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCksIC4uLlFVT1RBX1JFUVVFU1RfT1BUSU9OUyB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICBsb2dnZXIud2FybignUVVPVEFfRkFJTF9PUEVOOiBRdW90YSBzZXJ2aWNlIHVucmVhY2hhYmxlLCBhbGxvd2luZyByZXF1ZXN0JywgeyBvcmdJZCwgcXVvdGFUeXBlIH0pO1xuICAgICAgICByZXR1cm4gY3JlYXRlRmFpbE9wZW5SZXN1bHQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCB8fCAhcmVzcG9uc2UuYm9keS5zdWNjZXNzIHx8ICFyZXNwb25zZS5ib2R5LmRhdGE/LnN0YXR1cykge1xuICAgICAgICBsb2dnZXIud2FybignUVVPVEFfRkFJTF9PUEVOOiBRdW90YSBjaGVjayByZXR1cm5lZCBub24tb2ssIGFsbG93aW5nIHJlcXVlc3QnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzQ29kZSwgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZS5ib2R5LmRhdGEuc3RhdHVzO1xuICAgIH0sXG5cbiAgICBhc3luYyBpbmNyZW1lbnQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50OiBudW1iZXIgPSAxLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9L2luY3JlbWVudGA7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50XG4gICAgICAgIC5wb3N0KHBhdGgsIHsgcXVvdGFUeXBlLCBhbW91bnQgfSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCksIC4uLlFVT1RBX1JFUVVFU1RfT1BUSU9OUyB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZSB8fCByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBpbmNyZW1lbnQgcXVvdGEnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgYW1vdW50LCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1F1b3RhIGluY3JlbWVudGVkJywgeyBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHVwZGF0ZUxpbWl0cyhcbiAgICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgICBsaW1pdHM6IFBhcnRpYWw8UmVjb3JkPFF1b3RhVHlwZSwgbnVtYmVyPj4sXG4gICAgICBhdXRoSGVhZGVyOiBzdHJpbmcsXG4gICAgICByZXF1ZXN0SWQ/OiBzdHJpbmcsXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfWA7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnB1dChwYXRoLCBsaW1pdHMsIHsgaGVhZGVyczogYnVpbGRIZWFkZXJzKG9yZ0lkLCBhdXRoSGVhZGVyLCByZXF1ZXN0SWQpIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIHVwZGF0ZSBxdW90YSBsaW1pdHMnLCB7XG4gICAgICAgICAgb3JnSWQsIGxpbWl0cywgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKCdRdW90YSBsaW1pdHMgdXBkYXRlZCcsIHsgb3JnSWQsIGxpbWl0cyB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICBhc3luYyByZXNldChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU/OiBRdW90YVR5cGUsIGF1dGhIZWFkZXI/OiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX0vcmVzZXRgO1xuXG4gICAgICBjb25zdCBib2R5ID0gcXVvdGFUeXBlID8geyBxdW90YVR5cGUgfSA6IHt9O1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucG9zdChwYXRoLCBib2R5LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciA/PyAnJywgcmVxdWVzdElkKSB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZSB8fCByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byByZXNldCBxdW90YScsIHtcbiAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1F1b3RhIHJlc2V0JywgeyBvcmdJZCwgcXVvdGFUeXBlOiBxdW90YVR5cGUgPz8gJ2FsbCcgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEZpcmUtYW5kLWZvcmdldCBxdW90YSBpbmNyZW1lbnQgd2l0aCBzdGFuZGFyZGl6ZWQgZXJyb3IgbG9nZ2luZy5cbiAqXG4gKiBXcmFwcyBgcXVvdGFTZXJ2aWNlLmluY3JlbWVudCgpYCB3aXRoIGEgYC5jYXRjaCgpYCB0aGF0IGxvZ3MgYSB3YXJuaW5nLlxuICogRWxpbWluYXRlcyB0aGUgaWRlbnRpY2FsIG9uZS1saW5lciByZXBlYXRlZCBhY3Jvc3MgZXZlcnkgcmVhZCByb3V0ZS5cbiAqXG4gKiBAcGFyYW0gcXVvdGFTZXJ2aWNlIC0gUXVvdGEgc2VydmljZSBjbGllbnRcbiAqIEBwYXJhbSBvcmdJZCAtIE9yZ2FuaXphdGlvbiBJRFxuICogQHBhcmFtIHF1b3RhVHlwZSAtIFF1b3RhIHR5cGUgdG8gaW5jcmVtZW50XG4gKiBAcGFyYW0gYXV0aEhlYWRlciAtIEF1dGhvcml6YXRpb24gaGVhZGVyIHZhbHVlXG4gKiBAcGFyYW0gbG9nV2FybiAtIExvZ2dpbmcgZnVuY3Rpb24gZm9yIHdhcm5pbmdzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmNyZW1lbnRRdW90YShcbiAgcXVvdGFTZXJ2aWNlOiBRdW90YVNlcnZpY2UsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHF1b3RhVHlwZTogUXVvdGFUeXBlLFxuICBhdXRoSGVhZGVyOiBzdHJpbmcsXG4gIGxvZ1dhcm46IChtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIHF1b3RhU2VydmljZS5pbmNyZW1lbnQob3JnSWQsIHF1b3RhVHlwZSwgYXV0aEhlYWRlcikuY2F0Y2goKGVycjogdW5rbm93bikgPT5cbiAgICBsb2dXYXJuKCdRdW90YSBpbmNyZW1lbnQgZmFpbGVkJywgeyBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pLFxuICApO1xufVxuIl19
|
|
202
|
+
/**
|
|
203
|
+
* Atomic reserve helper for the "reserve + commit / rollback" pattern.
|
|
204
|
+
* Use for expensive resources (pipelines, plugins, AI calls) where the
|
|
205
|
+
* fire-and-forget post-hoc `incrementQuota` allows concurrent over-spend.
|
|
206
|
+
*
|
|
207
|
+
* Returns the structured result so the caller can decide whether to run
|
|
208
|
+
* the gated action or 429 the client.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const reservation = await reserveQuota(quotaService, orgId, 'pipelines', authHeader);
|
|
213
|
+
* if (reservation.exceeded) return sendQuotaExceeded(res, 'pipelines', reservation.quota);
|
|
214
|
+
* try {
|
|
215
|
+
* await doExpensiveThing();
|
|
216
|
+
* } catch (err) {
|
|
217
|
+
* await decrementQuota(quotaService, orgId, 'pipelines', authHeader);
|
|
218
|
+
* throw err;
|
|
219
|
+
* }
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
function reserveQuota(quotaService, orgId, quotaType, authHeader, amount = 1, requestId) {
|
|
223
|
+
return quotaService.reserve(orgId, quotaType, authHeader, amount, requestId);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Fire-and-forget rollback for a previously reserved quota slot.
|
|
227
|
+
* Logs on failure but never throws the action that needed the rollback
|
|
228
|
+
* has already failed, no point compounding the error.
|
|
229
|
+
*/
|
|
230
|
+
function decrementQuota(quotaService, orgId, quotaType, authHeader, logWarn, amount = 1) {
|
|
231
|
+
quotaService.decrement(orgId, quotaType, authHeader, amount).catch((err) => logWarn('Quota rollback failed', { error: err instanceof Error ? err.message : String(err) }));
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvcXVvdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7O0FBMkh0QyxnREF1S0M7QUFjRCx3Q0FTQztBQXNCRCxvQ0FRQztBQU9ELHdDQVVDO0FBdFdELCtDQUFpRTtBQUVqRSxzREFBNEU7QUFDNUUsNENBQStDO0FBQy9DLDREQUFzRDtBQUV0RCx5RUFBeUU7QUFDekUsTUFBTSxxQkFBcUIsR0FBK0Q7SUFDeEYsbUJBQW1CLEVBQUUsQ0FBQztJQUN0QixVQUFVLEVBQUUsQ0FBQztDQUNkLENBQUM7QUFFRixNQUFNLE1BQU0sR0FBRyxJQUFBLHFCQUFZLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFpRXJDOztHQUVHO0FBQ0gsU0FBUyxvQkFBb0I7SUFDM0IsT0FBTztRQUNMLE9BQU8sRUFBRSxJQUFJO1FBQ2IsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNULElBQUksRUFBRSxDQUFDO1FBQ1AsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUNiLE9BQU8sRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtRQUNqQyxTQUFTLEVBQUUsSUFBSTtLQUNoQixDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxZQUFZLENBQUMsS0FBYSxFQUFFLFVBQW1CLEVBQUUsU0FBa0I7SUFDMUUsTUFBTSxPQUFPLEdBQTJCLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQzlELElBQUksVUFBVTtRQUFFLE9BQU8sQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDO0lBQ25ELElBQUksU0FBUztRQUFFLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxTQUFTLENBQUM7SUFDbkQsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsU0FBZ0Isa0JBQWtCLENBQUMs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LEVBQUUsQ0FBQyxDQUM3RixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVTYWZlQ2xpZW50LCBSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vaHR0cC1jbGllbnQnO1xuaW1wb3J0IHsgUXVvdGFUeXBlLCBRdW90YUNoZWNrUmVzdWx0LCBTZXJ2aWNlQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMvY29tbW9uJztcbmltcG9ydCB7IERFRkFVTFRfVElFUiwgaXNWYWxpZFRpZXIsIFF1b3RhVGllciB9IGZyb20gJy4uL3R5cGVzL3F1b3RhLXRpZXJzJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQgeyBlbWl0Q291bnRlciB9IGZyb20gJy4uL3V0aWxzL21ldHJpYy1lbWl0dGVyJztcblxuLyoqIFJldHJ5IG9wdGlvbnMgZm9yIHF1b3RhIGNhbGxzICBmYWlsIGZhc3Qgc2luY2UgcXVvdGEgaXMgZmFpbC1vcGVuLiAqL1xuY29uc3QgUVVPVEFfUkVRVUVTVF9PUFRJT05TOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAnbWF4UmF0ZUxpbWl0UmV0cmllcycgfCAnbWF4UmV0cmllcyc+ID0ge1xuICBtYXhSYXRlTGltaXRSZXRyaWVzOiAxLFxuICBtYXhSZXRyaWVzOiAxLFxufTtcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdxdW90YScpO1xuXG4vKipcbiAqIFJlc3VsdCBvZiBhIHN5bmNocm9ub3VzIHF1b3RhIHJlc2VydmF0aW9uICB0aGUgYXRvbWljIGNoZWNrK2luY3JlbWVudFxuICogdmFyaWFudC4gYGV4Y2VlZGVkOiB0cnVlYCBtZWFucyB0aGUgb3BlcmF0aW9uIHdhcyByZWplY3RlZCBhdCB0aGUgREJcbiAqIGxldmVsOyB0aGUgY2FsbGVyIHNob3VsZCByZXR1cm4gNDI5IHdpdGhvdXQgcnVubmluZyB0aGUgZ2F0ZWQgYWN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1b3RhUmVzZXJ2ZVJlc3VsdCB7XG4gIGV4Y2VlZGVkOiBib29sZWFuO1xuICBxdW90YToge1xuICAgIHR5cGU6IFF1b3RhVHlwZTtcbiAgICBsaW1pdDogbnVtYmVyO1xuICAgIHVzZWQ6IG51bWJlcjtcbiAgICByZW1haW5pbmc6IG51bWJlcjtcbiAgICByZXNldEF0Pzogc3RyaW5nO1xuICB9O1xufVxuXG4vKipcbiAqIFF1b3RhIHNlcnZpY2UgY2xpZW50IGludGVyZmFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YVNlcnZpY2Uge1xuICAvKiogQ2hlY2sgaWYgcXVvdGEgaXMgYXZhaWxhYmxlIChmYWlsLW9wZW4gb24gZXJyb3IpLiAqL1xuICBjaGVjayhvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhQ2hlY2tSZXN1bHQ+O1xuICAvKiogSW5jcmVtZW50IHF1b3RhIHVzYWdlLiBSZXR1cm5zIGEgcHJvbWlzZSBzbyBjYWxsZXJzIGNhbiBvcHRpb25hbGx5IGhhbmRsZSBlcnJvcnMuICovXG4gIGluY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ/OiBudW1iZXIsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBBdG9taWMgcmVzZXJ2ZSAgdGhlIHNhbWUgYXRvbWljIGNoZWNrK2luY3JlbWVudCBhcyBgaW5jcmVtZW50YCwgYnV0XG4gICAqIHBhcnNlcyB0aGUgcmVzcG9uc2Ugc28gY2FsbGVycyBjYW4gc2VlIHdoZXRoZXIgdGhlIHNsb3Qgd2FzIGFjdHVhbGx5XG4gICAqIHJlc2VydmVkLiBVc2UgdGhpcyBmb3IgZXhwZW5zaXZlIHJlc291cmNlcyB3aGVyZSB0aGUgcG9zdC1ob2MgZmlyZS1cbiAgICogYW5kLWZvcmdldCBwYXR0ZXJuIGFsbG93cyBjb25jdXJyZW50IG92ZXItc3BlbmQuXG4gICAqXG4gICAqIEZhaWwtb3BlbiBzZW1hbnRpY3Mgb24gdHJhbnNwb3J0IGVycm9yczogcmV0dXJucyBgZXhjZWVkZWQ6IGZhbHNlYCBzb1xuICAgKiB0aGUgY2FsbGVyIGNhbiBwcm9jZWVkIGFuZCB0aGUgcmVxdWVzdCBpc24ndCBibG9ja2VkIGJ5IHF1b3RhLXNlcnZpY2VcbiAgICogb3V0YWdlcyAobWF0Y2hlcyBgY2hlY2soKWApLlxuICAgKi9cbiAgcmVzZXJ2ZShvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ/OiBudW1iZXIsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFSZXNlcnZlUmVzdWx0PjtcbiAgLyoqIFJvbGwgYmFjayBhIHByZXZpb3VzbHkgcmVzZXJ2ZWQgc2xvdC4gRmlyZS1hbmQtZm9yZ2V0ICBuZXZlciB0aHJvd3MuICovXG4gIGRlY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ/OiBudW1iZXIsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIC8qKiBVcGRhdGUgcXVvdGEgbGltaXRzLiBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4gKi9cbiAgdXBkYXRlTGltaXRzKG9yZ0lkOiBzdHJpbmcsIGxpbWl0czogUGFydGlhbDxSZWNvcmQ8UXVvdGFUeXBlLCBudW1iZXI+PiwgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAvKiogUmVzZXQgcXVvdGEgdXNhZ2UuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLiAqL1xuICByZXNldChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU/OiBRdW90YVR5cGUsIGF1dGhIZWFkZXI/OiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj47XG4gIC8qKlxuICAgKiBHZXQgdGhlIG9yZydzIHF1b3RhIHRpZXIgKCdkZXZlbG9wZXInIHwgJ3BybycgfCAndW5saW1pdGVkJykuIFVzZWQgYnlcbiAgICogdGhlIHBsdWdpbi1idWlsZCBxdWV1ZSBwYXJ0aXRpb25pbmcgdG8gcm91dGUgYSBidWlsZCB0byB0aGVcbiAgICogcmlnaHQgcGVyLXRpZXIgcXVldWUuIEZhaWwtb3BlbiByZXR1cm5zIERFRkFVTFRfVElFUiAoJ2RldmVsb3BlcicpXG4gICAqIGEgbWlzY2xhc3NpZmllZCBwcm8vdW5saW1pdGVkIG9yZyB3aWxsIGxhbmQgaW4gdGhlIGRldmVsb3BlciBxdWV1ZVxuICAgKiBhbmQgc3RpbGwgYnVpbGQsIGp1c3Qgd2l0aG91dCB0aGUgdGllci1zY29wZWQgc2NoZWR1bGluZyBib29zdC5cbiAgICovXG4gIGdldFRpZXIob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhVGllcj47XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgcXVvdGEgc2VydmljZSBjbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFTZXJ2aWNlQ29uZmlnIHtcbiAgLyoqIFF1b3RhIHNlcnZpY2UgaG9zdCAoZGVmYXVsdDogZW52IFFVT1RBX1NFUlZJQ0VfSE9TVCBvciAncXVvdGEnKSAqL1xuICBob3N0Pzogc3RyaW5nO1xuICAvKiogUXVvdGEgc2VydmljZSBwb3J0IChkZWZhdWx0OiBlbnYgUVVPVEFfU0VSVklDRV9QT1JUIG9yIDMwMDApICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChkZWZhdWx0OiA1MDAwKSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGZhaWwtb3BlbiBxdW90YSByZXN1bHQgKGFsbG93cyB0aGUgcmVxdWVzdCkuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk6IFF1b3RhQ2hlY2tSZXN1bHQge1xuICByZXR1cm4ge1xuICAgIGFsbG93ZWQ6IHRydWUsXG4gICAgbGltaXQ6IC0xLFxuICAgIHVzZWQ6IDAsXG4gICAgcmVtYWluaW5nOiAtMSxcbiAgICByZXNldEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgdW5saW1pdGVkOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGNvbW1vbiByZXF1ZXN0IGhlYWRlcnMgd2l0aCBvcHRpb25hbCByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nLlxuICovXG5mdW5jdGlvbiBidWlsZEhlYWRlcnMob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7ICd4LW9yZy1pZCc6IG9yZ0lkIH07XG4gIGlmIChhdXRoSGVhZGVyKSBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBhdXRoSGVhZGVyO1xuICBpZiAocmVxdWVzdElkKSBoZWFkZXJzWydYLVJlcXVlc3QtSWQnXSA9IHJlcXVlc3RJZDtcbiAgcmV0dXJuIGhlYWRlcnM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgcXVvdGEgc2VydmljZSBjbGllbnQuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIHNlcnZpY2UgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgUXVvdGEgc2VydmljZSBjbGllbnRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcXVvdGFTZXJ2aWNlID0gY3JlYXRlUXVvdGFTZXJ2aWNlKCk7XG4gKlxuICogLy8gQ2hlY2sgcXVvdGEgYmVmb3JlIHByb2Nlc3NpbmdcbiAqIGNvbnN0IHF1b3RhID0gYXdhaXQgcXVvdGFTZXJ2aWNlLmNoZWNrKG9yZ0lkLCAnYXBpQ2FsbHMnLCBhdXRoSGVhZGVyKTtcbiAqIGlmICghcXVvdGEuYWxsb3dlZCkge1xuICogcmV0dXJuIHJlcy5zdGF0dXMoNDI5KS5qc29uKHsgZXJyb3I6ICdRdW90YSBleGNlZWRlZCcgfSk7XG4gKiB9XG4gKlxuICogLy8gSW5jcmVtZW50IHF1b3RhIGFmdGVyIHN1Y2Nlc3NcbiAqIHF1b3RhU2VydmljZS5pbmNyZW1lbnQob3JnSWQsICdhcGlDYWxscycsIGF1dGhIZWFkZXIpLmNhdGNoKGVyciA9PiBsb2dnZXIud2FybignUXVvdGEgaW5jcmVtZW50IGZhaWxlZCcsIHsgZXJyb3I6IGVyciB9KSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVF1b3RhU2VydmljZShjb25maWc6IFF1b3RhU2VydmljZUNvbmZpZyA9IHt9KTogUXVvdGFTZXJ2aWNlIHtcbiAgY29uc3Qgc2VydmljZUNvbmZpZzogU2VydmljZUNvbmZpZyA9IHtcbiAgICBob3N0OiBjb25maWcuaG9zdCA/PyBwcm9jZXNzLmVudi5RVU9UQV9TRVJWSUNFX0hPU1QgPz8gJ3F1b3RhJyxcbiAgICBwb3J0OiBjb25maWcucG9ydCA/PyBwYXJzZUludChwcm9jZXNzLmVudi5RVU9UQV9TRVJWSUNFX1BPUlQgPz8gJzMwMDAnLCAxMCksXG4gICAgdGltZW91dDogY29uZmlnLnRpbWVvdXQgPz8gNTAwMCxcbiAgfTtcblxuICBjb25zdCBjbGllbnQgPSBjcmVhdGVTYWZlQ2xpZW50KHNlcnZpY2VDb25maWcpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgY2hlY2sob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxRdW90YUNoZWNrUmVzdWx0PiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS8ke2VuY29kZVVSSUNvbXBvbmVudChxdW90YVR5cGUpfWA7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmdldDx7XG4gICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgIGRhdGE/OiB7IHF1b3RhVHlwZTogc3RyaW5nOyBzdGF0dXM6IFF1b3RhQ2hlY2tSZXN1bHQgfTtcbiAgICAgICAgbWVzc2FnZT86IHN0cmluZztcbiAgICAgIH0+KHBhdGgsIHsgaGVhZGVyczogYnVpbGRIZWFkZXJzKG9yZ0lkLCBhdXRoSGVhZGVyLCByZXF1ZXN0SWQpLCAuLi5RVU9UQV9SRVFVRVNUX09QVElPTlMgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgc2VydmljZSB1bnJlYWNoYWJsZSwgYWxsb3dpbmcgcmVxdWVzdCcsIHsgb3JnSWQsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfb3Blbl90b3RhbCcsIHsgb3BlcmF0aW9uOiAnY2hlY2snLCByZWFzb246ICd1bnJlYWNoYWJsZScsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDAgfHwgIXJlc3BvbnNlLmJvZHkuc3VjY2VzcyB8fCAhcmVzcG9uc2UuYm9keS5kYXRhPy5zdGF0dXMpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgY2hlY2sgcmV0dXJuZWQgbm9uLW9rLCBhbGxvd2luZyByZXF1ZXN0Jywge1xuICAgICAgICAgIG9yZ0lkLCBxdW90YVR5cGUsIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1c0NvZGUsIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ2NoZWNrJywgcmVhc29uOiAnbm9uLW9rJywgcXVvdGFUeXBlIH0pO1xuICAgICAgICByZXR1cm4gY3JlYXRlRmFpbE9wZW5SZXN1bHQoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuZGF0YS5zdGF0dXM7XG4gICAgfSxcblxuICAgIGFzeW5jIGluY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX0vaW5jcmVtZW50YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAgICAgLnBvc3QocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGluY3JlbWVudCBxdW90YScsIHtcbiAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQsIHN0YXR1c0NvZGU6IHJlc3BvbnNlPy5zdGF0dXNDb2RlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUXVvdGEgaW5jcmVtZW50ZWQnLCB7IG9yZ0lkLCBxdW90YVR5cGUsIGFtb3VudCB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgcmVzZXJ2ZShvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFSZXNlcnZlUmVzdWx0PiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9pbmNyZW1lbnRgO1xuXG4gICAgICAvLyAyMDAgY2FycmllcyBgZGF0YS5xdW90YWA7IDQyOSAoUVVPVEFfRVhDRUVERUQpIGNhcnJpZXMgYGRldGFpbHMucXVvdGFgLlxuICAgICAgLy8gQm90aCBzaGFwZXMgYXJlIG5vcm1hbGl6ZWQgaW50byBRdW90YVJlc2VydmVSZXN1bHQuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0PHtcbiAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgZGF0YT86IHsgcXVvdGE/OiBRdW90YVJlc2VydmVSZXN1bHRbJ3F1b3RhJ10gfTtcbiAgICAgICAgZGV0YWlscz86IHsgcXVvdGE/OiBRdW90YVJlc2VydmVSZXN1bHRbJ3F1b3RhJ10gfTtcbiAgICAgICAgZXJyb3JDb2RlPzogc3RyaW5nO1xuICAgICAgfT4ocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IFF1b3RhIHNlcnZpY2UgdW5yZWFjaGFibGUgb24gcmVzZXJ2ZSwgYWxsb3dpbmcgcmVxdWVzdCcsIHsgb3JnSWQsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfb3Blbl90b3RhbCcsIHsgb3BlcmF0aW9uOiAncmVzZXJ2ZScsIHJlYXNvbjogJ3VucmVhY2hhYmxlJywgcXVvdGFUeXBlIH0pO1xuICAgICAgICByZXR1cm4geyBleGNlZWRlZDogZmFsc2UsIHF1b3RhOiB7IHR5cGU6IHF1b3RhVHlwZSwgbGltaXQ6IC0xLCB1c2VkOiAwLCByZW1haW5pbmc6IC0xIH0gfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDQyOSkge1xuICAgICAgICBjb25zdCBxID0gcmVzcG9uc2UuYm9keS5kZXRhaWxzPy5xdW90YTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBleGNlZWRlZDogdHJ1ZSxcbiAgICAgICAgICBxdW90YTogcSA/PyB7IHR5cGU6IHF1b3RhVHlwZSwgbGltaXQ6IDAsIHVzZWQ6IDAsIHJlbWFpbmluZzogMCB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwIHx8ICFyZXNwb25zZS5ib2R5LnN1Y2Nlc3MpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgcmVzZXJ2ZSByZXR1cm5lZCBub24tb2ssIGFsbG93aW5nIHJlcXVlc3QnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ3Jlc2VydmUnLCByZWFzb246ICdub24tb2snLCBxdW90YVR5cGUgfSk7XG4gICAgICAgIHJldHVybiB7IGV4Y2VlZGVkOiBmYWxzZSwgcXVvdGE6IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogLTEsIHVzZWQ6IDAsIHJlbWFpbmluZzogLTEgfSB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBxID0gcmVzcG9uc2UuYm9keS5kYXRhPy5xdW90YTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGV4Y2VlZGVkOiBmYWxzZSxcbiAgICAgICAgcXVvdGE6IHEgPz8geyB0eXBlOiBxdW90YVR5cGUsIGxpbWl0OiAtMSwgdXNlZDogMCwgcmVtYWluaW5nOiAtMSB9LFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVjcmVtZW50KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZTogUXVvdGFUeXBlLCBhdXRoSGVhZGVyOiBzdHJpbmcsIGFtb3VudDogbnVtYmVyID0gMSwgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9kZWNyZW1lbnRgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAgICAgLnBvc3QocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICAvLyBSb2xsYmFjayBmYWlsdXJlIGlzIGxvZ2dlZCBidXQgbmV2ZXIgcHJvcGFnYXRlZCAgdGhlIGFjdGlvbidzIG93blxuICAgICAgICAvLyBmYWlsdXJlIGhhcyBhbHJlYWR5IGJlZW4gc3VyZmFjZWQgdG8gdGhlIGNhbGxlcjsgYSBzdHVjayBjb3VudGVyXG4gICAgICAgIC8vIHJlc29sdmVzIG9uIHRoZSBuZXh0IHBlcmlvZCByZXNldC5cbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBkZWNyZW1lbnQgcXVvdGEgKHNsb3Qgd2lsbCByZXNldCBvbiBuZXh0IHBlcmlvZCknLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgYW1vdW50LCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1F1b3RhIGRlY3JlbWVudGVkJywgeyBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHVwZGF0ZUxpbWl0cyggb3JnSWQ6IHN0cmluZyxcbiAgICAgIGxpbWl0czogUGFydGlhbDxSZWNvcmQ8UXVvdGFUeXBlLCBudW1iZXI+PixcbiAgICAgIGF1dGhIZWFkZXI6IHN0cmluZyxcbiAgICAgIHJlcXVlc3RJZD86IHN0cmluZyxcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucHV0KHBhdGgsIGxpbWl0cywgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gdXBkYXRlIHF1b3RhIGxpbWl0cycsIHtcbiAgICAgICAgICBvcmdJZCwgbGltaXRzLCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1F1b3RhIGxpbWl0cyB1cGRhdGVkJywgeyBvcmdJZCwgbGltaXRzIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFRpZXIob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhVGllcj4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX1gO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQ8e1xuICAgICAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgICAgICBkYXRhPzogeyBxdW90YT86IHsgdGllcj86IHN0cmluZyB9IH07XG4gICAgICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgICB9PihwYXRoLCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCB8fCAhcmVzcG9uc2UuYm9keS5zdWNjZXNzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IHRpZXIgbG9va3VwIGZhaWxlZCwgZGVmYXVsdGluZyB0byBkZXZlbG9wZXIgdGllcicsIHtcbiAgICAgICAgICBvcmdJZCwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsXG4gICAgICAgIH0pO1xuICAgICAgICBlbWl0Q291bnRlcigncXVvdGFfZmFpbF9vcGVuX3RvdGFsJywgeyBvcGVyYXRpb246ICd0aWVyJywgcmVhc29uOiByZXNwb25zZSA/ICdub24tb2snIDogJ3VucmVhY2hhYmxlJywgcXVvdGFUeXBlOiAndGllcicgfSk7XG4gICAgICAgIHJldHVybiBERUZBVUxUX1RJRVI7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRpZXIgPSByZXNwb25zZS5ib2R5LmRhdGE/LnF1b3RhPy50aWVyO1xuICAgICAgcmV0dXJuIHRpZXIgJiYgaXNWYWxpZFRpZXIodGllcikgPyB0aWVyOiBERUZBVUxUX1RJRVI7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2V0KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZT86IFF1b3RhVHlwZSwgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9yZXNldGA7XG5cbiAgICAgIGNvbnN0IGJvZHkgPSBxdW90YVR5cGUgPyB7IHF1b3RhVHlwZSB9OiB7fTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QocGF0aCwgYm9keSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIgPz8gJycsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gcmVzZXQgcXVvdGEnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKCdRdW90YSByZXNldCcsIHsgb3JnSWQsIHF1b3RhVHlwZTogcXVvdGFUeXBlID8/ICdhbGwnIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBGaXJlLWFuZC1mb3JnZXQgcXVvdGEgaW5jcmVtZW50IHdpdGggc3RhbmRhcmRpemVkIGVycm9yIGxvZ2dpbmcuXG4gKlxuICogV3JhcHMgYHF1b3RhU2VydmljZS5pbmNyZW1lbnQoKWAgd2l0aCBhIGAuY2F0Y2goKWAgdGhhdCBsb2dzIGEgd2FybmluZy5cbiAqIEVsaW1pbmF0ZXMgdGhlIGlkZW50aWNhbCBvbmUtbGluZXIgcmVwZWF0ZWQgYWNyb3NzIGV2ZXJ5IHJlYWQgcm91dGUuXG4gKlxuICogQHBhcmFtIHF1b3RhU2VydmljZSAtIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKiBAcGFyYW0gb3JnSWQgLSBPcmdhbml6YXRpb24gSURcbiAqIEBwYXJhbSBxdW90YVR5cGUgLSBRdW90YSB0eXBlIHRvIGluY3JlbWVudFxuICogQHBhcmFtIGF1dGhIZWFkZXIgLSBBdXRob3JpemF0aW9uIGhlYWRlciB2YWx1ZVxuICogQHBhcmFtIGxvZ1dhcm4gLSBMb2dnaW5nIGZ1bmN0aW9uIGZvciB3YXJuaW5nc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50UXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBsb2dXYXJuOiAobWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBxdW90YVNlcnZpY2UuaW5jcmVtZW50KG9yZ0lkLCBxdW90YVR5cGUsIGF1dGhIZWFkZXIpLmNhdGNoKChlcnI6IHVua25vd24pID0+XG4gICAgbG9nV2FybignUXVvdGEgaW5jcmVtZW50IGZhaWxlZCcsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2U6IFN0cmluZyhlcnIpIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEF0b21pYyByZXNlcnZlIGhlbHBlciBmb3IgdGhlIFwicmVzZXJ2ZSArIGNvbW1pdCAvIHJvbGxiYWNrXCIgcGF0dGVybi5cbiAqIFVzZSBmb3IgZXhwZW5zaXZlIHJlc291cmNlcyAocGlwZWxpbmVzLCBwbHVnaW5zLCBBSSBjYWxscykgd2hlcmUgdGhlXG4gKiBmaXJlLWFuZC1mb3JnZXQgcG9zdC1ob2MgYGluY3JlbWVudFF1b3RhYCBhbGxvd3MgY29uY3VycmVudCBvdmVyLXNwZW5kLlxuICpcbiAqIFJldHVybnMgdGhlIHN0cnVjdHVyZWQgcmVzdWx0IHNvIHRoZSBjYWxsZXIgY2FuIGRlY2lkZSB3aGV0aGVyIHRvIHJ1blxuICogdGhlIGdhdGVkIGFjdGlvbiBvciA0MjkgdGhlIGNsaWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzZXJ2YXRpb24gPSBhd2FpdCByZXNlcnZlUXVvdGEocXVvdGFTZXJ2aWNlLCBvcmdJZCwgJ3BpcGVsaW5lcycsIGF1dGhIZWFkZXIpO1xuICogaWYgKHJlc2VydmF0aW9uLmV4Y2VlZGVkKSByZXR1cm4gc2VuZFF1b3RhRXhjZWVkZWQocmVzLCAncGlwZWxpbmVzJywgcmVzZXJ2YXRpb24ucXVvdGEpO1xuICogdHJ5IHtcbiAqIGF3YWl0IGRvRXhwZW5zaXZlVGhpbmcoKTtcbiAqIH0gY2F0Y2ggKGVycikge1xuICogYXdhaXQgZGVjcmVtZW50UXVvdGEocXVvdGFTZXJ2aWNlLCBvcmdJZCwgJ3BpcGVsaW5lcycsIGF1dGhIZWFkZXIpO1xuICogdGhyb3cgZXJyO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNlcnZlUXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBhbW91bnQ6IG51bWJlciA9IDEsXG4gIHJlcXVlc3RJZD86IHN0cmluZyxcbik6IFByb21pc2U8UXVvdGFSZXNlcnZlUmVzdWx0PiB7XG4gIHJldHVybiBxdW90YVNlcnZpY2UucmVzZXJ2ZShvcmdJZCwgcXVvdGFUeXBlLCBhdXRoSGVhZGVyLCBhbW91bnQsIHJlcXVlc3RJZCk7XG59XG5cbi8qKlxuICogRmlyZS1hbmQtZm9yZ2V0IHJvbGxiYWNrIGZvciBhIHByZXZpb3VzbHkgcmVzZXJ2ZWQgcXVvdGEgc2xvdC5cbiAqIExvZ3Mgb24gZmFpbHVyZSBidXQgbmV2ZXIgdGhyb3dzICB0aGUgYWN0aW9uIHRoYXQgbmVlZGVkIHRoZSByb2xsYmFja1xuICogaGFzIGFscmVhZHkgZmFpbGVkLCBubyBwb2ludCBjb21wb3VuZGluZyB0aGUgZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNyZW1lbnRRdW90YSggcXVvdGFTZXJ2aWNlOiBRdW90YVNlcnZpY2UsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHF1b3RhVHlwZTogUXVvdGFUeXBlLFxuICBhdXRoSGVhZGVyOiBzdHJpbmcsXG4gIGxvZ1dhcm46IChtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKSA9PiB2b2lkLFxuICBhbW91bnQ6IG51bWJlciA9IDEsXG4pOiB2b2lkIHtcbiAgcXVvdGFTZXJ2aWNlLmRlY3JlbWVudChvcmdJZCwgcXVvdGFUeXBlLCBhdXRoSGVhZGVyLCBhbW91bnQpLmNhdGNoKChlcnI6IHVua25vd24pID0+XG4gICAgbG9nV2FybignUXVvdGEgcm9sbGJhY2sgZmFpbGVkJywgeyBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZTogU3RyaW5nKGVycikgfSksXG4gICk7XG59XG4iXX0=
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subset of platform's AuditAction enum that non-platform services emit.
|
|
3
|
+
* Kept in sync manually with platform/src/models/audit-event.ts; mismatched
|
|
4
|
+
* actions are rejected by the platform ingest endpoint (400) so a drift is
|
|
5
|
+
* visible in logs rather than silently dropped.
|
|
6
|
+
*/
|
|
7
|
+
export type RemoteAuditAction = 'plugin.build.completed' | 'plugin.build.failed' | 'plugin.build.timeout';
|
|
8
|
+
export interface RemoteAuditEvent {
|
|
9
|
+
action: RemoteAuditAction;
|
|
10
|
+
actorId: string;
|
|
11
|
+
actorEmail?: string;
|
|
12
|
+
orgId?: string;
|
|
13
|
+
affectedOrgId?: string;
|
|
14
|
+
targetType?: string;
|
|
15
|
+
targetId?: string;
|
|
16
|
+
details?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Client for POSTing audit events to the platform's `/audit-events` ingest
|
|
20
|
+
* endpoint. Mints a fresh service token per call (5 min TTL) there's no
|
|
21
|
+
* meaningful caching benefit when emissions are sparse.
|
|
22
|
+
*/
|
|
23
|
+
export interface RemoteAuditClient {
|
|
24
|
+
/**
|
|
25
|
+
* Fire-and-forget audit emission. Failures are logged at warn level but
|
|
26
|
+
* never thrown the originating action (e.g. a plugin build) has its
|
|
27
|
+
* own success/failure path that shouldn't get polluted by a flaky audit
|
|
28
|
+
* downstream.
|
|
29
|
+
*/
|
|
30
|
+
record(event: RemoteAuditEvent, serviceName: string): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Configuration for the remote audit client.
|
|
34
|
+
*/
|
|
35
|
+
export interface RemoteAuditClientConfig {
|
|
36
|
+
/** Platform service host (default: env PLATFORM_SERVICE_HOST or 'platform') */
|
|
37
|
+
host?: string;
|
|
38
|
+
/** Platform service port (default: env PLATFORM_SERVICE_PORT or 3000) */
|
|
39
|
+
port?: number;
|
|
40
|
+
/** Request timeout ms (default 3000 audit shouldn't block the worker). */
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Construct a remote-audit client targeted at the platform service.
|
|
45
|
+
*
|
|
46
|
+
* Used by api/plugin's build worker to push `plugin.build.*` events into
|
|
47
|
+
* the platform's MongoDB `audit_events` collection. Other services
|
|
48
|
+
* with worker-style emitters can use the same client.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const auditClient = createRemoteAuditClient();
|
|
53
|
+
* auditClient.record({
|
|
54
|
+
* action: 'plugin.build.completed',
|
|
55
|
+
* actorId: 'user-123',
|
|
56
|
+
* orgId: 'org-acme',
|
|
57
|
+
* targetType: 'plugin',
|
|
58
|
+
* targetId: 'plugin-abc',
|
|
59
|
+
* details: { name: 'my-plugin', version: '1.0.0' },
|
|
60
|
+
* }, 'plugin');
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function createRemoteAuditClient(config?: RemoteAuditClientConfig): RemoteAuditClient;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.createRemoteAuditClient = createRemoteAuditClient;
|
|
6
|
+
const http_client_1 = require("./http-client");
|
|
7
|
+
const auth_1 = require("../middleware/auth");
|
|
8
|
+
const logger_1 = require("../utils/logger");
|
|
9
|
+
const logger = (0, logger_1.createLogger)('remote-audit');
|
|
10
|
+
/** Tight retries audit ingest is best-effort, never block the caller. */
|
|
11
|
+
const AUDIT_REQUEST_OPTIONS = {
|
|
12
|
+
maxRateLimitRetries: 0,
|
|
13
|
+
maxRetries: 1,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Construct a remote-audit client targeted at the platform service.
|
|
17
|
+
*
|
|
18
|
+
* Used by api/plugin's build worker to push `plugin.build.*` events into
|
|
19
|
+
* the platform's MongoDB `audit_events` collection. Other services
|
|
20
|
+
* with worker-style emitters can use the same client.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const auditClient = createRemoteAuditClient();
|
|
25
|
+
* auditClient.record({
|
|
26
|
+
* action: 'plugin.build.completed',
|
|
27
|
+
* actorId: 'user-123',
|
|
28
|
+
* orgId: 'org-acme',
|
|
29
|
+
* targetType: 'plugin',
|
|
30
|
+
* targetId: 'plugin-abc',
|
|
31
|
+
* details: { name: 'my-plugin', version: '1.0.0' },
|
|
32
|
+
* }, 'plugin');
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function createRemoteAuditClient(config = {}) {
|
|
36
|
+
const serviceConfig = {
|
|
37
|
+
host: config.host ?? process.env.PLATFORM_SERVICE_HOST ?? 'platform',
|
|
38
|
+
port: config.port ?? parseInt(process.env.PLATFORM_SERVICE_PORT ?? '3000', 10),
|
|
39
|
+
timeout: config.timeout ?? 3000,
|
|
40
|
+
};
|
|
41
|
+
const client = (0, http_client_1.createSafeClient)(serviceConfig);
|
|
42
|
+
return {
|
|
43
|
+
record(event, serviceName) {
|
|
44
|
+
const authHeader = (0, auth_1.getServiceAuthHeader)({ serviceName, orgId: event.orgId });
|
|
45
|
+
// Strip the `Bearer ` prefix for InternalHttpClient it sets the
|
|
46
|
+
// Authorization header itself; the value here is raw.
|
|
47
|
+
const headers = { Authorization: authHeader };
|
|
48
|
+
// Path is /audit/events the platform mounts the audit router under
|
|
49
|
+
// /audit, and the internal ingest endpoint lives at /events under that.
|
|
50
|
+
client.post('/audit/events', event, { headers, ...AUDIT_REQUEST_OPTIONS })
|
|
51
|
+
.then((response) => {
|
|
52
|
+
if (!response || response.statusCode !== 200) {
|
|
53
|
+
logger.warn('Remote audit ingest non-ok', {
|
|
54
|
+
action: event.action, statusCode: response?.statusCode,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
logger.warn('Remote audit ingest threw', {
|
|
60
|
+
action: event.action,
|
|
61
|
+
error: err instanceof Error ? err.message : String(err),
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLWF1ZGl0LWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9yZW1vdGUtYXVkaXQtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOztBQW9GdEMsMERBZ0NDO0FBbEhELCtDQUFpRTtBQUNqRSw2Q0FBMEQ7QUFFMUQsNENBQStDO0FBRS9DLE1BQU0sTUFBTSxHQUFHLElBQUEscUJBQVksRUFBQyxjQUFjLENBQUMsQ0FBQztBQUU1QywwRUFBMEU7QUFDMUUsTUFBTSxxQkFBcUIsR0FBK0Q7SUFDeEYsbUJBQW1CLEVBQUUsQ0FBQztJQUN0QixVQUFVLEVBQUUsQ0FBQztDQUNkLENBQUM7QUFtREY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxTQUFnQix1QkFBdUIsQ0FBQyxTQUFrQyxFQUFFO0lBQzFFLE1BQU0sYUFBYSxHQUFrQjtRQUNuQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixJQUFJLFVBQVU7UUFDcEUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUM5RSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sSUFBSSxJQUFJO0tBQ2hDLENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxJQUFBLDhCQUFnQixFQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRS9DLE9BQU87UUFDTCxNQUFNLENBQUMsS0FBSyxFQUFFLFdBQVc7WUFDdkIsTUFBTSxVQUFVLEdBQUcsSUFBQSwyQkFBb0IsRUFBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0UsaUVBQWlFO1lBQ2pFLHNEQUFzRDtZQUN0RCxNQUFNLE9BQU8sR0FBMkIsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDdEUsb0VBQW9FO1lBQ3BFLHdFQUF3RTtZQUN4RSxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxxQkFBcUIsRUFBRSxDQUFDO2lCQUN2RSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDakIsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLEdBQUcsRUFBRSxDQUFDO29CQUM3QyxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFO3dCQUN4QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVU7cUJBQ3ZELENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxDQUFDLEdBQVksRUFBRSxFQUFFO2dCQUN0QixNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFO29CQUN2QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07b0JBQ3BCLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2lCQUN2RCxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVTYWZlQ2xpZW50LCBSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vaHR0cC1jbGllbnQnO1xuaW1wb3J0IHsgZ2V0U2VydmljZUF1dGhIZWFkZXIgfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGgnO1xuaW1wb3J0IHsgU2VydmljZUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbic7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXInO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlbW90ZS1hdWRpdCcpO1xuXG4vKiogVGlnaHQgcmV0cmllcyAgYXVkaXQgaW5nZXN0IGlzIGJlc3QtZWZmb3J0LCBuZXZlciBibG9jayB0aGUgY2FsbGVyLiAqL1xuY29uc3QgQVVESVRfUkVRVUVTVF9PUFRJT05TOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAnbWF4UmF0ZUxpbWl0UmV0cmllcycgfCAnbWF4UmV0cmllcyc+ID0ge1xuICBtYXhSYXRlTGltaXRSZXRyaWVzOiAwLFxuICBtYXhSZXRyaWVzOiAxLFxufTtcblxuLyoqXG4gKiBTdWJzZXQgb2YgcGxhdGZvcm0ncyBBdWRpdEFjdGlvbiBlbnVtIHRoYXQgbm9uLXBsYXRmb3JtIHNlcnZpY2VzIGVtaXQuXG4gKiBLZXB0IGluIHN5bmMgbWFudWFsbHkgd2l0aCBwbGF0Zm9ybS9zcmMvbW9kZWxzL2F1ZGl0LWV2ZW50LnRzOyBtaXNtYXRjaGVkXG4gKiBhY3Rpb25zIGFyZSByZWplY3RlZCBieSB0aGUgcGxhdGZvcm0gaW5nZXN0IGVuZHBvaW50ICg0MDApIHNvIGEgZHJpZnQgaXNcbiAqIHZpc2libGUgaW4gbG9ncyByYXRoZXIgdGhhbiBzaWxlbnRseSBkcm9wcGVkLlxuICovXG5leHBvcnQgdHlwZSBSZW1vdGVBdWRpdEFjdGlvbiA9XG4gIHwgJ3BsdWdpbi5idWlsZC5jb21wbGV0ZWQnXG4gIHwgJ3BsdWdpbi5idWlsZC5mYWlsZWQnXG4gIHwgJ3BsdWdpbi5idWlsZC50aW1lb3V0JztcblxuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVBdWRpdEV2ZW50IHtcbiAgYWN0aW9uOiBSZW1vdGVBdWRpdEFjdGlvbjtcbiAgYWN0b3JJZDogc3RyaW5nO1xuICBhY3RvckVtYWlsPzogc3RyaW5nO1xuICBvcmdJZD86IHN0cmluZztcbiAgYWZmZWN0ZWRPcmdJZD86IHN0cmluZztcbiAgdGFyZ2V0VHlwZT86IHN0cmluZztcbiAgdGFyZ2V0SWQ/OiBzdHJpbmc7XG4gIGRldGFpbHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuLyoqXG4gKiBDbGllbnQgZm9yIFBPU1RpbmcgYXVkaXQgZXZlbnRzIHRvIHRoZSBwbGF0Zm9ybSdzIGAvYXVkaXQtZXZlbnRzYCBpbmdlc3RcbiAqIGVuZHBvaW50LiBNaW50cyBhIGZyZXNoIHNlcnZpY2UgdG9rZW4gcGVyIGNhbGwgKDUgbWluIFRUTCkgIHRoZXJlJ3Mgbm9cbiAqIG1lYW5pbmdmdWwgY2FjaGluZyBiZW5lZml0IHdoZW4gZW1pc3Npb25zIGFyZSBzcGFyc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlQXVkaXRDbGllbnQge1xuICAvKipcbiAgICogRmlyZS1hbmQtZm9yZ2V0IGF1ZGl0IGVtaXNzaW9uLiBGYWlsdXJlcyBhcmUgbG9nZ2VkIGF0IHdhcm4gbGV2ZWwgYnV0XG4gICAqIG5ldmVyIHRocm93biAgdGhlIG9yaWdpbmF0aW5nIGFjdGlvbiAoZS5nLiBhIHBsdWdpbiBidWlsZCkgaGFzIGl0c1xuICAgKiBvd24gc3VjY2Vzcy9mYWlsdXJlIHBhdGggdGhhdCBzaG91bGRuJ3QgZ2V0IHBvbGx1dGVkIGJ5IGEgZmxha3kgYXVkaXRcbiAgICogZG93bnN0cmVhbS5cbiAgICovXG4gIHJlY29yZChldmVudDogUmVtb3RlQXVkaXRFdmVudCwgc2VydmljZU5hbWU6IHN0cmluZyk6IHZvaWQ7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIHJlbW90ZSBhdWRpdCBjbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlQXVkaXRDbGllbnRDb25maWcge1xuICAvKiogUGxhdGZvcm0gc2VydmljZSBob3N0IChkZWZhdWx0OiBlbnYgUExBVEZPUk1fU0VSVklDRV9IT1NUIG9yICdwbGF0Zm9ybScpICovXG4gIGhvc3Q/OiBzdHJpbmc7XG4gIC8qKiBQbGF0Zm9ybSBzZXJ2aWNlIHBvcnQgKGRlZmF1bHQ6IGVudiBQTEFURk9STV9TRVJWSUNFX1BPUlQgb3IgMzAwMCkgKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqIFJlcXVlc3QgdGltZW91dCBtcyAoZGVmYXVsdCAzMDAwICBhdWRpdCBzaG91bGRuJ3QgYmxvY2sgdGhlIHdvcmtlcikuICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgcmVtb3RlLWF1ZGl0IGNsaWVudCB0YXJnZXRlZCBhdCB0aGUgcGxhdGZvcm0gc2VydmljZS5cbiAqXG4gKiBVc2VkIGJ5IGFwaS9wbHVnaW4ncyBidWlsZCB3b3JrZXIgdG8gcHVzaCBgcGx1Z2luLmJ1aWxkLipgIGV2ZW50cyBpbnRvXG4gKiB0aGUgcGxhdGZvcm0ncyBNb25nb0RCIGBhdWRpdF9ldmVudHNgIGNvbGxlY3Rpb24uIE90aGVyIHNlcnZpY2VzXG4gKiB3aXRoIHdvcmtlci1zdHlsZSBlbWl0dGVycyBjYW4gdXNlIHRoZSBzYW1lIGNsaWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYXVkaXRDbGllbnQgPSBjcmVhdGVSZW1vdGVBdWRpdENsaWVudCgpO1xuICogYXVkaXRDbGllbnQucmVjb3JkKHtcbiAqIGFjdGlvbjogJ3BsdWdpbi5idWlsZC5jb21wbGV0ZWQnLFxuICogYWN0b3JJZDogJ3VzZXItMTIzJyxcbiAqIG9yZ0lkOiAnb3JnLWFjbWUnLFxuICogdGFyZ2V0VHlwZTogJ3BsdWdpbicsXG4gKiB0YXJnZXRJZDogJ3BsdWdpbi1hYmMnLFxuICogZGV0YWlsczogeyBuYW1lOiAnbXktcGx1Z2luJywgdmVyc2lvbjogJzEuMC4wJyB9LFxuICogfSwgJ3BsdWdpbicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZW1vdGVBdWRpdENsaWVudChjb25maWc6IFJlbW90ZUF1ZGl0Q2xpZW50Q29uZmlnID0ge30pOiBSZW1vdGVBdWRpdENsaWVudCB7XG4gIGNvbnN0IHNlcnZpY2VDb25maWc6IFNlcnZpY2VDb25maWcgPSB7XG4gICAgaG9zdDogY29uZmlnLmhvc3QgPz8gcHJvY2Vzcy5lbnYuUExBVEZPUk1fU0VSVklDRV9IT1NUID8/ICdwbGF0Zm9ybScsXG4gICAgcG9ydDogY29uZmlnLnBvcnQgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuUExBVEZPUk1fU0VSVklDRV9QT1JUID8/ICczMDAwJywgMTApLFxuICAgIHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0ID8/IDMwMDAsXG4gIH07XG4gIGNvbnN0IGNsaWVudCA9IGNyZWF0ZVNhZmVDbGllbnQoc2VydmljZUNvbmZpZyk7XG5cbiAgcmV0dXJuIHtcbiAgICByZWNvcmQoZXZlbnQsIHNlcnZpY2VOYW1lKSB7XG4gICAgICBjb25zdCBhdXRoSGVhZGVyID0gZ2V0U2VydmljZUF1dGhIZWFkZXIoeyBzZXJ2aWNlTmFtZSwgb3JnSWQ6IGV2ZW50Lm9yZ0lkIH0pO1xuICAgICAgLy8gU3RyaXAgdGhlIGBCZWFyZXIgYCBwcmVmaXggZm9yIEludGVybmFsSHR0cENsaWVudCAgaXQgc2V0cyB0aGVcbiAgICAgIC8vIEF1dGhvcml6YXRpb24gaGVhZGVyIGl0c2VsZjsgdGhlIHZhbHVlIGhlcmUgaXMgcmF3LlxuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgQXV0aG9yaXphdGlvbjogYXV0aEhlYWRlciB9O1xuICAgICAgLy8gUGF0aCBpcyAvYXVkaXQvZXZlbnRzICB0aGUgcGxhdGZvcm0gbW91bnRzIHRoZSBhdWRpdCByb3V0ZXIgdW5kZXJcbiAgICAgIC8vIC9hdWRpdCwgYW5kIHRoZSBpbnRlcm5hbCBpbmdlc3QgZW5kcG9pbnQgbGl2ZXMgYXQgL2V2ZW50cyB1bmRlciB0aGF0LlxuICAgICAgY2xpZW50LnBvc3QoJy9hdWRpdC9ldmVudHMnLCBldmVudCwgeyBoZWFkZXJzLCAuLi5BVURJVF9SRVFVRVNUX09QVElPTlMgfSlcbiAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgaWYgKCFyZXNwb25zZSB8fCByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdSZW1vdGUgYXVkaXQgaW5nZXN0IG5vbi1vaycsIHtcbiAgICAgICAgICAgICAgYWN0aW9uOiBldmVudC5hY3Rpb24sIHN0YXR1c0NvZGU6IHJlc3BvbnNlPy5zdGF0dXNDb2RlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdSZW1vdGUgYXVkaXQgaW5nZXN0IHRocmV3Jywge1xuICAgICAgICAgICAgYWN0aW9uOiBldmVudC5hY3Rpb24sXG4gICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZTogU3RyaW5nKGVyciksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG4iXX0=
|
package/lib/types/common.d.ts
CHANGED
|
@@ -5,12 +5,25 @@
|
|
|
5
5
|
* - `apiCalls` — generic API call count (read-heavy paths)
|
|
6
6
|
* - `aiCalls` — AI provider invocations (counted separately because each call
|
|
7
7
|
* has external dollar cost; sized smaller than apiCalls per tier)
|
|
8
|
+
* - `storageBytes` — registry storage budget per org. Unlike the others
|
|
9
|
+
* (which count discrete events), this is a measured total recomputed
|
|
10
|
+
* on demand. Incremented by the image-registry's push-gate before
|
|
11
|
+
* issuing a token whose scope includes `push`; the GC scheduler
|
|
12
|
+
* eventually frees the bytes, then the next push-gate check reads
|
|
13
|
+
* the lower value. NOT a counter-style quota in the sense of
|
|
14
|
+
* `incrementUsage` — the registry pushes the measured total via
|
|
15
|
+
* `updateLimits`/`resetUsage` flows. Tier limits are bytes.
|
|
16
|
+
* - `dashboards` / `alertRules` / `alertDestinations` / `idpConfigs` —
|
|
17
|
+
* resource-count quotas added to close per-org DoS surfaces in the
|
|
18
|
+
* user-editable feature tables. Without these caps a single org could
|
|
19
|
+
* spam thousands of dashboards / rules and bloat the shared Postgres /
|
|
20
|
+
* Mongo working sets. Counted at create time; decremented on delete.
|
|
8
21
|
*/
|
|
9
|
-
export type QuotaType = 'plugins' | 'pipelines' | 'apiCalls' | 'aiCalls';
|
|
22
|
+
export type QuotaType = 'plugins' | 'pipelines' | 'apiCalls' | 'aiCalls' | 'storageBytes' | 'dashboards' | 'alertRules' | 'alertDestinations' | 'idpConfigs';
|
|
10
23
|
/**
|
|
11
24
|
* Valid quota type values.
|
|
12
25
|
*/
|
|
13
|
-
export declare const VALID_QUOTA_TYPES: readonly ["plugins", "pipelines", "apiCalls", "aiCalls"];
|
|
26
|
+
export declare const VALID_QUOTA_TYPES: readonly ["plugins", "pipelines", "apiCalls", "aiCalls", "storageBytes", "dashboards", "alertRules", "alertDestinations", "idpConfigs"];
|
|
14
27
|
/**
|
|
15
28
|
* Type guard to check if a value is a valid QuotaType.
|
|
16
29
|
*
|
|
@@ -117,6 +130,16 @@ export interface JwtPayload {
|
|
|
117
130
|
role: 'owner' | 'admin' | 'member';
|
|
118
131
|
/** Derived: true when role is 'admin' or 'owner' in the active organization */
|
|
119
132
|
isAdmin?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Global super-admin flag (cross-org). When `true`, the user is treated
|
|
135
|
+
* as a system administrator regardless of which org they're currently
|
|
136
|
+
* acting under. This is the canonical signal for sysadmin authority —
|
|
137
|
+
* previously the only path was membership in the well-known "system" org
|
|
138
|
+
* with role admin/owner, which conflated "Pipeline Builder operator" with
|
|
139
|
+
* "real customer tenant" in the data model. Either path still works
|
|
140
|
+
* during the rollout; new users should be granted via `isSuperAdmin`.
|
|
141
|
+
*/
|
|
142
|
+
isSuperAdmin?: boolean;
|
|
120
143
|
/** Organization's quota tier ('developer' | 'pro' | 'unlimited') */
|
|
121
144
|
tier?: string;
|
|
122
145
|
/** Resolved feature flags for this user/org */
|
|
@@ -125,6 +148,18 @@ export interface JwtPayload {
|
|
|
125
148
|
organizationId?: string;
|
|
126
149
|
/** Active organization name */
|
|
127
150
|
organizationName?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Set on tokens issued by the sysadmin impersonation flow
|
|
153
|
+
* (`POST /admin/impersonate/:userId`). Carries the original sysadmin's
|
|
154
|
+
* user id so audit events still attribute actions correctly.
|
|
155
|
+
*/
|
|
156
|
+
impersonatorId?: string;
|
|
157
|
+
/**
|
|
158
|
+
* When true, the token is read-only — any non-GET request is rejected
|
|
159
|
+
* upstream by the platform's read-only impersonation gate. Lets
|
|
160
|
+
* sysadmins "view as user X" without risking a destructive action.
|
|
161
|
+
*/
|
|
162
|
+
impersonationReadOnly?: boolean;
|
|
128
163
|
/** Token type */
|
|
129
164
|
type: 'access' | 'refresh';
|
|
130
165
|
/** Issued at timestamp */
|
package/lib/types/common.js
CHANGED
|
@@ -8,7 +8,10 @@ exports.validateQuotaType = validateQuotaType;
|
|
|
8
8
|
/**
|
|
9
9
|
* Valid quota type values.
|
|
10
10
|
*/
|
|
11
|
-
exports.VALID_QUOTA_TYPES = [
|
|
11
|
+
exports.VALID_QUOTA_TYPES = [
|
|
12
|
+
'plugins', 'pipelines', 'apiCalls', 'aiCalls', 'storageBytes',
|
|
13
|
+
'dashboards', 'alertRules', 'alertDestinations', 'idpConfigs',
|
|
14
|
+
];
|
|
12
15
|
/**
|
|
13
16
|
* Type guard to check if a value is a valid QuotaType.
|
|
14
17
|
*
|
|
@@ -50,4 +53,4 @@ function validateQuotaType(value, fieldName = 'quotaType') {
|
|
|
50
53
|
}
|
|
51
54
|
return value;
|
|
52
55
|
}
|
|
53
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7O0FBOEJ0Qyw0Q0FFQztBQXFCRCw4Q0FPQztBQWhERDs7R0FFRztBQUNVLFFBQUEsaUJBQWlCLEdBQUcsQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxTQUFTLENBQVUsQ0FBQztBQUUxRjs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxLQUFjO0lBQzdDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLHlCQUFpQixDQUFDLFFBQVEsQ0FBQyxLQUFrQixDQUFDLENBQUM7QUFDckYsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxLQUFjLEVBQUUsU0FBUyxHQUFHLFdBQVc7SUFDdkUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLFNBQVMsTUFBTSxLQUFLLHNCQUFzQix5QkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDcEYsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBRdW90YSB0eXBlIGlkZW50aWZpZXJzLlxuICpcbiAqIC0gYHBsdWdpbnNgIC8gYHBpcGVsaW5lc2Ag4oCUIGNvdW50IG9mIGNyZWF0ZWQgZW50aXRpZXNcbiAqIC0gYGFwaUNhbGxzYCDigJQgZ2VuZXJpYyBBUEkgY2FsbCBjb3VudCAocmVhZC1oZWF2eSBwYXRocylcbiAqIC0gYGFpQ2FsbHNgIOKAlCBBSSBwcm92aWRlciBpbnZvY2F0aW9ucyAoY291bnRlZCBzZXBhcmF0ZWx5IGJlY2F1c2UgZWFjaCBjYWxsXG4gKiAgIGhhcyBleHRlcm5hbCBkb2xsYXIgY29zdDsgc2l6ZWQgc21hbGxlciB0aGFuIGFwaUNhbGxzIHBlciB0aWVyKVxuICovXG5leHBvcnQgdHlwZSBRdW90YVR5cGUgPSAncGx1Z2lucycgfCAncGlwZWxpbmVzJyB8ICdhcGlDYWxscycgfCAnYWlDYWxscyc7XG5cbi8qKlxuICogVmFsaWQgcXVvdGEgdHlwZSB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBWQUxJRF9RVU9UQV9UWVBFUyA9IFsncGx1Z2lucycsICdwaXBlbGluZXMnLCAnYXBpQ2FsbHMnLCAnYWlDYWxscyddIGFzIGNvbnN0O1xuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIHZhbGlkIFF1b3RhVHlwZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB2YWx1ZSBpcyBhIHZhbGlkIFF1b3RhVHlwZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNWYWxpZFF1b3RhVHlwZShyZXEuYm9keS5xdW90YVR5cGUpKSB7XG4gKiAgIC8vIHF1b3RhVHlwZSBpcyBndWFyYW50ZWVkIHRvIGJlIFF1b3RhVHlwZVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUXVvdGFUeXBlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUXVvdGFUeXBlIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgVkFMSURfUVVPVEFfVFlQRVMuaW5jbHVkZXModmFsdWUgYXMgUXVvdGFUeXBlKTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhbmQgYXNzZXJ0IHRoYXQgYSB2YWx1ZSBpcyBhIHZhbGlkIFF1b3RhVHlwZS5cbiAqIFRocm93cyBhbiBlcnJvciBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIHZhbGlkYXRlXG4gKiBAcGFyYW0gZmllbGROYW1lIC0gTmFtZSBvZiB0aGUgZmllbGQgYmVpbmcgdmFsaWRhdGVkIChmb3IgZXJyb3IgbWVzc2FnZXMpXG4gKiBAcmV0dXJucyBUaGUgdmFsaWRhdGVkIFF1b3RhVHlwZVxuICogQHRocm93cyBFcnJvciBpZiB2YWx1ZSBpcyBub3QgYSB2YWxpZCBRdW90YVR5cGVcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogdHJ5IHtcbiAqICAgY29uc3QgcXVvdGFUeXBlID0gdmFsaWRhdGVRdW90YVR5cGUocmVxLmJvZHkucXVvdGFUeXBlLCAncXVvdGFUeXBlJyk7XG4gKiAgIC8vIFVzZSBxdW90YVR5cGUgc2FmZWx5XG4gKiB9IGNhdGNoIChlcnIpIHtcbiAqICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIDQwMCwgZXJyLm1lc3NhZ2UpO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVF1b3RhVHlwZSh2YWx1ZTogdW5rbm93biwgZmllbGROYW1lID0gJ3F1b3RhVHlwZScpOiBRdW90YVR5cGUge1xuICBpZiAoIWlzVmFsaWRRdW90YVR5cGUodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgJHtmaWVsZE5hbWV9OiBcIiR7dmFsdWV9XCIuIE11c3QgYmUgb25lIG9mOiAke1ZBTElEX1FVT1RBX1RZUEVTLmpvaW4oJywgJyl9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBSZXN1bHQgZnJvbSBxdW90YSBjaGVjayBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFDaGVja1Jlc3VsdCB7XG4gIC8qKiBXaGV0aGVyIHRoZSByZXF1ZXN0IGlzIGFsbG93ZWQgKi9cbiAgYWxsb3dlZDogYm9vbGVhbjtcbiAgLyoqIE1heGltdW0gcXVvdGEgbGltaXQgKC0xIGZvciB1bmxpbWl0ZWQpICovXG4gIGxpbWl0OiBudW1iZXI7XG4gIC8qKiBDdXJyZW50IHVzYWdlIGNvdW50ICovXG4gIHVzZWQ6IG51bWJlcjtcbiAgLyoqIFJlbWFpbmluZyBxdW90YSAoLTEgZm9yIHVubGltaXRlZCkgKi9cbiAgcmVtYWluaW5nOiBudW1iZXI7XG4gIC8qKiBJU08gdGltZXN0YW1wIHdoZW4gcXVvdGEgcmVzZXRzICovXG4gIHJlc2V0QXQ6IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgcXVvdGEgaXMgdW5saW1pdGVkICovXG4gIHVubGltaXRlZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBRdW90YSBpbmZvcm1hdGlvbiBmb3IgZXJyb3IgcmVzcG9uc2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1b3RhSW5mbyB7XG4gIHR5cGU6IFF1b3RhVHlwZTtcbiAgbGltaXQ6IG51bWJlcjtcbiAgdXNlZDogbnVtYmVyO1xuICByZW1haW5pbmc6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBBUEkgc3VjY2VzcyByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcGlTdWNjZXNzUmVzcG9uc2U8VCA9IHVua25vd24+IHtcbiAgc3VjY2VzczogdHJ1ZTtcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xuICBkYXRhPzogVDtcbiAgbWVzc2FnZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBBUEkgZXJyb3IgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBpRXJyb3JSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGZhbHNlO1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgY29kZT86IHN0cmluZztcbiAgZGV0YWlscz86IHVua25vd247XG4gIHF1b3RhPzogUXVvdGFJbmZvO1xufVxuXG4vKipcbiAqIENvbWJpbmVkIEFQSSByZXNwb25zZSB0eXBlLlxuICovXG5leHBvcnQgdHlwZSBBcGlSZXNwb25zZTxUID0gdW5rbm93bj4gPSBBcGlTdWNjZXNzUmVzcG9uc2U8VD4gfCBBcGlFcnJvclJlc3BvbnNlO1xuXG4vKipcbiAqIEpXVCBwYXlsb2FkIGZyb20gYWNjZXNzIHRva2Vucy5cbiAqXG4gKiBVc2VycyBjYW4gYmVsb25nIHRvIG11bHRpcGxlIG9yZ2FuaXphdGlvbnMuIFRoZSB0b2tlbiBpcyBzY29wZWQgdG8gb25lXG4gKiBhY3RpdmUgb3JnYW5pemF0aW9uIGF0IGEgdGltZS4gVGhlIGByb2xlYCBmaWVsZCBpcyB0aGUgdXNlcidzIHBlci1vcmdcbiAqIHJvbGUgaW4gdGhhdCBvcmdhbml6YXRpb24gKGZyb20gdGhlIFVzZXJPcmdhbml6YXRpb24ganVuY3Rpb24gY29sbGVjdGlvbiksXG4gKiBhbmQgYGlzQWRtaW5gIGlzIGRlcml2ZWQgYXMgYHJvbGUgPT09ICdhZG1pbicgfHwgcm9sZSA9PT0gJ293bmVyJ2AuXG4gKlxuICogVXNlIGBQT1NUIC9hdXRoL3N3aXRjaC1vcmdgIHRvIGNoYW5nZSB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbiwgd2hpY2hcbiAqIHJlLWlzc3VlcyB0b2tlbnMgd2l0aCB0aGUgbmV3IG9yZydzIHJvbGUgYW5kIGNvbnRleHQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSnd0UGF5bG9hZCB7XG4gIC8qKiBVc2VyIElEIChzdWJqZWN0KSAqL1xuICBzdWI6IHN0cmluZztcbiAgLyoqIFVzZXJuYW1lICovXG4gIHVzZXJuYW1lOiBzdHJpbmc7XG4gIC8qKiBVc2VyIGVtYWlsICovXG4gIGVtYWlsOiBzdHJpbmc7XG4gIC8qKiBQZXItb3JnIHJvbGUgaW4gdGhlIGFjdGl2ZSBvcmdhbml6YXRpb24gKCdvd25lcicgfCAnYWRtaW4nIHwgJ21lbWJlcicpLiBOb3QgYSBnbG9iYWwgcm9sZS4gKi9cbiAgcm9sZTogJ293bmVyJyB8ICdhZG1pbicgfCAnbWVtYmVyJztcbiAgLyoqIERlcml2ZWQ6IHRydWUgd2hlbiByb2xlIGlzICdhZG1pbicgb3IgJ293bmVyJyBpbiB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbiAqL1xuICBpc0FkbWluPzogYm9vbGVhbjtcbiAgLyoqIE9yZ2FuaXphdGlvbidzIHF1b3RhIHRpZXIgKCdkZXZlbG9wZXInIHwgJ3BybycgfCAndW5saW1pdGVkJykgKi9cbiAgdGllcj86IHN0cmluZztcbiAgLyoqIFJlc29sdmVkIGZlYXR1cmUgZmxhZ3MgZm9yIHRoaXMgdXNlci9vcmcgKi9cbiAgZmVhdHVyZXM/OiBzdHJpbmdbXTtcbiAgLyoqIEFjdGl2ZSBvcmdhbml6YXRpb24gSUQgKGZyb20gVXNlck9yZ2FuaXphdGlvbiBtZW1iZXJzaGlwKSAqL1xuICBvcmdhbml6YXRpb25JZD86IHN0cmluZztcbiAgLyoqIEFjdGl2ZSBvcmdhbml6YXRpb24gbmFtZSAqL1xuICBvcmdhbml6YXRpb25OYW1lPzogc3RyaW5nO1xuICAvKiogVG9rZW4gdHlwZSAqL1xuICB0eXBlOiAnYWNjZXNzJyB8ICdyZWZyZXNoJztcbiAgLyoqIElzc3VlZCBhdCB0aW1lc3RhbXAgKi9cbiAgaWF0PzogbnVtYmVyO1xuICAvKiogRXhwaXJhdGlvbiB0aW1lc3RhbXAgKi9cbiAgZXhwPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEV4dGVuZGVkIEV4cHJlc3MgUmVxdWVzdCB3aXRoIHVzZXIgcHJvcGVydHkuXG4gKi9cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgbmFtZXNwYWNlIEV4cHJlc3Mge1xuICAgIGludGVyZmFjZSBSZXF1ZXN0IHtcbiAgICAgIHVzZXI/OiBKd3RQYXlsb2FkO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNlcnZpY2UgY29uZmlndXJhdGlvbiBmb3IgaW50ZXJuYWwgSFRUUCBjbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZUNvbmZpZyB7XG4gIC8qKiBTZXJ2aWNlIGhvc3RuYW1lICovXG4gIGhvc3Q6IHN0cmluZztcbiAgLyoqIFNlcnZpY2UgcG9ydCAqL1xuICBwb3J0OiBudW1iZXI7XG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogSGVhbHRoIGNoZWNrIHJlc3BvbnNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhlYWx0aENoZWNrUmVzcG9uc2Uge1xuICBzdGF0dXM6ICdoZWFsdGh5JyB8ICd1bmhlYWx0aHknO1xuICBzZXJ2aWNlOiBzdHJpbmc7XG4gIHRpbWVzdGFtcDogc3RyaW5nO1xuICB1cHRpbWU6IG51bWJlcjtcbiAgdmVyc2lvbj86IHN0cmluZztcbiAgZGVwZW5kZW5jaWVzPzogUmVjb3JkPHN0cmluZywgJ2Nvbm5lY3RlZCcgfCAnZGlzY29ubmVjdGVkJyB8ICd1bmtub3duJz47XG59XG4iXX0=
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7O0FBZ0R0Qyw0Q0FFQztBQXFCRCw4Q0FPQztBQW5ERDs7R0FFRztBQUNVLFFBQUEsaUJBQWlCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLGNBQWM7SUFDN0QsWUFBWSxFQUFFLFlBQVksRUFBRSxtQkFBbUIsRUFBRSxZQUFZO0NBQ3JELENBQUM7QUFFWDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxLQUFjO0lBQzdDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLHlCQUFpQixDQUFDLFFBQVEsQ0FBQyxLQUFrQixDQUFDLENBQUM7QUFDckYsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxLQUFjLEVBQUUsU0FBUyxHQUFHLFdBQVc7SUFDdkUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLFNBQVMsTUFBTSxLQUFLLHNCQUFzQix5QkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDcEYsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBRdW90YSB0eXBlIGlkZW50aWZpZXJzLlxuICpcbiAqIC0gYHBsdWdpbnNgIC8gYHBpcGVsaW5lc2Ag4oCUIGNvdW50IG9mIGNyZWF0ZWQgZW50aXRpZXNcbiAqIC0gYGFwaUNhbGxzYCDigJQgZ2VuZXJpYyBBUEkgY2FsbCBjb3VudCAocmVhZC1oZWF2eSBwYXRocylcbiAqIC0gYGFpQ2FsbHNgIOKAlCBBSSBwcm92aWRlciBpbnZvY2F0aW9ucyAoY291bnRlZCBzZXBhcmF0ZWx5IGJlY2F1c2UgZWFjaCBjYWxsXG4gKiAgIGhhcyBleHRlcm5hbCBkb2xsYXIgY29zdDsgc2l6ZWQgc21hbGxlciB0aGFuIGFwaUNhbGxzIHBlciB0aWVyKVxuICogLSBgc3RvcmFnZUJ5dGVzYCDigJQgcmVnaXN0cnkgc3RvcmFnZSBidWRnZXQgcGVyIG9yZy4gVW5saWtlIHRoZSBvdGhlcnNcbiAqICAgKHdoaWNoIGNvdW50IGRpc2NyZXRlIGV2ZW50cyksIHRoaXMgaXMgYSBtZWFzdXJlZCB0b3RhbCByZWNvbXB1dGVkXG4gKiAgIG9uIGRlbWFuZC4gSW5jcmVtZW50ZWQgYnkgdGhlIGltYWdlLXJlZ2lzdHJ5J3MgcHVzaC1nYXRlIGJlZm9yZVxuICogICBpc3N1aW5nIGEgdG9rZW4gd2hvc2Ugc2NvcGUgaW5jbHVkZXMgYHB1c2hgOyB0aGUgR0Mgc2NoZWR1bGVyXG4gKiAgIGV2ZW50dWFsbHkgZnJlZXMgdGhlIGJ5dGVzLCB0aGVuIHRoZSBuZXh0IHB1c2gtZ2F0ZSBjaGVjayByZWFkc1xuICogICB0aGUgbG93ZXIgdmFsdWUuIE5PVCBhIGNvdW50ZXItc3R5bGUgcXVvdGEgaW4gdGhlIHNlbnNlIG9mXG4gKiAgIGBpbmNyZW1lbnRVc2FnZWAg4oCUIHRoZSByZWdpc3RyeSBwdXNoZXMgdGhlIG1lYXN1cmVkIHRvdGFsIHZpYVxuICogICBgdXBkYXRlTGltaXRzYC9gcmVzZXRVc2FnZWAgZmxvd3MuIFRpZXIgbGltaXRzIGFyZSBieXRlcy5cbiAqIC0gYGRhc2hib2FyZHNgIC8gYGFsZXJ0UnVsZXNgIC8gYGFsZXJ0RGVzdGluYXRpb25zYCAvIGBpZHBDb25maWdzYCDigJRcbiAqICAgcmVzb3VyY2UtY291bnQgcXVvdGFzIGFkZGVkIHRvIGNsb3NlIHBlci1vcmcgRG9TIHN1cmZhY2VzIGluIHRoZVxuICogICB1c2VyLWVkaXRhYmxlIGZlYXR1cmUgdGFibGVzLiBXaXRob3V0IHRoZXNlIGNhcHMgYSBzaW5nbGUgb3JnIGNvdWxkXG4gKiAgIHNwYW0gdGhvdXNhbmRzIG9mIGRhc2hib2FyZHMgLyBydWxlcyBhbmQgYmxvYXQgdGhlIHNoYXJlZCBQb3N0Z3JlcyAvXG4gKiAgIE1vbmdvIHdvcmtpbmcgc2V0cy4gQ291bnRlZCBhdCBjcmVhdGUgdGltZTsgZGVjcmVtZW50ZWQgb24gZGVsZXRlLlxuICovXG5leHBvcnQgdHlwZSBRdW90YVR5cGUgPVxuICB8ICdwbHVnaW5zJyB8ICdwaXBlbGluZXMnIHwgJ2FwaUNhbGxzJyB8ICdhaUNhbGxzJyB8ICdzdG9yYWdlQnl0ZXMnXG4gIHwgJ2Rhc2hib2FyZHMnIHwgJ2FsZXJ0UnVsZXMnIHwgJ2FsZXJ0RGVzdGluYXRpb25zJyB8ICdpZHBDb25maWdzJztcblxuLyoqXG4gKiBWYWxpZCBxdW90YSB0eXBlIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IFZBTElEX1FVT1RBX1RZUEVTID0gW1xuICAncGx1Z2lucycsICdwaXBlbGluZXMnLCAnYXBpQ2FsbHMnLCAnYWlDYWxscycsICdzdG9yYWdlQnl0ZXMnLFxuICAnZGFzaGJvYXJkcycsICdhbGVydFJ1bGVzJywgJ2FsZXJ0RGVzdGluYXRpb25zJywgJ2lkcENvbmZpZ3MnLFxuXSBhcyBjb25zdDtcblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSB2YWxpZCBRdW90YVR5cGUuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdmFsdWUgaXMgYSB2YWxpZCBRdW90YVR5cGVcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzVmFsaWRRdW90YVR5cGUocmVxLmJvZHkucXVvdGFUeXBlKSkge1xuICogICAvLyBxdW90YVR5cGUgaXMgZ3VhcmFudGVlZCB0byBiZSBRdW90YVR5cGVcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFF1b3RhVHlwZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFF1b3RhVHlwZSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIFZBTElEX1FVT1RBX1RZUEVTLmluY2x1ZGVzKHZhbHVlIGFzIFF1b3RhVHlwZSk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW5kIGFzc2VydCB0aGF0IGEgdmFsdWUgaXMgYSB2YWxpZCBRdW90YVR5cGUuXG4gKiBUaHJvd3MgYW4gZXJyb3IgaWYgdmFsaWRhdGlvbiBmYWlscy5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byB2YWxpZGF0ZVxuICogQHBhcmFtIGZpZWxkTmFtZSAtIE5hbWUgb2YgdGhlIGZpZWxkIGJlaW5nIHZhbGlkYXRlZCAoZm9yIGVycm9yIG1lc3NhZ2VzKVxuICogQHJldHVybnMgVGhlIHZhbGlkYXRlZCBRdW90YVR5cGVcbiAqIEB0aHJvd3MgRXJyb3IgaWYgdmFsdWUgaXMgbm90IGEgdmFsaWQgUXVvdGFUeXBlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyeSB7XG4gKiAgIGNvbnN0IHF1b3RhVHlwZSA9IHZhbGlkYXRlUXVvdGFUeXBlKHJlcS5ib2R5LnF1b3RhVHlwZSwgJ3F1b3RhVHlwZScpO1xuICogICAvLyBVc2UgcXVvdGFUeXBlIHNhZmVseVxuICogfSBjYXRjaCAoZXJyKSB7XG4gKiAgIHJldHVybiBzZW5kRXJyb3IocmVzLCA0MDAsIGVyci5tZXNzYWdlKTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVRdW90YVR5cGUodmFsdWU6IHVua25vd24sIGZpZWxkTmFtZSA9ICdxdW90YVR5cGUnKTogUXVvdGFUeXBlIHtcbiAgaWYgKCFpc1ZhbGlkUXVvdGFUeXBlKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnZhbGlkICR7ZmllbGROYW1lfTogXCIke3ZhbHVlfVwiLiBNdXN0IGJlIG9uZSBvZjogJHtWQUxJRF9RVU9UQV9UWVBFUy5qb2luKCcsICcpfWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogUmVzdWx0IGZyb20gcXVvdGEgY2hlY2sgb3BlcmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1b3RhQ2hlY2tSZXN1bHQge1xuICAvKiogV2hldGhlciB0aGUgcmVxdWVzdCBpcyBhbGxvd2VkICovXG4gIGFsbG93ZWQ6IGJvb2xlYW47XG4gIC8qKiBNYXhpbXVtIHF1b3RhIGxpbWl0ICgtMSBmb3IgdW5saW1pdGVkKSAqL1xuICBsaW1pdDogbnVtYmVyO1xuICAvKiogQ3VycmVudCB1c2FnZSBjb3VudCAqL1xuICB1c2VkOiBudW1iZXI7XG4gIC8qKiBSZW1haW5pbmcgcXVvdGEgKC0xIGZvciB1bmxpbWl0ZWQpICovXG4gIHJlbWFpbmluZzogbnVtYmVyO1xuICAvKiogSVNPIHRpbWVzdGFtcCB3aGVuIHF1b3RhIHJlc2V0cyAqL1xuICByZXNldEF0OiBzdHJpbmc7XG4gIC8qKiBXaGV0aGVyIHF1b3RhIGlzIHVubGltaXRlZCAqL1xuICB1bmxpbWl0ZWQ6IGJvb2xlYW47XG59XG5cbi8qKlxuICogUXVvdGEgaW5mb3JtYXRpb24gZm9yIGVycm9yIHJlc3BvbnNlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YUluZm8ge1xuICB0eXBlOiBRdW90YVR5cGU7XG4gIGxpbWl0OiBudW1iZXI7XG4gIHVzZWQ6IG51bWJlcjtcbiAgcmVtYWluaW5nOiBudW1iZXI7XG59XG5cbi8qKlxuICogU3RhbmRhcmQgQVBJIHN1Y2Nlc3MgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBpU3VjY2Vzc1Jlc3BvbnNlPFQgPSB1bmtub3duPiB7XG4gIHN1Y2Nlc3M6IHRydWU7XG4gIHN0YXR1c0NvZGU6IG51bWJlcjtcbiAgZGF0YT86IFQ7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU3RhbmRhcmQgQVBJIGVycm9yIHJlc3BvbnNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwaUVycm9yUmVzcG9uc2Uge1xuICBzdWNjZXNzOiBmYWxzZTtcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGNvZGU/OiBzdHJpbmc7XG4gIGRldGFpbHM/OiB1bmtub3duO1xuICBxdW90YT86IFF1b3RhSW5mbztcbn1cblxuLyoqXG4gKiBDb21iaW5lZCBBUEkgcmVzcG9uc2UgdHlwZS5cbiAqL1xuZXhwb3J0IHR5cGUgQXBpUmVzcG9uc2U8VCA9IHVua25vd24+ID0gQXBpU3VjY2Vzc1Jlc3BvbnNlPFQ+IHwgQXBpRXJyb3JSZXNwb25zZTtcblxuLyoqXG4gKiBKV1QgcGF5bG9hZCBmcm9tIGFjY2VzcyB0b2tlbnMuXG4gKlxuICogVXNlcnMgY2FuIGJlbG9uZyB0byBtdWx0aXBsZSBvcmdhbml6YXRpb25zLiBUaGUgdG9rZW4gaXMgc2NvcGVkIHRvIG9uZVxuICogYWN0aXZlIG9yZ2FuaXphdGlvbiBhdCBhIHRpbWUuIFRoZSBgcm9sZWAgZmllbGQgaXMgdGhlIHVzZXIncyBwZXItb3JnXG4gKiByb2xlIGluIHRoYXQgb3JnYW5pemF0aW9uIChmcm9tIHRoZSBVc2VyT3JnYW5pemF0aW9uIGp1bmN0aW9uIGNvbGxlY3Rpb24pLFxuICogYW5kIGBpc0FkbWluYCBpcyBkZXJpdmVkIGFzIGByb2xlID09PSAnYWRtaW4nIHx8IHJvbGUgPT09ICdvd25lcidgLlxuICpcbiAqIFVzZSBgUE9TVCAvYXV0aC9zd2l0Y2gtb3JnYCB0byBjaGFuZ2UgdGhlIGFjdGl2ZSBvcmdhbml6YXRpb24sIHdoaWNoXG4gKiByZS1pc3N1ZXMgdG9rZW5zIHdpdGggdGhlIG5ldyBvcmcncyByb2xlIGFuZCBjb250ZXh0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEp3dFBheWxvYWQge1xuICAvKiogVXNlciBJRCAoc3ViamVjdCkgKi9cbiAgc3ViOiBzdHJpbmc7XG4gIC8qKiBVc2VybmFtZSAqL1xuICB1c2VybmFtZTogc3RyaW5nO1xuICAvKiogVXNlciBlbWFpbCAqL1xuICBlbWFpbDogc3RyaW5nO1xuICAvKiogUGVyLW9yZyByb2xlIGluIHRoZSBhY3RpdmUgb3JnYW5pemF0aW9uICgnb3duZXInIHwgJ2FkbWluJyB8ICdtZW1iZXInKS4gTm90IGEgZ2xvYmFsIHJvbGUuICovXG4gIHJvbGU6ICdvd25lcicgfCAnYWRtaW4nIHwgJ21lbWJlcic7XG4gIC8qKiBEZXJpdmVkOiB0cnVlIHdoZW4gcm9sZSBpcyAnYWRtaW4nIG9yICdvd25lcicgaW4gdGhlIGFjdGl2ZSBvcmdhbml6YXRpb24gKi9cbiAgaXNBZG1pbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBHbG9iYWwgc3VwZXItYWRtaW4gZmxhZyAoY3Jvc3Mtb3JnKS4gV2hlbiBgdHJ1ZWAsIHRoZSB1c2VyIGlzIHRyZWF0ZWRcbiAgICogYXMgYSBzeXN0ZW0gYWRtaW5pc3RyYXRvciByZWdhcmRsZXNzIG9mIHdoaWNoIG9yZyB0aGV5J3JlIGN1cnJlbnRseVxuICAgKiBhY3RpbmcgdW5kZXIuIFRoaXMgaXMgdGhlIGNhbm9uaWNhbCBzaWduYWwgZm9yIHN5c2FkbWluIGF1dGhvcml0eSDigJRcbiAgICogcHJldmlvdXNseSB0aGUgb25seSBwYXRoIHdhcyBtZW1iZXJzaGlwIGluIHRoZSB3ZWxsLWtub3duIFwic3lzdGVtXCIgb3JnXG4gICAqIHdpdGggcm9sZSBhZG1pbi9vd25lciwgd2hpY2ggY29uZmxhdGVkIFwiUGlwZWxpbmUgQnVpbGRlciBvcGVyYXRvclwiIHdpdGhcbiAgICogXCJyZWFsIGN1c3RvbWVyIHRlbmFudFwiIGluIHRoZSBkYXRhIG1vZGVsLiBFaXRoZXIgcGF0aCBzdGlsbCB3b3Jrc1xuICAgKiBkdXJpbmcgdGhlIHJvbGxvdXQ7IG5ldyB1c2VycyBzaG91bGQgYmUgZ3JhbnRlZCB2aWEgYGlzU3VwZXJBZG1pbmAuXG4gICAqL1xuICBpc1N1cGVyQWRtaW4/OiBib29sZWFuO1xuICAvKiogT3JnYW5pemF0aW9uJ3MgcXVvdGEgdGllciAoJ2RldmVsb3BlcicgfCAncHJvJyB8ICd1bmxpbWl0ZWQnKSAqL1xuICB0aWVyPzogc3RyaW5nO1xuICAvKiogUmVzb2x2ZWQgZmVhdHVyZSBmbGFncyBmb3IgdGhpcyB1c2VyL29yZyAqL1xuICBmZWF0dXJlcz86IHN0cmluZ1tdO1xuICAvKiogQWN0aXZlIG9yZ2FuaXphdGlvbiBJRCAoZnJvbSBVc2VyT3JnYW5pemF0aW9uIG1lbWJlcnNoaXApICovXG4gIG9yZ2FuaXphdGlvbklkPzogc3RyaW5nO1xuICAvKiogQWN0aXZlIG9yZ2FuaXphdGlvbiBuYW1lICovXG4gIG9yZ2FuaXphdGlvbk5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTZXQgb24gdG9rZW5zIGlzc3VlZCBieSB0aGUgc3lzYWRtaW4gaW1wZXJzb25hdGlvbiBmbG93XG4gICAqIChgUE9TVCAvYWRtaW4vaW1wZXJzb25hdGUvOnVzZXJJZGApLiBDYXJyaWVzIHRoZSBvcmlnaW5hbCBzeXNhZG1pbidzXG4gICAqIHVzZXIgaWQgc28gYXVkaXQgZXZlbnRzIHN0aWxsIGF0dHJpYnV0ZSBhY3Rpb25zIGNvcnJlY3RseS5cbiAgICovXG4gIGltcGVyc29uYXRvcklkPzogc3RyaW5nO1xuICAvKipcbiAgICogV2hlbiB0cnVlLCB0aGUgdG9rZW4gaXMgcmVhZC1vbmx5IOKAlCBhbnkgbm9uLUdFVCByZXF1ZXN0IGlzIHJlamVjdGVkXG4gICAqIHVwc3RyZWFtIGJ5IHRoZSBwbGF0Zm9ybSdzIHJlYWQtb25seSBpbXBlcnNvbmF0aW9uIGdhdGUuIExldHNcbiAgICogc3lzYWRtaW5zIFwidmlldyBhcyB1c2VyIFhcIiB3aXRob3V0IHJpc2tpbmcgYSBkZXN0cnVjdGl2ZSBhY3Rpb24uXG4gICAqL1xuICBpbXBlcnNvbmF0aW9uUmVhZE9ubHk/OiBib29sZWFuO1xuICAvKiogVG9rZW4gdHlwZSAqL1xuICB0eXBlOiAnYWNjZXNzJyB8ICdyZWZyZXNoJztcbiAgLyoqIElzc3VlZCBhdCB0aW1lc3RhbXAgKi9cbiAgaWF0PzogbnVtYmVyO1xuICAvKiogRXhwaXJhdGlvbiB0aW1lc3RhbXAgKi9cbiAgZXhwPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEV4dGVuZGVkIEV4cHJlc3MgUmVxdWVzdCB3aXRoIHVzZXIgcHJvcGVydHkuXG4gKi9cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgbmFtZXNwYWNlIEV4cHJlc3Mge1xuICAgIGludGVyZmFjZSBSZXF1ZXN0IHtcbiAgICAgIHVzZXI/OiBKd3RQYXlsb2FkO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNlcnZpY2UgY29uZmlndXJhdGlvbiBmb3IgaW50ZXJuYWwgSFRUUCBjbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZUNvbmZpZyB7XG4gIC8qKiBTZXJ2aWNlIGhvc3RuYW1lICovXG4gIGhvc3Q6IHN0cmluZztcbiAgLyoqIFNlcnZpY2UgcG9ydCAqL1xuICBwb3J0OiBudW1iZXI7XG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogSGVhbHRoIGNoZWNrIHJlc3BvbnNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhlYWx0aENoZWNrUmVzcG9uc2Uge1xuICBzdGF0dXM6ICdoZWFsdGh5JyB8ICd1bmhlYWx0aHknO1xuICBzZXJ2aWNlOiBzdHJpbmc7XG4gIHRpbWVzdGFtcDogc3RyaW5nO1xuICB1cHRpbWU6IG51bWJlcjtcbiAgdmVyc2lvbj86IHN0cmluZztcbiAgZGVwZW5kZW5jaWVzPzogUmVjb3JkPHN0cmluZywgJ2Nvbm5lY3RlZCcgfCAnZGlzY29ubmVjdGVkJyB8ICd1bmtub3duJz47XG59XG4iXX0=
|
|
@@ -15,24 +15,24 @@ export declare const FEATURE_METADATA: Record<FeatureFlag, {
|
|
|
15
15
|
/**
|
|
16
16
|
* Resolve a user's effective feature set.
|
|
17
17
|
*
|
|
18
|
-
* 1.
|
|
18
|
+
* 1. Sysadmins (isSuperAdmin) always get ALL features.
|
|
19
19
|
* 2. Start with the tier's default features.
|
|
20
20
|
* 3. Apply per-user overrides: `true` adds a feature, `false` removes it.
|
|
21
21
|
* 4. Invalid override keys are silently ignored.
|
|
22
22
|
*
|
|
23
23
|
* @param tier - The organization's quota tier
|
|
24
24
|
* @param featureOverrides - Per-user overrides (key = feature flag, value = enabled)
|
|
25
|
-
* @param
|
|
25
|
+
* @param isSuperAdmin - Whether the user has the global super-admin flag
|
|
26
26
|
* @returns Sorted array of enabled feature flags
|
|
27
27
|
*/
|
|
28
|
-
export declare function resolveUserFeatures(tier: QuotaTier, featureOverrides?: Record<string, boolean> | null,
|
|
28
|
+
export declare function resolveUserFeatures(tier: QuotaTier, featureOverrides?: Record<string, boolean> | null, isSuperAdmin?: boolean): FeatureFlag[];
|
|
29
29
|
/**
|
|
30
30
|
* Check if a specific feature is enabled for a user.
|
|
31
31
|
*
|
|
32
32
|
* @param tier - The organization's quota tier
|
|
33
33
|
* @param feature - The feature flag to check
|
|
34
34
|
* @param featureOverrides - Per-user overrides
|
|
35
|
-
* @param
|
|
35
|
+
* @param isSuperAdmin - Whether the user has the global super-admin flag
|
|
36
36
|
* @returns true if the feature is enabled
|
|
37
37
|
*/
|
|
38
|
-
export declare function hasFeature(tier: QuotaTier, feature: FeatureFlag, featureOverrides?: Record<string, boolean> | null,
|
|
38
|
+
export declare function hasFeature(tier: QuotaTier, feature: FeatureFlag, featureOverrides?: Record<string, boolean> | null, isSuperAdmin?: boolean): boolean;
|