@pipeline-builder/api-core 4.1.7 → 4.1.9
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 +8 -0
- package/lib/helpers/org-hierarchy.d.ts +19 -0
- package/lib/helpers/org-hierarchy.js +29 -1
- package/lib/index.d.ts +26 -0
- package/lib/index.js +27 -1
- package/lib/services/api-key-exchange.js +3 -2
- package/lib/services/audit-spool.js +3 -2
- package/lib/services/cache-service.js +5 -4
- package/lib/services/compliance-event-subscriber.js +3 -2
- package/lib/services/durable-event-bus.js +3 -2
- package/lib/services/entity-events.js +3 -2
- package/lib/services/env-redis.js +3 -2
- package/lib/services/http-client.js +8 -7
- package/lib/services/index.d.ts +6 -2
- package/lib/services/index.js +11 -3
- package/lib/services/jwks-cache.d.ts +0 -12
- package/lib/services/jwks-cache.js +7 -6
- package/lib/services/leader-lock.js +3 -2
- package/lib/services/notification-channels.d.ts +112 -0
- package/lib/services/notification-channels.js +123 -0
- package/lib/services/quota.js +4 -4
- package/lib/services/remote-audit-client.d.ts +1 -1
- package/lib/services/remote-audit-client.js +4 -4
- package/lib/services/retry-forever.d.ts +37 -0
- package/lib/services/retry-forever.js +58 -0
- package/lib/services/retry-strategy.d.ts +7 -3
- package/lib/services/retry-strategy.js +2 -2
- package/lib/services/scheduler.js +2 -2
- package/lib/services/service-boot.d.ts +20 -4
- package/lib/services/service-boot.js +10 -6
- package/lib/services/service-keys.js +6 -5
- package/lib/services/sse-ticket-store.js +3 -2
- package/lib/services/token-revocation.js +6 -5
- package/lib/testing/mock-api-core.d.ts +150 -0
- package/lib/testing/mock-api-core.js +246 -0
- package/lib/testing/mock-drizzle.d.ts +6 -0
- package/lib/testing/mock-drizzle.js +57 -0
- package/lib/types/http.d.ts +4 -0
- package/lib/types/http.js +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +2 -1
- package/lib/types/metadata-keys.d.ts +543 -0
- package/lib/types/metadata-keys.js +117 -0
- package/lib/types/permissions.d.ts +19 -0
- package/lib/types/permissions.js +33 -1
- package/lib/types/quota-tiers.js +21 -31
- package/lib/utils/api-key.d.ts +0 -9
- package/lib/utils/api-key.js +2 -13
- package/lib/utils/audit.js +3 -2
- package/lib/utils/env.d.ts +6 -2
- package/lib/utils/env.js +9 -4
- package/lib/utils/identity.d.ts +37 -1
- package/lib/utils/identity.js +62 -10
- package/lib/utils/index.d.ts +2 -1
- package/lib/utils/index.js +7 -2
- package/lib/utils/params.d.ts +35 -0
- package/lib/utils/params.js +24 -1
- package/lib/utils/secret-encryption.d.ts +4 -4
- package/lib/utils/secret-encryption.js +5 -5
- package/lib/utils/ssrf.d.ts +73 -14
- package/lib/utils/ssrf.js +138 -21
- package/package.json +26 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { createEnvRedisClient, createRedisReadyGate } from './env-redis.js';
|
|
4
4
|
import { createLogger } from '../utils/logger.js';
|
|
5
5
|
import { emitCounter } from '../utils/metric-emitter.js';
|
|
6
|
+
import { errorMessage } from '../utils/response.js';
|
|
6
7
|
const logger = createLogger('token-revocation');
|
|
7
8
|
/**
|
|
8
9
|
* Redis key namespace for the per-user current `tokenVersion`. The platform
|
|
@@ -59,7 +60,7 @@ export function createRedisTokenRevocationStore(redis) {
|
|
|
59
60
|
// which is a deliberate opt-out, not a degradation.
|
|
60
61
|
emitCounter('token_revocation_fail_open_total', { reason: 'read-error' });
|
|
61
62
|
logger.debug('Token-revocation read failed (fail-open)', {
|
|
62
|
-
userId, error:
|
|
63
|
+
userId, error: errorMessage(err),
|
|
63
64
|
});
|
|
64
65
|
return null;
|
|
65
66
|
}
|
|
@@ -75,7 +76,7 @@ export function createRedisTokenRevocationStore(redis) {
|
|
|
75
76
|
// support impersonation everywhere — is visible and alertable.
|
|
76
77
|
emitCounter('session_revocation_unavailable_total', { reason: 'read-error' });
|
|
77
78
|
logger.debug('Session-revocation read failed (rejecting impersonation token)', {
|
|
78
|
-
error:
|
|
79
|
+
error: errorMessage(err),
|
|
79
80
|
});
|
|
80
81
|
return 'unavailable';
|
|
81
82
|
}
|
|
@@ -163,7 +164,7 @@ export async function publishTokenRevocation(redis, userId, tokenVersion, ttlSec
|
|
|
163
164
|
}
|
|
164
165
|
catch (err) {
|
|
165
166
|
logger.warn('Token-revocation publish failed (services fall back to token expiry)', {
|
|
166
|
-
userId, error:
|
|
167
|
+
userId, error: errorMessage(err),
|
|
167
168
|
});
|
|
168
169
|
}
|
|
169
170
|
}
|
|
@@ -188,9 +189,9 @@ export async function publishSessionRevocation(redis, jti, ttlMs) {
|
|
|
188
189
|
}
|
|
189
190
|
catch (err) {
|
|
190
191
|
logger.warn('Session-revocation publish failed (other services will honour the token until it expires)', {
|
|
191
|
-
error:
|
|
192
|
+
error: errorMessage(err),
|
|
192
193
|
});
|
|
193
194
|
return false;
|
|
194
195
|
}
|
|
195
196
|
}
|
|
196
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tcmV2b2NhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy90b2tlbi1yZXZvY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBRWxHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFaEQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQUcsYUFBYSxDQUFDO0FBRXpELHdDQUF3QztBQUN4QyxNQUFNLFVBQVUsa0JBQWtCLENBQUMsTUFBYztJQUMvQyxPQUFPLEdBQUcsMkJBQTJCLEdBQUcsTUFBTSxFQUFFLENBQUM7QUFDbkQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxjQUFjLENBQUM7QUFFNUQscURBQXFEO0FBQ3JELE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxHQUFXO0lBQzlDLE9BQU8sR0FBRyw2QkFBNkIsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNsRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsS0FBdUI7SUFDckUsT0FBTztRQUNMLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFjO1lBQ3BDLElBQUksQ0FBQztnQkFDSCxNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDeEQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTLElB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Q0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsS0FBdUIsRUFDdkIsR0FBVyxFQUNYLEtBQWE7SUFFYixJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQywyRkFBMkYsRUFBRTtZQUN2RyxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztTQUN4RCxDQUFDLENBQUM7UUFDSCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVkaXNDYWNoZUNsaWVudCB9IGZyb20gJy4vY2FjaGUtc2VydmljZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0NsaWVudCwgY3JlYXRlUmVkaXNSZWFkeUdhdGUsIHR5cGUgUmVhZHlBd2FyZVJlZGlzIH0gZnJvbSAnLi9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTZXNzaW9uUmV2b2NhdGlvblN0YXRlLCBUb2tlblJldm9jYXRpb25TdG9yZSB9IGZyb20gJy4uL21pZGRsZXdhcmUvYXV0aC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigndG9rZW4tcmV2b2NhdGlvbicpO1xuXG4vKipcbiAqIFJlZGlzIGtleSBuYW1lc3BhY2UgZm9yIHRoZSBwZXItdXNlciBjdXJyZW50IGB0b2tlblZlcnNpb25gLiBUaGUgcGxhdGZvcm1cbiAqIFBVQkxJU0hFUyB0byB0aGlzIGtleSBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlOyB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzIFJFQURcbiAqIGl0IGluIGByZXF1aXJlQXV0aGAgKHZpYSB7QGxpbmsgY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZX0pIHRvIHJlamVjdFxuICogdG9rZW5zIG1pbnRlZCBiZWZvcmUgdGhhdCBjaGFuZ2UuIFB1Ymxpc2hlciBhbmQgcmVhZGVycyBNVVNUIHNoYXJlIHRoaXMgZXhhY3RcbiAqIHByZWZpeCDigJQgaGVuY2UgYm90aCBoZWxwZXJzIGxpdmUgaGVyZSwgaW4gb25lIHBsYWNlLlxuICovXG5leHBvcnQgY29uc3QgVE9LRU5fUkVWT0NBVElPTl9LRVlfUFJFRklYID0gJ2F1dGhyZXY6dHY6JztcblxuLyoqIFRoZSByZXZvY2F0aW9uIGtleSBmb3IgYSB1c2VyIGlkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtUT0tFTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVh9JHt1c2VySWR9YDtcbn1cblxuLyoqXG4gKiBSZWRpcyBrZXkgbmFtZXNwYWNlIGZvciBlbmRlZCBJTVBFUlNPTkFUSU9OIHNlc3Npb25zLCBieSB0b2tlbiBganRpYC4gU2FtZVxuICogcHVibGlzaC9yZWFkIHNwbGl0IGFzIHRoZSB0b2tlblZlcnNpb24ga2V5cyBhYm92ZSwgYW5kIGtlcHQgYmVzaWRlIHRoZW0gZm9yIHRoZVxuICogc2FtZSByZWFzb246IHB1Ymxpc2hlciBhbmQgcmVhZGVycyBtdXN0IGFncmVlIG9uIHRoaXMgZXhhY3QgcHJlZml4LlxuICovXG5leHBvcnQgY29uc3QgU0VTU0lPTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVggPSAnYXV0aHJldjpqdGk6JztcblxuLyoqIFRoZSByZXZvY2F0aW9uIGtleSBmb3Igb25lIHNlc3Npb24ncyB0b2tlbiBpZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXNzaW9uUmV2b2NhdGlvbktleShqdGk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtTRVNTSU9OX1JFVk9DQVRJT05fS0VZX1BSRUZJWH0ke2p0aX1gO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEge0BsaW5rIFRva2VuUmV2b2NhdGlvblN0b3JlfSBiYWNrZWQgYnkgYSBSZWRpcyBjbGllbnQsIGZvciBhIHN0YXRlbGVzc1xuICogc2VydmljZSB0byByZWdpc3RlciB2aWEgYHNldFRva2VuUmV2b2NhdGlvblN0b3JlYC4gUmVhZHMgdGhlIGN1cnJlbnRcbiAqIGB0b2tlblZlcnNpb25gIHRoZSBwbGF0Zm9ybSBwdWJsaXNoZWQgZm9yIHRoZSB1c2VyLlxuICpcbiAqIEZhaWwtb3BlbiBieSBjb250cmFjdDogYSBtaXNzLCBhIHBhcnNlIGZhaWx1cmUsIG9yIGEgUmVkaXMgZXJyb3IgYWxsIHlpZWxkXG4gKiBgbnVsbGAgKOKAlCBgcmVxdWlyZUF1dGhgIHRyZWF0cyB0aGF0IGFzIFwibm8ga25vd24gcmV2b2NhdGlvblwiKSwgc28gYSBSZWRpc1xuICogb3V0YWdlIGRlZ3JhZGVzIHRvIHRoZSBwcmUtZXhpc3RpbmcgYmVoYXZpb3VyIHJhdGhlciB0aGFuIGxvY2tpbmcgdXNlcnMgb3V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZShyZWRpczogUmVkaXNDYWNoZUNsaWVudCk6IFRva2VuUmV2b2NhdGlvblN0b3JlIHtcbiAgcmV0dXJuIHtcbiAgICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmF3ID0gYXdhaXQgcmVkaXMuZ2V0KHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQpKTtcbiAgICAgICAgaWYgKHJhdyA9PT0gbnVsbCB8fCByYXcgPT09IHVuZGVmaW5lZCB8fCByYXcudHJpbSgpID09PSAnJykgcmV0dXJuIG51bGw7XG4gICAgICAgIC8vIFN0cmljdCBpbnRlZ2VyIHBhcnNlOiBgTnVtYmVyYCAodW5saWtlIGBwYXJzZUludGApIHJlamVjdHMgdHJhaWxpbmdcbiAgICAgICAgLy8gZ2FyYmFnZSAoXCI1YWJjXCIg4oaSIE5hTiksIHNvIGEgY29ycnVwdGVkIGVudHJ5IGZhaWxzIG9wZW4gKG51bGwg4oaSIFwibm90XG4gICAgICAgIC8vIHJldm9rZWRcIikgcmF0aGVyIHRoYW4gYmVpbmcgcmVhZCBhcyBhIGJvZ3VzIHZlcnNpb24uIFRoZSBlbXB0eS1zdHJpbmdcbiAgICAgICAgLy8gZ3VhcmQgYWJvdmUgbWF0dGVycyBiZWNhdXNlIGBOdW1iZXIoJycpYCBpcyAwLCBub3QgTmFOLlxuICAgICAgICBjb25zdCBuID0gTnVtYmVyKHJhdyk7XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKG4pID8gbiA6IG51bGw7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gUmVkaXMgd2FzIHJlYWNoYWJsZSBlbm91Z2ggdG8gdHJ5IGJ1dCB0aGUgcmVhZCBlcnJvcmVkIOKAlCB0aGlzIGlzIGFcbiAgICAgICAgLy8gREVHUkFEQVRJT046IHdoaWxlIGl0IHBlcnNpc3RzLCBmb3JjZWQgbG9nb3V0cyAvIHByaXZpbGVnZSByZXZvY2F0aW9uc1xuICAgICAgICAvLyBzaWxlbnRseSBzdG9wIHRha2luZyBlZmZlY3QgdW50aWwgbmF0dXJhbCB0b2tlbiBleHBpcnkuIEVtaXQgYSBjb3VudGVyXG4gICAgICAgIC8vIHNvIGBUb2tlblJldm9jYXRpb25GYWlsaW5nT3BlbmAgY2FuIGFsZXJ0IG9uIGEgU1VTVEFJTkVEIHJhdGUgKG1pcnJvcnNcbiAgICAgICAgLy8gdGhlIHF1b3RhX2ZhaWxfb3Blbl90b3RhbCBwYXR0ZXJuKS4gTm90IGVtaXR0ZWQgZm9yIHRoZSBcIlJlZGlzIG5vdFxuICAgICAgICAvLyBjb25maWd1cmVkXCIgcGF0aCAoY3JlYXRlRW52UmVkaXNUb2tlblJldm9jYXRpb25TdG9yZSDihpIgbnVsbCBjbGllbnQpLFxuICAgICAgICAvLyB3aGljaCBpcyBhIGRlbGliZXJhdGUgb3B0LW91dCwgbm90IGEgZGVncmFkYXRpb24uXG4gICAgICAgIGVtaXRDb3VudGVyKCd0b2tlbl9yZXZvY2F0aW9uX2ZhaWxfb3Blbl90b3RhbCcsIHsgcmVhc29uOiAncmVhZC1lcnJvcicgfSk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnVG9rZW4tcmV2b2NhdGlvbiByZWFkIGZhaWxlZCAoZmFpbC1vcGVuKScsIHtcbiAgICAgICAgICB1c2VySWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5nZXQoc2Vzc2lvblJldm9jYXRpb25LZXkoanRpKSk7XG4gICAgICAgIHJldHVybiByYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgPyAnbGl2ZScgOiAncmV2b2tlZCc7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gTk9UIGZhaWwtb3BlbiwgdW5saWtlIGdldEN1cnJlbnRWZXJzaW9uIGFib3ZlOiBgdW5hdmFpbGFibGVgIHJlamVjdHNcbiAgICAgICAgLy8gdGhlIGltcGVyc29uYXRpb24gdG9rZW4uIENvdW50ZWQgc28gYSBzdXN0YWluZWQgb3V0YWdlIOKAlCB3aGljaCBzdG9wc1xuICAgICAgICAvLyBzdXBwb3J0IGltcGVyc29uYXRpb24gZXZlcnl3aGVyZSDigJQgaXMgdmlzaWJsZSBhbmQgYWxlcnRhYmxlLlxuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdyZWFkLWVycm9yJyB9KTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZXNzaW9uLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKHJlamVjdGluZyBpbXBlcnNvbmF0aW9uIHRva2VuKScsIHtcbiAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuICd1bmF2YWlsYWJsZSc7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHtAbGluayBUb2tlblJldm9jYXRpb25TdG9yZX0gYmFja2VkIGJ5IGEgUmVkaXMgY2xpZW50IHRoYXQgaXMgbGF6aWx5XG4gKiBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBzdGFuZGFyZCBgUkVESVNfVVJMYCBvciBgUkVESVNfU0VOVElORUxTYCBlbnYg4oCUXG4gKiBmb3IgYSBzdGF0ZWxlc3Mgc2VydmljZSB0aGF0IGtlZXBzIE5PIFJlZGlzIGNsaWVudCBvZiBpdHMgb3duLiBUaGUgY2xpZW50IGlzXG4gKiBidWlsdCBvbiBmaXJzdCBgZ2V0Q3VycmVudFZlcnNpb25gIGNhbGwgYW5kIG1lbW9pemVkOyBgaW9yZWRpc2AgaXMgbG9hZGVkIHZpYVxuICogYSBndWFyZGVkIGR5bmFtaWMgcmVxdWlyZSBzbyBtZXJlbHkgaW1wb3J0aW5nIHRoaXMgbmV2ZXIgYnJlYWtzIGEgYnVpbGQvdGVzdFxuICogd2hlcmUgUmVkaXMgaXNuJ3QgcHJlc2VudC5cbiAqXG4gKiBGVUxMWSBGQUlMLU9QRU46IG5vIGVudiBjb25maWd1cmVkLCBhbiBpb3JlZGlzIGxvYWQgZmFpbHVyZSwgYSBjb25uZWN0IGVycm9yLFxuICogb3IgYW55IHJlYWQgZmFpbHVyZSBhbGwgcmVzb2x2ZSB0byBgbnVsbGAgKFwibm8ga25vd24gcmV2b2NhdGlvblwiKSwgc28gYVxuICogc2VydmljZSBkZWdyYWRlcyB0byBuYXR1cmFsIHRva2VuIGV4cGlyeSByYXRoZXIgdGhhbiBsb2NraW5nIHVzZXJzIG91dC4gQVxuICogc2VydmljZSBvcHRzIGluIHdpdGggYSBzaW5nbGUgYm9vdCBsaW5lOlxuICogICBgc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoY3JlYXRlRW52UmVkaXNUb2tlblJldm9jYXRpb25TdG9yZSgpKTtgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKCk6IFRva2VuUmV2b2NhdGlvblN0b3JlIHtcbiAgdHlwZSBSZWFkZXJSZWRpcyA9IFJlZGlzQ2FjaGVDbGllbnQgJiBSZWFkeUF3YXJlUmVkaXM7XG4gIC8vIHVuZGVmaW5lZCA9IG5vdCB5ZXQgYXR0ZW1wdGVkOyBudWxsID0gYXR0ZW1wdGVkIGFuZCB1bmF2YWlsYWJsZSAoc3RheSBvZmYpLlxuICBsZXQgY2FjaGVkOiBSZWFkZXJSZWRpcyB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIGxldCByZWFkeTogKCgpID0+IFByb21pc2U8dm9pZD4pIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVhZGVyIGNsaWVudCwgYnVpbHQgb24gZmlyc3QgdXNlLiBUaGUgZW52IGNsaWVudCBoYXMgbm8gb2ZmbGluZSBxdWV1ZSxcbiAgICogc28gYSBHRVQgYmVmb3JlIHRoZSBmaXJzdCBjb25uZWN0aW9uIGNvbXBsZXRlcyBpcyByZWplY3RlZCDigJQgd2hpY2ggbWFkZSB0aGVcbiAgICogRklSU1QgaW1wZXJzb25hdGlvbiBjaGVjayBvbiBldmVyeSBwb2QgcmVhZCAndW5hdmFpbGFibGUnICg0MDEpLiBXYWl0XG4gICAqIChib3VuZGVkLCBuZXZlciByZWplY3RpbmcpIGZvciByZWFkaW5lc3M7IGEgZ2VudWluZWx5IGRvd24gUmVkaXMgdGhlbiBrZWVwc1xuICAgKiB0aGUgZXhpc3RpbmcgZmFpbC1vcGVuIC8gJ3VuYXZhaWxhYmxlJyBzZW1hbnRpY3MuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBjbGllbnQoKTogUHJvbWlzZTxSZWFkZXJSZWRpcyB8IG51bGw+IHtcbiAgICBpZiAoY2FjaGVkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFNoYXJlZCBlbnYtY29uZmlndXJlZCBpb3JlZGlzIGNvbnN0cnVjdGlvbiAoZXJyb3IgbGlzdGVuZXIgYXR0YWNoZWQsIG51bGxcbiAgICAgIC8vIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZCk7IHRoZSByZWFkZXIgc3RheXMgZmFpbC1vcGVuIOKAlCBhIG51bGwgY2xpZW50XG4gICAgICAvLyBqdXN0IGZhbGxzIGJhY2sgdG8gbmF0dXJhbCB0b2tlbiBleHBpcnkuXG4gICAgICBjYWNoZWQgPSBjcmVhdGVFbnZSZWRpc0NsaWVudDxSZWFkZXJSZWRpcz4oJ3Jldm9jYXRpb24tcmVhZGVyJyk7XG4gICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdSZWRpcyB0b2tlbi1yZXZvY2F0aW9uIHJlYWRlciBpbml0aWFsaXplZCcpO1xuICAgICAgICByZWFkeSA9IGNyZWF0ZVJlZGlzUmVhZHlHYXRlKGNhY2hlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZWFkeSkgYXdhaXQgcmVhZHkoKTtcbiAgICByZXR1cm4gY2FjaGVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgY29uc3QgcmVkaXMgPSBhd2FpdCBjbGllbnQoKTtcbiAgICAgIGlmICghcmVkaXMpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXMpLmdldEN1cnJlbnRWZXJzaW9uKHVzZXJJZCk7XG4gICAgfSxcbiAgICBhc3luYyBnZXRTZXNzaW9uUmV2b2NhdGlvbihqdGk6IHN0cmluZyk6IFByb21pc2U8U2Vzc2lvblJldm9jYXRpb25TdGF0ZT4ge1xuICAgICAgY29uc3QgcmVkaXMgPSBhd2FpdCBjbGllbnQoKTtcbiAgICAgIC8vIE5vIFJlZGlzIGNvbmZpZ3VyZWQg4oeSIHRoZXJlIGlzIG5vIHdheSB0byBsZWFybiBhIHNlc3Npb24gd2FzIGVuZGVkLCBzb1xuICAgICAgLy8gYW4gaW1wZXJzb25hdGlvbiB0b2tlbiBjYW4ndCBiZSB0cnVzdGVkLiBFdmVyeSByZWFsIGRlcGxveW1lbnQgcnVucyBSZWRpc1xuICAgICAgLy8gKHRoZSBidWlsZCBxdWV1ZSBuZWVkcyBpdCksIHNvIHRoaXMgb25seSBiaXRlcyBhIG1pc2NvbmZpZ3VyZWQgc2VydmljZS5cbiAgICAgIGlmICghcmVkaXMpIHtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3Nlc3Npb25fcmV2b2NhdGlvbl91bmF2YWlsYWJsZV90b3RhbCcsIHsgcmVhc29uOiAnbm90LWNvbmZpZ3VyZWQnIH0pO1xuICAgICAgICByZXR1cm4gJ3VuYXZhaWxhYmxlJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKHJlZGlzKS5nZXRTZXNzaW9uUmV2b2NhdGlvbiEoanRpKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFB1Ymxpc2ggYSB1c2VyJ3MgY3VycmVudCBgdG9rZW5WZXJzaW9uYCBzbyB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzIHNlZSB0aGVcbiAqIHJldm9jYXRpb24gaW1tZWRpYXRlbHkgKHBsYXRmb3JtIHNpZGUpLiBCZXN0LWVmZm9ydCDigJQgbmV2ZXIgdGhyb3dzOyBhIGZhaWx1cmVcbiAqIGp1c3QgbWVhbnMgdGhlIHNlcnZpY2VzIGZhbGwgYmFjayB0byBuYXR1cmFsIHRva2VuIGV4cGlyeSBmb3IgdGhpcyBjaGFuZ2UuXG4gKlxuICogVGhlIGtleSBpcyB3cml0dGVuIHdpdGggYSBUVEwgZXF1YWwgdG8gdGhlIGFjY2Vzcy10b2tlbiBsaWZldGltZTogYW55IHRva2VuXG4gKiB0aGF0IGNvdWxkIHN0aWxsIGNhcnJ5IGFuIG9sZGVyIHZlcnNpb24gaGFzIGV4cGlyZWQgYnkgdGhlIHRpbWUgdGhlIGVudHJ5XG4gKiBsYXBzZXMsIHNvIGFuIGV4cGlyZWQgZW50cnkgY2FuIG5ldmVyIGNhdXNlIGEgZmFsc2UgXCJyZXZva2VkXCIgbm9yIGEgbWlzc2VkIG9uZS5cbiAqXG4gKiBAcGFyYW0gcmVkaXMgLSB0aGUgcGxhdGZvcm0ncyBSZWRpcyBjbGllbnRcbiAqIEBwYXJhbSB1c2VySWQgLSB0aGUgdXNlciB3aG9zZSBzZXNzaW9ucyBjaGFuZ2VkXG4gKiBAcGFyYW0gdG9rZW5WZXJzaW9uIC0gdGhlIHVzZXIncyBORVcgKHBvc3QtaW5jcmVtZW50KSB0b2tlblZlcnNpb25cbiAqIEBwYXJhbSB0dGxTZWNvbmRzIC0gYWNjZXNzLXRva2VuIGxpZmV0aW1lIGluIHNlY29uZHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2hUb2tlblJldm9jYXRpb24oXG4gIHJlZGlzOiBSZWRpc0NhY2hlQ2xpZW50LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgdG9rZW5WZXJzaW9uOiBudW1iZXIsXG4gIHR0bFNlY29uZHM6IG51bWJlcixcbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIC8vIGlvcmVkaXMtc3R5bGUgdmFyaWFkaWMgU0VUIHdpdGggZXhwaXJ5OiBTRVQga2V5IHZhbCBFWCB0dGwuXG4gICAgYXdhaXQgcmVkaXMuc2V0KHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQpLCBTdHJpbmcodG9rZW5WZXJzaW9uKSwgJ0VYJywgTWF0aC5tYXgoMSwgTWF0aC5mbG9vcih0dGxTZWNvbmRzKSkpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignVG9rZW4tcmV2b2NhdGlvbiBwdWJsaXNoIGZhaWxlZCAoc2VydmljZXMgZmFsbCBiYWNrIHRvIHRva2VuIGV4cGlyeSknLCB7XG4gICAgICB1c2VySWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWJsaXNoIHRoYXQgb25lIElNUEVSU09OQVRJT04gc2Vzc2lvbiBoYXMgZW5kZWQsIHNvIGV2ZXJ5IHN0YXRlbGVzcyBzZXJ2aWNlXG4gKiByZWplY3RzIGl0cyB0b2tlbiBvbiB0aGUgbmV4dCByZXF1ZXN0IChwbGF0Zm9ybSBzaWRlKS5cbiAqXG4gKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHB1Ymxpc2ggbGFuZGVkIOKAlCB1bmxpa2UgYHB1Ymxpc2hUb2tlblJldm9jYXRpb25gLCB3aGljaCBpc1xuICogZmlyZS1hbmQtZm9yZ2V0LiBUaGUgY2FsbGVyIG11c3QgYmUgYWJsZSB0byB0ZWxsIHRoZSBwZXJzb24gd2hvIGVuZGVkIHRoZVxuICogc2Vzc2lvbiB0aGF0IGl0IGRpZCBOT1QgZW5kIGV2ZXJ5d2hlcmUsIHJhdGhlciB0aGFuIHJlcG9ydGluZyBzdWNjZXNzIHdoaWxlXG4gKiB0aGUgdG9rZW4gc3RpbGwgd29ya3MgYWdhaW5zdCBvdGhlciBzZXJ2aWNlcy5cbiAqXG4gKiBUaGUgZW50cnkgZXhwaXJlcyB3aXRoIHRoZSBzZXNzaW9uOiBvbmNlIHRoZSB0b2tlbiBpdHNlbGYgY2FuIG5vIGxvbmdlciBiZVxuICogdXNlZCwgdGhlcmUgaXMgbm90aGluZyBsZWZ0IHRvIHJldm9rZSwgc28gdGhlIGtleSBjbGVhbnMgaXRzZWxmIHVwLlxuICpcbiAqIEBwYXJhbSB0dGxNcyAtIHRpbWUgcmVtYWluaW5nIG9uIHRoZSBzZXNzaW9uJ3MgdG9rZW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2hTZXNzaW9uUmV2b2NhdGlvbihcbiAgcmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQsXG4gIGp0aTogc3RyaW5nLFxuICB0dGxNczogbnVtYmVyLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVkaXMuc2V0KHNlc3Npb25SZXZvY2F0aW9uS2V5KGp0aSksICcxJywgJ1BYJywgTWF0aC5tYXgoMTAwMCwgTWF0aC5jZWlsKHR0bE1zKSkpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignU2Vzc2lvbi1yZXZvY2F0aW9uIHB1Ymxpc2ggZmFpbGVkIChvdGhlciBzZXJ2aWNlcyB3aWxsIGhvbm91ciB0aGUgdG9rZW4gdW50aWwgaXQgZXhwaXJlcyknLCB7XG4gICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
|
|
197
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tcmV2b2NhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy90b2tlbi1yZXZvY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBRWxHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXBELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRWhEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLGFBQWEsQ0FBQztBQUV6RCx3Q0FBd0M7QUFDeEMsTUFBTSxVQUFVLGtCQUFrQixDQUFDLE1BQWM7SUFDL0MsT0FBTyxHQUFHLDJCQUEyQixHQUFHLE1BQU0sRUFBRSxDQUFDO0FBQ25ELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsY0FBYyxDQUFDO0FBRTVELHFEQUFxRDtBQUNyRCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsR0FBVztJQUM5QyxPQUFPLEdBQUcsNkJBQTZCLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQixDQUFDLEtBQXVCO0lBQ3JFLE9BQU87UUFDTCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBYztZQUNwQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ3hE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TUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkZBQTJGLEVBQUU7WUFDdkcsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDekIsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IFJlZGlzQ2FjaGVDbGllbnQgfSBmcm9tICcuL2NhY2hlLXNlcnZpY2UuanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQsIGNyZWF0ZVJlZGlzUmVhZHlHYXRlLCB0eXBlIFJlYWR5QXdhcmVSZWRpcyB9IGZyb20gJy4vZW52LXJlZGlzLmpzJztcbmltcG9ydCB0eXBlIHsgU2Vzc2lvblJldm9jYXRpb25TdGF0ZSwgVG9rZW5SZXZvY2F0aW9uU3RvcmUgfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGguanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3Rva2VuLXJldm9jYXRpb24nKTtcblxuLyoqXG4gKiBSZWRpcyBrZXkgbmFtZXNwYWNlIGZvciB0aGUgcGVyLXVzZXIgY3VycmVudCBgdG9rZW5WZXJzaW9uYC4gVGhlIHBsYXRmb3JtXG4gKiBQVUJMSVNIRVMgdG8gdGhpcyBrZXkgb24gZXZlcnkgcHJpdmlsZWdlIGNoYW5nZTsgdGhlIHN0YXRlbGVzcyBzZXJ2aWNlcyBSRUFEXG4gKiBpdCBpbiBgcmVxdWlyZUF1dGhgICh2aWEge0BsaW5rIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmV9KSB0byByZWplY3RcbiAqIHRva2VucyBtaW50ZWQgYmVmb3JlIHRoYXQgY2hhbmdlLiBQdWJsaXNoZXIgYW5kIHJlYWRlcnMgTVVTVCBzaGFyZSB0aGlzIGV4YWN0XG4gKiBwcmVmaXgg4oCUIGhlbmNlIGJvdGggaGVscGVycyBsaXZlIGhlcmUsIGluIG9uZSBwbGFjZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFRPS0VOX1JFVk9DQVRJT05fS0VZX1BSRUZJWCA9ICdhdXRocmV2OnR2Oic7XG5cbi8qKiBUaGUgcmV2b2NhdGlvbiBrZXkgZm9yIGEgdXNlciBpZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2tlblJldm9jYXRpb25LZXkodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7VE9LRU5fUkVWT0NBVElPTl9LRVlfUFJFRklYfSR7dXNlcklkfWA7XG59XG5cbi8qKlxuICogUmVkaXMga2V5IG5hbWVzcGFjZSBmb3IgZW5kZWQgSU1QRVJTT05BVElPTiBzZXNzaW9ucywgYnkgdG9rZW4gYGp0aWAuIFNhbWVcbiAqIHB1Ymxpc2gvcmVhZCBzcGxpdCBhcyB0aGUgdG9rZW5WZXJzaW9uIGtleXMgYWJvdmUsIGFuZCBrZXB0IGJlc2lkZSB0aGVtIGZvciB0aGVcbiAqIHNhbWUgcmVhc29uOiBwdWJsaXNoZXIgYW5kIHJlYWRlcnMgbXVzdCBhZ3JlZSBvbiB0aGlzIGV4YWN0IHByZWZpeC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNFU1NJT05fUkVWT0NBVElPTl9LRVlfUFJFRklYID0gJ2F1dGhyZXY6anRpOic7XG5cbi8qKiBUaGUgcmV2b2NhdGlvbiBrZXkgZm9yIG9uZSBzZXNzaW9uJ3MgdG9rZW4gaWQuICovXG5leHBvcnQgZnVuY3Rpb24gc2Vzc2lvblJldm9jYXRpb25LZXkoanRpOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7U0VTU0lPTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVh9JHtqdGl9YDtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHtAbGluayBUb2tlblJldm9jYXRpb25TdG9yZX0gYmFja2VkIGJ5IGEgUmVkaXMgY2xpZW50LCBmb3IgYSBzdGF0ZWxlc3NcbiAqIHNlcnZpY2UgdG8gcmVnaXN0ZXIgdmlhIGBzZXRUb2tlblJldm9jYXRpb25TdG9yZWAuIFJlYWRzIHRoZSBjdXJyZW50XG4gKiBgdG9rZW5WZXJzaW9uYCB0aGUgcGxhdGZvcm0gcHVibGlzaGVkIGZvciB0aGUgdXNlci5cbiAqXG4gKiBGYWlsLW9wZW4gYnkgY29udHJhY3Q6IGEgbWlzcywgYSBwYXJzZSBmYWlsdXJlLCBvciBhIFJlZGlzIGVycm9yIGFsbCB5aWVsZFxuICogYG51bGxgICjigJQgYHJlcXVpcmVBdXRoYCB0cmVhdHMgdGhhdCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiksIHNvIGEgUmVkaXNcbiAqIG91dGFnZSBkZWdyYWRlcyB0byB0aGUgcHJlLWV4aXN0aW5nIGJlaGF2aW91ciByYXRoZXIgdGhhbiBsb2NraW5nIHVzZXJzIG91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQpOiBUb2tlblJldm9jYXRpb25TdG9yZSB7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgZ2V0Q3VycmVudFZlcnNpb24odXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJhdyA9IGF3YWl0IHJlZGlzLmdldCh0b2tlblJldm9jYXRpb25LZXkodXNlcklkKSk7XG4gICAgICAgIGlmIChyYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgfHwgcmF3LnRyaW0oKSA9PT0gJycpIHJldHVybiBudWxsO1xuICAgICAgICAvLyBTdHJpY3QgaW50ZWdlciBwYXJzZTogYE51bWJlcmAgKHVubGlrZSBgcGFyc2VJbnRgKSByZWplY3RzIHRyYWlsaW5nXG4gICAgICAgIC8vIGdhcmJhZ2UgKFwiNWFiY1wiIOKGkiBOYU4pLCBzbyBhIGNvcnJ1cHRlZCBlbnRyeSBmYWlscyBvcGVuIChudWxsIOKGkiBcIm5vdFxuICAgICAgICAvLyByZXZva2VkXCIpIHJhdGhlciB0aGFuIGJlaW5nIHJlYWQgYXMgYSBib2d1cyB2ZXJzaW9uLiBUaGUgZW1wdHktc3RyaW5nXG4gICAgICAgIC8vIGd1YXJkIGFib3ZlIG1hdHRlcnMgYmVjYXVzZSBgTnVtYmVyKCcnKWAgaXMgMCwgbm90IE5hTi5cbiAgICAgICAgY29uc3QgbiA9IE51bWJlcihyYXcpO1xuICAgICAgICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihuKSA/IG4gOiBudWxsO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIFJlZGlzIHdhcyByZWFjaGFibGUgZW5vdWdoIHRvIHRyeSBidXQgdGhlIHJlYWQgZXJyb3JlZCDigJQgdGhpcyBpcyBhXG4gICAgICAgIC8vIERFR1JBREFUSU9OOiB3aGlsZSBpdCBwZXJzaXN0cywgZm9yY2VkIGxvZ291dHMgLyBwcml2aWxlZ2UgcmV2b2NhdGlvbnNcbiAgICAgICAgLy8gc2lsZW50bHkgc3RvcCB0YWtpbmcgZWZmZWN0IHVudGlsIG5hdHVyYWwgdG9rZW4gZXhwaXJ5LiBFbWl0IGEgY291bnRlclxuICAgICAgICAvLyBzbyBgVG9rZW5SZXZvY2F0aW9uRmFpbGluZ09wZW5gIGNhbiBhbGVydCBvbiBhIFNVU1RBSU5FRCByYXRlIChtaXJyb3JzXG4gICAgICAgIC8vIHRoZSBxdW90YV9mYWlsX29wZW5fdG90YWwgcGF0dGVybikuIE5vdCBlbWl0dGVkIGZvciB0aGUgXCJSZWRpcyBub3RcbiAgICAgICAgLy8gY29uZmlndXJlZFwiIHBhdGggKGNyZWF0ZUVudlJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUg4oaSIG51bGwgY2xpZW50KSxcbiAgICAgICAgLy8gd2hpY2ggaXMgYSBkZWxpYmVyYXRlIG9wdC1vdXQsIG5vdCBhIGRlZ3JhZGF0aW9uLlxuICAgICAgICBlbWl0Q291bnRlcigndG9rZW5fcmV2b2NhdGlvbl9mYWlsX29wZW5fdG90YWwnLCB7IHJlYXNvbjogJ3JlYWQtZXJyb3InIH0pO1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Rva2VuLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKGZhaWwtb3BlbiknLCB7XG4gICAgICAgICAgdXNlcklkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5nZXQoc2Vzc2lvblJldm9jYXRpb25LZXkoanRpKSk7XG4gICAgICAgIHJldHVybiByYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgPyAnbGl2ZScgOiAncmV2b2tlZCc7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gTk9UIGZhaWwtb3BlbiwgdW5saWtlIGdldEN1cnJlbnRWZXJzaW9uIGFib3ZlOiBgdW5hdmFpbGFibGVgIHJlamVjdHNcbiAgICAgICAgLy8gdGhlIGltcGVyc29uYXRpb24gdG9rZW4uIENvdW50ZWQgc28gYSBzdXN0YWluZWQgb3V0YWdlIOKAlCB3aGljaCBzdG9wc1xuICAgICAgICAvLyBzdXBwb3J0IGltcGVyc29uYXRpb24gZXZlcnl3aGVyZSDigJQgaXMgdmlzaWJsZSBhbmQgYWxlcnRhYmxlLlxuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdyZWFkLWVycm9yJyB9KTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZXNzaW9uLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKHJlamVjdGluZyBpbXBlcnNvbmF0aW9uIHRva2VuKScsIHtcbiAgICAgICAgICBlcnJvcjogZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gJ3VuYXZhaWxhYmxlJztcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGEge0BsaW5rIFRva2VuUmV2b2NhdGlvblN0b3JlfSBiYWNrZWQgYnkgYSBSZWRpcyBjbGllbnQgdGhhdCBpcyBsYXppbHlcbiAqIGNvbnN0cnVjdGVkIGZyb20gdGhlIHN0YW5kYXJkIGBSRURJU19VUkxgIG9yIGBSRURJU19TRU5USU5FTFNgIGVudiDigJRcbiAqIGZvciBhIHN0YXRlbGVzcyBzZXJ2aWNlIHRoYXQga2VlcHMgTk8gUmVkaXMgY2xpZW50IG9mIGl0cyBvd24uIFRoZSBjbGllbnQgaXNcbiAqIGJ1aWx0IG9uIGZpcnN0IGBnZXRDdXJyZW50VmVyc2lvbmAgY2FsbCBhbmQgbWVtb2l6ZWQ7IGBpb3JlZGlzYCBpcyBsb2FkZWQgdmlhXG4gKiBhIGd1YXJkZWQgZHluYW1pYyByZXF1aXJlIHNvIG1lcmVseSBpbXBvcnRpbmcgdGhpcyBuZXZlciBicmVha3MgYSBidWlsZC90ZXN0XG4gKiB3aGVyZSBSZWRpcyBpc24ndCBwcmVzZW50LlxuICpcbiAqIEZVTExZIEZBSUwtT1BFTjogbm8gZW52IGNvbmZpZ3VyZWQsIGFuIGlvcmVkaXMgbG9hZCBmYWlsdXJlLCBhIGNvbm5lY3QgZXJyb3IsXG4gKiBvciBhbnkgcmVhZCBmYWlsdXJlIGFsbCByZXNvbHZlIHRvIGBudWxsYCAoXCJubyBrbm93biByZXZvY2F0aW9uXCIpLCBzbyBhXG4gKiBzZXJ2aWNlIGRlZ3JhZGVzIHRvIG5hdHVyYWwgdG9rZW4gZXhwaXJ5IHJhdGhlciB0aGFuIGxvY2tpbmcgdXNlcnMgb3V0LiBBXG4gKiBzZXJ2aWNlIG9wdHMgaW4gd2l0aCBhIHNpbmdsZSBib290IGxpbmU6XG4gKiAgIGBzZXRUb2tlblJldm9jYXRpb25TdG9yZShjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKCkpO2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVudlJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUoKTogVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICB0eXBlIFJlYWRlclJlZGlzID0gUmVkaXNDYWNoZUNsaWVudCAmIFJlYWR5QXdhcmVSZWRpcztcbiAgLy8gdW5kZWZpbmVkID0gbm90IHlldCBhdHRlbXB0ZWQ7IG51bGwgPSBhdHRlbXB0ZWQgYW5kIHVuYXZhaWxhYmxlIChzdGF5IG9mZikuXG4gIGxldCBjYWNoZWQ6IFJlYWRlclJlZGlzIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgbGV0IHJlYWR5OiAoKCkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSByZWFkZXIgY2xpZW50LCBidWlsdCBvbiBmaXJzdCB1c2UuIFRoZSBlbnYgY2xpZW50IGhhcyBubyBvZmZsaW5lIHF1ZXVlLFxuICAgKiBzbyBhIEdFVCBiZWZvcmUgdGhlIGZpcnN0IGNvbm5lY3Rpb24gY29tcGxldGVzIGlzIHJlamVjdGVkIOKAlCB3aGljaCBtYWRlIHRoZVxuICAgKiBGSVJTVCBpbXBlcnNvbmF0aW9uIGNoZWNrIG9uIGV2ZXJ5IHBvZCByZWFkICd1bmF2YWlsYWJsZScgKDQwMSkuIFdhaXRcbiAgICogKGJvdW5kZWQsIG5ldmVyIHJlamVjdGluZykgZm9yIHJlYWRpbmVzczsgYSBnZW51aW5lbHkgZG93biBSZWRpcyB0aGVuIGtlZXBzXG4gICAqIHRoZSBleGlzdGluZyBmYWlsLW9wZW4gLyAndW5hdmFpbGFibGUnIHNlbWFudGljcy5cbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGNsaWVudCgpOiBQcm9taXNlPFJlYWRlclJlZGlzIHwgbnVsbD4ge1xuICAgIGlmIChjYWNoZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gU2hhcmVkIGVudi1jb25maWd1cmVkIGlvcmVkaXMgY29uc3RydWN0aW9uIChlcnJvciBsaXN0ZW5lciBhdHRhY2hlZCwgbnVsbFxuICAgICAgLy8gd2hlbiBSZWRpcyBpc24ndCBjb25maWd1cmVkKTsgdGhlIHJlYWRlciBzdGF5cyBmYWlsLW9wZW4g4oCUIGEgbnVsbCBjbGllbnRcbiAgICAgIC8vIGp1c3QgZmFsbHMgYmFjayB0byBuYXR1cmFsIHRva2VuIGV4cGlyeS5cbiAgICAgIGNhY2hlZCA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PFJlYWRlclJlZGlzPigncmV2b2NhdGlvbi1yZWFkZXInKTtcbiAgICAgIGlmIChjYWNoZWQpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlZGlzIHRva2VuLXJldm9jYXRpb24gcmVhZGVyIGluaXRpYWxpemVkJyk7XG4gICAgICAgIHJlYWR5ID0gY3JlYXRlUmVkaXNSZWFkeUdhdGUoY2FjaGVkKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlYWR5KSBhd2FpdCByZWFkeSgpO1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldEN1cnJlbnRWZXJzaW9uKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBjb25zdCByZWRpcyA9IGF3YWl0IGNsaWVudCgpO1xuICAgICAgaWYgKCFyZWRpcykgcmV0dXJuIG51bGw7XG4gICAgICByZXR1cm4gY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZShyZWRpcykuZ2V0Q3VycmVudFZlcnNpb24odXNlcklkKTtcbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICBjb25zdCByZWRpcyA9IGF3YWl0IGNsaWVudCgpO1xuICAgICAgLy8gTm8gUmVkaXMgY29uZmlndXJlZCDih5IgdGhlcmUgaXMgbm8gd2F5IHRvIGxlYXJuIGEgc2Vzc2lvbiB3YXMgZW5kZWQsIHNvXG4gICAgICAvLyBhbiBpbXBlcnNvbmF0aW9uIHRva2VuIGNhbid0IGJlIHRydXN0ZWQuIEV2ZXJ5IHJlYWwgZGVwbG95bWVudCBydW5zIFJlZGlzXG4gICAgICAvLyAodGhlIGJ1aWxkIHF1ZXVlIG5lZWRzIGl0KSwgc28gdGhpcyBvbmx5IGJpdGVzIGEgbWlzY29uZmlndXJlZCBzZXJ2aWNlLlxuICAgICAgaWYgKCFyZWRpcykge1xuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdub3QtY29uZmlndXJlZCcgfSk7XG4gICAgICAgIHJldHVybiAndW5hdmFpbGFibGUnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXMpLmdldFNlc3Npb25SZXZvY2F0aW9uIShqdGkpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUHVibGlzaCBhIHVzZXIncyBjdXJyZW50IGB0b2tlblZlcnNpb25gIHNvIHRoZSBzdGF0ZWxlc3Mgc2VydmljZXMgc2VlIHRoZVxuICogcmV2b2NhdGlvbiBpbW1lZGlhdGVseSAocGxhdGZvcm0gc2lkZSkuIEJlc3QtZWZmb3J0IOKAlCBuZXZlciB0aHJvd3M7IGEgZmFpbHVyZVxuICoganVzdCBtZWFucyB0aGUgc2VydmljZXMgZmFsbCBiYWNrIHRvIG5hdHVyYWwgdG9rZW4gZXhwaXJ5IGZvciB0aGlzIGNoYW5nZS5cbiAqXG4gKiBUaGUga2V5IGlzIHdyaXR0ZW4gd2l0aCBhIFRUTCBlcXVhbCB0byB0aGUgYWNjZXNzLXRva2VuIGxpZmV0aW1lOiBhbnkgdG9rZW5cbiAqIHRoYXQgY291bGQgc3RpbGwgY2FycnkgYW4gb2xkZXIgdmVyc2lvbiBoYXMgZXhwaXJlZCBieSB0aGUgdGltZSB0aGUgZW50cnlcbiAqIGxhcHNlcywgc28gYW4gZXhwaXJlZCBlbnRyeSBjYW4gbmV2ZXIgY2F1c2UgYSBmYWxzZSBcInJldm9rZWRcIiBub3IgYSBtaXNzZWQgb25lLlxuICpcbiAqIEBwYXJhbSByZWRpcyAtIHRoZSBwbGF0Zm9ybSdzIFJlZGlzIGNsaWVudFxuICogQHBhcmFtIHVzZXJJZCAtIHRoZSB1c2VyIHdob3NlIHNlc3Npb25zIGNoYW5nZWRcbiAqIEBwYXJhbSB0b2tlblZlcnNpb24gLSB0aGUgdXNlcidzIE5FVyAocG9zdC1pbmNyZW1lbnQpIHRva2VuVmVyc2lvblxuICogQHBhcmFtIHR0bFNlY29uZHMgLSBhY2Nlc3MtdG9rZW4gbGlmZXRpbWUgaW4gc2Vjb25kc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVibGlzaFRva2VuUmV2b2NhdGlvbihcbiAgcmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQsXG4gIHVzZXJJZDogc3RyaW5nLFxuICB0b2tlblZlcnNpb246IG51bWJlcixcbiAgdHRsU2Vjb25kczogbnVtYmVyLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgLy8gaW9yZWRpcy1zdHlsZSB2YXJpYWRpYyBTRVQgd2l0aCBleHBpcnk6IFNFVCBrZXkgdmFsIEVYIHR0bC5cbiAgICBhd2FpdCByZWRpcy5zZXQodG9rZW5SZXZvY2F0aW9uS2V5KHVzZXJJZCksIFN0cmluZyh0b2tlblZlcnNpb24pLCAnRVgnLCBNYXRoLm1heCgxLCBNYXRoLmZsb29yKHR0bFNlY29uZHMpKSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdUb2tlbi1yZXZvY2F0aW9uIHB1Ymxpc2ggZmFpbGVkIChzZXJ2aWNlcyBmYWxsIGJhY2sgdG8gdG9rZW4gZXhwaXJ5KScsIHtcbiAgICAgIHVzZXJJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogUHVibGlzaCB0aGF0IG9uZSBJTVBFUlNPTkFUSU9OIHNlc3Npb24gaGFzIGVuZGVkLCBzbyBldmVyeSBzdGF0ZWxlc3Mgc2VydmljZVxuICogcmVqZWN0cyBpdHMgdG9rZW4gb24gdGhlIG5leHQgcmVxdWVzdCAocGxhdGZvcm0gc2lkZSkuXG4gKlxuICogUmV0dXJucyB3aGV0aGVyIHRoZSBwdWJsaXNoIGxhbmRlZCDigJQgdW5saWtlIGBwdWJsaXNoVG9rZW5SZXZvY2F0aW9uYCwgd2hpY2ggaXNcbiAqIGZpcmUtYW5kLWZvcmdldC4gVGhlIGNhbGxlciBtdXN0IGJlIGFibGUgdG8gdGVsbCB0aGUgcGVyc29uIHdobyBlbmRlZCB0aGVcbiAqIHNlc3Npb24gdGhhdCBpdCBkaWQgTk9UIGVuZCBldmVyeXdoZXJlLCByYXRoZXIgdGhhbiByZXBvcnRpbmcgc3VjY2VzcyB3aGlsZVxuICogdGhlIHRva2VuIHN0aWxsIHdvcmtzIGFnYWluc3Qgb3RoZXIgc2VydmljZXMuXG4gKlxuICogVGhlIGVudHJ5IGV4cGlyZXMgd2l0aCB0aGUgc2Vzc2lvbjogb25jZSB0aGUgdG9rZW4gaXRzZWxmIGNhbiBubyBsb25nZXIgYmVcbiAqIHVzZWQsIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCB0byByZXZva2UsIHNvIHRoZSBrZXkgY2xlYW5zIGl0c2VsZiB1cC5cbiAqXG4gKiBAcGFyYW0gdHRsTXMgLSB0aW1lIHJlbWFpbmluZyBvbiB0aGUgc2Vzc2lvbidzIHRva2VuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwdWJsaXNoU2Vzc2lvblJldm9jYXRpb24oXG4gIHJlZGlzOiBSZWRpc0NhY2hlQ2xpZW50LFxuICBqdGk6IHN0cmluZyxcbiAgdHRsTXM6IG51bWJlcixcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGF3YWl0IHJlZGlzLnNldChzZXNzaW9uUmV2b2NhdGlvbktleShqdGkpLCAnMScsICdQWCcsIE1hdGgubWF4KDEwMDAsIE1hdGguY2VpbCh0dGxNcykpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1Nlc3Npb24tcmV2b2NhdGlvbiBwdWJsaXNoIGZhaWxlZCAob3RoZXIgc2VydmljZXMgd2lsbCBob25vdXIgdGhlIHRva2VuIHVudGlsIGl0IGV4cGlyZXMpJywge1xuICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared `@pipeline-builder/api-core` mock factory for ESM suites.
|
|
3
|
+
*
|
|
4
|
+
* WHY: every project kept its own `test/helpers/mock-api-core.ts` — twelve forks
|
|
5
|
+
* of the same ~150-line file, ranging from 23 to 61 overridden keys against an
|
|
6
|
+
* api-core barrel exporting ~357 symbols. Each fork re-declared the same logger
|
|
7
|
+
* stub, the same `ErrorCode` proxy, the same error classes and the same
|
|
8
|
+
* service-gate re-implementations, and each drifted independently.
|
|
9
|
+
*
|
|
10
|
+
* THE FIX: the shared parts live here, once. A project's helper keeps ONLY the
|
|
11
|
+
* defaults that are genuinely project-specific (its tier fixtures, its compliance
|
|
12
|
+
* client, its response helpers) and layers them on top:
|
|
13
|
+
*
|
|
14
|
+
* const actualApiCore = jest.requireActual('@pipeline-builder/api-core') as Record<string, unknown>;
|
|
15
|
+
* export function apiCoreMock(overrides: Record<string, unknown> = {}) {
|
|
16
|
+
* return baseApiCoreMock(actualApiCore, { ...projectDefaults, ...overrides });
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* Both this module and the per-project helpers start from `requireActual`, so an
|
|
20
|
+
* export ADDED to api-core is inherited automatically and can never again break a
|
|
21
|
+
* suite with "does not provide an export named X".
|
|
22
|
+
*
|
|
23
|
+
* WHY IT LIVES IN api-core: the deep path
|
|
24
|
+
* `@pipeline-builder/api-core/lib/testing/mock-api-core.js` is a different
|
|
25
|
+
* specifier from the `@pipeline-builder/api-core` barrel, so a suite's module
|
|
26
|
+
* mock does NOT intercept it — the factory can therefore read the real module
|
|
27
|
+
* without recursing into its own mock. Same trick as `tier-mock.ts`.
|
|
28
|
+
*/
|
|
29
|
+
import { jest } from '@jest/globals';
|
|
30
|
+
/** Minimal Express-ish shapes the gate/response stubs below touch. */
|
|
31
|
+
type MockRes = {
|
|
32
|
+
status: (n: number) => {
|
|
33
|
+
json: (b: unknown) => unknown;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
type Next = () => void;
|
|
37
|
+
/** A bare `jest.fn()`, named so the emitted `.d.ts` stays portable (TS2883). */
|
|
38
|
+
type MockFn = ReturnType<typeof jest.fn>;
|
|
39
|
+
/** The winston double every suite asserts on: four spies, nothing else. */
|
|
40
|
+
export interface MockLogger {
|
|
41
|
+
info: MockFn;
|
|
42
|
+
warn: MockFn;
|
|
43
|
+
error: MockFn;
|
|
44
|
+
debug: MockFn;
|
|
45
|
+
}
|
|
46
|
+
/** The 4-method winston stub every suite repeats; a fresh set of spies per call. */
|
|
47
|
+
export declare const loggerMock: () => MockLogger;
|
|
48
|
+
/** Mirrors api-core: `ErrorCode.ANY_CODE` resolves to the string `'ANY_CODE'`. */
|
|
49
|
+
export declare const mockErrorCode: Record<string, string>;
|
|
50
|
+
/** No-op guard: the default mock covers route wiring, not the permission gate. */
|
|
51
|
+
export declare const passThroughMiddleware: (_req: unknown, _res: unknown, next: Next) => void;
|
|
52
|
+
/** Mirrors api-core's `AppError` base (typed HTTP error: statusCode + code). */
|
|
53
|
+
export declare class MockAppError extends Error {
|
|
54
|
+
readonly statusCode: number;
|
|
55
|
+
readonly code: string;
|
|
56
|
+
constructor(statusCode: number, code: string, message?: string);
|
|
57
|
+
}
|
|
58
|
+
/** Mirrors api-core's NotFoundError (404 / NOT_FOUND). */
|
|
59
|
+
export declare class MockNotFoundError extends MockAppError {
|
|
60
|
+
constructor(message?: string);
|
|
61
|
+
}
|
|
62
|
+
/** Mirrors api-core's ConflictError (409 / CONFLICT). */
|
|
63
|
+
export declare class MockConflictError extends MockAppError {
|
|
64
|
+
constructor(message?: string);
|
|
65
|
+
}
|
|
66
|
+
/** Mirrors api-core's ForbiddenError (403 / INSUFFICIENT_PERMISSIONS). */
|
|
67
|
+
export declare class MockForbiddenError extends MockAppError {
|
|
68
|
+
constructor(message?: string);
|
|
69
|
+
}
|
|
70
|
+
/** Mirrors api-core's ValidationError (400 / VALIDATION_ERROR). */
|
|
71
|
+
export declare class MockValidationError extends MockAppError {
|
|
72
|
+
constructor(message?: string);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Capability-aware stand-in for api-core's `requirePermission` /
|
|
76
|
+
* `requireAllPermissions` gate factories. Mirrors the real gate's decision (minus
|
|
77
|
+
* the denial-audit side effect): superadmin passes, otherwise the caller must
|
|
78
|
+
* hold the permission(s); a miss is a 403 with the real message shape.
|
|
79
|
+
*
|
|
80
|
+
* `onAnonymous` picks what happens when there is no `req.user` at all: `'pass'`
|
|
81
|
+
* (suites with no auth layer mounted) or `'401'` (suites that drive the gate).
|
|
82
|
+
* `shape` picks the denial envelope the project's suites assert on.
|
|
83
|
+
*/
|
|
84
|
+
export declare function mockPermissionGate(options?: {
|
|
85
|
+
mode?: 'some' | 'every';
|
|
86
|
+
allowService?: boolean;
|
|
87
|
+
onAnonymous?: 'pass' | '401';
|
|
88
|
+
shape?: 'error' | 'message';
|
|
89
|
+
}): (...permissions: string[]) => (req: {
|
|
90
|
+
user?: {
|
|
91
|
+
isSuperAdmin?: boolean;
|
|
92
|
+
permissions?: string[];
|
|
93
|
+
sub?: string;
|
|
94
|
+
};
|
|
95
|
+
}, res: MockRes, next: Next) => unknown;
|
|
96
|
+
/**
|
|
97
|
+
* The defaults shared by every service / package mock: the logger stub, the
|
|
98
|
+
* pagination constants, the inert scheduler / leader-lock / redis-audit wiring a
|
|
99
|
+
* boot module links at load, and the error + cache shapes. A project layers its
|
|
100
|
+
* own defaults on top by passing them in `overrides`.
|
|
101
|
+
*/
|
|
102
|
+
export declare function serviceApiCoreDefaults(): Record<string, unknown>;
|
|
103
|
+
/**
|
|
104
|
+
* The audit / security wiring a service's boot module (`src/index.ts`,
|
|
105
|
+
* `src/services/audit.ts`) links at load time. Inert by default: nothing asserts
|
|
106
|
+
* on the registration, and pulling the real graph in would drag Redis + HTTP
|
|
107
|
+
* clients into every route suite.
|
|
108
|
+
*/
|
|
109
|
+
export declare function serviceAuditDefaults(): Record<string, unknown>;
|
|
110
|
+
/**
|
|
111
|
+
* Build an api-core mock namespace: REAL api-core, then the shared service
|
|
112
|
+
* defaults, then `overrides` (a project's own defaults merged with the suite's).
|
|
113
|
+
*
|
|
114
|
+
* `actualApiCore` is supplied by the CALLER (`jest.requireActual(...)` at the top
|
|
115
|
+
* of the project's `test/helpers/mock-api-core.ts`) rather than resolved here.
|
|
116
|
+
* That is deliberate: `requireActual` on an ESM barrel only succeeds at a moment
|
|
117
|
+
* when nothing else is mid-`import()` of it, and the project helper — a static
|
|
118
|
+
* import of the test file, evaluated before any `await import(SUT)` — is the one
|
|
119
|
+
* point where that always holds. Resolving it from inside this module (which
|
|
120
|
+
* lives in the api-core package itself) races that import in some suites.
|
|
121
|
+
*/
|
|
122
|
+
export declare function baseApiCoreMock(actualApiCore: Record<string, unknown>, overrides?: Record<string, unknown>): Record<string, unknown>;
|
|
123
|
+
/**
|
|
124
|
+
* Build an api-core mock namespace with NO service defaults — REAL api-core plus
|
|
125
|
+
* the logger stub and `ErrorCode` proxy only. Platform uses this: it deliberately
|
|
126
|
+
* keeps api-core's real pagination/report constants and supplies its own
|
|
127
|
+
* (large) identity/tier/permission default set.
|
|
128
|
+
*/
|
|
129
|
+
export declare function primitiveApiCoreMock(actualApiCore: Record<string, unknown>, overrides?: Record<string, unknown>): Record<string, unknown>;
|
|
130
|
+
/**
|
|
131
|
+
* Mirror api-core's `requireInternalService({ callers })`: refuse any user token,
|
|
132
|
+
* then refuse a service whose name is not in the route's caller list. Resolved
|
|
133
|
+
* from the MERGED mock (rather than inherited from `requireActual`) so it uses
|
|
134
|
+
* the suite's `isServicePrincipal` / `serviceNameOf` / `sendError`, which the real
|
|
135
|
+
* one closes over and would write past.
|
|
136
|
+
*/
|
|
137
|
+
export declare function withInternalServiceGate(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
|
|
138
|
+
/**
|
|
139
|
+
* Mirror api-core's `requireServicePrincipal`: reject a non-service caller with a
|
|
140
|
+
* 403 INSUFFICIENT_PERMISSIONS (an authorization refusal, not a 400), resolving
|
|
141
|
+
* `isServicePrincipal` / `sendError` from the merged mock.
|
|
142
|
+
*/
|
|
143
|
+
export declare function withServicePrincipalGate(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
|
|
144
|
+
/**
|
|
145
|
+
* `sendBadRequest` delegating to the (possibly-overridden) `sendError`, mirroring
|
|
146
|
+
* the real implementation — so a suite spying on `sendError` also observes the
|
|
147
|
+
* 400s routed through `sendBadRequest`.
|
|
148
|
+
*/
|
|
149
|
+
export declare function withDelegatingSendBadRequest(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
|
|
150
|
+
export {};
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Shared `@pipeline-builder/api-core` mock factory for ESM suites.
|
|
5
|
+
*
|
|
6
|
+
* WHY: every project kept its own `test/helpers/mock-api-core.ts` — twelve forks
|
|
7
|
+
* of the same ~150-line file, ranging from 23 to 61 overridden keys against an
|
|
8
|
+
* api-core barrel exporting ~357 symbols. Each fork re-declared the same logger
|
|
9
|
+
* stub, the same `ErrorCode` proxy, the same error classes and the same
|
|
10
|
+
* service-gate re-implementations, and each drifted independently.
|
|
11
|
+
*
|
|
12
|
+
* THE FIX: the shared parts live here, once. A project's helper keeps ONLY the
|
|
13
|
+
* defaults that are genuinely project-specific (its tier fixtures, its compliance
|
|
14
|
+
* client, its response helpers) and layers them on top:
|
|
15
|
+
*
|
|
16
|
+
* const actualApiCore = jest.requireActual('@pipeline-builder/api-core') as Record<string, unknown>;
|
|
17
|
+
* export function apiCoreMock(overrides: Record<string, unknown> = {}) {
|
|
18
|
+
* return baseApiCoreMock(actualApiCore, { ...projectDefaults, ...overrides });
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* Both this module and the per-project helpers start from `requireActual`, so an
|
|
22
|
+
* export ADDED to api-core is inherited automatically and can never again break a
|
|
23
|
+
* suite with "does not provide an export named X".
|
|
24
|
+
*
|
|
25
|
+
* WHY IT LIVES IN api-core: the deep path
|
|
26
|
+
* `@pipeline-builder/api-core/lib/testing/mock-api-core.js` is a different
|
|
27
|
+
* specifier from the `@pipeline-builder/api-core` barrel, so a suite's module
|
|
28
|
+
* mock does NOT intercept it — the factory can therefore read the real module
|
|
29
|
+
* without recursing into its own mock. Same trick as `tier-mock.ts`.
|
|
30
|
+
*/
|
|
31
|
+
import { jest } from '@jest/globals';
|
|
32
|
+
/** The 4-method winston stub every suite repeats; a fresh set of spies per call. */
|
|
33
|
+
export const loggerMock = () => ({
|
|
34
|
+
info: jest.fn(),
|
|
35
|
+
warn: jest.fn(),
|
|
36
|
+
error: jest.fn(),
|
|
37
|
+
debug: jest.fn(),
|
|
38
|
+
});
|
|
39
|
+
/** Mirrors api-core: `ErrorCode.ANY_CODE` resolves to the string `'ANY_CODE'`. */
|
|
40
|
+
export const mockErrorCode = new Proxy({}, { get: (_t, key) => key });
|
|
41
|
+
/** No-op guard: the default mock covers route wiring, not the permission gate. */
|
|
42
|
+
export const passThroughMiddleware = (_req, _res, next) => next();
|
|
43
|
+
/** Mirrors api-core's `AppError` base (typed HTTP error: statusCode + code). */
|
|
44
|
+
export class MockAppError extends Error {
|
|
45
|
+
statusCode;
|
|
46
|
+
code;
|
|
47
|
+
constructor(statusCode, code, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.statusCode = statusCode;
|
|
50
|
+
this.code = code;
|
|
51
|
+
this.name = 'AppError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Mirrors api-core's NotFoundError (404 / NOT_FOUND). */
|
|
55
|
+
export class MockNotFoundError extends MockAppError {
|
|
56
|
+
constructor(message) {
|
|
57
|
+
super(404, 'NOT_FOUND', message);
|
|
58
|
+
this.name = 'NotFoundError';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Mirrors api-core's ConflictError (409 / CONFLICT). */
|
|
62
|
+
export class MockConflictError extends MockAppError {
|
|
63
|
+
constructor(message) {
|
|
64
|
+
super(409, 'CONFLICT', message);
|
|
65
|
+
this.name = 'ConflictError';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Mirrors api-core's ForbiddenError (403 / INSUFFICIENT_PERMISSIONS). */
|
|
69
|
+
export class MockForbiddenError extends MockAppError {
|
|
70
|
+
constructor(message) {
|
|
71
|
+
super(403, 'INSUFFICIENT_PERMISSIONS', message);
|
|
72
|
+
this.name = 'ForbiddenError';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Mirrors api-core's ValidationError (400 / VALIDATION_ERROR). */
|
|
76
|
+
export class MockValidationError extends MockAppError {
|
|
77
|
+
constructor(message) {
|
|
78
|
+
super(400, 'VALIDATION_ERROR', message);
|
|
79
|
+
this.name = 'ValidationError';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Capability-aware stand-in for api-core's `requirePermission` /
|
|
84
|
+
* `requireAllPermissions` gate factories. Mirrors the real gate's decision (minus
|
|
85
|
+
* the denial-audit side effect): superadmin passes, otherwise the caller must
|
|
86
|
+
* hold the permission(s); a miss is a 403 with the real message shape.
|
|
87
|
+
*
|
|
88
|
+
* `onAnonymous` picks what happens when there is no `req.user` at all: `'pass'`
|
|
89
|
+
* (suites with no auth layer mounted) or `'401'` (suites that drive the gate).
|
|
90
|
+
* `shape` picks the denial envelope the project's suites assert on.
|
|
91
|
+
*/
|
|
92
|
+
export function mockPermissionGate(options = {}) {
|
|
93
|
+
const { mode = 'some', allowService = false, onAnonymous = 'pass', shape = 'message' } = options;
|
|
94
|
+
const joiner = mode === 'some' ? ' or ' : ' and ';
|
|
95
|
+
const deny = (msg) => (shape === 'error' ? { error: msg } : { success: false, message: msg });
|
|
96
|
+
return (...permissions) => {
|
|
97
|
+
const gate = (req, res, next) => {
|
|
98
|
+
const user = req?.user;
|
|
99
|
+
if (!user)
|
|
100
|
+
return onAnonymous === 'pass' ? next() : res.status(401).json({ error: 'Authentication required' });
|
|
101
|
+
if (allowService && typeof user.sub === 'string' && user.sub.startsWith('service:'))
|
|
102
|
+
return next();
|
|
103
|
+
if (user.isSuperAdmin === true)
|
|
104
|
+
return next();
|
|
105
|
+
const held = Array.isArray(user.permissions) ? user.permissions : [];
|
|
106
|
+
const ok = mode === 'some' ? permissions.some((p) => held.includes(p)) : permissions.every((p) => held.includes(p));
|
|
107
|
+
if (ok)
|
|
108
|
+
return next();
|
|
109
|
+
return res.status(403).json(deny(`Missing required permission: ${permissions.join(joiner)}`));
|
|
110
|
+
};
|
|
111
|
+
// Tags let a wiring suite locate the gate layer in a router stack and assert
|
|
112
|
+
// which flavour was mounted.
|
|
113
|
+
gate.__permission = permissions.join(joiner);
|
|
114
|
+
gate.__allowService = allowService;
|
|
115
|
+
return gate;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The defaults shared by every service / package mock: the logger stub, the
|
|
120
|
+
* pagination constants, the inert scheduler / leader-lock / redis-audit wiring a
|
|
121
|
+
* boot module links at load, and the error + cache shapes. A project layers its
|
|
122
|
+
* own defaults on top by passing them in `overrides`.
|
|
123
|
+
*/
|
|
124
|
+
export function serviceApiCoreDefaults() {
|
|
125
|
+
return {
|
|
126
|
+
createLogger: loggerMock,
|
|
127
|
+
MAX_PAGE_LIMIT: 1000,
|
|
128
|
+
DEFAULT_PAGE_LIMIT: 100,
|
|
129
|
+
closeLeaderLock: async () => undefined,
|
|
130
|
+
loadAndRestore: async () => null,
|
|
131
|
+
REPORT_INTERVALS: ['day', 'week', 'month'],
|
|
132
|
+
scrubAwsIdentifiersFromString: (s) => s,
|
|
133
|
+
scrubAwsIdentifiers: (v) => v,
|
|
134
|
+
createScheduler: () => ({ start: () => undefined, stop: () => undefined }),
|
|
135
|
+
createEnvRedisLock: () => null,
|
|
136
|
+
requireStepUp: (_req, _res, next) => next(),
|
|
137
|
+
SYSTEM_ORG_ID: '000000000000000000000001',
|
|
138
|
+
ComputeType: { SMALL: 'SMALL', MEDIUM: 'MEDIUM', LARGE: 'LARGE', X2_LARGE: 'X2_LARGE' },
|
|
139
|
+
PluginType: { CODE_BUILD_STEP: 'CodeBuildStep', SHELL_STEP: 'ShellStep', MANUAL_APPROVAL_STEP: 'ManualApprovalStep' },
|
|
140
|
+
ErrorCode: mockErrorCode,
|
|
141
|
+
errorMessage: (e) => (e instanceof Error ? e.message : String(e)),
|
|
142
|
+
NotFoundError: MockNotFoundError,
|
|
143
|
+
createCacheService: () => ({
|
|
144
|
+
getOrSet: (_key, factory) => factory(),
|
|
145
|
+
invalidatePattern: () => Promise.resolve(0),
|
|
146
|
+
}),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The audit / security wiring a service's boot module (`src/index.ts`,
|
|
151
|
+
* `src/services/audit.ts`) links at load time. Inert by default: nothing asserts
|
|
152
|
+
* on the registration, and pulling the real graph in would drag Redis + HTTP
|
|
153
|
+
* clients into every route suite.
|
|
154
|
+
*/
|
|
155
|
+
export function serviceAuditDefaults() {
|
|
156
|
+
return {
|
|
157
|
+
createRemoteAuditClient: () => ({ record: jest.fn() }),
|
|
158
|
+
createEnvRedisAuditSpool: () => null,
|
|
159
|
+
createServiceAuditClient: () => ({ emit: jest.fn(), client: { record: jest.fn() } }),
|
|
160
|
+
createRemoteAuditAccessor: () => ({ getAuditClient: () => ({ record: jest.fn() }), emit: jest.fn() }),
|
|
161
|
+
setAuthzDenialAuditor: () => { },
|
|
162
|
+
wireAuthzDenialAuditor: () => { },
|
|
163
|
+
wireServiceSecurity: () => { },
|
|
164
|
+
setTokenRevocationStore: () => { },
|
|
165
|
+
createRedisTokenRevocationStore: () => ({ getCurrentVersion: async () => null }),
|
|
166
|
+
createEnvRedisTokenRevocationStore: () => ({ getCurrentVersion: async () => null }),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Build an api-core mock namespace: REAL api-core, then the shared service
|
|
171
|
+
* defaults, then `overrides` (a project's own defaults merged with the suite's).
|
|
172
|
+
*
|
|
173
|
+
* `actualApiCore` is supplied by the CALLER (`jest.requireActual(...)` at the top
|
|
174
|
+
* of the project's `test/helpers/mock-api-core.ts`) rather than resolved here.
|
|
175
|
+
* That is deliberate: `requireActual` on an ESM barrel only succeeds at a moment
|
|
176
|
+
* when nothing else is mid-`import()` of it, and the project helper — a static
|
|
177
|
+
* import of the test file, evaluated before any `await import(SUT)` — is the one
|
|
178
|
+
* point where that always holds. Resolving it from inside this module (which
|
|
179
|
+
* lives in the api-core package itself) races that import in some suites.
|
|
180
|
+
*/
|
|
181
|
+
export function baseApiCoreMock(actualApiCore, overrides = {}) {
|
|
182
|
+
return { ...actualApiCore, ...serviceApiCoreDefaults(), ...overrides };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Build an api-core mock namespace with NO service defaults — REAL api-core plus
|
|
186
|
+
* the logger stub and `ErrorCode` proxy only. Platform uses this: it deliberately
|
|
187
|
+
* keeps api-core's real pagination/report constants and supplies its own
|
|
188
|
+
* (large) identity/tier/permission default set.
|
|
189
|
+
*/
|
|
190
|
+
export function primitiveApiCoreMock(actualApiCore, overrides = {}) {
|
|
191
|
+
return { ...actualApiCore, createLogger: loggerMock, ErrorCode: mockErrorCode, ...overrides };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Mirror api-core's `requireInternalService({ callers })`: refuse any user token,
|
|
195
|
+
* then refuse a service whose name is not in the route's caller list. Resolved
|
|
196
|
+
* from the MERGED mock (rather than inherited from `requireActual`) so it uses
|
|
197
|
+
* the suite's `isServicePrincipal` / `serviceNameOf` / `sendError`, which the real
|
|
198
|
+
* one closes over and would write past.
|
|
199
|
+
*/
|
|
200
|
+
export function withInternalServiceGate(mock, overrides) {
|
|
201
|
+
if (overrides.requireInternalService !== undefined)
|
|
202
|
+
return mock;
|
|
203
|
+
mock.requireInternalService = ({ callers }) => (req, res, next) => {
|
|
204
|
+
const isSvc = mock.isServicePrincipal;
|
|
205
|
+
const nameOf = mock.serviceNameOf;
|
|
206
|
+
const caller = nameOf?.(req.user);
|
|
207
|
+
if (isSvc?.(req) && caller && callers.includes(caller)) {
|
|
208
|
+
next();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const sendError = mock.sendError;
|
|
212
|
+
sendError(res, 403, 'Internal service calls only', 'INSUFFICIENT_PERMISSIONS');
|
|
213
|
+
};
|
|
214
|
+
return mock;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Mirror api-core's `requireServicePrincipal`: reject a non-service caller with a
|
|
218
|
+
* 403 INSUFFICIENT_PERMISSIONS (an authorization refusal, not a 400), resolving
|
|
219
|
+
* `isServicePrincipal` / `sendError` from the merged mock.
|
|
220
|
+
*/
|
|
221
|
+
export function withServicePrincipalGate(mock, overrides) {
|
|
222
|
+
if (overrides.requireServicePrincipal !== undefined)
|
|
223
|
+
return mock;
|
|
224
|
+
mock.requireServicePrincipal = (req, res, next) => {
|
|
225
|
+
const isSvc = mock.isServicePrincipal;
|
|
226
|
+
if (isSvc?.(req)) {
|
|
227
|
+
next();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const sendError = mock.sendError;
|
|
231
|
+
sendError(res, 403, 'Internal service calls only', 'INSUFFICIENT_PERMISSIONS');
|
|
232
|
+
};
|
|
233
|
+
return mock;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* `sendBadRequest` delegating to the (possibly-overridden) `sendError`, mirroring
|
|
237
|
+
* the real implementation — so a suite spying on `sendError` also observes the
|
|
238
|
+
* 400s routed through `sendBadRequest`.
|
|
239
|
+
*/
|
|
240
|
+
export function withDelegatingSendBadRequest(mock, overrides) {
|
|
241
|
+
if ('sendBadRequest' in overrides)
|
|
242
|
+
return mock;
|
|
243
|
+
mock.sendBadRequest = (res, message, code) => mock.sendError(res, 400, message, code ?? mockErrorCode.VALIDATION_ERROR);
|
|
244
|
+
return mock;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1hcGktY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL21vY2stYXBpLWNvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBRUgsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQWlCckMsb0ZBQW9GO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxHQUFlLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO0lBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7SUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtJQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtDQUNqQixDQUFDLENBQUM7QUFFSCxrRkFBa0Y7QUFDbEYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUEyQixDQUFDO0FBRWhHLGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLElBQWEsRUFBRSxJQUFhLEVBQUUsSUFBVSxFQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUVoRyxnRkFBZ0Y7QUFDaEYsTUFBTSxPQUFPLFlBQWEsU0FBUSxLQUFLO0lBQ1QsVUFBVTtJQUEwQixJQUFJO0lBQXBFLFlBQTRCLFVBQWtCLEVBQWtCLElBQVksRUFBRSxPQUFnQjtRQUM1RixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7MEJBRFcsVUFBVTtvQkFBMEIsSUFBSTtRQUVsRSxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztJQUN6QixDQUFDO0NBQ0Y7QUFFRCwwREFBMEQ7QUFDMUQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLFlBQVk7SUFDakQsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsSUFBSSxHQUFHLGVBQWUsQ0FBQztJQUM5QixDQUFDO0NBQ0Y7QUFFRCx5REFBeUQ7QUFDekQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLFlBQVk7SUFDakQsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsSUFBSSxHQUFHLGVBQWUsQ0FBQztJQUM5QixDQUFDO0NBQ0Y7QUFFRCwwRUFBMEU7QUFDMUUsTUFBTSxPQUFPLGtCQUFtQixTQUFRLFlBQVk7SUFDbEQsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENBQUMsR0FBRyxFQUFFLDBCQUEwQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCLENBQUM7SUFDL0IsQ0FBQztDQUNGO0FBRUQsbUVBQW1FO0FBQ25FLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxZQUFZO0lBQ25ELFlBQVksT0FBZ0I7UUFDMUIsS0FBSyxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDO0lBQ2hDLENBQUM7Q0FDRjtBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxPQUFPLEdBS3RDLEVBQUU7SUFDSixNQUFNLEVBQUUsSUFBSSxHQUFHLE1BQU0sRUFBRSxZQUFZLEdBQUcsS0FBSyxFQUFFLFdBQVcsR0FBRyxNQUFNLEVBQUUsS0FBSyxHQUFHLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUNqRyxNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztJQUNsRCxNQUFNLElBQUksR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ3RHLE9BQU8sQ0FBQyxHQUFHLFdBQXFCLEVBQUUsRUFBRTtRQUNsQyxNQUFNLElBQUksR0FBRyxDQUFDLEdBQWdGLEVBQUUsR0FBWSxFQUFFLElBQVUsRUFBVyxFQUFFO1lBQ25JLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUM7WUFDdkIsSUFBSSxDQUFDLElBQUk7Z0JBQUUsT0FBTyxXQUFXLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUseUJBQXlCLEVBQUUsQ0FBQyxDQUFDO1lBQy9HLElBQUksWUFBWSxJQUFJLE9BQU8sSUFBSSxDQUFDLEdBQUcsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO2dCQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDbkcsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUk7Z0JBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUM5QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3JFLE1BQU0sRUFBRSxHQUFHLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BILElBQUksRUFBRTtnQkFBRSxPQUFPLElBQUksRUFBRSxDQUFDO1lBQ3RCLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLENBQUMsQ0FBQztRQUNGLDZFQUE2RTtRQUM3RSw2QkFBNkI7UUFDNUIsSUFBMkMsQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwRixJQUEyQyxDQUFDLGNBQWMsR0FBRyxZQUFZLENBQUM7UUFDM0UsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsc0JBQXNCO0lBQ3BDLE9BQU87UUFDTCxZQUFZLEVBQUUsVUFBVTtRQUN4QixjQUFjLEVBQUUsSUFBSTtRQUNwQixrQkFBa0IsRUFBRSxHQUFHO1FBQ3ZCLGVBQWUsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLFNBQVM7UUFDdEMsY0FBYyxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsSUFBSTtRQUNoQyxnQkFBZ0IsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDO1FBQzFDLDZCQUE2QixFQUFFLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9DLG1CQUFtQixFQUFFLENBQUksQ0FBSSxFQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLGVBQWUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDMUUsa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSTtRQUM5QixhQUFhLEVBQUUsQ0FBQyxJQUFhLEVBQUUsSUFBYSxFQUFFLElBQVUsRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQ25FLGFBQWEsRUFBRSwwQkFBMEI7UUFDekMsV0FBVyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRTtRQUN2RixVQUFVLEVBQUUsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUU7UUFDckgsU0FBUyxFQUFFLGFBQWE7UUFDeEIsWUFBWSxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRSxhQUFhLEVBQUUsaUJBQWlCO1FBQ2hDLGtCQUFrQixFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDekIsUUFBUSxFQUFFLENBQUMsSUFBWSxFQUFFLE9BQStCLEVBQUUsRUFBRSxDQUFDLE9BQU8sRUFBRTtZQUN0RSxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUM1QyxDQUFDO0tBQ0gsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMsT0FBTztRQUNMLHVCQUF1QixFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDdEQsd0JBQXdCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSTtRQUNwQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRix5QkFBeUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDckcscUJBQXFCLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztRQUMvQixzQkFBc0IsRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO1FBQ2hDLG1CQUFtQixFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7UUFDN0IsdUJBQXVCLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztRQUNqQywrQkFBK0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoRixrQ0FBa0MsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztLQUNwRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsYUFBc0MsRUFDdEMsU0FBUyxHQUE0QixFQUFFO0lBRXZDLE9BQU8sRUFBRSxHQUFHLGFBQWEsRUFBRSxHQUFHLHNCQUFzQixFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQztBQUN6RSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLGFBQXNDLEVBQ3RDLFNBQVMsR0FBNEIsRUFBRTtJQUV2QyxPQUFPLEVBQUUsR0FBRyxhQUFhLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEdBQUcsU0FBUyxFQUFFLENBQUM7QUFDaEcsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxJQUE2QixFQUFFLFNBQWtDO0lBQ3ZHLElBQUksU0FBUyxDQUFDLHNCQUFzQixLQUFLLFNBQVM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNoRSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBa0MsRUFBRSxFQUFFLENBQzVFLENBQUMsR0FBWSxFQUFFLEdBQVksRUFBRSxJQUFVLEVBQUUsRUFBRTtRQUN6QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsa0JBQTJELENBQUM7UUFDL0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWlFLENBQUM7UUFDdEYsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUUsR0FBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxRCxJQUFJLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLE1BQU0sSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdkQsSUFBSSxFQUFFLENBQUM7WUFDUCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFxRSxDQUFDO1FBQzdGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLDZCQUE2QixFQUFFLDBCQUEwQixDQUFDLENBQUM7SUFDakYsQ0FBQyxDQUFDO0lBQ0osT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxJQUE2QixFQUFFLFNBQWtDO0lBQ3hHLElBQUksU0FBUyxDQUFDLHVCQUF1QixLQUFLLFNBQVM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxHQUFZLEVBQUUsR0FBWSxFQUFFLElBQVUsRUFBRSxFQUFFO1FBQ3hFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxrQkFBMkQsQ0FBQztRQUMvRSxJQUFJLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDakIsSUFBSSxFQUFFLENBQUM7WUFDUCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFxRSxDQUFDO1FBQzdGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLDZCQUE2QixFQUFFLDBCQUEwQixDQUFDLENBQUM7SUFDakYsQ0FBQyxDQUFDO0lBQ0YsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxJQUE2QixFQUFFLFNBQWtDO0lBQzVHLElBQUksZ0JBQWdCLElBQUksU0FBUztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9DLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxHQUFZLEVBQUUsT0FBZSxFQUFFLElBQWEsRUFBRSxFQUFFLENBQ3BFLElBQUksQ0FBQyxTQUF1RSxDQUMzRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLElBQUksYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDL0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogU2hhcmVkIGBAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZWAgbW9jayBmYWN0b3J5IGZvciBFU00gc3VpdGVzLlxuICpcbiAqIFdIWTogZXZlcnkgcHJvamVjdCBrZXB0IGl0cyBvd24gYHRlc3QvaGVscGVycy9tb2NrLWFwaS1jb3JlLnRzYCDigJQgdHdlbHZlIGZvcmtzXG4gKiBvZiB0aGUgc2FtZSB+MTUwLWxpbmUgZmlsZSwgcmFuZ2luZyBmcm9tIDIzIHRvIDYxIG92ZXJyaWRkZW4ga2V5cyBhZ2FpbnN0IGFuXG4gKiBhcGktY29yZSBiYXJyZWwgZXhwb3J0aW5nIH4zNTcgc3ltYm9scy4gRWFjaCBmb3JrIHJlLWRlY2xhcmVkIHRoZSBzYW1lIGxvZ2dlclxuICogc3R1YiwgdGhlIHNhbWUgYEVycm9yQ29kZWAgcHJveHksIHRoZSBzYW1lIGVycm9yIGNsYXNzZXMgYW5kIHRoZSBzYW1lXG4gKiBzZXJ2aWNlLWdhdGUgcmUtaW1wbGVtZW50YXRpb25zLCBhbmQgZWFjaCBkcmlmdGVkIGluZGVwZW5kZW50bHkuXG4gKlxuICogVEhFIEZJWDogdGhlIHNoYXJlZCBwYXJ0cyBsaXZlIGhlcmUsIG9uY2UuIEEgcHJvamVjdCdzIGhlbHBlciBrZWVwcyBPTkxZIHRoZVxuICogZGVmYXVsdHMgdGhhdCBhcmUgZ2VudWluZWx5IHByb2plY3Qtc3BlY2lmaWMgKGl0cyB0aWVyIGZpeHR1cmVzLCBpdHMgY29tcGxpYW5jZVxuICogY2xpZW50LCBpdHMgcmVzcG9uc2UgaGVscGVycykgYW5kIGxheWVycyB0aGVtIG9uIHRvcDpcbiAqXG4gKiAgIGNvbnN0IGFjdHVhbEFwaUNvcmUgPSBqZXN0LnJlcXVpcmVBY3R1YWwoJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJykgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gKiAgIGV4cG9ydCBmdW5jdGlvbiBhcGlDb3JlTW9jayhvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30pIHtcbiAqICAgICByZXR1cm4gYmFzZUFwaUNvcmVNb2NrKGFjdHVhbEFwaUNvcmUsIHsgLi4ucHJvamVjdERlZmF1bHRzLCAuLi5vdmVycmlkZXMgfSk7XG4gKiAgIH1cbiAqXG4gKiBCb3RoIHRoaXMgbW9kdWxlIGFuZCB0aGUgcGVyLXByb2plY3QgaGVscGVycyBzdGFydCBmcm9tIGByZXF1aXJlQWN0dWFsYCwgc28gYW5cbiAqIGV4cG9ydCBBRERFRCB0byBhcGktY29yZSBpcyBpbmhlcml0ZWQgYXV0b21hdGljYWxseSBhbmQgY2FuIG5ldmVyIGFnYWluIGJyZWFrIGFcbiAqIHN1aXRlIHdpdGggXCJkb2VzIG5vdCBwcm92aWRlIGFuIGV4cG9ydCBuYW1lZCBYXCIuXG4gKlxuICogV0hZIElUIExJVkVTIElOIGFwaS1jb3JlOiB0aGUgZGVlcCBwYXRoXG4gKiBgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUvbGliL3Rlc3RpbmcvbW9jay1hcGktY29yZS5qc2AgaXMgYSBkaWZmZXJlbnRcbiAqIHNwZWNpZmllciBmcm9tIHRoZSBgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmVgIGJhcnJlbCwgc28gYSBzdWl0ZSdzIG1vZHVsZVxuICogbW9jayBkb2VzIE5PVCBpbnRlcmNlcHQgaXQg4oCUIHRoZSBmYWN0b3J5IGNhbiB0aGVyZWZvcmUgcmVhZCB0aGUgcmVhbCBtb2R1bGVcbiAqIHdpdGhvdXQgcmVjdXJzaW5nIGludG8gaXRzIG93biBtb2NrLiBTYW1lIHRyaWNrIGFzIGB0aWVyLW1vY2sudHNgLlxuICovXG5cbmltcG9ydCB7IGplc3QgfSBmcm9tICdAamVzdC9nbG9iYWxzJztcblxuLyoqIE1pbmltYWwgRXhwcmVzcy1pc2ggc2hhcGVzIHRoZSBnYXRlL3Jlc3BvbnNlIHN0dWJzIGJlbG93IHRvdWNoLiAqL1xudHlwZSBNb2NrUmVzID0geyBzdGF0dXM6IChuOiBudW1iZXIpID0+IHsganNvbjogKGI6IHVua25vd24pID0+IHVua25vd24gfSB9O1xudHlwZSBOZXh0ID0gKCkgPT4gdm9pZDtcblxuLyoqIEEgYmFyZSBgamVzdC5mbigpYCwgbmFtZWQgc28gdGhlIGVtaXR0ZWQgYC5kLnRzYCBzdGF5cyBwb3J0YWJsZSAoVFMyODgzKS4gKi9cbnR5cGUgTW9ja0ZuID0gUmV0dXJuVHlwZTx0eXBlb2YgamVzdC5mbj47XG5cbi8qKiBUaGUgd2luc3RvbiBkb3VibGUgZXZlcnkgc3VpdGUgYXNzZXJ0cyBvbjogZm91ciBzcGllcywgbm90aGluZyBlbHNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2NrTG9nZ2VyIHtcbiAgaW5mbzogTW9ja0ZuO1xuICB3YXJuOiBNb2NrRm47XG4gIGVycm9yOiBNb2NrRm47XG4gIGRlYnVnOiBNb2NrRm47XG59XG5cbi8qKiBUaGUgNC1tZXRob2Qgd2luc3RvbiBzdHViIGV2ZXJ5IHN1aXRlIHJlcGVhdHM7IGEgZnJlc2ggc2V0IG9mIHNwaWVzIHBlciBjYWxsLiAqL1xuZXhwb3J0IGNvbnN0IGxvZ2dlck1vY2sgPSAoKTogTW9ja0xvZ2dlciA9PiAoe1xuICBpbmZvOiBqZXN0LmZuKCksXG4gIHdhcm46IGplc3QuZm4oKSxcbiAgZXJyb3I6IGplc3QuZm4oKSxcbiAgZGVidWc6IGplc3QuZm4oKSxcbn0pO1xuXG4vKiogTWlycm9ycyBhcGktY29yZTogYEVycm9yQ29kZS5BTllfQ09ERWAgcmVzb2x2ZXMgdG8gdGhlIHN0cmluZyBgJ0FOWV9DT0RFJ2AuICovXG5leHBvcnQgY29uc3QgbW9ja0Vycm9yQ29kZSA9IG5ldyBQcm94eSh7fSwgeyBnZXQ6IChfdCwga2V5KSA9PiBrZXkgfSkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuLyoqIE5vLW9wIGd1YXJkOiB0aGUgZGVmYXVsdCBtb2NrIGNvdmVycyByb3V0ZSB3aXJpbmcsIG5vdCB0aGUgcGVybWlzc2lvbiBnYXRlLiAqL1xuZXhwb3J0IGNvbnN0IHBhc3NUaHJvdWdoTWlkZGxld2FyZSA9IChfcmVxOiB1bmtub3duLCBfcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KTogdm9pZCA9PiBuZXh0KCk7XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgYEFwcEVycm9yYCBiYXNlICh0eXBlZCBIVFRQIGVycm9yOiBzdGF0dXNDb2RlICsgY29kZSkuICovXG5leHBvcnQgY2xhc3MgTW9ja0FwcEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgc3RhdHVzQ29kZTogbnVtYmVyLCBwdWJsaWMgcmVhZG9ubHkgY29kZTogc3RyaW5nLCBtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ0FwcEVycm9yJztcbiAgfVxufVxuXG4vKiogTWlycm9ycyBhcGktY29yZSdzIE5vdEZvdW5kRXJyb3IgKDQwNCAvIE5PVF9GT1VORCkuICovXG5leHBvcnQgY2xhc3MgTW9ja05vdEZvdW5kRXJyb3IgZXh0ZW5kcyBNb2NrQXBwRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoNDA0LCAnTk9UX0ZPVU5EJywgbWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ05vdEZvdW5kRXJyb3InO1xuICB9XG59XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgQ29uZmxpY3RFcnJvciAoNDA5IC8gQ09ORkxJQ1QpLiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tDb25mbGljdEVycm9yIGV4dGVuZHMgTW9ja0FwcEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZT86IHN0cmluZykge1xuICAgIHN1cGVyKDQwOSwgJ0NPTkZMSUNUJywgbWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ0NvbmZsaWN0RXJyb3InO1xuICB9XG59XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgRm9yYmlkZGVuRXJyb3IgKDQwMyAvIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUykuICovXG5leHBvcnQgY2xhc3MgTW9ja0ZvcmJpZGRlbkVycm9yIGV4dGVuZHMgTW9ja0FwcEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZT86IHN0cmluZykge1xuICAgIHN1cGVyKDQwMywgJ0lOU1VGRklDSUVOVF9QRVJNSVNTSU9OUycsIG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdGb3JiaWRkZW5FcnJvcic7XG4gIH1cbn1cblxuLyoqIE1pcnJvcnMgYXBpLWNvcmUncyBWYWxpZGF0aW9uRXJyb3IgKDQwMCAvIFZBTElEQVRJT05fRVJST1IpLiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBNb2NrQXBwRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoNDAwLCAnVkFMSURBVElPTl9FUlJPUicsIG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdWYWxpZGF0aW9uRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogQ2FwYWJpbGl0eS1hd2FyZSBzdGFuZC1pbiBmb3IgYXBpLWNvcmUncyBgcmVxdWlyZVBlcm1pc3Npb25gIC9cbiAqIGByZXF1aXJlQWxsUGVybWlzc2lvbnNgIGdhdGUgZmFjdG9yaWVzLiBNaXJyb3JzIHRoZSByZWFsIGdhdGUncyBkZWNpc2lvbiAobWludXNcbiAqIHRoZSBkZW5pYWwtYXVkaXQgc2lkZSBlZmZlY3QpOiBzdXBlcmFkbWluIHBhc3Nlcywgb3RoZXJ3aXNlIHRoZSBjYWxsZXIgbXVzdFxuICogaG9sZCB0aGUgcGVybWlzc2lvbihzKTsgYSBtaXNzIGlzIGEgNDAzIHdpdGggdGhlIHJlYWwgbWVzc2FnZSBzaGFwZS5cbiAqXG4gKiBgb25Bbm9ueW1vdXNgIHBpY2tzIHdoYXQgaGFwcGVucyB3aGVuIHRoZXJlIGlzIG5vIGByZXEudXNlcmAgYXQgYWxsOiBgJ3Bhc3MnYFxuICogKHN1aXRlcyB3aXRoIG5vIGF1dGggbGF5ZXIgbW91bnRlZCkgb3IgYCc0MDEnYCAoc3VpdGVzIHRoYXQgZHJpdmUgdGhlIGdhdGUpLlxuICogYHNoYXBlYCBwaWNrcyB0aGUgZGVuaWFsIGVudmVsb3BlIHRoZSBwcm9qZWN0J3Mgc3VpdGVzIGFzc2VydCBvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vY2tQZXJtaXNzaW9uR2F0ZShvcHRpb25zOiB7XG4gIG1vZGU/OiAnc29tZScgfCAnZXZlcnknO1xuICBhbGxvd1NlcnZpY2U/OiBib29sZWFuO1xuICBvbkFub255bW91cz86ICdwYXNzJyB8ICc0MDEnO1xuICBzaGFwZT86ICdlcnJvcicgfCAnbWVzc2FnZSc7XG59ID0ge30pIHtcbiAgY29uc3QgeyBtb2RlID0gJ3NvbWUnLCBhbGxvd1NlcnZpY2UgPSBmYWxzZSwgb25Bbm9ueW1vdXMgPSAncGFzcycsIHNoYXBlID0gJ21lc3NhZ2UnIH0gPSBvcHRpb25zO1xuICBjb25zdCBqb2luZXIgPSBtb2RlID09PSAnc29tZScgPyAnIG9yICcgOiAnIGFuZCAnO1xuICBjb25zdCBkZW55ID0gKG1zZzogc3RyaW5nKSA9PiAoc2hhcGUgPT09ICdlcnJvcicgPyB7IGVycm9yOiBtc2cgfSA6IHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IG1zZyB9KTtcbiAgcmV0dXJuICguLi5wZXJtaXNzaW9uczogc3RyaW5nW10pID0+IHtcbiAgICBjb25zdCBnYXRlID0gKHJlcTogeyB1c2VyPzogeyBpc1N1cGVyQWRtaW4/OiBib29sZWFuOyBwZXJtaXNzaW9ucz86IHN0cmluZ1tdOyBzdWI/OiBzdHJpbmcgfSB9LCByZXM6IE1vY2tSZXMsIG5leHQ6IE5leHQpOiB1bmtub3duID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSByZXE/LnVzZXI7XG4gICAgICBpZiAoIXVzZXIpIHJldHVybiBvbkFub255bW91cyA9PT0gJ3Bhc3MnID8gbmV4dCgpIDogcmVzLnN0YXR1cyg0MDEpLmpzb24oeyBlcnJvcjogJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJyB9KTtcbiAgICAgIGlmIChhbGxvd1NlcnZpY2UgJiYgdHlwZW9mIHVzZXIuc3ViID09PSAnc3RyaW5nJyAmJiB1c2VyLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gbmV4dCgpO1xuICAgICAgaWYgKHVzZXIuaXNTdXBlckFkbWluID09PSB0cnVlKSByZXR1cm4gbmV4dCgpO1xuICAgICAgY29uc3QgaGVsZCA9IEFycmF5LmlzQXJyYXkodXNlci5wZXJtaXNzaW9ucykgPyB1c2VyLnBlcm1pc3Npb25zIDogW107XG4gICAgICBjb25zdCBvayA9IG1vZGUgPT09ICdzb21lJyA/IHBlcm1pc3Npb25zLnNvbWUoKHApID0+IGhlbGQuaW5jbHVkZXMocCkpIDogcGVybWlzc2lvbnMuZXZlcnkoKHApID0+IGhlbGQuaW5jbHVkZXMocCkpO1xuICAgICAgaWYgKG9rKSByZXR1cm4gbmV4dCgpO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAzKS5qc29uKGRlbnkoYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKGpvaW5lcil9YCkpO1xuICAgIH07XG4gICAgLy8gVGFncyBsZXQgYSB3aXJpbmcgc3VpdGUgbG9jYXRlIHRoZSBnYXRlIGxheWVyIGluIGEgcm91dGVyIHN0YWNrIGFuZCBhc3NlcnRcbiAgICAvLyB3aGljaCBmbGF2b3VyIHdhcyBtb3VudGVkLlxuICAgIChnYXRlIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLl9fcGVybWlzc2lvbiA9IHBlcm1pc3Npb25zLmpvaW4oam9pbmVyKTtcbiAgICAoZ2F0ZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5fX2FsbG93U2VydmljZSA9IGFsbG93U2VydmljZTtcbiAgICByZXR1cm4gZ2F0ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdHMgc2hhcmVkIGJ5IGV2ZXJ5IHNlcnZpY2UgLyBwYWNrYWdlIG1vY2s6IHRoZSBsb2dnZXIgc3R1YiwgdGhlXG4gKiBwYWdpbmF0aW9uIGNvbnN0YW50cywgdGhlIGluZXJ0IHNjaGVkdWxlciAvIGxlYWRlci1sb2NrIC8gcmVkaXMtYXVkaXQgd2lyaW5nIGFcbiAqIGJvb3QgbW9kdWxlIGxpbmtzIGF0IGxvYWQsIGFuZCB0aGUgZXJyb3IgKyBjYWNoZSBzaGFwZXMuIEEgcHJvamVjdCBsYXllcnMgaXRzXG4gKiBvd24gZGVmYXVsdHMgb24gdG9wIGJ5IHBhc3NpbmcgdGhlbSBpbiBgb3ZlcnJpZGVzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcnZpY2VBcGlDb3JlRGVmYXVsdHMoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4ge1xuICAgIGNyZWF0ZUxvZ2dlcjogbG9nZ2VyTW9jayxcbiAgICBNQVhfUEFHRV9MSU1JVDogMTAwMCxcbiAgICBERUZBVUxUX1BBR0VfTElNSVQ6IDEwMCxcbiAgICBjbG9zZUxlYWRlckxvY2s6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICBsb2FkQW5kUmVzdG9yZTogYXN5bmMgKCkgPT4gbnVsbCxcbiAgICBSRVBPUlRfSU5URVJWQUxTOiBbJ2RheScsICd3ZWVrJywgJ21vbnRoJ10sXG4gICAgc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmc6IChzOiBzdHJpbmcpID0+IHMsXG4gICAgc2NydWJBd3NJZGVudGlmaWVyczogPFQ+KHY6IFQpOiBUID0+IHYsXG4gICAgY3JlYXRlU2NoZWR1bGVyOiAoKSA9PiAoeyBzdGFydDogKCkgPT4gdW5kZWZpbmVkLCBzdG9wOiAoKSA9PiB1bmRlZmluZWQgfSksXG4gICAgY3JlYXRlRW52UmVkaXNMb2NrOiAoKSA9PiBudWxsLFxuICAgIHJlcXVpcmVTdGVwVXA6IChfcmVxOiB1bmtub3duLCBfcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KSA9PiBuZXh0KCksXG4gICAgU1lTVEVNX09SR19JRDogJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScsXG4gICAgQ29tcHV0ZVR5cGU6IHsgU01BTEw6ICdTTUFMTCcsIE1FRElVTTogJ01FRElVTScsIExBUkdFOiAnTEFSR0UnLCBYMl9MQVJHRTogJ1gyX0xBUkdFJyB9LFxuICAgIFBsdWdpblR5cGU6IHsgQ09ERV9CVUlMRF9TVEVQOiAnQ29kZUJ1aWxkU3RlcCcsIFNIRUxMX1NURVA6ICdTaGVsbFN0ZXAnLCBNQU5VQUxfQVBQUk9WQUxfU1RFUDogJ01hbnVhbEFwcHJvdmFsU3RlcCcgfSxcbiAgICBFcnJvckNvZGU6IG1vY2tFcnJvckNvZGUsXG4gICAgZXJyb3JNZXNzYWdlOiAoZTogdW5rbm93bikgPT4gKGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKSksXG4gICAgTm90Rm91bmRFcnJvcjogTW9ja05vdEZvdW5kRXJyb3IsXG4gICAgY3JlYXRlQ2FjaGVTZXJ2aWNlOiAoKSA9PiAoe1xuICAgICAgZ2V0T3JTZXQ6IChfa2V5OiBzdHJpbmcsIGZhY3Rvcnk6ICgpID0+IFByb21pc2U8dW5rbm93bj4pID0+IGZhY3RvcnkoKSxcbiAgICAgIGludmFsaWRhdGVQYXR0ZXJuOiAoKSA9PiBQcm9taXNlLnJlc29sdmUoMCksXG4gICAgfSksXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGF1ZGl0IC8gc2VjdXJpdHkgd2lyaW5nIGEgc2VydmljZSdzIGJvb3QgbW9kdWxlIChgc3JjL2luZGV4LnRzYCxcbiAqIGBzcmMvc2VydmljZXMvYXVkaXQudHNgKSBsaW5rcyBhdCBsb2FkIHRpbWUuIEluZXJ0IGJ5IGRlZmF1bHQ6IG5vdGhpbmcgYXNzZXJ0c1xuICogb24gdGhlIHJlZ2lzdHJhdGlvbiwgYW5kIHB1bGxpbmcgdGhlIHJlYWwgZ3JhcGggaW4gd291bGQgZHJhZyBSZWRpcyArIEhUVFBcbiAqIGNsaWVudHMgaW50byBldmVyeSByb3V0ZSBzdWl0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcnZpY2VBdWRpdERlZmF1bHRzKCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHtcbiAgICBjcmVhdGVSZW1vdGVBdWRpdENsaWVudDogKCkgPT4gKHsgcmVjb3JkOiBqZXN0LmZuKCkgfSksXG4gICAgY3JlYXRlRW52UmVkaXNBdWRpdFNwb29sOiAoKSA9PiBudWxsLFxuICAgIGNyZWF0ZVNlcnZpY2VBdWRpdENsaWVudDogKCkgPT4gKHsgZW1pdDogamVzdC5mbigpLCBjbGllbnQ6IHsgcmVjb3JkOiBqZXN0LmZuKCkgfSB9KSxcbiAgICBjcmVhdGVSZW1vdGVBdWRpdEFjY2Vzc29yOiAoKSA9PiAoeyBnZXRBdWRpdENsaWVudDogKCkgPT4gKHsgcmVjb3JkOiBqZXN0LmZuKCkgfSksIGVtaXQ6IGplc3QuZm4oKSB9KSxcbiAgICBzZXRBdXRoekRlbmlhbEF1ZGl0b3I6ICgpID0+IHt9LFxuICAgIHdpcmVBdXRoekRlbmlhbEF1ZGl0b3I6ICgpID0+IHt9LFxuICAgIHdpcmVTZXJ2aWNlU2VjdXJpdHk6ICgpID0+IHt9LFxuICAgIHNldFRva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiB7fSxcbiAgICBjcmVhdGVSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiAoeyBnZXRDdXJyZW50VmVyc2lvbjogYXN5bmMgKCkgPT4gbnVsbCB9KSxcbiAgICBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiAoeyBnZXRDdXJyZW50VmVyc2lvbjogYXN5bmMgKCkgPT4gbnVsbCB9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBhcGktY29yZSBtb2NrIG5hbWVzcGFjZTogUkVBTCBhcGktY29yZSwgdGhlbiB0aGUgc2hhcmVkIHNlcnZpY2VcbiAqIGRlZmF1bHRzLCB0aGVuIGBvdmVycmlkZXNgIChhIHByb2plY3QncyBvd24gZGVmYXVsdHMgbWVyZ2VkIHdpdGggdGhlIHN1aXRlJ3MpLlxuICpcbiAqIGBhY3R1YWxBcGlDb3JlYCBpcyBzdXBwbGllZCBieSB0aGUgQ0FMTEVSIChgamVzdC5yZXF1aXJlQWN0dWFsKC4uLilgIGF0IHRoZSB0b3BcbiAqIG9mIHRoZSBwcm9qZWN0J3MgYHRlc3QvaGVscGVycy9tb2NrLWFwaS1jb3JlLnRzYCkgcmF0aGVyIHRoYW4gcmVzb2x2ZWQgaGVyZS5cbiAqIFRoYXQgaXMgZGVsaWJlcmF0ZTogYHJlcXVpcmVBY3R1YWxgIG9uIGFuIEVTTSBiYXJyZWwgb25seSBzdWNjZWVkcyBhdCBhIG1vbWVudFxuICogd2hlbiBub3RoaW5nIGVsc2UgaXMgbWlkLWBpbXBvcnQoKWAgb2YgaXQsIGFuZCB0aGUgcHJvamVjdCBoZWxwZXIg4oCUIGEgc3RhdGljXG4gKiBpbXBvcnQgb2YgdGhlIHRlc3QgZmlsZSwgZXZhbHVhdGVkIGJlZm9yZSBhbnkgYGF3YWl0IGltcG9ydChTVVQpYCDigJQgaXMgdGhlIG9uZVxuICogcG9pbnQgd2hlcmUgdGhhdCBhbHdheXMgaG9sZHMuIFJlc29sdmluZyBpdCBmcm9tIGluc2lkZSB0aGlzIG1vZHVsZSAod2hpY2hcbiAqIGxpdmVzIGluIHRoZSBhcGktY29yZSBwYWNrYWdlIGl0c2VsZikgcmFjZXMgdGhhdCBpbXBvcnQgaW4gc29tZSBzdWl0ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlQXBpQ29yZU1vY2soXG4gIGFjdHVhbEFwaUNvcmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB7IC4uLmFjdHVhbEFwaUNvcmUsIC4uLnNlcnZpY2VBcGlDb3JlRGVmYXVsdHMoKSwgLi4ub3ZlcnJpZGVzIH07XG59XG5cbi8qKlxuICogQnVpbGQgYW4gYXBpLWNvcmUgbW9jayBuYW1lc3BhY2Ugd2l0aCBOTyBzZXJ2aWNlIGRlZmF1bHRzIOKAlCBSRUFMIGFwaS1jb3JlIHBsdXNcbiAqIHRoZSBsb2dnZXIgc3R1YiBhbmQgYEVycm9yQ29kZWAgcHJveHkgb25seS4gUGxhdGZvcm0gdXNlcyB0aGlzOiBpdCBkZWxpYmVyYXRlbHlcbiAqIGtlZXBzIGFwaS1jb3JlJ3MgcmVhbCBwYWdpbmF0aW9uL3JlcG9ydCBjb25zdGFudHMgYW5kIHN1cHBsaWVzIGl0cyBvd25cbiAqIChsYXJnZSkgaWRlbnRpdHkvdGllci9wZXJtaXNzaW9uIGRlZmF1bHQgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJpbWl0aXZlQXBpQ29yZU1vY2soXG4gIGFjdHVhbEFwaUNvcmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB7IC4uLmFjdHVhbEFwaUNvcmUsIGNyZWF0ZUxvZ2dlcjogbG9nZ2VyTW9jaywgRXJyb3JDb2RlOiBtb2NrRXJyb3JDb2RlLCAuLi5vdmVycmlkZXMgfTtcbn1cblxuLyoqXG4gKiBNaXJyb3IgYXBpLWNvcmUncyBgcmVxdWlyZUludGVybmFsU2VydmljZSh7IGNhbGxlcnMgfSlgOiByZWZ1c2UgYW55IHVzZXIgdG9rZW4sXG4gKiB0aGVuIHJlZnVzZSBhIHNlcnZpY2Ugd2hvc2UgbmFtZSBpcyBub3QgaW4gdGhlIHJvdXRlJ3MgY2FsbGVyIGxpc3QuIFJlc29sdmVkXG4gKiBmcm9tIHRoZSBNRVJHRUQgbW9jayAocmF0aGVyIHRoYW4gaW5oZXJpdGVkIGZyb20gYHJlcXVpcmVBY3R1YWxgKSBzbyBpdCB1c2VzXG4gKiB0aGUgc3VpdGUncyBgaXNTZXJ2aWNlUHJpbmNpcGFsYCAvIGBzZXJ2aWNlTmFtZU9mYCAvIGBzZW5kRXJyb3JgLCB3aGljaCB0aGUgcmVhbFxuICogb25lIGNsb3NlcyBvdmVyIGFuZCB3b3VsZCB3cml0ZSBwYXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEludGVybmFsU2VydmljZUdhdGUobW9jazogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChvdmVycmlkZXMucmVxdWlyZUludGVybmFsU2VydmljZSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gbW9jaztcbiAgbW9jay5yZXF1aXJlSW50ZXJuYWxTZXJ2aWNlID0gKHsgY2FsbGVycyB9OiB7IGNhbGxlcnM6IHJlYWRvbmx5IHN0cmluZ1tdIH0pID0+XG4gICAgKHJlcTogdW5rbm93biwgcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KSA9PiB7XG4gICAgICBjb25zdCBpc1N2YyA9IG1vY2suaXNTZXJ2aWNlUHJpbmNpcGFsIGFzICgocjogdW5rbm93bikgPT4gYm9vbGVhbikgfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBuYW1lT2YgPSBtb2NrLnNlcnZpY2VOYW1lT2YgYXMgKChjOiB1bmtub3duKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQpIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY2FsbGVyID0gbmFtZU9mPy4oKHJlcSBhcyB7IHVzZXI/OiB1bmtub3duIH0pLnVzZXIpO1xuICAgICAgaWYgKGlzU3ZjPy4ocmVxKSAmJiBjYWxsZXIgJiYgY2FsbGVycy5pbmNsdWRlcyhjYWxsZXIpKSB7XG4gICAgICAgIG5leHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2VuZEVycm9yID0gbW9jay5zZW5kRXJyb3IgYXMgKHI6IHVua25vd24sIHM6IG51bWJlciwgbTogc3RyaW5nLCBjOiBzdHJpbmcpID0+IHVua25vd247XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCAnSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TJyk7XG4gICAgfTtcbiAgcmV0dXJuIG1vY2s7XG59XG5cbi8qKlxuICogTWlycm9yIGFwaS1jb3JlJ3MgYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYDogcmVqZWN0IGEgbm9uLXNlcnZpY2UgY2FsbGVyIHdpdGggYVxuICogNDAzIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyAoYW4gYXV0aG9yaXphdGlvbiByZWZ1c2FsLCBub3QgYSA0MDApLCByZXNvbHZpbmdcbiAqIGBpc1NlcnZpY2VQcmluY2lwYWxgIC8gYHNlbmRFcnJvcmAgZnJvbSB0aGUgbWVyZ2VkIG1vY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoU2VydmljZVByaW5jaXBhbEdhdGUobW9jazogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChvdmVycmlkZXMucmVxdWlyZVNlcnZpY2VQcmluY2lwYWwgIT09IHVuZGVmaW5lZCkgcmV0dXJuIG1vY2s7XG4gIG1vY2sucmVxdWlyZVNlcnZpY2VQcmluY2lwYWwgPSAocmVxOiB1bmtub3duLCByZXM6IHVua25vd24sIG5leHQ6IE5leHQpID0+IHtcbiAgICBjb25zdCBpc1N2YyA9IG1vY2suaXNTZXJ2aWNlUHJpbmNpcGFsIGFzICgocjogdW5rbm93bikgPT4gYm9vbGVhbikgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGlzU3ZjPy4ocmVxKSkge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZW5kRXJyb3IgPSBtb2NrLnNlbmRFcnJvciBhcyAocjogdW5rbm93biwgczogbnVtYmVyLCBtOiBzdHJpbmcsIGM6IHN0cmluZykgPT4gdW5rbm93bjtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCAnSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TJyk7XG4gIH07XG4gIHJldHVybiBtb2NrO1xufVxuXG4vKipcbiAqIGBzZW5kQmFkUmVxdWVzdGAgZGVsZWdhdGluZyB0byB0aGUgKHBvc3NpYmx5LW92ZXJyaWRkZW4pIGBzZW5kRXJyb3JgLCBtaXJyb3JpbmdcbiAqIHRoZSByZWFsIGltcGxlbWVudGF0aW9uIOKAlCBzbyBhIHN1aXRlIHNweWluZyBvbiBgc2VuZEVycm9yYCBhbHNvIG9ic2VydmVzIHRoZVxuICogNDAwcyByb3V0ZWQgdGhyb3VnaCBgc2VuZEJhZFJlcXVlc3RgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aERlbGVnYXRpbmdTZW5kQmFkUmVxdWVzdChtb2NrOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgb3ZlcnJpZGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgaWYgKCdzZW5kQmFkUmVxdWVzdCcgaW4gb3ZlcnJpZGVzKSByZXR1cm4gbW9jaztcbiAgbW9jay5zZW5kQmFkUmVxdWVzdCA9IChyZXM6IHVua25vd24sIG1lc3NhZ2U6IHN0cmluZywgY29kZT86IHN0cmluZykgPT5cbiAgICAobW9jay5zZW5kRXJyb3IgYXMgKHI6IHVua25vd24sIHM6IG51bWJlciwgbTogc3RyaW5nLCBjPzogc3RyaW5nKSA9PiB1bmtub3duKShcbiAgICAgIHJlcywgNDAwLCBtZXNzYWdlLCBjb2RlID8/IG1vY2tFcnJvckNvZGUuVkFMSURBVElPTl9FUlJPUik7XG4gIHJldHVybiBtb2NrO1xufVxuIl19
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a `drizzle-orm` mock namespace: every real export, with `overrides`
|
|
3
|
+
* spread last so a suite can swap an operator for an inspectable stub (or a
|
|
4
|
+
* `jest.fn()` it asserts on) without having to enumerate the rest.
|
|
5
|
+
*/
|
|
6
|
+
export declare function drizzleMock(overrides?: Record<string, unknown>): Record<string, unknown>;
|