@pipeline-builder/api-core 3.4.95 → 3.4.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/constants/ai-providers.d.ts +0 -7
  2. package/lib/constants/ai-providers.js +1 -10
  3. package/lib/helpers/access-helpers.d.ts +2 -1
  4. package/lib/helpers/access-helpers.js +11 -5
  5. package/lib/helpers/org-hierarchy-http.d.ts +13 -3
  6. package/lib/helpers/org-hierarchy-http.js +10 -5
  7. package/lib/index.d.ts +4 -4
  8. package/lib/index.js +5 -5
  9. package/lib/middleware/auth.d.ts +16 -5
  10. package/lib/middleware/auth.js +17 -7
  11. package/lib/services/audit-spool.d.ts +4 -5
  12. package/lib/services/audit-spool.js +10 -27
  13. package/lib/services/cache-service.js +11 -10
  14. package/lib/services/env-redis.d.ts +20 -0
  15. package/lib/services/env-redis.js +47 -0
  16. package/lib/services/leader-lock.d.ts +10 -0
  17. package/lib/services/leader-lock.js +19 -1
  18. package/lib/services/quota.js +14 -5
  19. package/lib/services/remote-audit-client.d.ts +19 -1
  20. package/lib/services/remote-audit-client.js +41 -1
  21. package/lib/services/scheduler.js +15 -1
  22. package/lib/services/token-revocation.js +8 -30
  23. package/lib/types/common.d.ts +0 -20
  24. package/lib/types/common.js +1 -26
  25. package/lib/types/feature-flags.d.ts +1 -14
  26. package/lib/types/feature-flags.js +6 -16
  27. package/lib/utils/identity.d.ts +0 -21
  28. package/lib/utils/identity.js +1 -30
  29. package/lib/utils/index.d.ts +0 -1
  30. package/lib/utils/index.js +1 -2
  31. package/lib/utils/params.d.ts +0 -19
  32. package/lib/utils/params.js +1 -35
  33. package/lib/utils/response.d.ts +0 -38
  34. package/lib/utils/response.js +1 -41
  35. package/lib/validation/middleware.d.ts +2 -6
  36. package/lib/validation/middleware.js +3 -9
  37. package/package.json +1 -1
  38. package/lib/utils/org-aws-credentials.d.ts +0 -154
  39. package/lib/utils/org-aws-credentials.js +0 -139
@@ -1,139 +0,0 @@
1
- // Copyright 2026 Pipeline Builder Contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
- /**
4
- * Per-process manager that resolves and caches per-org credential providers.
5
- * One instance per service; share it across handlers.
6
- */
7
- export class OrgAwsCredentialsManager {
8
- resolver;
9
- fallbackOverride;
10
- region;
11
- endpoint;
12
- cache = new Map();
13
- inFlight = new Map();
14
- /** Lazy default chain. Built once per manager so we don't import the
15
- * credential-providers SDK in test environments that never touch the
16
- * fallback path. */
17
- fallbackCache;
18
- constructor(opts) {
19
- this.resolver = opts.resolver;
20
- this.fallbackOverride = opts.fallback;
21
- this.region = opts.region ?? process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION;
22
- this.endpoint = opts.endpoint ?? process.env.AWS_STS_ENDPOINT;
23
- }
24
- /**
25
- * Return an AwsCredentialIdentityProvider scoped to `orgId`. Pass the
26
- * returned value into any SDK v3 client's `credentials` option.
27
- *
28
- * Concurrent first-touch callers share one resolver invocation; later
29
- * calls hit the cache. The provider itself caches and refreshes
30
- * AssumeRole-derived credentials internally.
31
- */
32
- async getCredentials(orgId) {
33
- if (!orgId)
34
- throw new Error('OrgAwsCredentialsManager.getCredentials requires a non-empty orgId');
35
- const cached = this.cache.get(orgId);
36
- if (cached)
37
- return cached;
38
- let pending = this.inFlight.get(orgId);
39
- if (!pending) {
40
- pending = this.resolveAndBuild(orgId);
41
- this.inFlight.set(orgId, pending);
42
- void pending.finally(() => {
43
- if (this.inFlight.get(orgId) === pending)
44
- this.inFlight.delete(orgId);
45
- });
46
- }
47
- return pending;
48
- }
49
- /** Drop the cached provider for an org. Call after the operator rotates
50
- * the role ARN or external id so the next request rebuilds. */
51
- evict(orgId) {
52
- this.cache.delete(orgId);
53
- }
54
- /** Drop every cached provider. Useful in tests; rarely in production. */
55
- evictAll() {
56
- this.cache.clear();
57
- }
58
- async resolveAndBuild(orgId) {
59
- const cfg = await this.resolver(orgId);
60
- if (!cfg || !cfg.assumeRoleArn) {
61
- const fallback = await this.getFallback();
62
- this.cache.set(orgId, fallback);
63
- return fallback;
64
- }
65
- const provider = await this.buildAssumeRoleProvider(orgId, cfg);
66
- this.cache.set(orgId, provider);
67
- return provider;
68
- }
69
- async getFallback() {
70
- if (this.fallbackOverride)
71
- return this.fallbackOverride;
72
- if (this.fallbackCache)
73
- return this.fallbackCache;
74
- // Lazy-import so test envs that supply their own resolver/fallback
75
- // don't load the credential-providers SDK.
76
- const { fromNodeProviderChain } = await import('@aws-sdk/credential-providers');
77
- this.fallbackCache = fromNodeProviderChain();
78
- return this.fallbackCache;
79
- }
80
- async buildAssumeRoleProvider(orgId, cfg) {
81
- // Dynamic import — credential-providers is heavyweight and services that
82
- // never have per-org roles configured shouldn't load it.
83
- const { fromTemporaryCredentials } = await import('@aws-sdk/credential-providers');
84
- const masterCredentials = this.fallbackOverride ?? (await this.getFallback());
85
- const sessionName = cfg.roleSessionName ?? `pipeline-builder-${orgId}`.slice(0, 64);
86
- const region = cfg.region ?? this.region;
87
- return fromTemporaryCredentials({
88
- // Inner STS client uses the service's own credentials (the fallback
89
- // chain). Those creds need `sts:AssumeRole` on the org's role.
90
- masterCredentials,
91
- clientConfig: {
92
- region,
93
- ...(this.endpoint ? { endpoint: this.endpoint } : {}),
94
- // Cast to the exact clientConfig type fromTemporaryCredentials expects.
95
- // @aws-sdk ships STSClientConfig from both `client-sts` and the
96
- // `nested-clients` STS submodule at independently-bumped versions, so a
97
- // `typeof STSClient` cast can resolve to the wrong one; deriving it from
98
- // the function's own Parameters keeps them in lockstep.
99
- },
100
- params: {
101
- RoleArn: cfg.assumeRoleArn,
102
- RoleSessionName: sessionName,
103
- DurationSeconds: cfg.sessionDurationSeconds ?? 3600,
104
- ...(cfg.externalId ? { ExternalId: cfg.externalId } : {}),
105
- },
106
- });
107
- }
108
- }
109
- /** Convenience: directly resolve credentials for a single call. The manager
110
- * doesn't cache when called this way — useful in CLIs / one-shot scripts. */
111
- export async function resolveOrgCredentialsOnce(orgId, resolver) {
112
- const manager = new OrgAwsCredentialsManager({ resolver });
113
- const provider = await manager.getCredentials(orgId);
114
- return provider();
115
- }
116
- /**
117
- * Adapter: resolve per-org credentials and construct an AWS SDK client
118
- * pre-bound to them. The factory is async because credential resolution may
119
- * need to make a network call (fetching org config + AssumeRole). Once
120
- * resolved, the returned client is ready for normal SDK calls; the provider
121
- * inside refreshes credentials automatically before they expire.
122
- *
123
- * Typical usage:
124
- * ```ts
125
- * const s3 = await withOrgAwsCredentials(manager, orgId, (creds) =>
126
- * new S3Client({ credentials: creds, region: 'us-west-2' }));
127
- * await s3.send(new ListObjectsV2Command({ Bucket: bucketFor(orgId) }));
128
- * ```
129
- *
130
- * The factory is invoked exactly once per call — callers that need a
131
- * long-lived client should cache the result themselves rather than rebuilding
132
- * on every operation. (Re-resolving on every op is fine for cold paths and
133
- * a wasted couple of object allocations on hot paths.)
134
- */
135
- export async function withOrgAwsCredentials(manager, orgId, factory) {
136
- const credentials = await manager.getCredentials(orgId);
137
- return factory(credentials);
138
- }
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnLWF3cy1jcmVkZW50aWFscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9vcmctYXdzLWNyZWRlbnRpYWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUF5R3RDOzs7R0FHRztBQUNILE1BQU0sT0FBTyx3QkFBd0I7SUFDbEIsUUFBUSxDQUF1QjtJQUMvQixnQkFBZ0IsQ0FBaUM7SUFDakQsTUFBTSxDQUFVO0lBQ2hCLFFBQVEsQ0FBVTtJQUNsQixLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXlDLENBQUM7SUFDekQsUUFBUSxHQUFHLElBQUksR0FBRyxFQUFrRCxDQUFDO0lBQ3RGOzt5QkFFcUI7SUFDYixhQUFhLENBQWlDO0lBRXRELFlBQVksSUFBcUM7UUFDL0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQzlCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDO1FBQ3RGLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDO0lBQ2hFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFhO1FBQ2hDLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO1FBRWxHLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksTUFBTTtZQUFFLE9BQU8sTUFBTSxDQUFDO1FBRTFCLElBQUks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dCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBQZXItb3JnIElBTSByb2xlIGFzc3VtcHRpb24gZm9yIGJ1aWxkIC8gcnVudGltZSBBV1MgQVBJIGNhbGxzLlxuICpcbiAqIFRoZSBzaGFyZWQgcG9zdHVyZSBmb3IgQVdTIGNhbGxzIHRvZGF5IGlzIFwidGhlIHNlcnZpY2UncyBJQU0gcm9sZSwgZnVsbFxuICogYmxhc3QgcmFkaXVzIGFjcm9zcyBldmVyeSBvcmcuXCIgVGhlIG9wZXJhdG9yLXNpZGUgbWl0aWdhdGlvbiBvcGVyYXRvcnNcbiAqIGFjdHVhbGx5IHdhbnQgaXM6IGVhY2ggY3VzdG9tZXIgb3JnIGdldHMgaXRzIG93biBJQU0gcm9sZSBpbiBpdHMgb3duXG4gKiBhY2NvdW50OyBidWlsZC9ydW50aW1lIEFXUyBjYWxscyBmb3IgdGhhdCBvcmcgYHN0czpBc3N1bWVSb2xlYCBpbnRvIHRoZVxuICogY3VzdG9tZXIncyByb2xlOyBhIGNvbXByb21pc2Ugb2Ygb25lIG9yZydzIHJvbGUgY2FuJ3QgZW51bWVyYXRlIGFub3RoZXJcbiAqIG9yZydzIFMzIGJ1Y2tldHMgLyBFQ1IgcmVwb3MuXG4gKlxuICogVGhpcyBtb2R1bGUgaXMgdGhlIGNyZWRlbnRpYWwtcHJvdmlkZXIgcHJpbWl0aXZlLiBJdCdzIHBsdWdnYWJsZSBvbiB0aGVcbiAqIG9yZy1jb25maWcgcmVzb2x2ZXIgc28gdGhlIHNhbWUgY29kZSBwYXRoIHdvcmtzIHdoZXRoZXIgY29uZmlnIGlzIHJlYWRcbiAqIGZyb20gTW9uZ28sIFBvc3RncmVzLCBvciBlbnYgdmFycy4gQ2FsbGVycyByZWNlaXZlIGEgc3RhbmRhcmQgU0RLIHYzXG4gKiBgQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXJgIGFuZCBwYXNzIGl0IHRvIGFueSBTREsgY2xpZW50XG4gKiAoYG5ldyBDb2RlQnVpbGRDbGllbnQoeyBjcmVkZW50aWFscyB9KWAsIGV0Yy4pLlxuICpcbiAqIE5vIGdsb2JhbCBzdGF0ZSDigJQgY2FsbGVycyBjb25zdHJ1Y3Qgb25lIGBPcmdBd3NDcmVkZW50aWFsc01hbmFnZXJgIHBlclxuICogcHJvY2VzcyBhbmQgYGF3YWl0IG1hbmFnZXIuZ2V0Q3JlZGVudGlhbHMob3JnSWQpYCBiZWZvcmUgZWFjaCBBV1MgY2FsbC5cbiAqIFRoZSByZXR1cm5lZCBwcm92aWRlciBoYW5kbGVzIGNyZWRlbnRpYWwgcmVmcmVzaCBpbnRlcm5hbGx5ICh0aGVcbiAqIHVuZGVybHlpbmcgYGZyb21UZW1wb3JhcnlDcmVkZW50aWFsc2AgcmUtY2FsbHMgQXNzdW1lUm9sZSB+NSBtaW4gYmVmb3JlXG4gKiB0aGUgdGVtcG9yYXJ5IGNyZWRlbnRpYWxzIGV4cGlyZSksIHNvIGNhbGwgc2l0ZXMgZG9uJ3QgbWFuYWdlIFRUTC5cbiAqXG4gKiBTYWZldHkgcHJvcGVydGllczpcbiAqICAtIGBleHRlcm5hbElkYCBpcyBwbHVtYmVkIHRocm91Z2ggdG8gQXNzdW1lUm9sZS4gT3BlcmF0b3JzIGJha2UgdGhpc1xuICogICAgaW50byB0aGUgSUFNIHRydXN0IHBvbGljeSBhcyB0aGUgXCJjb25mdXNlZCBkZXB1dHlcIiBtaXRpZ2F0aW9uOyB0aGlzXG4gKiAgICBtb2R1bGUgbmV2ZXIgc2lsZW50bHkgb21pdHMgaXQuXG4gKiAgLSBPcmdzIHdpdGhvdXQgYSBjb25maWd1cmVkIHJvbGUgZmFsbCB0aHJvdWdoIHRvIHRoZSBzdXBwbGllZFxuICogICAgYGZhbGxiYWNrYCBwcm92aWRlciAodHlwaWNhbGx5IHRoZSBTREsgZGVmYXVsdCBjaGFpbikuIE1peGVkLW1vZGVcbiAqICAgIGRlcGxveW1lbnRzIHdoZXJlIHNvbWUgb3JncyBoYXZlIHBlci1vcmcgcm9sZXMgYW5kIG90aGVycyB1c2UgdGhlXG4gKiAgICBzaGFyZWQgcm9sZSBhcmUgZXhwbGljaXRseSBzdXBwb3J0ZWQuXG4gKiAgLSBgZXZpY3Qob3JnSWQpYCBkcm9wcyB0aGUgY2FjaGVkIHByb3ZpZGVyIHNvIHRoZSBuZXh0IGNhbGwgcmUtcmVzb2x2ZXNcbiAqICAgIGZyb20gdGhlIHJlc29sdmVyIOKAlCB1c2UgYWZ0ZXIgdGhlIG9wZXJhdG9yIGNoYW5nZXMgYW4gb3JnJ3Mgcm9sZS5cbiAqXG4gKiBJbnRlZ3JhdGlvbiBwYXR0ZXJuIGZvciBBV1MgU0RLIGNsaWVudHM6XG4gKlxuICogICBgYGB0c1xuICogICBpbXBvcnQgeyBTM0NsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zMyc7XG4gKiAgIGltcG9ydCB7IHdpdGhPcmdBd3NDcmVkZW50aWFscyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbiAqXG4gKiAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgT3JnQXdzQ3JlZGVudGlhbHNNYW5hZ2VyKHsgcmVzb2x2ZXIgfSk7XG4gKlxuICogICBhc3luYyBmdW5jdGlvbiBzM0Zvck9yZyhvcmdJZDogc3RyaW5nKSB7XG4gKiAgICAgcmV0dXJuIHdpdGhPcmdBd3NDcmVkZW50aWFscyhtYW5hZ2VyLCBvcmdJZCwgKGNyZWRzKSA9PlxuICogICAgICAgbmV3IFMzQ2xpZW50KHsgY3JlZGVudGlhbHM6IGNyZWRzLCByZWdpb246ICd1cy13ZXN0LTInIH0pKTtcbiAqICAgfVxuICogICBgYGBcbiAqXG4gKiBUb2RheSdzIGNvZGViYXNlOiBubyBwbGF0Zm9ybS1zaWRlIHNlcnZpY2UgbWFrZXMgQVdTIEFQSSBjYWxscyBzY29wZWQgdG9cbiAqIGEgY3VzdG9tZXIgb3JnIChidWlsZCBydW5uZXJzIHVzZSBidWlsZGtpdGQ7IEFXUyBMYW1iZGEgaGFuZGxlcnMgcnVuIGluXG4gKiBjdXN0b21lciB0ZXJyaXRvcnkgd2l0aCB0aGVpciBvd24gSUFNKS4gVGhpcyBwcmltaXRpdmUgaXMgaW4gcGxhY2UgZm9yXG4gKiB3aGVuIHRoZSBhcmNoaXRlY3R1cmUgZ3Jvd3MgdG8gYWRkIHN1Y2ggY2FsbCBzaXRlcyDigJQgcGVyLW9yZyBTMyBidWNrZXRzLFxuICogcGVyLW9yZyBFQ1IgcmVwb3MsIHBlci1vcmcgQ29kZUJ1aWxkIHByb2plY3RzIOKAlCB3aXRob3V0IGZvcmNpbmcgYW5cbiAqIGluc2VjdXJlIGRlZmF1bHQuXG4gKi9cblxuLyoqIFN0cnVjdHVyYWwgc2hhcGUgb2YgYW4gQVdTIGNyZWRlbnRpYWwuIE1hdGNoZXMgYEBzbWl0aHkvdHlwZXMjQXdzQ3JlZGVudGlhbElkZW50aXR5YFxuICogIGV4YWN0bHkg4oCUIGRlZmluZWQgbG9jYWxseSBzbyBhcGktY29yZSBkb2Vzbid0IG5lZWQgdG8gZGVjbGFyZSBAc21pdGh5L3R5cGVzXG4gKiAgYXMgYSBkaXJlY3QgZGVwIChpdCdzIGEgdHJhbnNpdGl2ZSBvZiBldmVyeSBBV1MgU0RLIGNsaWVudCB3ZSB1c2UpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NDcmVkZW50aWFsSWRlbnRpdHkge1xuICBhY2Nlc3NLZXlJZDogc3RyaW5nO1xuICBzZWNyZXRBY2Nlc3NLZXk6IHN0cmluZztcbiAgc2Vzc2lvblRva2VuPzogc3RyaW5nO1xuICBleHBpcmF0aW9uPzogRGF0ZTtcbiAgY3JlZGVudGlhbFNjb3BlPzogc3RyaW5nO1xuICBhY2NvdW50SWQ/OiBzdHJpbmc7XG59XG5cbi8qKiBTdGFuZGFyZCBjcmVkZW50aWFsLXByb3ZpZGVyIGNhbGxhYmxlLiBNYXRjaGVzIGBAc21pdGh5L3R5cGVzI0F3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyYC4gKi9cbmV4cG9ydCB0eXBlIEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyID0gKCkgPT4gUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHk+O1xuXG4vKiogT3BlcmF0b3Itc3VwcGxpZWQgcGVyLW9yZyBJQU0gcm9sZSArIHJlZ2lvbiBwaW5uaW5nLiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmdBd3NDb25maWcge1xuICAvKiogQVJOIG9mIHRoZSByb2xlIHRoaXMgb3JnJ3MgYnVpbGQvcnVudGltZSBjb2RlIHNob3VsZCBhc3N1bWUuICovXG4gIGFzc3VtZVJvbGVBcm46IHN0cmluZztcbiAgLyoqIEV4dGVybmFsIGlkIGJha2VkIGludG8gdGhlIHJvbGUncyB0cnVzdCBwb2xpY3kgKHJlY29tbWVuZGVkKS4gKi9cbiAgZXh0ZXJuYWxJZD86IHN0cmluZztcbiAgLyoqIFJlZ2lvbiB0byB1c2Ugd2hlbiB0aGUgY2FsbGluZyBjb2RlIGRvZXNuJ3QgcGluIG9uZS4gKi9cbiAgcmVnaW9uPzogc3RyaW5nO1xuICAvKiogQXNzdW1lUm9sZSBzZXNzaW9uIGR1cmF0aW9uIChzZWNvbmRzKS4gQVdTIGFsbG93cyA5MDAtNDMyMDA7IHRoZVxuICAgKiAgZWZmZWN0aXZlIGNlaWxpbmcgaXMgdGhlIHJvbGUncyBgTWF4U2Vzc2lvbkR1cmF0aW9uYC4gRGVmYXVsdCAzNjAwLiAqL1xuICBzZXNzaW9uRHVyYXRpb25TZWNvbmRzPzogbnVtYmVyO1xuICAvKiogU2Vzc2lvbiBuYW1lIGVtYmVkZGVkIGluIENsb3VkVHJhaWwuIFVzZWZ1bCBmb3IgaW5jaWRlbnQtcmVzcG9uc2VcbiAgICogIGF0dHJpYnV0aW9uLiBEZWZhdWx0IGBwaXBlbGluZS1idWlsZGVyLTxvcmdJZD5gLiAqL1xuICByb2xlU2Vzc2lvbk5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKiBBc3luYyByZXNvbHZlcjogb3JnSWQg4oaSIGNvbmZpZyB8IG51bGwuIFJldHVybmluZyBudWxsIG1lYW5zIFwidGhpcyBvcmdcbiAqICBoYXMgbm8gcGVyLW9yZyByb2xlOyB1c2UgdGhlIGZhbGxiYWNrIHByb3ZpZGVyLlwiICovXG5leHBvcnQgdHlwZSBPcmdBd3NDb25maWdSZXNvbHZlciA9IChvcmdJZDogc3RyaW5nKSA9PiBQcm9taXNlPE9yZ0F3c0NvbmZpZyB8IG51bGw+O1xuXG4vKiogQ29uc3RydWN0b3Igb3B0aW9ucy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3JnQXdzQ3JlZGVudGlhbHNNYW5hZ2VyT3B0aW9ucyB7XG4gIHJlc29sdmVyOiBPcmdBd3NDb25maWdSZXNvbHZlcjtcbiAgLyoqIFByb3ZpZGVyIHVzZWQgZm9yIG9yZ3Mgd2hvc2UgcmVzb2x2ZXIgcmV0dXJucyBudWxsLiBEZWZhdWx0OiB0aGUgU0RLXG4gICAqICBkZWZhdWx0IGNoYWluIHZpYSBgQGF3cy1zZGsvY3JlZGVudGlhbC1wcm92aWRlcnMjZnJvbU5vZGVQcm92aWRlckNoYWluYC4gKi9cbiAgZmFsbGJhY2s/OiBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcjtcbiAgLyoqIFJlZ2lvbiBwYXNzZWQgdG8gdGhlIGlubmVyIFNUUyBjbGllbnQgd2hlbiB0aGUgb3JnIGNvbmZpZyBkb2Vzbid0XG4gICAqICBwaW4gb25lLiBEZWZhdWx0OiBgQVdTX1JFR0lPTmAgLyBgQVdTX0RFRkFVTFRfUkVHSU9OYCBlbnYuICovXG4gIHJlZ2lvbj86IHN0cmluZztcbiAgLyoqIFNUUyBlbmRwb2ludCBvdmVycmlkZSAoTG9jYWxTdGFjaywgVlBDIGVuZHBvaW50KS4gRGVmYXVsdDogU0RLIGRlZmF1bHQuICovXG4gIGVuZHBvaW50Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBlci1wcm9jZXNzIG1hbmFnZXIgdGhhdCByZXNvbHZlcyBhbmQgY2FjaGVzIHBlci1vcmcgY3JlZGVudGlhbCBwcm92aWRlcnMuXG4gKiBPbmUgaW5zdGFuY2UgcGVyIHNlcnZpY2U7IHNoYXJlIGl0IGFjcm9zcyBoYW5kbGVycy5cbiAqL1xuZXhwb3J0IGNsYXNzIE9yZ0F3c0NyZWRlbnRpYWxzTWFuYWdlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb2x2ZXI6IE9yZ0F3c0NvbmZpZ1Jlc29sdmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGZhbGxiYWNrT3ZlcnJpZGU/OiBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcj4+KCk7XG4gIC8qKiBMYXp5IGRlZmF1bHQgY2hhaW4uIEJ1aWx0IG9uY2UgcGVyIG1hbmFnZXIgc28gd2UgZG9uJ3QgaW1wb3J0IHRoZVxuICAgKiAgY3JlZGVudGlhbC1wcm92aWRlcnMgU0RLIGluIHRlc3QgZW52aXJvbm1lbnRzIHRoYXQgbmV2ZXIgdG91Y2ggdGhlXG4gICAqICBmYWxsYmFjayBwYXRoLiAqL1xuICBwcml2YXRlIGZhbGxiYWNrQ2FjaGU/OiBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcjtcblxuICBjb25zdHJ1Y3RvcihvcHRzOiBPcmdBd3NDcmVkZW50aWFsc01hbmFnZXJPcHRpb25zKSB7XG4gICAgdGhpcy5yZXNvbHZlciA9IG9wdHMucmVzb2x2ZXI7XG4gICAgdGhpcy5mYWxsYmFja092ZXJyaWRlID0gb3B0cy5mYWxsYmFjaztcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHMucmVnaW9uID8/IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OO1xuICAgIHRoaXMuZW5kcG9pbnQgPSBvcHRzLmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19TVFNfRU5EUE9JTlQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyIHNjb3BlZCB0byBgb3JnSWRgLiBQYXNzIHRoZVxuICAgKiByZXR1cm5lZCB2YWx1ZSBpbnRvIGFueSBTREsgdjMgY2xpZW50J3MgYGNyZWRlbnRpYWxzYCBvcHRpb24uXG4gICAqXG4gICAqIENvbmN1cnJlbnQgZmlyc3QtdG91Y2ggY2FsbGVycyBzaGFyZSBvbmUgcmVzb2x2ZXIgaW52b2NhdGlvbjsgbGF0ZXJcbiAgICogY2FsbHMgaGl0IHRoZSBjYWNoZS4gVGhlIHByb3ZpZGVyIGl0c2VsZiBjYWNoZXMgYW5kIHJlZnJlc2hlc1xuICAgKiBBc3N1bWVSb2xlLWRlcml2ZWQgY3JlZGVudGlhbHMgaW50ZXJuYWxseS5cbiAgICovXG4gIGFzeW5jIGdldENyZWRlbnRpYWxzKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyPiB7XG4gICAgaWYgKCFvcmdJZCkgdGhyb3cgbmV3IEVycm9yKCdPcmdBd3NDcmVkZW50aWFsc01hbmFnZXIuZ2V0Q3JlZGVudGlhbHMgcmVxdWlyZXMgYSBub24tZW1wdHkgb3JnSWQnKTtcblxuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuY2FjaGUuZ2V0KG9yZ0lkKTtcbiAgICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkO1xuXG4gICAgbGV0IHBlbmRpbmcgPSB0aGlzLmluRmxpZ2h0LmdldChvcmdJZCk7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gdGhpcy5yZXNvbHZlQW5kQnVpbGQob3JnSWQpO1xuICAgICAgdGhpcy5pbkZsaWdodC5zZXQob3JnSWQsIHBlbmRpbmcpO1xuICAgICAgdm9pZCBwZW5kaW5nLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5pbkZsaWdodC5nZXQob3JnSWQpID09PSBwZW5kaW5nKSB0aGlzLmluRmxpZ2h0LmRlbGV0ZShvcmdJZCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBlbmRpbmc7XG4gIH1cblxuICAvKiogRHJvcCB0aGUgY2FjaGVkIHByb3ZpZGVyIGZvciBhbiBvcmcuIENhbGwgYWZ0ZXIgdGhlIG9wZXJhdG9yIHJvdGF0ZXNcbiAgICogIHRoZSByb2xlIEFSTiBvciBleHRlcm5hbCBpZCBzbyB0aGUgbmV4dCByZXF1ZXN0IHJlYnVpbGRzLiAqL1xuICBldmljdChvcmdJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYWNoZS5kZWxldGUob3JnSWQpO1xuICB9XG5cbiAgLyoqIERyb3AgZXZlcnkgY2FjaGVkIHByb3ZpZGVyLiBVc2VmdWwgaW4gdGVzdHM7IHJhcmVseSBpbiBwcm9kdWN0aW9uLiAqL1xuICBldmljdEFsbCgpOiB2b2lkIHtcbiAgICB0aGlzLmNhY2hlLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVBbmRCdWlsZChvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcj4ge1xuICAgIGNvbnN0IGNmZyA9IGF3YWl0IHRoaXMucmVzb2x2ZXIob3JnSWQpO1xuICAgIGlmICghY2ZnIHx8ICFjZmcuYXNzdW1lUm9sZUFybikge1xuICAgICAgY29uc3QgZmFsbGJhY2sgPSBhd2FpdCB0aGlzLmdldEZhbGxiYWNrKCk7XG4gICAgICB0aGlzLmNhY2hlLnNldChvcmdJZCwgZmFsbGJhY2spO1xuICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgdGhpcy5idWlsZEFzc3VtZVJvbGVQcm92aWRlcihvcmdJZCwgY2ZnKTtcbiAgICB0aGlzLmNhY2hlLnNldChvcmdJZCwgcHJvdmlkZXIpO1xuICAgIHJldHVybiBwcm92aWRlcjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RmFsbGJhY2soKTogUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcj4ge1xuICAgIGlmICh0aGlzLmZhbGxiYWNrT3ZlcnJpZGUpIHJldHVybiB0aGlzLmZhbGxiYWNrT3ZlcnJpZGU7XG4gICAgaWYgKHRoaXMuZmFsbGJhY2tDYWNoZSkgcmV0dXJuIHRoaXMuZmFsbGJhY2tDYWNoZTtcbiAgICAvLyBMYXp5LWltcG9ydCBzbyB0ZXN0IGVudnMgdGhhdCBzdXBwbHkgdGhlaXIgb3duIHJlc29sdmVyL2ZhbGxiYWNrXG4gICAgLy8gZG9uJ3QgbG9hZCB0aGUgY3JlZGVudGlhbC1wcm92aWRlcnMgU0RLLlxuICAgIGNvbnN0IHsgZnJvbU5vZGVQcm92aWRlckNoYWluIH0gPSBhd2FpdCBpbXBvcnQoJ0Bhd3Mtc2RrL2NyZWRlbnRpYWwtcHJvdmlkZXJzJyk7XG4gICAgdGhpcy5mYWxsYmFja0NhY2hlID0gZnJvbU5vZGVQcm92aWRlckNoYWluKCk7XG4gICAgcmV0dXJuIHRoaXMuZmFsbGJhY2tDYWNoZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYnVpbGRBc3N1bWVSb2xlUHJvdmlkZXIob3JnSWQ6IHN0cmluZywgY2ZnOiBPcmdBd3NDb25maWcpOiBQcm9taXNlPEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyPiB7XG4gICAgLy8gRHluYW1pYyBpbXBvcnQg4oCUIGNyZWRlbnRpYWwtcHJvdmlkZXJzIGlzIGhlYXZ5d2VpZ2h0IGFuZCBzZXJ2aWNlcyB0aGF0XG4gICAgLy8gbmV2ZXIgaGF2ZSBwZXItb3JnIHJvbGVzIGNvbmZpZ3VyZWQgc2hvdWxkbid0IGxvYWQgaXQuXG4gICAgY29uc3QgeyBmcm9tVGVtcG9yYXJ5Q3JlZGVudGlhbHMgfSA9IGF3YWl0IGltcG9ydCgnQGF3cy1zZGsvY3JlZGVudGlhbC1wcm92aWRlcnMnKTtcblxuICAgIGNvbnN0IG1hc3RlckNyZWRlbnRpYWxzID0gdGhpcy5mYWxsYmFja092ZXJyaWRlID8/IChhd2FpdCB0aGlzLmdldEZhbGxiYWNrKCkpO1xuXG4gICAgY29uc3Qgc2Vzc2lvbk5hbWUgPSBjZmcucm9sZVNlc3Npb25OYW1lID8/IGBwaXBlbGluZS1idWlsZGVyLSR7b3JnSWR9YC5zbGljZSgwLCA2NCk7XG4gICAgY29uc3QgcmVnaW9uID0gY2ZnLnJlZ2lvbiA/PyB0aGlzLnJlZ2lvbjtcblxuICAgIHJldHVybiBmcm9tVGVtcG9yYXJ5Q3JlZGVudGlhbHMoe1xuICAgICAgLy8gSW5uZXIgU1RTIGNsaWVudCB1c2VzIHRoZSBzZXJ2aWNlJ3Mgb3duIGNyZWRlbnRpYWxzICh0aGUgZmFsbGJhY2tcbiAgICAgIC8vIGNoYWluKS4gVGhvc2UgY3JlZHMgbmVlZCBgc3RzOkFzc3VtZVJvbGVgIG9uIHRoZSBvcmcncyByb2xlLlxuICAgICAgbWFzdGVyQ3JlZGVudGlhbHMsXG4gICAgICBjbGllbnRDb25maWc6IHtcbiAgICAgICAgcmVnaW9uLFxuICAgICAgICAuLi4odGhpcy5lbmRwb2ludCA/IHsgZW5kcG9pbnQ6IHRoaXMuZW5kcG9pbnQgfSA6IHt9KSxcbiAgICAgICAgLy8gQ2FzdCB0byB0aGUgZXhhY3QgY2xpZW50Q29uZmlnIHR5cGUgZnJvbVRlbXBvcmFyeUNyZWRlbnRpYWxzIGV4cGVjdHMuXG4gICAgICAgIC8vIEBhd3Mtc2RrIHNoaXBzIFNUU0NsaWVudENvbmZpZyBmcm9tIGJvdGggYGNsaWVudC1zdHNgIGFuZCB0aGVcbiAgICAgICAgLy8gYG5lc3RlZC1jbGllbnRzYCBTVFMgc3VibW9kdWxlIGF0IGluZGVwZW5kZW50bHktYnVtcGVkIHZlcnNpb25zLCBzbyBhXG4gICAgICAgIC8vIGB0eXBlb2YgU1RTQ2xpZW50YCBjYXN0IGNhbiByZXNvbHZlIHRvIHRoZSB3cm9uZyBvbmU7IGRlcml2aW5nIGl0IGZyb21cbiAgICAgICAgLy8gdGhlIGZ1bmN0aW9uJ3Mgb3duIFBhcmFtZXRlcnMga2VlcHMgdGhlbSBpbiBsb2Nrc3RlcC5cbiAgICAgIH0gYXMgdW5rbm93biBhcyBQYXJhbWV0ZXJzPHR5cGVvZiBmcm9tVGVtcG9yYXJ5Q3JlZGVudGlhbHM+WzBdWydjbGllbnRDb25maWcnXSxcbiAgICAgIHBhcmFtczoge1xuICAgICAgICBSb2xlQXJuOiBjZmcuYXNzdW1lUm9sZUFybixcbiAgICAgICAgUm9sZVNlc3Npb25OYW1lOiBzZXNzaW9uTmFtZSxcbiAgICAgICAgRHVyYXRpb25TZWNvbmRzOiBjZmcuc2Vzc2lvbkR1cmF0aW9uU2Vjb25kcyA/PyAzNjAwLFxuICAgICAgICAuLi4oY2ZnLmV4dGVybmFsSWQgPyB7IEV4dGVybmFsSWQ6IGNmZy5leHRlcm5hbElkIH0gOiB7fSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKiBDb252ZW5pZW5jZTogZGlyZWN0bHkgcmVzb2x2ZSBjcmVkZW50aWFscyBmb3IgYSBzaW5nbGUgY2FsbC4gVGhlIG1hbmFnZXJcbiAqICBkb2Vzbid0IGNhY2hlIHdoZW4gY2FsbGVkIHRoaXMgd2F5IOKAlCB1c2VmdWwgaW4gQ0xJcyAvIG9uZS1zaG90IHNjcmlwdHMuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU9yZ0NyZWRlbnRpYWxzT25jZShcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcmVzb2x2ZXI6IE9yZ0F3c0NvbmZpZ1Jlc29sdmVyLFxuKTogUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHk+IHtcbiAgY29uc3QgbWFuYWdlciA9IG5ldyBPcmdBd3NDcmVkZW50aWFsc01hbmFnZXIoeyByZXNvbHZlciB9KTtcbiAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBtYW5hZ2VyLmdldENyZWRlbnRpYWxzKG9yZ0lkKTtcbiAgcmV0dXJuIHByb3ZpZGVyKCk7XG59XG5cbi8qKlxuICogQWRhcHRlcjogcmVzb2x2ZSBwZXItb3JnIGNyZWRlbnRpYWxzIGFuZCBjb25zdHJ1Y3QgYW4gQVdTIFNESyBjbGllbnRcbiAqIHByZS1ib3VuZCB0byB0aGVtLiBUaGUgZmFjdG9yeSBpcyBhc3luYyBiZWNhdXNlIGNyZWRlbnRpYWwgcmVzb2x1dGlvbiBtYXlcbiAqIG5lZWQgdG8gbWFrZSBhIG5ldHdvcmsgY2FsbCAoZmV0Y2hpbmcgb3JnIGNvbmZpZyArIEFzc3VtZVJvbGUpLiBPbmNlXG4gKiByZXNvbHZlZCwgdGhlIHJldHVybmVkIGNsaWVudCBpcyByZWFkeSBmb3Igbm9ybWFsIFNESyBjYWxsczsgdGhlIHByb3ZpZGVyXG4gKiBpbnNpZGUgcmVmcmVzaGVzIGNyZWRlbnRpYWxzIGF1dG9tYXRpY2FsbHkgYmVmb3JlIHRoZXkgZXhwaXJlLlxuICpcbiAqIFR5cGljYWwgdXNhZ2U6XG4gKiAgIGBgYHRzXG4gKiAgIGNvbnN0IHMzID0gYXdhaXQgd2l0aE9yZ0F3c0NyZWRlbnRpYWxzKG1hbmFnZXIsIG9yZ0lkLCAoY3JlZHMpID0+XG4gKiAgICAgbmV3IFMzQ2xpZW50KHsgY3JlZGVudGlhbHM6IGNyZWRzLCByZWdpb246ICd1cy13ZXN0LTInIH0pKTtcbiAqICAgYXdhaXQgczMuc2VuZChuZXcgTGlzdE9iamVjdHNWMkNvbW1hbmQoeyBCdWNrZXQ6IGJ1Y2tldEZvcihvcmdJZCkgfSkpO1xuICogICBgYGBcbiAqXG4gKiBUaGUgZmFjdG9yeSBpcyBpbnZva2VkIGV4YWN0bHkgb25jZSBwZXIgY2FsbCDigJQgY2FsbGVycyB0aGF0IG5lZWQgYVxuICogbG9uZy1saXZlZCBjbGllbnQgc2hvdWxkIGNhY2hlIHRoZSByZXN1bHQgdGhlbXNlbHZlcyByYXRoZXIgdGhhbiByZWJ1aWxkaW5nXG4gKiBvbiBldmVyeSBvcGVyYXRpb24uIChSZS1yZXNvbHZpbmcgb24gZXZlcnkgb3AgaXMgZmluZSBmb3IgY29sZCBwYXRocyBhbmRcbiAqIGEgd2FzdGVkIGNvdXBsZSBvZiBvYmplY3QgYWxsb2NhdGlvbnMgb24gaG90IHBhdGhzLilcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhPcmdBd3NDcmVkZW50aWFsczxUQ2xpZW50PihcbiAgbWFuYWdlcjogT3JnQXdzQ3JlZGVudGlhbHNNYW5hZ2VyLFxuICBvcmdJZDogc3RyaW5nLFxuICBmYWN0b3J5OiAoY3JlZGVudGlhbHM6IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyKSA9PiBUQ2xpZW50LFxuKTogUHJvbWlzZTxUQ2xpZW50PiB7XG4gIGNvbnN0IGNyZWRlbnRpYWxzID0gYXdhaXQgbWFuYWdlci5nZXRDcmVkZW50aWFscyhvcmdJZCk7XG4gIHJldHVybiBmYWN0b3J5KGNyZWRlbnRpYWxzKTtcbn1cbiJdfQ==