@pipeline-builder/api-core 4.1.2 → 4.1.4
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 +3 -3
- package/lib/errors/app-errors.d.ts +0 -4
- package/lib/errors/app-errors.js +1 -8
- package/lib/helpers/restore-helpers.d.ts +3 -3
- package/lib/helpers/restore-helpers.js +4 -4
- package/lib/helpers/sse-helpers.d.ts +8 -1
- package/lib/helpers/sse-helpers.js +11 -3
- package/lib/middleware/auth.d.ts +174 -43
- package/lib/middleware/auth.js +384 -179
- package/lib/middleware/index.d.ts +1 -0
- package/lib/middleware/index.js +2 -1
- package/lib/middleware/route-table.d.ts +104 -0
- package/lib/middleware/route-table.js +230 -0
- package/lib/middleware/step-up.d.ts +48 -16
- package/lib/middleware/step-up.js +74 -36
- package/lib/services/api-key-exchange.d.ts +25 -0
- package/lib/services/api-key-exchange.js +219 -0
- package/lib/services/audit-spool.d.ts +2 -3
- package/lib/services/audit-spool.js +3 -4
- package/lib/services/cache-service.d.ts +65 -21
- package/lib/services/cache-service.js +173 -78
- package/lib/services/compliance-event-subscriber.d.ts +5 -4
- package/lib/services/compliance-event-subscriber.js +8 -6
- package/lib/services/durable-event-bus.d.ts +22 -39
- package/lib/services/durable-event-bus.js +109 -47
- package/lib/services/env-redis.d.ts +114 -35
- package/lib/services/env-redis.js +215 -73
- package/lib/services/http-client.d.ts +10 -15
- package/lib/services/http-client.js +32 -27
- package/lib/services/index.d.ts +3 -0
- package/lib/services/index.js +4 -1
- package/lib/services/jwks-cache.d.ts +102 -0
- package/lib/services/jwks-cache.js +222 -0
- package/lib/services/leader-lock.d.ts +6 -3
- package/lib/services/leader-lock.js +20 -5
- package/lib/services/quota.d.ts +44 -10
- package/lib/services/quota.js +95 -51
- package/lib/services/remote-audit-client.d.ts +1 -1
- package/lib/services/remote-audit-client.js +32 -1
- package/lib/services/scheduler.d.ts +2 -3
- package/lib/services/scheduler.js +2 -2
- package/lib/services/service-boot.d.ts +4 -2
- package/lib/services/service-boot.js +7 -3
- package/lib/services/service-keys.d.ts +83 -0
- package/lib/services/service-keys.js +354 -0
- package/lib/services/sse-ticket-store.d.ts +55 -22
- package/lib/services/sse-ticket-store.js +122 -79
- package/lib/services/token-revocation.d.ts +1 -1
- package/lib/services/token-revocation.js +31 -19
- package/lib/testing/route-coverage.d.ts +64 -0
- package/lib/testing/route-coverage.js +183 -0
- package/lib/testing/service-tokens.d.ts +66 -0
- package/lib/testing/service-tokens.js +137 -0
- package/lib/testing/tier-mock.d.ts +2 -2
- package/lib/testing/tier-mock.js +3 -3
- package/lib/testing/user-tokens.d.ts +75 -0
- package/lib/testing/user-tokens.js +115 -0
- package/lib/types/catalog-metadata.d.ts +0 -2
- package/lib/types/catalog-metadata.js +1 -3
- package/lib/types/common.d.ts +103 -4
- package/lib/types/common.js +11 -1
- package/lib/types/error-codes.d.ts +15 -0
- package/lib/types/error-codes.js +22 -1
- package/lib/types/permissions.d.ts +35 -1
- package/lib/types/permissions.js +70 -2
- package/lib/utils/api-key.d.ts +34 -0
- package/lib/utils/api-key.js +75 -0
- package/lib/utils/env.d.ts +0 -2
- package/lib/utils/env.js +1 -6
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.js +4 -1
- package/lib/utils/jwk.d.ts +98 -0
- package/lib/utils/jwk.js +139 -0
- package/lib/utils/logger.d.ts +4 -1
- package/lib/utils/logger.js +1 -22
- package/lib/utils/secret-encryption.d.ts +7 -2
- package/lib/utils/secret-encryption.js +47 -4
- package/lib/utils/secret-rotation.d.ts +17 -0
- package/lib/utils/secret-rotation.js +54 -0
- package/lib/validation/common-schemas.js +5 -4
- package/package.json +20 -1
|
@@ -156,10 +156,9 @@ export function createRedisAuditSpool(redis, opts = {}) {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
|
-
* Build a Redis-backed audit spool from the ambient `REDIS_URL` / `
|
|
159
|
+
* Build a Redis-backed audit spool from the ambient `REDIS_URL` / `REDIS_SENTINELS`
|
|
160
160
|
* env via the shared `createEnvRedisClient`. Returns `null` when Redis is not
|
|
161
|
-
* configured
|
|
162
|
-
* spool (pre-spool best-effort behavior), never crashing. The shared helper loads
|
|
161
|
+
* configured — the caller then runs without a spool (best-effort behavior). The shared helper loads
|
|
163
162
|
* ioredis via `createRequire`, so this stays importable where Redis isn't present.
|
|
164
163
|
*/
|
|
165
164
|
export function createEnvRedisAuditSpool(opts = {}) {
|
|
@@ -169,4 +168,4 @@ export function createEnvRedisAuditSpool(opts = {}) {
|
|
|
169
168
|
logger.info('Redis audit spool initialized');
|
|
170
169
|
return createRedisAuditSpool(inst, opts);
|
|
171
170
|
}
|
|
172
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaXQtc3Bvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvYXVkaXQtc3Bvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQStEM0MsTUFBTSxpQkFBaUIsR0FBRyxhQUFhLENBQUM7QUFDeEMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUM7QUFDakMsb0ZBQW9GO0FBQ3BGLE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDO0FBRXBDLFNBQVMsTUFBTSxDQUFDLEdBQVk7SUFDMUIsT0FBTyxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEdBQVc7SUFDNUIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQW9CLENBQUM7UUFDbEQsT0FBTyxNQUFNLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN0RSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQ25DLEtBQXNCLEVBQ3RCLElBQUksR0FBd0Ms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LENBQUM7Z0JBQ0QsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ2xCLFdBQVcsQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBQzFELE1BQU0sQ0FBQyxJQUFJLENBQUMsbURBQW1ELEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUNsRixDQUFDO2dCQUNELE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztRQUVELEtBQUssQ0FBQyxLQUFLO1lBQ1QsSUFBSSxDQUFDO2dCQUNILE9BQU8sTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLHdCQUF3QixDQUFDLElBQUksR0FBd0MsRUFBRTtJQUNyRixNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBa0IsYUFBYSxDQUFDLENBQUM7SUFDbEUsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2QixNQUFNLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFDN0MsT0FBTyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0NsaWVudCB9IGZyb20gJy4vZW52LXJlZGlzLmpzJztcbmltcG9ydCB0eXBlIHsgUmVtb3RlQXVkaXRFdmVudCB9IGZyb20gJy4vcmVtb3RlLWF1ZGl0LWNsaWVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignYXVkaXQtc3Bvb2wnKTtcblxuLyoqIEEgYnVmZmVyZWQgZW1pc3Npb246IHRoZSBldmVudCBwbHVzIHdoaWNoIHNlcnZpY2UgbXVzdCByZS1kZWxpdmVyIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdWRpdFNwb29sRW50cnkge1xuICBldmVudDogUmVtb3RlQXVkaXRFdmVudDtcbiAgc2VydmljZU5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEdXJhYmxlIGJ1ZmZlciBmb3IgYXVkaXQgZXZlbnRzIHRoYXQgZmFpbGVkIExJVkUgZGVsaXZlcnkgdG8gdGhlIHBsYXRmb3JtXG4gKiAocmV0cmllcyBleGhhdXN0ZWQgZHVyaW5nIGEgc3VzdGFpbmVkIG91dGFnZSkuIFdpdGhvdXQgdGhpcywgdGhlIGF1ZGl0IHRyYWlsIOKAlFxuICogYSBzZWN1cml0eSBsb2cg4oCUIGlzIHNpbGVudGx5IGxvc3QgdGhlIG1vbWVudCB0aGUgcGxhdGZvcm0gaXMgZG93biBmb3IgbG9uZ2VyXG4gKiB0aGFuIHRoZSBjbGllbnQncyBzbWFsbCByZXRyeSBidWRnZXQuXG4gKlxuICogQ29udHJhY3Q6XG4gKiAtIEJPVU5ERUQuIEEgc2VjdXJpdHkgbG9nIG11c3QgZGVncmFkZSB0byBcImRyb3BwZWQgdGhlIG9sZGVzdCwgbG91ZGx5XCIgKGFcbiAqICAgbWV0cmljKSByYXRoZXIgdGhhbiBncm93IHdpdGhvdXQgbGltaXQgYW5kIE9PTSB0aGUgZW1pdHRlci5cbiAqIC0gRkFJTC1TQUZFLiBFdmVyeSBtZXRob2Qgc3dhbGxvd3MgaXRzIG93biBlcnJvcnMg4oCUIGEgYnJva2VuL3VucmVhY2hhYmxlIHNwb29sXG4gKiAgIG11c3QgbmV2ZXIgYnJlYWsgb3IgYmxvY2sgdGhlIGF1ZGl0IGVtaXNzaW9uIHBhdGggKHdoaWNoIGlzIGl0c2VsZlxuICogICBmaXJlLWFuZC1mb3JnZXQpLiBBIHNwb29sIHByb2JsZW0gZGVncmFkZXMgdG8gdGhlIHByZS1zcG9vbCBiZWhhdmlvci5cbiAqIC0gT3JkZXJpbmcgaXMgYmVzdC1lZmZvcnQuIFJlLWRlbGl2ZXJlZCBldmVudHMgY2hhaW4gYXQgcmUtZGVsaXZlcnkgdGltZVxuICogICAodGhhdCdzIHdoZW4gdGhlIHBsYXRmb3JtIGluc2VydHMgdGhlbSksIHNvIGVhY2ggZXZlbnQgYWxzbyBjYXJyaWVzIGFuXG4gKiAgIGBvY2N1cnJlZEF0YCBzdGFtcGVkIGF0IGVtaXNzaW9uIGZvciByZXZpZXdlcnMg4oCUIHNlZSBSZW1vdGVBdWRpdEV2ZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1ZGl0U3Bvb2wge1xuICAvKiogQnVmZmVyIGFuIGV2ZW50IHRoYXQgZmFpbGVkIGxpdmUgZGVsaXZlcnkuICovXG4gIGVucXVldWUoZW50cnk6IEF1ZGl0U3Bvb2xFbnRyeSk6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBBdG9taWNhbGx5IE1PVkUgdXAgdG8gYG1heGAgYnVmZmVyZWQgZW50cmllcyBvbnRvIGFuIGluLXByb2dyZXNzIGxpc3QgYW5kXG4gICAqIHJldHVybiB0aGVtLiBCZWNhdXNlIHRoZSBlbnRyaWVzIGFyZSBtb3ZlZCAobm90IHBvcHBlZC1hbmQtZHJvcHBlZCksIGEgY3Jhc2hcbiAgICogbWlkLWRyYWluIGxlYXZlcyB0aGVtIHJlY292ZXJhYmxlIG9uIHRoZSBpbi1wcm9ncmVzcyBsaXN0IOKAlCBzZWUgYHJlY292ZXJgLlxuICAgKiBFYWNoIHRha2VuIGVudHJ5IE1VU1QgYmUgcmVzb2x2ZWQgd2l0aCBleGFjdGx5IG9uZSBvZiBgYWNrYCAoZGVsaXZlcmVkKSBvclxuICAgKiBgcmVxdWV1ZWAgKHN0aWxsIGZhaWxpbmcpLCBvciBpdCBsaW5nZXJzIG9uIHRoZSBpbi1wcm9ncmVzcyBsaXN0IHVudGlsIHRoZVxuICAgKiBuZXh0IGByZWNvdmVyYC5cbiAgICovXG4gIHRha2UobWF4OiBudW1iZXIpOiBQcm9taXNlPEF1ZGl0U3Bvb2xFbnRyeVtdPjtcbiAgLyoqIEFja25vd2xlZGdlIHN1Y2Nlc3NmdWxseSByZS1kZWxpdmVyZWQgZW50cmllcyDigJQgcmVtb3ZlcyB0aGVtIGZyb20gdGhlXG4gICAqICBpbi1wcm9ncmVzcyBsaXN0IHNvIHRoZXkgYXJlIG5vdCByZWNvdmVyZWQgYWdhaW4uICovXG4gIGFjayhlbnRyaWVzOiBBdWRpdFNwb29sRW50cnlbXSk6IFByb21pc2U8dm9pZD47XG4gIC8qKiBSZXR1cm4gZW50cmllcyB3aG9zZSByZS1kZWxpdmVyeSBmYWlsZWQgdG8gdGhlIEhFQUQgb2YgdGhlIGJ1ZmZlciAocmV0cmllZFxuICAgKiAgZmlyc3QpIGFuZCBjbGVhciB0aGVtIGZyb20gdGhlIGluLXByb2dyZXNzIGxpc3QuIEJlc3QtZWZmb3J0LiAqL1xuICByZXF1ZXVlKGVudHJpZXM6IEF1ZGl0U3Bvb2xFbnRyeVtdKTogUHJvbWlzZTx2b2lkPjtcbiAgLyoqIFJlY2xhaW0gYW55IGVudHJpZXMgc3RyYW5kZWQgb24gdGhlIGluLXByb2dyZXNzIGxpc3QgYnkgYSBwcmlvciBjcmFzaCxcbiAgICogIG1vdmluZyB0aGVtIGJhY2sgdG8gdGhlIGhlYWQgb2YgdGhlIG1haW4gYnVmZmVyLiBDYWxsIG9uY2UgYXQgc3RhcnR1cC5cbiAgICogIFJldHVybnMgdGhlIG51bWJlciByZWNsYWltZWQuICovXG4gIHJlY292ZXIoKTogUHJvbWlzZTxudW1iZXI+O1xuICAvKiogQXBwcm94aW1hdGUgY3VycmVudCBkZXB0aCAoZm9yIG1ldHJpY3MgLyBkcmFpbiBkZWNpc2lvbnMpLiAqL1xuICBkZXB0aCgpOiBQcm9taXNlPG51bWJlcj47XG59XG5cbi8qKiBNaW5pbWFsIFJlZGlzIExJU1Qgc3VyZmFjZSB0aGUgc3Bvb2wgbmVlZHMgKGEgc3Vic2V0IG9mIGlvcmVkaXMpLiAqL1xuaW50ZXJmYWNlIFJlZGlzTGlzdENsaWVudCB7XG4gIHJwdXNoKGtleTogc3RyaW5nLCAuLi52YWx1ZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+O1xuICBscHVzaChrZXk6IHN0cmluZywgLi4udmFsdWVzOiBzdHJpbmdbXSk6IFByb21pc2U8bnVtYmVyPjtcbiAgbHBvcChrZXk6IHN0cmluZywgY291bnQ6IG51bWJlcik6IFByb21pc2U8c3RyaW5nW10gfCBudWxsPjtcbiAgbHRyaW0oa2V5OiBzdHJpbmcsIHN0YXJ0OiBudW1iZXIsIHN0b3A6IG51bWJlcik6IFByb21pc2U8dW5rbm93bj47XG4gIGxsZW4oa2V5OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj47XG4gIC8qKiBBdG9taWNhbGx5IHBvcCBmcm9tIG9uZSBsaXN0IGVuZCBhbmQgcHVzaCB0byBhbm90aGVyIChSZWRpcyDiiaUgNi4yKS4gKi9cbiAgbG1vdmUoc291cmNlOiBzdHJpbmcsIGRlc3RpbmF0aW9uOiBzdHJpbmcsIGZyb206ICdMRUZUJyB8ICdSSUdIVCcsIHRvOiAnTEVGVCcgfCAnUklHSFQnKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPjtcbiAgLyoqIFJlbW92ZSBgY291bnRgIG9jY3VycmVuY2VzIG9mIGB2YWx1ZWAgZnJvbSBhIGxpc3QuICovXG4gIGxyZW0oa2V5OiBzdHJpbmcsIGNvdW50OiBudW1iZXIsIHZhbHVlOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj47XG59XG5cbmNvbnN0IERFRkFVTFRfU1BPT0xfS0VZID0gJ2F1ZGl0OnNwb29sJztcbmNvbnN0IERFRkFVTFRfTUFYX0RFUFRIID0gMTBfMDAwO1xuLyoqIEd1YXJkIHNvIGEgcGF0aG9sb2dpY2FsIGluLXByb2dyZXNzIGxpc3QgY2FuJ3Qgc3BpbiBgcmVjb3ZlcmAvYHRha2VgIGZvcmV2ZXIuICovXG5jb25zdCBNQVhfTU9WRV9JVEVSQVRJT05TID0gMTAwXzAwMDtcblxuZnVuY3Rpb24gZXJyTXNnKGVycjogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG59XG5cbmZ1bmN0aW9uIHNhZmVQYXJzZShyYXc6IHN0cmluZyk6IEF1ZGl0U3Bvb2xFbnRyeSB8IG51bGwge1xuICB0cnkge1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KSBhcyBBdWRpdFNwb29sRW50cnk7XG4gICAgcmV0dXJuIHBhcnNlZCAmJiBwYXJzZWQuZXZlbnQgJiYgcGFyc2VkLnNlcnZpY2VOYW1lID8gcGFyc2VkIDogbnVsbDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBSZWRpcy1MSVNULWJhY2tlZCBzcG9vbC4gRHVyYWJsZSBhY3Jvc3MgcHJvY2VzcyByZXN0YXJ0cyAodW5saWtlIGFuIGluLW1lbW9yeVxuICogb3IgcGVyLXBvZC1kaXNrIGJ1ZmZlciksIHNoYXJlZCBieSBhbGwgcmVwbGljYXMgb2YgYSBzZXJ2aWNlLCBhbmQgYm91bmRlZCB2aWFcbiAqIGEgdHJpbS10by10YWlsIG9uIG92ZXJmbG93IChkcm9wcyB0aGUgT0xERVNULCBlbWl0dGluZyBgYXVkaXRfc3Bvb2xfZHJvcHBlZF90b3RhbGApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVkaXNBdWRpdFNwb29sKFxuICByZWRpczogUmVkaXNMaXN0Q2xpZW50LFxuICBvcHRzOiB7IG1heERlcHRoPzogbnVtYmVyOyBrZXk/OiBzdHJpbmcgfSA9IHt9LFxuKTogQXVkaXRTcG9vbCB7XG4gIGNvbnN0IGtleSA9IG9wdHMua2V5ID8/IERFRkFVTFRfU1BPT0xfS0VZO1xuICAvLyBUaGUgaW4tcHJvZ3Jlc3MgXCJwcm9jZXNzaW5nXCIgbGlzdCDigJQgYSB0YWtlbiBiYXRjaCBsaXZlcyBoZXJlIHVudGlsIGl0IGlzXG4gIC8vIGFja2VkIChkZWxpdmVyZWQpIG9yIHJlcXVldWVkIChzdGlsbCBmYWlsaW5nKS4gSXQgaXMgYSBzZWN1cml0eSBsb2cnc1xuICAvLyBkdXJhYmlsaXR5IG5ldDogYSBjcmFzaCBiZXR3ZWVuIHRha2UgYW5kIGFjay9yZXF1ZXVlIGxlYXZlcyB0aGUgYmF0Y2ggaGVyZSxcbiAgLy8gYW5kIGByZWNvdmVyYCByZWNsYWltcyBpdCBvbiByZXN0YXJ0IGluc3RlYWQgb2Ygc2lsZW50bHkgbG9zaW5nIGl0LlxuICBjb25zdCBpblByb2dyZXNzS2V5ID0gYCR7a2V5fTppbmZsaWdodGA7XG4gIGNvbnN0IG1heERlcHRoID0gTWF0aC5tYXgoMSwgb3B0cy5tYXhEZXB0aCA/PyBERUZBVUxUX01BWF9ERVBUSCk7XG5cbiAgLy8gVGhlIEVYQUNUIHNlcmlhbGl6ZWQgc3RyaW5nIGVhY2ggcmV0dXJuZWQgZW50cnkgd2FzIHBhcnNlZCBmcm9tLCBzbyBgYWNrYCAvXG4gIC8vIGByZXF1ZXVlYCBjYW4gTFJFTSB0aGUgcHJlY2lzZSB2YWx1ZSBvZmYgdGhlIGluLXByb2dyZXNzIGxpc3QuIEtleWVkIGJ5IHRoZVxuICAvLyByZXR1cm5lZCBvYmplY3QgaWRlbnRpdHkgKHRoZSBkcmFpbiBjb25zdW1lciBwYXNzZXMgdGhlIFNBTUUgb2JqZWN0cyBiYWNrKSxcbiAgLy8gc28gaXQgbmVlZHMgbm8gc3RhYmxlIHJlLXNlcmlhbGl6YXRpb24uIFdlYWtNYXAg4oaSIGVudHJpZXMgR0MgbmF0dXJhbGx5LlxuICBjb25zdCByYXdCeUVudHJ5ID0gbmV3IFdlYWtNYXA8QXVkaXRTcG9vbEVudHJ5LCBzdHJpbmc+KCk7XG4gIGNvbnN0IHJhd09mID0gKGVudHJ5OiBBdWRpdFNwb29sRW50cnkpOiBzdHJpbmcgPT4gcmF3QnlFbnRyeS5nZXQoZW50cnkpID8/IEpTT04uc3RyaW5naWZ5KGVudHJ5KTtcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGVucXVldWUoZW50cnkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGF3YWl0IHJlZGlzLnJwdXNoKGtleSwgSlNPTi5zdHJpbmdpZnkoZW50cnkpKTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ2F1ZGl0X3Nwb29sX2VucXVldWVkX3RvdGFsJywgeyBzZXJ2aWNlOiBlbnRyeS5zZXJ2aWNlTmFtZSB9KTtcbiAgICAgICAgaWYgKGxlbiA+IG1heERlcHRoKSB7XG4gICAgICAgICAgLy8gS2VlcCBvbmx5IHRoZSBuZXdlc3QgYG1heERlcHRoYDsgZHJvcCB0aGUgb3ZlcmZsb3cgYXQgdGhlIGhlYWQuXG4gICAgICAgICAgY29uc3QgZHJvcHBlZCA9IGxlbiAtIG1heERlcHRoO1xuICAgICAgICAgIGF3YWl0IHJlZGlzLmx0cmltKGtleSwgZHJvcHBlZCwgLTEpO1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9zcG9vbF9kcm9wcGVkX3RvdGFsJywgeyBzZXJ2aWNlOiBlbnRyeS5zZXJ2aWNlTmFtZSB9LCBkcm9wcGVkKTtcbiAgICAgICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgb3ZlcmZsb3cg4oCUIGRyb3BwZWQgb2xkZXN0IGJ1ZmZlcmVkIGV2ZW50cycsIHsgZHJvcHBlZCwgbWF4RGVwdGggfSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgZW5xdWV1ZSBmYWlsZWQgKGV2ZW50IGxvc3QpJywgeyBlcnJvcjogZXJyTXNnKGVycikgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHRha2UobWF4KSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBvdXQ6IEF1ZGl0U3Bvb2xFbnRyeVtdID0gW107XG4gICAgICAgIGNvbnN0IGxpbWl0ID0gTWF0aC5tYXgoMSwgbWF4KTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW1pdDsgaSsrKSB7XG4gICAgICAgICAgLy8gQXRvbWljYWxseSBNT1ZFIGhlYWTihpJpbi1wcm9ncmVzcy10YWlsIHNvIHRoZSBlbnRyeSBpcyBuZXZlciBpbiBsaW1ibzpcbiAgICAgICAgICAvLyBpdCBpcyBvbiBleGFjdGx5IG9uZSBsaXN0IGF0IGFsbCB0aW1lcywgcmVjb3ZlcmFibGUgYWZ0ZXIgYSBjcmFzaC5cbiAgICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5sbW92ZShrZXksIGluUHJvZ3Jlc3NLZXksICdMRUZUJywgJ1JJR0hUJyk7XG4gICAgICAgICAgaWYgKHJhdyA9PT0gbnVsbCB8fCByYXcgPT09IHVuZGVmaW5lZCkgYnJlYWs7XG4gICAgICAgICAgY29uc3QgcGFyc2VkID0gc2FmZVBhcnNlKHJhdyk7XG4gICAgICAgICAgaWYgKHBhcnNlZCkge1xuICAgICAgICAgICAgcmF3QnlFbnRyeS5zZXQocGFyc2VkLCByYXcpO1xuICAgICAgICAgICAgb3V0LnB1c2gocGFyc2VkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ29ycnVwdCBwYXlsb2FkIOKAlCBkcm9wIGl0IG9mZiB0aGUgaW4tcHJvZ3Jlc3MgbGlzdCBzbyBpdCBjYW4ndCB3ZWRnZVxuICAgICAgICAgICAgLy8gdGhlIGRyYWluLCBhbmQgYWNjb3VudCBmb3IgaXQuXG4gICAgICAgICAgICBhd2FpdCByZWRpcy5scmVtKGluUHJvZ3Jlc3NLZXksIDEsIHJhdyk7XG4gICAgICAgICAgICBlbWl0Q291bnRlcignYXVkaXRfc3Bvb2xfZHJvcHBlZF90b3RhbCcsIHsgc2VydmljZTogJ3Vua25vd24nIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCB0YWtlIGZhaWxlZCcsIHsgZXJyb3I6IGVyck1zZyhlcnIpIH0pO1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIGFjayhlbnRyaWVzKSB7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICAgIGF3YWl0IHJlZGlzLmxyZW0oaW5Qcm9ncmVzc0tleSwgMSwgcmF3T2YoZW50cnkpKTtcbiAgICAgICAgICByYXdCeUVudHJ5LmRlbGV0ZShlbnRyeSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgYWNrIGZhaWxlZCAobWF5IHJlLWRlbGl2ZXIgb24gcmVjb3ZlciknLCB7IGVycm9yOiBlcnJNc2coZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgcmVxdWV1ZShlbnRyaWVzKSB7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFB1dCBmYWlsZWQgcmUtZGVsaXZlcmllcyBiYWNrIGF0IHRoZSBIRUFEIHNvIHRoZXkncmUgcmV0cmllZCBmaXJzdCBhbmRcbiAgICAgICAgLy8gcm91Z2ggZW1pc3Npb24gb3JkZXIgaXMgcHJlc2VydmVkIGFjcm9zcyB0aGUgb3V0YWdlIOKAlCBhbmQgY2xlYXIgdGhlbVxuICAgICAgICAvLyBmcm9tIHRoZSBpbi1wcm9ncmVzcyBsaXN0IHNvIGByZWNvdmVyYCBkb2Vzbid0IGRvdWJsZSB0aGVtLiBJdGVyYXRlIGluXG4gICAgICAgIC8vIHJldmVyc2Ugc28gbHB1c2ggcmVzdG9yZXMgdGhlIGJhdGNoJ3Mgb3JpZ2luYWwgb3JkZXIgYXQgdGhlIGhlYWQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIE9SREVSSU5HIElOVkFSSUFOVCAoYXQtbGVhc3Qtb25jZSk6IGxwdXNoIHRvIHRoZSBtYWluIGxpc3QgRklSU1QsIFRIRU5cbiAgICAgICAgLy8gbHJlbSBmcm9tIGluLXByb2dyZXNzLiBBIGNyYXNoIGJldHdlZW4gdGhlIHR3byBsZWF2ZXMgdGhlIGVudHJ5IG9uIEJPVEhcbiAgICAgICAgLy8gbGlzdHMg4oaSIGhhcm1sZXNzIGRvdWJsZS1kZWxpdmVyeSAoZGVkdXBlZCBkb3duc3RyZWFtIGJ5IGlkZW1wb3RlbmN5XG4gICAgICAgIC8vIHJldXNlKSwgbmV2ZXIgYSBMT1NTLiBUaGUgcmV2ZXJzZSBvcmRlciAobHJlbSB0aGVuIGxwdXNoKSB3b3VsZCBkcm9wIHRoZVxuICAgICAgICAvLyBldmVudCBvdXRyaWdodCBvbiBhIGNyYXNoIGluIHRoZSBnYXAsIHdoaWNoIGEgc2VjdXJpdHkgbG9nIG11c3Qgbm90IGRvLlxuICAgICAgICBmb3IgKGxldCBpID0gZW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGNvbnN0IHJhdyA9IHJhd09mKGVudHJpZXNbaV0pO1xuICAgICAgICAgIGF3YWl0IHJlZGlzLmxwdXNoKGtleSwgcmF3KTtcbiAgICAgICAgICBhd2FpdCByZWRpcy5scmVtKGluUHJvZ3Jlc3NLZXksIDEsIHJhdyk7XG4gICAgICAgICAgcmF3QnlFbnRyeS5kZWxldGUoZW50cmllc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgcmVxdWV1ZSBmYWlsZWQgKGV2ZW50cyBsb3N0KScsIHsgZXJyb3I6IGVyck1zZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyByZWNvdmVyKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHJlY2xhaW1lZCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTUFYX01PVkVfSVRFUkFUSU9OUzsgaSsrKSB7XG4gICAgICAgICAgLy8gTW92ZSBpbi1wcm9ncmVzcy10YWlsIOKGkiBtYWluLWhlYWQ6IGFuIG9sZGVyIHN0cmFuZGVkIGVudHJ5IChuZWFyZXIgdGhlXG4gICAgICAgICAgLy8gaW4tcHJvZ3Jlc3MgaGVhZCkgZW5kcyB1cCBhaGVhZCBvZiBhIG5ld2VyIG9uZSwgcHJlc2VydmluZyBvcmRlci5cbiAgICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5sbW92ZShpblByb2dyZXNzS2V5LCBrZXksICdSSUdIVCcsICdMRUZUJyk7XG4gICAgICAgICAgaWYgKHJhdyA9PT0gbnVsbCB8fCByYXcgPT09IHVuZGVmaW5lZCkgYnJlYWs7XG4gICAgICAgICAgcmVjbGFpbWVkKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlY2xhaW1lZCA+IDApIHtcbiAgICAgICAgICBlbWl0Q291bnRlcignYXVkaXRfc3Bvb2xfcmVjb3ZlcmVkX3RvdGFsJywge30sIHJlY2xhaW1lZCk7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ0F1ZGl0IHNwb29sIHJlY292ZXJlZCBzdHJhbmRlZCBpbi1wcm9ncmVzcyBldmVudHMnLCB7IHJlY2xhaW1lZCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVjbGFpbWVkO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCByZWNvdmVyIGZhaWxlZCcsIHsgZXJyb3I6IGVyck1zZyhlcnIpIH0pO1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgZGVwdGgoKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgcmVkaXMubGxlbihrZXkpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgYSBSZWRpcy1iYWNrZWQgYXVkaXQgc3Bvb2wgZnJvbSB0aGUgYW1iaWVudCBgUkVESVNfVVJMYCAvIGBSRURJU19IT1NUYFxuICogZW52IHZpYSB0aGUgc2hhcmVkIGBjcmVhdGVFbnZSZWRpc0NsaWVudGAuIFJldHVybnMgYG51bGxgIHdoZW4gUmVkaXMgaXMgbm90XG4gKiBjb25maWd1cmVkIG9yIHRoZSBjbGllbnQgY2FuJ3QgYmUgY29uc3RydWN0ZWQg4oCUIHRoZSBjYWxsZXIgdGhlbiBydW5zIHdpdGhvdXQgYVxuICogc3Bvb2wgKHByZS1zcG9vbCBiZXN0LWVmZm9ydCBiZWhhdmlvciksIG5ldmVyIGNyYXNoaW5nLiBUaGUgc2hhcmVkIGhlbHBlciBsb2Fkc1xuICogaW9yZWRpcyB2aWEgYGNyZWF0ZVJlcXVpcmVgLCBzbyB0aGlzIHN0YXlzIGltcG9ydGFibGUgd2hlcmUgUmVkaXMgaXNuJ3QgcHJlc2VudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVudlJlZGlzQXVkaXRTcG9vbChvcHRzOiB7IG1heERlcHRoPzogbnVtYmVyOyBrZXk/OiBzdHJpbmcgfSA9IHt9KTogQXVkaXRTcG9vbCB8IG51bGwge1xuICBjb25zdCBpbnN0ID0gY3JlYXRlRW52UmVkaXNDbGllbnQ8UmVkaXNMaXN0Q2xpZW50PignYXVkaXQtc3Bvb2wnKTtcbiAgaWYgKCFpbnN0KSByZXR1cm4gbnVsbDtcbiAgbG9nZ2VyLmluZm8oJ1JlZGlzIGF1ZGl0IHNwb29sIGluaXRpYWxpemVkJyk7XG4gIHJldHVybiBjcmVhdGVSZWRpc0F1ZGl0U3Bvb2woaW5zdCwgb3B0cyk7XG59XG4iXX0=
|
|
171
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaXQtc3Bvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvYXVkaXQtc3Bvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQStEM0MsTUFBTSxpQkFBaUIsR0FBRyxhQUFhLENBQUM7QUFDeEMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUM7QUFDakMsb0ZBQW9GO0FBQ3BGLE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDO0FBRXBDLFNBQVMsTUFBTSxDQUFDLEdBQVk7SUFDMUIsT0FBTyxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEdBQVc7SUFDNUIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQW9CLENBQUM7UUFDbEQsT0FBTyxNQUFNLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN0RSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQ25DLEtBQXNCLEVBQ3RCLElBQUksR0FBd0Ms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LENBQUM7Z0JBQ0QsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ2xCLFdBQVcsQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBQzFELE1BQU0sQ0FBQyxJQUFJLENBQUMsbURBQW1ELEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUNsRixDQUFDO2dCQUNELE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztRQUVELEtBQUssQ0FBQyxLQUFLO1lBQ1QsSUFBSSxDQUFDO2dCQUNILE9BQU8sTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsd0JBQXdCLENBQUMsSUFBSSxHQUF3QyxFQUFFO0lBQ3JGLE1BQU0sSUFBSSxHQUFHLG9CQUFvQixDQUFrQixhQUFhLENBQUMsQ0FBQztJQUNsRSxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsQ0FBQztJQUM3QyxPQUFPLHFCQUFxQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUMzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZUVudlJlZGlzQ2xpZW50IH0gZnJvbSAnLi9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHR5cGUgeyBSZW1vdGVBdWRpdEV2ZW50IH0gZnJvbSAnLi9yZW1vdGUtYXVkaXQtY2xpZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBlbWl0Q291bnRlciB9IGZyb20gJy4uL3V0aWxzL21ldHJpYy1lbWl0dGVyLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdhdWRpdC1zcG9vbCcpO1xuXG4vKiogQSBidWZmZXJlZCBlbWlzc2lvbjogdGhlIGV2ZW50IHBsdXMgd2hpY2ggc2VydmljZSBtdXN0IHJlLWRlbGl2ZXIgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1ZGl0U3Bvb2xFbnRyeSB7XG4gIGV2ZW50OiBSZW1vdGVBdWRpdEV2ZW50O1xuICBzZXJ2aWNlTmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIER1cmFibGUgYnVmZmVyIGZvciBhdWRpdCBldmVudHMgdGhhdCBmYWlsZWQgTElWRSBkZWxpdmVyeSB0byB0aGUgcGxhdGZvcm1cbiAqIChyZXRyaWVzIGV4aGF1c3RlZCBkdXJpbmcgYSBzdXN0YWluZWQgb3V0YWdlKS4gV2l0aG91dCB0aGlzLCB0aGUgYXVkaXQgdHJhaWwg4oCUXG4gKiBhIHNlY3VyaXR5IGxvZyDigJQgaXMgc2lsZW50bHkgbG9zdCB0aGUgbW9tZW50IHRoZSBwbGF0Zm9ybSBpcyBkb3duIGZvciBsb25nZXJcbiAqIHRoYW4gdGhlIGNsaWVudCdzIHNtYWxsIHJldHJ5IGJ1ZGdldC5cbiAqXG4gKiBDb250cmFjdDpcbiAqIC0gQk9VTkRFRC4gQSBzZWN1cml0eSBsb2cgbXVzdCBkZWdyYWRlIHRvIFwiZHJvcHBlZCB0aGUgb2xkZXN0LCBsb3VkbHlcIiAoYVxuICogICBtZXRyaWMpIHJhdGhlciB0aGFuIGdyb3cgd2l0aG91dCBsaW1pdCBhbmQgT09NIHRoZSBlbWl0dGVyLlxuICogLSBGQUlMLVNBRkUuIEV2ZXJ5IG1ldGhvZCBzd2FsbG93cyBpdHMgb3duIGVycm9ycyDigJQgYSBicm9rZW4vdW5yZWFjaGFibGUgc3Bvb2xcbiAqICAgbXVzdCBuZXZlciBicmVhayBvciBibG9jayB0aGUgYXVkaXQgZW1pc3Npb24gcGF0aCAod2hpY2ggaXMgaXRzZWxmXG4gKiAgIGZpcmUtYW5kLWZvcmdldCkuIEEgc3Bvb2wgcHJvYmxlbSBkZWdyYWRlcyB0byB0aGUgcHJlLXNwb29sIGJlaGF2aW9yLlxuICogLSBPcmRlcmluZyBpcyBiZXN0LWVmZm9ydC4gUmUtZGVsaXZlcmVkIGV2ZW50cyBjaGFpbiBhdCByZS1kZWxpdmVyeSB0aW1lXG4gKiAgICh0aGF0J3Mgd2hlbiB0aGUgcGxhdGZvcm0gaW5zZXJ0cyB0aGVtKSwgc28gZWFjaCBldmVudCBhbHNvIGNhcnJpZXMgYW5cbiAqICAgYG9jY3VycmVkQXRgIHN0YW1wZWQgYXQgZW1pc3Npb24gZm9yIHJldmlld2VycyDigJQgc2VlIFJlbW90ZUF1ZGl0RXZlbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXVkaXRTcG9vbCB7XG4gIC8qKiBCdWZmZXIgYW4gZXZlbnQgdGhhdCBmYWlsZWQgbGl2ZSBkZWxpdmVyeS4gKi9cbiAgZW5xdWV1ZShlbnRyeTogQXVkaXRTcG9vbEVudHJ5KTogUHJvbWlzZTx2b2lkPjtcbiAgLyoqXG4gICAqIEF0b21pY2FsbHkgTU9WRSB1cCB0byBgbWF4YCBidWZmZXJlZCBlbnRyaWVzIG9udG8gYW4gaW4tcHJvZ3Jlc3MgbGlzdCBhbmRcbiAgICogcmV0dXJuIHRoZW0uIEJlY2F1c2UgdGhlIGVudHJpZXMgYXJlIG1vdmVkIChub3QgcG9wcGVkLWFuZC1kcm9wcGVkKSwgYSBjcmFzaFxuICAgKiBtaWQtZHJhaW4gbGVhdmVzIHRoZW0gcmVjb3ZlcmFibGUgb24gdGhlIGluLXByb2dyZXNzIGxpc3Qg4oCUIHNlZSBgcmVjb3ZlcmAuXG4gICAqIEVhY2ggdGFrZW4gZW50cnkgTVVTVCBiZSByZXNvbHZlZCB3aXRoIGV4YWN0bHkgb25lIG9mIGBhY2tgIChkZWxpdmVyZWQpIG9yXG4gICAqIGByZXF1ZXVlYCAoc3RpbGwgZmFpbGluZyksIG9yIGl0IGxpbmdlcnMgb24gdGhlIGluLXByb2dyZXNzIGxpc3QgdW50aWwgdGhlXG4gICAqIG5leHQgYHJlY292ZXJgLlxuICAgKi9cbiAgdGFrZShtYXg6IG51bWJlcik6IFByb21pc2U8QXVkaXRTcG9vbEVudHJ5W10+O1xuICAvKiogQWNrbm93bGVkZ2Ugc3VjY2Vzc2Z1bGx5IHJlLWRlbGl2ZXJlZCBlbnRyaWVzIOKAlCByZW1vdmVzIHRoZW0gZnJvbSB0aGVcbiAgICogIGluLXByb2dyZXNzIGxpc3Qgc28gdGhleSBhcmUgbm90IHJlY292ZXJlZCBhZ2Fpbi4gKi9cbiAgYWNrKGVudHJpZXM6IEF1ZGl0U3Bvb2xFbnRyeVtdKTogUHJvbWlzZTx2b2lkPjtcbiAgLyoqIFJldHVybiBlbnRyaWVzIHdob3NlIHJlLWRlbGl2ZXJ5IGZhaWxlZCB0byB0aGUgSEVBRCBvZiB0aGUgYnVmZmVyIChyZXRyaWVkXG4gICAqICBmaXJzdCkgYW5kIGNsZWFyIHRoZW0gZnJvbSB0aGUgaW4tcHJvZ3Jlc3MgbGlzdC4gQmVzdC1lZmZvcnQuICovXG4gIHJlcXVldWUoZW50cmllczogQXVkaXRTcG9vbEVudHJ5W10pOiBQcm9taXNlPHZvaWQ+O1xuICAvKiogUmVjbGFpbSBhbnkgZW50cmllcyBzdHJhbmRlZCBvbiB0aGUgaW4tcHJvZ3Jlc3MgbGlzdCBieSBhIHByaW9yIGNyYXNoLFxuICAgKiAgbW92aW5nIHRoZW0gYmFjayB0byB0aGUgaGVhZCBvZiB0aGUgbWFpbiBidWZmZXIuIENhbGwgb25jZSBhdCBzdGFydHVwLlxuICAgKiAgUmV0dXJucyB0aGUgbnVtYmVyIHJlY2xhaW1lZC4gKi9cbiAgcmVjb3ZlcigpOiBQcm9taXNlPG51bWJlcj47XG4gIC8qKiBBcHByb3hpbWF0ZSBjdXJyZW50IGRlcHRoIChmb3IgbWV0cmljcyAvIGRyYWluIGRlY2lzaW9ucykuICovXG4gIGRlcHRoKCk6IFByb21pc2U8bnVtYmVyPjtcbn1cblxuLyoqIE1pbmltYWwgUmVkaXMgTElTVCBzdXJmYWNlIHRoZSBzcG9vbCBuZWVkcyAoYSBzdWJzZXQgb2YgaW9yZWRpcykuICovXG5pbnRlcmZhY2UgUmVkaXNMaXN0Q2xpZW50IHtcbiAgcnB1c2goa2V5OiBzdHJpbmcsIC4uLnZhbHVlczogc3RyaW5nW10pOiBQcm9taXNlPG51bWJlcj47XG4gIGxwdXNoKGtleTogc3RyaW5nLCAuLi52YWx1ZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+O1xuICBscG9wKGtleTogc3RyaW5nLCBjb3VudDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmdbXSB8IG51bGw+O1xuICBsdHJpbShrZXk6IHN0cmluZywgc3RhcnQ6IG51bWJlciwgc3RvcDogbnVtYmVyKTogUHJvbWlzZTx1bmtub3duPjtcbiAgbGxlbihrZXk6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcbiAgLyoqIEF0b21pY2FsbHkgcG9wIGZyb20gb25lIGxpc3QgZW5kIGFuZCBwdXNoIHRvIGFub3RoZXIgKFJlZGlzIOKJpSA2LjIpLiAqL1xuICBsbW92ZShzb3VyY2U6IHN0cmluZywgZGVzdGluYXRpb246IHN0cmluZywgZnJvbTogJ0xFRlQnIHwgJ1JJR0hUJywgdG86ICdMRUZUJyB8ICdSSUdIVCcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+O1xuICAvKiogUmVtb3ZlIGBjb3VudGAgb2NjdXJyZW5jZXMgb2YgYHZhbHVlYCBmcm9tIGEgbGlzdC4gKi9cbiAgbHJlbShrZXk6IHN0cmluZywgY291bnQ6IG51bWJlciwgdmFsdWU6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPjtcbn1cblxuY29uc3QgREVGQVVMVF9TUE9PTF9LRVkgPSAnYXVkaXQ6c3Bvb2wnO1xuY29uc3QgREVGQVVMVF9NQVhfREVQVEggPSAxMF8wMDA7XG4vKiogR3VhcmQgc28gYSBwYXRob2xvZ2ljYWwgaW4tcHJvZ3Jlc3MgbGlzdCBjYW4ndCBzcGluIGByZWNvdmVyYC9gdGFrZWAgZm9yZXZlci4gKi9cbmNvbnN0IE1BWF9NT1ZFX0lURVJBVElPTlMgPSAxMDBfMDAwO1xuXG5mdW5jdGlvbiBlcnJNc2coZXJyOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKTtcbn1cblxuZnVuY3Rpb24gc2FmZVBhcnNlKHJhdzogc3RyaW5nKTogQXVkaXRTcG9vbEVudHJ5IHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShyYXcpIGFzIEF1ZGl0U3Bvb2xFbnRyeTtcbiAgICByZXR1cm4gcGFyc2VkICYmIHBhcnNlZC5ldmVudCAmJiBwYXJzZWQuc2VydmljZU5hbWUgPyBwYXJzZWQgOiBudWxsO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIFJlZGlzLUxJU1QtYmFja2VkIHNwb29sLiBEdXJhYmxlIGFjcm9zcyBwcm9jZXNzIHJlc3RhcnRzICh1bmxpa2UgYW4gaW4tbWVtb3J5XG4gKiBvciBwZXItcG9kLWRpc2sgYnVmZmVyKSwgc2hhcmVkIGJ5IGFsbCByZXBsaWNhcyBvZiBhIHNlcnZpY2UsIGFuZCBib3VuZGVkIHZpYVxuICogYSB0cmltLXRvLXRhaWwgb24gb3ZlcmZsb3cgKGRyb3BzIHRoZSBPTERFU1QsIGVtaXR0aW5nIGBhdWRpdF9zcG9vbF9kcm9wcGVkX3RvdGFsYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZWRpc0F1ZGl0U3Bvb2woXG4gIHJlZGlzOiBSZWRpc0xpc3RDbGllbnQsXG4gIG9wdHM6IHsgbWF4RGVwdGg/OiBudW1iZXI7IGtleT86IHN0cmluZyB9ID0ge30sXG4pOiBBdWRpdFNwb29sIHtcbiAgY29uc3Qga2V5ID0gb3B0cy5rZXkgPz8gREVGQVVMVF9TUE9PTF9LRVk7XG4gIC8vIFRoZSBpbi1wcm9ncmVzcyBcInByb2Nlc3NpbmdcIiBsaXN0IOKAlCBhIHRha2VuIGJhdGNoIGxpdmVzIGhlcmUgdW50aWwgaXQgaXNcbiAgLy8gYWNrZWQgKGRlbGl2ZXJlZCkgb3IgcmVxdWV1ZWQgKHN0aWxsIGZhaWxpbmcpLiBJdCBpcyBhIHNlY3VyaXR5IGxvZydzXG4gIC8vIGR1cmFiaWxpdHkgbmV0OiBhIGNyYXNoIGJldHdlZW4gdGFrZSBhbmQgYWNrL3JlcXVldWUgbGVhdmVzIHRoZSBiYXRjaCBoZXJlLFxuICAvLyBhbmQgYHJlY292ZXJgIHJlY2xhaW1zIGl0IG9uIHJlc3RhcnQgaW5zdGVhZCBvZiBzaWxlbnRseSBsb3NpbmcgaXQuXG4gIGNvbnN0IGluUHJvZ3Jlc3NLZXkgPSBgJHtrZXl9OmluZmxpZ2h0YDtcbiAgY29uc3QgbWF4RGVwdGggPSBNYXRoLm1heCgxLCBvcHRzLm1heERlcHRoID8/IERFRkFVTFRfTUFYX0RFUFRIKTtcblxuICAvLyBUaGUgRVhBQ1Qgc2VyaWFsaXplZCBzdHJpbmcgZWFjaCByZXR1cm5lZCBlbnRyeSB3YXMgcGFyc2VkIGZyb20sIHNvIGBhY2tgIC9cbiAgLy8gYHJlcXVldWVgIGNhbiBMUkVNIHRoZSBwcmVjaXNlIHZhbHVlIG9mZiB0aGUgaW4tcHJvZ3Jlc3MgbGlzdC4gS2V5ZWQgYnkgdGhlXG4gIC8vIHJldHVybmVkIG9iamVjdCBpZGVudGl0eSAodGhlIGRyYWluIGNvbnN1bWVyIHBhc3NlcyB0aGUgU0FNRSBvYmplY3RzIGJhY2spLFxuICAvLyBzbyBpdCBuZWVkcyBubyBzdGFibGUgcmUtc2VyaWFsaXphdGlvbi4gV2Vha01hcCDihpIgZW50cmllcyBHQyBuYXR1cmFsbHkuXG4gIGNvbnN0IHJhd0J5RW50cnkgPSBuZXcgV2Vha01hcDxBdWRpdFNwb29sRW50cnksIHN0cmluZz4oKTtcbiAgY29uc3QgcmF3T2YgPSAoZW50cnk6IEF1ZGl0U3Bvb2xFbnRyeSk6IHN0cmluZyA9PiByYXdCeUVudHJ5LmdldChlbnRyeSkgPz8gSlNPTi5zdHJpbmdpZnkoZW50cnkpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgZW5xdWV1ZShlbnRyeSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbGVuID0gYXdhaXQgcmVkaXMucnB1c2goa2V5LCBKU09OLnN0cmluZ2lmeShlbnRyeSkpO1xuICAgICAgICBlbWl0Q291bnRlcignYXVkaXRfc3Bvb2xfZW5xdWV1ZWRfdG90YWwnLCB7IHNlcnZpY2U6IGVudHJ5LnNlcnZpY2VOYW1lIH0pO1xuICAgICAgICBpZiAobGVuID4gbWF4RGVwdGgpIHtcbiAgICAgICAgICAvLyBLZWVwIG9ubHkgdGhlIG5ld2VzdCBgbWF4RGVwdGhgOyBkcm9wIHRoZSBvdmVyZmxvdyBhdCB0aGUgaGVhZC5cbiAgICAgICAgICBjb25zdCBkcm9wcGVkID0gbGVuIC0gbWF4RGVwdGg7XG4gICAgICAgICAgYXdhaXQgcmVkaXMubHRyaW0oa2V5LCBkcm9wcGVkLCAtMSk7XG4gICAgICAgICAgZW1pdENvdW50ZXIoJ2F1ZGl0X3Nwb29sX2Ryb3BwZWRfdG90YWwnLCB7IHNlcnZpY2U6IGVudHJ5LnNlcnZpY2VOYW1lIH0sIGRyb3BwZWQpO1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCBvdmVyZmxvdyDigJQgZHJvcHBlZCBvbGRlc3QgYnVmZmVyZWQgZXZlbnRzJywgeyBkcm9wcGVkLCBtYXhEZXB0aCB9KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCBlbnF1ZXVlIGZhaWxlZCAoZXZlbnQgbG9zdCknLCB7IGVycm9yOiBlcnJNc2coZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgdGFrZShtYXgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG91dDogQXVkaXRTcG9vbEVudHJ5W10gPSBbXTtcbiAgICAgICAgY29uc3QgbGltaXQgPSBNYXRoLm1heCgxLCBtYXgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbWl0OyBpKyspIHtcbiAgICAgICAgICAvLyBBdG9taWNhbGx5IE1PVkUgaGVhZOKGkmluLXByb2dyZXNzLXRhaWwgc28gdGhlIGVudHJ5IGlzIG5ldmVyIGluIGxpbWJvOlxuICAgICAgICAgIC8vIGl0IGlzIG9uIGV4YWN0bHkgb25lIGxpc3QgYXQgYWxsIHRpbWVzLCByZWNvdmVyYWJsZSBhZnRlciBhIGNyYXNoLlxuICAgICAgICAgIGNvbnN0IHJhdyA9IGF3YWl0IHJlZGlzLmxtb3ZlKGtleSwgaW5Qcm9ncmVzc0tleSwgJ0xFRlQnLCAnUklHSFQnKTtcbiAgICAgICAgICBpZiAocmF3ID09PSBudWxsIHx8IHJhdyA9PT0gdW5kZWZpbmVkKSBicmVhaztcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBzYWZlUGFyc2UocmF3KTtcbiAgICAgICAgICBpZiAocGFyc2VkKSB7XG4gICAgICAgICAgICByYXdCeUVudHJ5LnNldChwYXJzZWQsIHJhdyk7XG4gICAgICAgICAgICBvdXQucHVzaChwYXJzZWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBDb3JydXB0IHBheWxvYWQg4oCUIGRyb3AgaXQgb2ZmIHRoZSBpbi1wcm9ncmVzcyBsaXN0IHNvIGl0IGNhbid0IHdlZGdlXG4gICAgICAgICAgICAvLyB0aGUgZHJhaW4sIGFuZCBhY2NvdW50IGZvciBpdC5cbiAgICAgICAgICAgIGF3YWl0IHJlZGlzLmxyZW0oaW5Qcm9ncmVzc0tleSwgMSwgcmF3KTtcbiAgICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9zcG9vbF9kcm9wcGVkX3RvdGFsJywgeyBzZXJ2aWNlOiAndW5rbm93bicgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0F1ZGl0IHNwb29sIHRha2UgZmFpbGVkJywgeyBlcnJvcjogZXJyTXNnKGVycikgfSk7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgYWNrKGVudHJpZXMpIHtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgYXdhaXQgcmVkaXMubHJlbShpblByb2dyZXNzS2V5LCAxLCByYXdPZihlbnRyeSkpO1xuICAgICAgICAgIHJhd0J5RW50cnkuZGVsZXRlKGVudHJ5KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCBhY2sgZmFpbGVkIChtYXkgcmUtZGVsaXZlciBvbiByZWNvdmVyKScsIHsgZXJyb3I6IGVyck1zZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyByZXF1ZXVlKGVudHJpZXMpIHtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gUHV0IGZhaWxlZCByZS1kZWxpdmVyaWVzIGJhY2sgYXQgdGhlIEhFQUQgc28gdGhleSdyZSByZXRyaWVkIGZpcnN0IGFuZFxuICAgICAgICAvLyByb3VnaCBlbWlzc2lvbiBvcmRlciBpcyBwcmVzZXJ2ZWQgYWNyb3NzIHRoZSBvdXRhZ2Ug4oCUIGFuZCBjbGVhciB0aGVtXG4gICAgICAgIC8vIGZyb20gdGhlIGluLXByb2dyZXNzIGxpc3Qgc28gYHJlY292ZXJgIGRvZXNuJ3QgZG91YmxlIHRoZW0uIEl0ZXJhdGUgaW5cbiAgICAgICAgLy8gcmV2ZXJzZSBzbyBscHVzaCByZXN0b3JlcyB0aGUgYmF0Y2gncyBvcmlnaW5hbCBvcmRlciBhdCB0aGUgaGVhZC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gT1JERVJJTkcgSU5WQVJJQU5UIChhdC1sZWFzdC1vbmNlKTogbHB1c2ggdG8gdGhlIG1haW4gbGlzdCBGSVJTVCwgVEhFTlxuICAgICAgICAvLyBscmVtIGZyb20gaW4tcHJvZ3Jlc3MuIEEgY3Jhc2ggYmV0d2VlbiB0aGUgdHdvIGxlYXZlcyB0aGUgZW50cnkgb24gQk9USFxuICAgICAgICAvLyBsaXN0cyDihpIgaGFybWxlc3MgZG91YmxlLWRlbGl2ZXJ5IChkZWR1cGVkIGRvd25zdHJlYW0gYnkgaWRlbXBvdGVuY3lcbiAgICAgICAgLy8gcmV1c2UpLCBuZXZlciBhIExPU1MuIFRoZSByZXZlcnNlIG9yZGVyIChscmVtIHRoZW4gbHB1c2gpIHdvdWxkIGRyb3AgdGhlXG4gICAgICAgIC8vIGV2ZW50IG91dHJpZ2h0IG9uIGEgY3Jhc2ggaW4gdGhlIGdhcCwgd2hpY2ggYSBzZWN1cml0eSBsb2cgbXVzdCBub3QgZG8uXG4gICAgICAgIGZvciAobGV0IGkgPSBlbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgY29uc3QgcmF3ID0gcmF3T2YoZW50cmllc1tpXSk7XG4gICAgICAgICAgYXdhaXQgcmVkaXMubHB1c2goa2V5LCByYXcpO1xuICAgICAgICAgIGF3YWl0IHJlZGlzLmxyZW0oaW5Qcm9ncmVzc0tleSwgMSwgcmF3KTtcbiAgICAgICAgICByYXdCeUVudHJ5LmRlbGV0ZShlbnRyaWVzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdBdWRpdCBzcG9vbCByZXF1ZXVlIGZhaWxlZCAoZXZlbnRzIGxvc3QpJywgeyBlcnJvcjogZXJyTXNnKGVycikgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHJlY292ZXIoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgcmVjbGFpbWVkID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNQVhfTU9WRV9JVEVSQVRJT05TOyBpKyspIHtcbiAgICAgICAgICAvLyBNb3ZlIGluLXByb2dyZXNzLXRhaWwg4oaSIG1haW4taGVhZDogYW4gb2xkZXIgc3RyYW5kZWQgZW50cnkgKG5lYXJlciB0aGVcbiAgICAgICAgICAvLyBpbi1wcm9ncmVzcyBoZWFkKSBlbmRzIHVwIGFoZWFkIG9mIGEgbmV3ZXIgb25lLCBwcmVzZXJ2aW5nIG9yZGVyLlxuICAgICAgICAgIGNvbnN0IHJhdyA9IGF3YWl0IHJlZGlzLmxtb3ZlKGluUHJvZ3Jlc3NLZXksIGtleSwgJ1JJR0hUJywgJ0xFRlQnKTtcbiAgICAgICAgICBpZiAocmF3ID09PSBudWxsIHx8IHJhdyA9PT0gdW5kZWZpbmVkKSBicmVhaztcbiAgICAgICAgICByZWNsYWltZWQrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVjbGFpbWVkID4gMCkge1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9zcG9vbF9yZWNvdmVyZWRfdG90YWwnLCB7fSwgcmVjbGFpbWVkKTtcbiAgICAgICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgcmVjb3ZlcmVkIHN0cmFuZGVkIGluLXByb2dyZXNzIGV2ZW50cycsIHsgcmVjbGFpbWVkIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWNsYWltZWQ7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0F1ZGl0IHNwb29sIHJlY292ZXIgZmFpbGVkJywgeyBlcnJvcjogZXJyTXNnKGVycikgfSk7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyBkZXB0aCgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCByZWRpcy5sbGVuKGtleSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIFJlZGlzLWJhY2tlZCBhdWRpdCBzcG9vbCBmcm9tIHRoZSBhbWJpZW50IGBSRURJU19VUkxgIC8gYFJFRElTX1NFTlRJTkVMU2BcbiAqIGVudiB2aWEgdGhlIHNoYXJlZCBgY3JlYXRlRW52UmVkaXNDbGllbnRgLiBSZXR1cm5zIGBudWxsYCB3aGVuIFJlZGlzIGlzIG5vdFxuICogY29uZmlndXJlZCDigJQgdGhlIGNhbGxlciB0aGVuIHJ1bnMgd2l0aG91dCBhIHNwb29sIChiZXN0LWVmZm9ydCBiZWhhdmlvcikuIFRoZSBzaGFyZWQgaGVscGVyIGxvYWRzXG4gKiBpb3JlZGlzIHZpYSBgY3JlYXRlUmVxdWlyZWAsIHNvIHRoaXMgc3RheXMgaW1wb3J0YWJsZSB3aGVyZSBSZWRpcyBpc24ndCBwcmVzZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW52UmVkaXNBdWRpdFNwb29sKG9wdHM6IHsgbWF4RGVwdGg/OiBudW1iZXI7IGtleT86IHN0cmluZyB9ID0ge30pOiBBdWRpdFNwb29sIHwgbnVsbCB7XG4gIGNvbnN0IGluc3QgPSBjcmVhdGVFbnZSZWRpc0NsaWVudDxSZWRpc0xpc3RDbGllbnQ+KCdhdWRpdC1zcG9vbCcpO1xuICBpZiAoIWluc3QpIHJldHVybiBudWxsO1xuICBsb2dnZXIuaW5mbygnUmVkaXMgYXVkaXQgc3Bvb2wgaW5pdGlhbGl6ZWQnKTtcbiAgcmV0dXJuIGNyZWF0ZVJlZGlzQXVkaXRTcG9vbChpbnN0LCBvcHRzKTtcbn1cbiJdfQ==
|
|
@@ -1,28 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Minimal Redis
|
|
3
|
-
*
|
|
2
|
+
* Minimal Redis key/value client surface (subset of ioredis) shared by the
|
|
3
|
+
* token-revocation publisher/reader and platform's Redis helpers.
|
|
4
4
|
*/
|
|
5
5
|
export interface RedisCacheClient {
|
|
6
6
|
get(key: string): Promise<string | null>;
|
|
7
7
|
set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
|
|
8
8
|
del(...keys: string[]): Promise<number>;
|
|
9
|
-
keys(pattern: string): Promise<string[]>;
|
|
10
|
-
/** SCAN-based iteration (preferred over KEYS for production). */
|
|
11
|
-
scanStream?(options: {
|
|
12
|
-
match: string;
|
|
13
|
-
count?: number;
|
|
14
|
-
}): NodeJS.ReadableStream;
|
|
15
9
|
}
|
|
16
10
|
export interface CacheConfig {
|
|
17
11
|
/** Key prefix for namespace isolation (e.g., 'plugin:', 'compliance:') */
|
|
18
12
|
prefix: string;
|
|
19
13
|
/** Default TTL in seconds */
|
|
20
14
|
defaultTtlSeconds: number;
|
|
21
|
-
/** Max entries for
|
|
15
|
+
/** Max entries for the cache (default 1000) */
|
|
22
16
|
maxEntries?: number;
|
|
23
|
-
/**
|
|
24
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Cross-replica invalidation bus. Omit to use the shared env-Redis bus (null
|
|
19
|
+
* when Redis isn't configured → single-process semantics); pass `null` to
|
|
20
|
+
* disable explicitly.
|
|
21
|
+
*/
|
|
22
|
+
invalidationBus?: CacheInvalidationBus | null;
|
|
23
|
+
}
|
|
24
|
+
/** One invalidation broadcast to every replica. */
|
|
25
|
+
export interface CacheInvalidationMessage {
|
|
26
|
+
/** Id of the CacheService instance that invalidated (it ignores its own echo). */
|
|
27
|
+
origin: string;
|
|
28
|
+
/** The cache namespace (`CacheConfig.prefix`) the invalidation applies to. */
|
|
29
|
+
prefix: string;
|
|
30
|
+
op: 'del' | 'pattern' | 'clear';
|
|
31
|
+
/** Un-prefixed key (`del`) or glob pattern (`pattern`). */
|
|
32
|
+
key?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Transport that fans cache invalidations out to every replica. */
|
|
35
|
+
export interface CacheInvalidationBus {
|
|
36
|
+
/** Fire-and-forget broadcast. Never throws. */
|
|
37
|
+
publish(msg: CacheInvalidationMessage): void;
|
|
38
|
+
/**
|
|
39
|
+
* Register handlers. `onMessage` receives every broadcast (including this
|
|
40
|
+
* process's own); `onResync` fires whenever the subscription is (re)established,
|
|
41
|
+
* i.e. whenever invalidations may have been missed.
|
|
42
|
+
*/
|
|
43
|
+
subscribe(onMessage: (msg: CacheInvalidationMessage) => void, onResync: () => void): void;
|
|
25
44
|
}
|
|
45
|
+
/** Minimal ioredis pub/sub surface the env bus needs. */
|
|
46
|
+
export interface RedisInvalidationClient {
|
|
47
|
+
publish(channel: string, message: string): Promise<number>;
|
|
48
|
+
subscribe(...channels: string[]): Promise<unknown>;
|
|
49
|
+
on(event: string, cb: (...args: any[]) => void): unknown;
|
|
50
|
+
duplicate(): RedisInvalidationClient;
|
|
51
|
+
status?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Redis pub/sub invalidation bus. PUBLISH on the given client; SUBSCRIBE on a
|
|
55
|
+
* `duplicate()` (a subscribed ioredis connection can't run other commands).
|
|
56
|
+
*
|
|
57
|
+
* The SUBSCRIBE is issued on every `ready` (initial connect AND each reconnect)
|
|
58
|
+
* rather than once at construction: the env client runs without an offline
|
|
59
|
+
* queue, so a subscribe issued before the connection is up is rejected and would
|
|
60
|
+
* never be retried. Each `ready` also triggers `onResync` so every cache flushes
|
|
61
|
+
* whatever it may have missed while disconnected.
|
|
62
|
+
*/
|
|
63
|
+
export declare function createRedisCacheInvalidationBus(publisher: RedisInvalidationClient): CacheInvalidationBus;
|
|
26
64
|
/**
|
|
27
65
|
* Cache service with get/set/del operations and automatic TTL expiry.
|
|
28
66
|
*
|
|
@@ -54,7 +92,14 @@ export declare class CacheService {
|
|
|
54
92
|
private readonly prefix;
|
|
55
93
|
private readonly defaultTtlMs;
|
|
56
94
|
private readonly maxEntries;
|
|
57
|
-
private readonly
|
|
95
|
+
private readonly bus;
|
|
96
|
+
private readonly instanceId;
|
|
97
|
+
/**
|
|
98
|
+
* Bumped on EVERY invalidation (local or remote). `getOrSet` only caches a
|
|
99
|
+
* factory result if no invalidation happened while the factory ran — otherwise
|
|
100
|
+
* it could re-cache a value read before the write that invalidated it.
|
|
101
|
+
*/
|
|
102
|
+
private generation;
|
|
58
103
|
/** Cache metrics — tracks hits, misses, and invalidations. */
|
|
59
104
|
readonly metrics: {
|
|
60
105
|
hits: number;
|
|
@@ -63,21 +108,23 @@ export declare class CacheService {
|
|
|
63
108
|
invalidations: number;
|
|
64
109
|
};
|
|
65
110
|
constructor(config: CacheConfig);
|
|
111
|
+
/** Broadcast an invalidation to the other replicas. */
|
|
112
|
+
private broadcast;
|
|
113
|
+
/** Apply an invalidation to THIS process's in-memory entries. Returns the count removed. */
|
|
114
|
+
private applyLocalInvalidation;
|
|
66
115
|
private fullKey;
|
|
67
116
|
/**
|
|
68
117
|
* Get a cached value. Returns null on miss or error.
|
|
69
118
|
*
|
|
70
119
|
* The returned value is an INDEPENDENT deep copy — mutating it never affects
|
|
71
|
-
* the cached entry
|
|
72
|
-
* Redis, which returns a fresh JSON clone). Callers may still treat results as
|
|
73
|
-
* immutable, but doing so is no longer load-bearing for cache integrity.
|
|
120
|
+
* the cached entry.
|
|
74
121
|
*/
|
|
75
122
|
get<T>(key: string): Promise<T | null>;
|
|
76
123
|
/**
|
|
77
124
|
* Set a cached value with optional TTL override.
|
|
78
125
|
*
|
|
79
126
|
* @param key - Cache key (prefix is added automatically)
|
|
80
|
-
* @param value - Value to cache
|
|
127
|
+
* @param value - Value to cache
|
|
81
128
|
* @param ttlSeconds - TTL override (uses default if not provided)
|
|
82
129
|
*/
|
|
83
130
|
set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
@@ -87,11 +134,9 @@ export declare class CacheService {
|
|
|
87
134
|
del(key: string): Promise<void>;
|
|
88
135
|
/**
|
|
89
136
|
* Invalidate all keys matching a pattern (e.g., 'org123:*').
|
|
90
|
-
*
|
|
137
|
+
* Only `*` is a wildcard.
|
|
91
138
|
*/
|
|
92
139
|
invalidatePattern(pattern: string): Promise<number>;
|
|
93
|
-
/** Collect keys via Redis SCAN (non-blocking alternative to KEYS). */
|
|
94
|
-
private scanKeys;
|
|
95
140
|
/**
|
|
96
141
|
* Get or compute: returns cached value if available, otherwise calls the
|
|
97
142
|
* factory function, caches the result, and returns it.
|
|
@@ -119,6 +164,5 @@ export declare class CacheService {
|
|
|
119
164
|
*
|
|
120
165
|
* @param prefix - Namespace prefix (e.g., 'compliance:', 'plugin:')
|
|
121
166
|
* @param defaultTtlSeconds - Default TTL in seconds (default 300 = 5 min)
|
|
122
|
-
* @param redis - Optional Redis client for cross-process caching
|
|
123
167
|
*/
|
|
124
|
-
export declare function createCacheService(prefix: string, defaultTtlSeconds?: number
|
|
168
|
+
export declare function createCacheService(prefix: string, defaultTtlSeconds?: number): CacheService;
|