@pipeline-builder/pipeline-data 4.1.24 → 4.1.26
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/lib/api/alert-destinations.d.ts +17 -0
- package/lib/api/alert-destinations.js +36 -0
- package/lib/api/reporting/analytics-queries.d.ts +274 -0
- package/lib/api/reporting/analytics-queries.js +598 -0
- package/lib/api/reporting/daily-rollup.d.ts +41 -0
- package/lib/api/reporting/daily-rollup.js +173 -0
- package/lib/api/reporting/deploy-rollup.d.ts +78 -0
- package/lib/api/reporting/deploy-rollup.js +203 -0
- package/lib/api/reporting/dora-scoring.d.ts +14 -0
- package/lib/api/reporting/dora-scoring.js +25 -1
- package/lib/api/reporting/dora.js +30 -6
- package/lib/api/reporting/failure-classifier.d.ts +54 -0
- package/lib/api/reporting/failure-classifier.js +179 -0
- package/lib/api/reporting/ingest.d.ts +2 -2
- package/lib/api/reporting/ingest.js +129 -4
- package/lib/api/reporting/last-deploy.d.ts +31 -0
- package/lib/api/reporting/last-deploy.js +93 -0
- package/lib/api/reporting/needs-attention.d.ts +93 -0
- package/lib/api/reporting/needs-attention.js +152 -0
- package/lib/api/reporting/plugin-exposure.d.ts +129 -0
- package/lib/api/reporting/plugin-exposure.js +312 -0
- package/lib/api/reporting/retention-sweep.js +9 -1
- package/lib/api/reporting/sql-helpers.d.ts +35 -2
- package/lib/api/reporting/sql-helpers.js +39 -1
- package/lib/api/reporting/stakeholder/compose.d.ts +115 -0
- package/lib/api/reporting/stakeholder/compose.js +234 -0
- package/lib/api/reporting/stakeholder/index.d.ts +14 -0
- package/lib/api/reporting/stakeholder/index.js +17 -0
- package/lib/api/reporting/stakeholder/period.d.ts +102 -0
- package/lib/api/reporting/stakeholder/period.js +273 -0
- package/lib/api/reporting/stakeholder/report-html.d.ts +93 -0
- package/lib/api/reporting/stakeholder/report-html.js +208 -0
- package/lib/api/reporting/stakeholder/sections.d.ts +117 -0
- package/lib/api/reporting/stakeholder/sections.js +249 -0
- package/lib/api/reporting/stakeholder/store.d.ts +450 -0
- package/lib/api/reporting/stakeholder/store.js +981 -0
- package/lib/api/reporting/stakeholder/templates.d.ts +21 -0
- package/lib/api/reporting/stakeholder/templates.js +104 -0
- package/lib/api/reporting/types.d.ts +73 -0
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +94 -5
- package/lib/api/reporting-service.js +169 -10
- package/lib/api/soft-delete-sweep.d.ts +11 -2
- package/lib/api/soft-delete-sweep.js +17 -6
- package/lib/database/drizzle-schema.d.ts +2244 -385
- package/lib/database/drizzle-schema.js +18 -7
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +4 -2
- package/lib/database/schema/compliance.d.ts +0 -682
- package/lib/database/schema/compliance.js +6 -66
- package/lib/database/schema/ecosystem.d.ts +20 -157
- package/lib/database/schema/ecosystem.js +23 -16
- package/lib/database/schema/pipeline.d.ts +200 -0
- package/lib/database/schema/pipeline.js +100 -1
- package/lib/database/schema/plugin.d.ts +20 -1
- package/lib/database/schema/plugin.js +13 -1
- package/lib/database/schema/reporting-analytics.d.ts +1212 -0
- package/lib/database/schema/reporting-analytics.js +250 -0
- package/lib/database/schema/reporting-stakeholder.d.ts +1373 -0
- package/lib/database/schema/reporting-stakeholder.js +251 -0
- package/lib/index.d.ts +10 -1
- package/lib/index.js +15 -1
- package/lib/testing/exports.json +67 -4
- package/package.json +4 -3
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* The rules, most specific first.
|
|
5
|
+
*
|
|
6
|
+
* Read this as the taxonomy itself. Each entry answers "what would somebody DO
|
|
7
|
+
* about this", which is why e.g. `permissions` and `authentication` are separate:
|
|
8
|
+
* one is a policy change, the other is a credential.
|
|
9
|
+
*/
|
|
10
|
+
const RULES = [
|
|
11
|
+
// Credentials and policy first: their messages often also contain words that
|
|
12
|
+
// would otherwise match `external_service` or `configuration`.
|
|
13
|
+
{
|
|
14
|
+
category: 'permissions',
|
|
15
|
+
patterns: [
|
|
16
|
+
/accessdenied/, /access denied/, /not authorized to perform/, /forbidden/,
|
|
17
|
+
/explicit deny/, /assumerole.*denied/, /iam.*permission/, /insufficient privileges/,
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
category: 'authentication',
|
|
22
|
+
patterns: [
|
|
23
|
+
/unauthorized/, /401/, /authentication failed/, /invalid credentials/,
|
|
24
|
+
/expired token/, /token.*expired/, /no basic auth/, /bad credentials/,
|
|
25
|
+
/could not be authenticated/,
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
category: 'source_checkout',
|
|
30
|
+
patterns: [
|
|
31
|
+
/could not resolve host: github/, /repository not found/, /fatal: could not read/,
|
|
32
|
+
/git clone.*failed/, /reference is not a tree/, /unable to access.*\.git/,
|
|
33
|
+
/source.*checkout.*failed/, /codecommit.*not found/,
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
category: 'dependency',
|
|
38
|
+
patterns: [
|
|
39
|
+
/npm err!.*(?:e404|etarget|eresolve)/, /could not resolve dependency/,
|
|
40
|
+
/no matching version found/, /unable to resolve dependency tree/,
|
|
41
|
+
/could not find a version that satisfies/, /pip.*could not find/,
|
|
42
|
+
/go: .*: unknown revision/, /maven.*could not resolve dependencies/,
|
|
43
|
+
/bundler.*could not find/, /cargo.*failed to select a version/,
|
|
44
|
+
/peer dep/, /lockfile.*out of sync/,
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
category: 'unit_test',
|
|
49
|
+
patterns: [/tests? failed/, /assertion(?:error)? failed/, /\d+ (?:tests?|specs?) failed/, /jest.*fail/, /pytest.*failed/],
|
|
50
|
+
action: /test|spec|jest|pytest|junit/i,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
category: 'integration_test',
|
|
54
|
+
patterns: [/tests? failed/, /assertion(?:error)? failed/, /connection refused/],
|
|
55
|
+
action: /integration|e2e|smoke|acceptance|contract/i,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
category: 'security_scan',
|
|
59
|
+
patterns: [
|
|
60
|
+
/vulnerabilit/, /cve-\d{4}/, /grype/, /trivy/, /sast/, /dependency check failed/,
|
|
61
|
+
/secret detected/, /license violation/, /policy violation.*scan/,
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
category: 'timeout',
|
|
66
|
+
patterns: [
|
|
67
|
+
/timed? ?out/, /etimedout/, /deadline exceeded/, /exceeded the.*timeout/,
|
|
68
|
+
/build.*exceeded.*minutes/, /context deadline/,
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
category: 'resource_exhaustion',
|
|
73
|
+
patterns: [
|
|
74
|
+
/out of memory/, /oomkilled/, /cannot allocate memory/, /no space left on device/,
|
|
75
|
+
/disk quota exceeded/, /enospc/, /too many open files/, /killed.*signal 9/,
|
|
76
|
+
/javascript heap out of memory/,
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
category: 'deployment',
|
|
81
|
+
patterns: [
|
|
82
|
+
/cloudformation.*rollback/, /stack.*rollback_complete/, /create_failed/, /update_rollback/,
|
|
83
|
+
/cdk deploy.*failed/, /ecs.*deployment.*failed/, /deployment.*circuit breaker/,
|
|
84
|
+
/health check.*failed.*target group/,
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
category: 'infrastructure',
|
|
89
|
+
patterns: [
|
|
90
|
+
/throttl/, /rate exceeded/, /limitexceeded/, /servicequotaexceeded/,
|
|
91
|
+
/capacity/, /insufficientinstancecapacity/, /host.*unreachable/,
|
|
92
|
+
/internal service error/, /5\d\d.*aws/,
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
category: 'external_service',
|
|
97
|
+
patterns: [
|
|
98
|
+
/could not resolve host/, /enotfound/, /econnrefused/, /econnreset/,
|
|
99
|
+
/getaddrinfo/, /socket hang up/, /bad gateway/, /502|503|504/,
|
|
100
|
+
/upstream.*unavailable/, /registry.*unreachable/,
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
category: 'configuration',
|
|
105
|
+
patterns: [
|
|
106
|
+
/is not defined/, /no such file or directory/, /enoent/, /invalid.*configuration/,
|
|
107
|
+
/missing required.*(?:variable|parameter|input)/,
|
|
108
|
+
// Both orders: "yaml parse error" and "error parsing YAML".
|
|
109
|
+
/yaml.*(?:parse|parsing|syntax)/, /(?:parse|parsing|syntax).*yaml/,
|
|
110
|
+
/unexpected token.*json/, /buildspec/, /command not found/,
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
category: 'build',
|
|
115
|
+
patterns: [
|
|
116
|
+
/compilation (?:failed|error)/, /error ts\d+/, /syntax error/, /cannot find module/,
|
|
117
|
+
/undefined reference/, /build failed/, /webpack.*error/, /tsc.*error/,
|
|
118
|
+
/docker build.*failed/, /failed to solve/,
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
/**
|
|
123
|
+
* The category for a failed action.
|
|
124
|
+
*
|
|
125
|
+
* `null` for anything that is not a failure — the caller stores nothing rather
|
|
126
|
+
* than labelling a success, so a category's presence always means "this broke".
|
|
127
|
+
*/
|
|
128
|
+
export function classifyFailure(input) {
|
|
129
|
+
const failed = /^(FAILED|FAILURE|ERROR|TIMED_OUT)$/i.test(input.status);
|
|
130
|
+
if (!failed)
|
|
131
|
+
return null;
|
|
132
|
+
const text = (input.errorMessage ?? '').toLowerCase();
|
|
133
|
+
const where = `${input.actionName ?? ''} ${input.stageName ?? ''}`;
|
|
134
|
+
for (const rule of RULES) {
|
|
135
|
+
if (rule.action && !rule.action.test(where))
|
|
136
|
+
continue;
|
|
137
|
+
if (rule.patterns.some((p) => p.test(text)))
|
|
138
|
+
return rule.category;
|
|
139
|
+
}
|
|
140
|
+
// Nothing matched. `other` rather than a guess, and counted, so the share of
|
|
141
|
+
// `other` measures how good the rules are and names the gap to close.
|
|
142
|
+
return 'other';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A human label for a category, for the report and the UI.
|
|
146
|
+
*
|
|
147
|
+
* Phrased as what broke rather than as an enum: a manager reading
|
|
148
|
+
* "Dependency resolution" understands it, and `integration_test` does not.
|
|
149
|
+
*/
|
|
150
|
+
export const FAILURE_CATEGORY_LABELS = {
|
|
151
|
+
source_checkout: 'Source checkout',
|
|
152
|
+
dependency: 'Dependency resolution',
|
|
153
|
+
build: 'Build / compile',
|
|
154
|
+
unit_test: 'Unit tests',
|
|
155
|
+
integration_test: 'Integration tests',
|
|
156
|
+
security_scan: 'Security scan',
|
|
157
|
+
infrastructure: 'Cloud infrastructure',
|
|
158
|
+
deployment: 'Deployment',
|
|
159
|
+
authentication: 'Authentication',
|
|
160
|
+
permissions: 'Permissions',
|
|
161
|
+
configuration: 'Configuration',
|
|
162
|
+
timeout: 'Timeout',
|
|
163
|
+
resource_exhaustion: 'Out of resources',
|
|
164
|
+
external_service: 'External service',
|
|
165
|
+
other: 'Unclassified',
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Whether a category is something the TEAM can act on, as opposed to something
|
|
169
|
+
* that happened to them.
|
|
170
|
+
*
|
|
171
|
+
* Used by the failure-analysis section to separate the two, because a week whose
|
|
172
|
+
* failures were all cloud throttling is a different conversation from one whose
|
|
173
|
+
* failures were all broken tests — and presenting them in one ranked list invites
|
|
174
|
+
* exactly the wrong conclusion.
|
|
175
|
+
*/
|
|
176
|
+
export function isTeamActionable(category) {
|
|
177
|
+
return !['infrastructure', 'external_service'].includes(category);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpbHVyZS1jbGFzc2lmaWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvZmFpbHVyZS1jbGFzc2lmaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUEwQ3RDOzs7Ozs7R0FNRztBQUNILE1BQU0sS0FBSyxHQUFXO0lBQ3BCLDZFQUE2RTtJQUM3RSwrREFBK0Q7SUFDL0Q7UUFDRSxRQUFRLEVBQUUsYUFBYTtRQUN2QixRQUFRLEVBQUU7WUFDUixjQUFjLEVBQUUsZUFBZSxFQUFFLDJCQUEyQixFQUFFLFdBQVc7WUFDekUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLHlCQUF5QjtTQUNwRjtLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLFFBQVEsRUFBRTtZQUNSLGNBQWMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCO1lBQ3JFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsaUJBQWlCO1lBQ3JFLDRCQUE0QjtTQUM3QjtLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVBQUUsaUJBQWlCO1FBQzNCLFFBQVEsRUFBRTtZQUNSLGdDQUFnQyxFQUFFLHNCQUFzQixFQUFFLHVCQUF1QjtZQUNqRixtQkFBbUIsRUFBRSx5QkFBeUIsRUFBRSx5QkFBeUI7WUFDekUsMEJBQTBCLEVBQUUsdUJBQXVCO1NBQ3BEO0tBQ0Y7SUFDRDtRQUNFLFFBQVEsRUFBRSxZQUFZO1FBQ3RCLFFBQVEsRUFBRTtZQUNSLHFDQUFxQyxFQUFFLDhCQUE4QjtZQUNyRSwyQkFBMkIsRUFBRSxtQ0FBbUM7WUFDaEUseUNBQXlDLEVBQUUscUJBQXFCO1lBQ2hFLDBCQUEwQixFQUFFLHVDQUF1QztZQUNuRSx5QkFBeUIsRUFBRSxtQ0FBbUM7WUFDOUQsVUFBVSxFQUFFLHVCQUF1QjtTQUNwQztLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVB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bGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBXaGF0IEtJTkQgb2YgdGhpbmcgYnJva2UuXG4gKlxuICogXCIzNCBmYWlsdXJlcyB0aGlzIHdlZWtcIiBpcyBub3QgYWN0aW9uYWJsZS4gXCIxOCBvZiB0aGVtIHdlcmUgZGVwZW5kZW5jeVxuICogcmVzb2x1dGlvbiwgYW5kIHRoZXkgYXJlIGFsbCBpbiBvbmUgcGlwZWxpbmVcIiBpcy4gVGhhdCBpcyB0aGUgd2hvbGUgcmVhc29uIHRoaXNcbiAqIGV4aXN0cyDigJQgYW5kIGl0IGlzIGFsc28gd2h5IHRoZSBjbGFzc2lmaWNhdGlvbiBoYXBwZW5zIGF0IElOR0VTVCByYXRoZXIgdGhhbiBhdFxuICogcmVhZCB0aW1lOiBlcnJvciB0ZXh0IGlzIHNjcnViYmVkIG9mIEFXUyBpZGVudGlmaWVycyBhdCB0aGUgcGVyc2lzdGVuY2UgYm91bmRhcnlcbiAqIGFuZCBldmVudHVhbGx5IHN3ZXB0IGJ5IHJldGVudGlvbiwgc28gYSBjYXRlZ29yeSBkZXJpdmVkIGxhdGVyIHdvdWxkIGhhdmVcbiAqIG5vdGhpbmcgbGVmdCB0byByZWFkLlxuICpcbiAqIFRIRSBSVUxFUyBBUkUgREFUQS4gQSBjYXRlZ29yeSBpcyBhIHByb3ZpZGVyL2FjdGlvbiBtYXRjaCBwbHVzIGFuIG9yZGVyZWQgbGlzdFxuICogb2YgcGF0dGVybnMgb3ZlciB0aGUgZXJyb3IgdGV4dCwgaW4gb25lIHRhYmxlIGJlbG93LCBzbyB0aGUgdGF4b25vbXkgY2FuIGdyb3dcbiAqIGZyb20gcmVhbCBtaXNzZXMgd2l0aG91dCB0b3VjaGluZyB0aGUgY2xhc3NpZmllci4gQW55dGhpbmcgdW5tYXRjaGVkIGxhbmRzIGluXG4gKiBgb3RoZXJgIGFuZCBpcyBjb3VudGVkLCBzbyB0aGUgc2l6ZSBvZiBgb3RoZXJgIGlzIHRoZSBtZWFzdXJlIG9mIGhvdyBnb29kIHRoZVxuICogcnVsZXMgYXJlLlxuICpcbiAqIFRIRSBDQVRFR09SSUVTIE9WRVJMQVAgVEhFIFBMVUdJTi1CVUlMRCBUQVhPTk9NWSBPTiBQVVJQT1NFLiBBIGRlcGVuZGVuY3lcbiAqIGZhaWx1cmUgaXMgYSBkZXBlbmRlbmN5IGZhaWx1cmUgd2hldGhlciBpdCBoYXBwZW5lZCBidWlsZGluZyBhIHBsdWdpbiBvciBydW5uaW5nXG4gKiBvbmU7IHR3byB2b2NhYnVsYXJpZXMgZm9yIHRoZSBzYW1lIHRoaW5nIHdvdWxkIG1ha2UgdGhlIHJlcG9ydCBhbmQgdGhlIGJ1aWxkXG4gKiBxdWV1ZSBkaXNhZ3JlZSBhYm91dCB0aGUgc2FtZSBpbmNpZGVudC5cbiAqXG4gKiBXSEFUIFRIRSBBSSBFVkVSIFNFRVMgaXMgdGhlIGNhdGVnb3J5LCBuZXZlciB0aGUgcmF3IGVycm9yLiBFcnJvciB0ZXh0IGZyb20gYVxuICogY3VzdG9tZXIncyBidWlsZCBpcyB0aGUgbGFzdCB0aGluZyB0aGF0IHNob3VsZCByZWFjaCBhIG1vZGVsLlxuICovXG5cbmltcG9ydCB0eXBlIHsgRmFpbHVyZUNhdGVnb3J5IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2Uvc2NoZW1hL3JlcG9ydGluZy1hbmFseXRpY3MuanMnO1xuXG4vKiogT25lIGNsYXNzaWZpY2F0aW9uIHJ1bGU6IHRoZSBjYXRlZ29yeSwgYW5kIGhvdyB0byByZWNvZ25pc2UgaXQuICovXG5pbnRlcmZhY2UgUnVsZSB7XG4gIGNhdGVnb3J5OiBGYWlsdXJlQ2F0ZWdvcnk7XG4gIC8qKlxuICAgKiBPcmRlcmVkIHBhdHRlcm5zIG92ZXIgdGhlIGxvd2VyY2FzZWQgZXJyb3IgdGV4dC4gRmlyc3QgcnVsZSB3aXRoIGFueSBtYXRjaFxuICAgKiB3aW5zLCBzbyB0aGUgdGFibGUncyBPUkRFUiBpcyBwYXJ0IG9mIGl0cyBtZWFuaW5nOiB0aGUgc3BlY2lmaWMgY2FzZXMgY29tZVxuICAgKiBiZWZvcmUgdGhlIGdlbmVyYWwgb25lcy5cbiAgICovXG4gIHBhdHRlcm5zOiBSZWdFeHBbXTtcbiAgLyoqIFdoZW4gc2V0LCB0aGUgcnVsZSBvbmx5IGFwcGxpZXMgdG8gYW4gYWN0aW9uL3N0YWdlIG5hbWUgbWF0Y2hpbmcgdGhpcy4gKi9cbiAgYWN0aW9uPzogUmVnRXhwO1xufVxuXG4vKipcbiAqIFRoZSBydWxlcywgbW9zdCBzcGVjaWZpYyBmaXJzdC5cbiAqXG4gKiBSZWFkIHRoaXMgYXMgdGhlIHRheG9ub215IGl0c2VsZi4gRWFjaCBlbnRyeSBhbnN3ZXJzIFwid2hhdCB3b3VsZCBzb21lYm9keSBET1xuICogYWJvdXQgdGhpc1wiLCB3aGljaCBpcyB3aHkgZS5nLiBgcGVybWlzc2lvbnNgIGFuZCBgYXV0aGVudGljYXRpb25gIGFyZSBzZXBhcmF0ZTpcbiAqIG9uZSBpcyBhIHBvbGljeSBjaGFuZ2UsIHRoZSBvdGhlciBpcyBhIGNyZWRlbnRpYWwuXG4gKi9cbmNvbnN0IFJVTEVTOiBSdWxlW10gPSBbXG4gIC8vIENyZWRlbnRpYWxzIGFuZCBwb2xpY3kgZmlyc3Q6IHRoZWlyIG1lc3NhZ2VzIG9mdGVuIGFsc28gY29udGFpbiB3b3JkcyB0aGF0XG4gIC8vIHdvdWxkIG90aGVyd2lzZSBtYXRjaCBgZXh0ZXJuYWxfc2VydmljZWAgb3IgYGNvbmZpZ3VyYXRpb25gLlxuICB7XG4gICAgY2F0ZWdvcnk6ICdwZXJtaXNzaW9ucycsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9hY2Nlc3NkZW5pZWQvLCAvYWNjZXNzIGRlbmllZC8sIC9ub3QgYXV0aG9yaXplZCB0byBwZXJmb3JtLywgL2ZvcmJpZGRlbi8sXG4gICAgICAvZXhwbGljaXQgZGVueS8sIC9hc3N1bWVyb2xlLipkZW5pZWQvLCAvaWFtLipwZXJtaXNzaW9uLywgL2luc3VmZmljaWVudCBwcml2aWxlZ2VzLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdhdXRoZW50aWNhdGlvbicsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC91bmF1dGhvcml6ZWQvLCAvNDAxLywgL2F1dGhlbnRpY2F0aW9uIGZhaWxlZC8sIC9pbnZhbGlkIGNyZWRlbnRpYWxzLyxcbiAgICAgIC9leHBpcmVkIHRva2VuLywgL3Rva2VuLipleHBpcmVkLywgL25vIGJhc2ljIGF1dGgvLCAvYmFkIGNyZWRlbnRpYWxzLyxcbiAgICAgIC9jb3VsZCBub3QgYmUgYXV0aGVudGljYXRlZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnc291cmNlX2NoZWNrb3V0JyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL2NvdWxkIG5vdCByZXNvbHZlIGhvc3Q6IGdpdGh1Yi8sIC9yZXBvc2l0b3J5IG5vdCBmb3VuZC8sIC9mYXRhbDogY291bGQgbm90IHJlYWQvLFxuICAgICAgL2dpdCBjbG9uZS4qZmFpbGVkLywgL3JlZmVyZW5jZSBpcyBub3QgYSB0cmVlLywgL3VuYWJsZSB0byBhY2Nlc3MuKlxcLmdpdC8sXG4gICAgICAvc291cmNlLipjaGVja291dC4qZmFpbGVkLywgL2NvZGVjb21taXQuKm5vdCBmb3VuZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnZGVwZW5kZW5jeScsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9ucG0gZXJyIS4qKD86ZTQwNHxldGFyZ2V0fGVyZXNvbHZlKS8sIC9jb3VsZCBub3QgcmVzb2x2ZSBkZXBlbmRlbmN5LyxcbiAgICAgIC9ubyBtYXRjaGluZyB2ZXJzaW9uIGZvdW5kLywgL3VuYWJsZSB0byByZXNvbHZlIGRlcGVuZGVuY3kgdHJlZS8sXG4gICAgICAvY291bGQgbm90IGZpbmQgYSB2ZXJzaW9uIHRoYXQgc2F0aXNmaWVzLywgL3BpcC4qY291bGQgbm90IGZpbmQvLFxuICAgICAgL2dvOiAuKjogdW5rbm93biByZXZpc2lvbi8sIC9tYXZlbi4qY291bGQgbm90IHJlc29sdmUgZGVwZW5kZW5jaWVzLyxcbiAgICAgIC9idW5kbGVyLipjb3VsZCBub3QgZmluZC8sIC9jYXJnby4qZmFpbGVkIHRvIHNlbGVjdCBhIHZlcnNpb24vLFxuICAgICAgL3BlZXIgZGVwLywgL2xvY2tmaWxlLipvdXQgb2Ygc3luYy8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAndW5pdF90ZXN0JyxcbiAgICBwYXR0ZXJuczogWy90ZXN0cz8gZmFpbGVkLywgL2Fzc2VydGlvbig/OmVycm9yKT8gZmFpbGVkLywgL1xcZCsgKD86dGVzdHM/fHNwZWNzPykgZmFpbGVkLywgL2plc3QuKmZhaWwvLCAvcHl0ZXN0LipmYWlsZWQvXSxcbiAgICBhY3Rpb246IC90ZXN0fHNwZWN8amVzdHxweXRlc3R8anVuaXQvaSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnaW50ZWdyYXRpb25fdGVzdCcsXG4gICAgcGF0dGVybnM6IFsvdGVzdHM/IGZhaWxlZC8sIC9hc3NlcnRpb24oPzplcnJvcik/IGZhaWxlZC8sIC9jb25uZWN0aW9uIHJlZnVzZWQvXSxcbiAgICBhY3Rpb246IC9pbnRlZ3JhdGlvbnxlMmV8c21va2V8YWNjZXB0YW5jZXxjb250cmFjdC9pLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdzZWN1cml0eV9zY2FuJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL3Z1bG5lcmFiaWxpdC8sIC9jdmUtXFxkezR9LywgL2dyeXBlLywgL3RyaXZ5LywgL3Nhc3QvLCAvZGVwZW5kZW5jeSBjaGVjayBmYWlsZWQvLFxuICAgICAgL3NlY3JldCBkZXRlY3RlZC8sIC9saWNlbnNlIHZpb2xhdGlvbi8sIC9wb2xpY3kgdmlvbGF0aW9uLipzY2FuLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICd0aW1lb3V0JyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL3RpbWVkPyA/b3V0LywgL2V0aW1lZG91dC8sIC9kZWFkbGluZSBleGNlZWRlZC8sIC9leGNlZWRlZCB0aGUuKnRpbWVvdXQvLFxuICAgICAgL2J1aWxkLipleGNlZWRlZC4qbWludXRlcy8sIC9jb250ZXh0IGRlYWRsaW5lLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdyZXNvdXJjZV9leGhhdXN0aW9uJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL291dCBvZiBtZW1vcnkvLCAvb29ta2lsbGVkLywgL2Nhbm5vdCBhbGxvY2F0ZSBtZW1vcnkvLCAvbm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UvLFxuICAgICAgL2Rpc2sgcXVvdGEgZXhjZWVkZWQvLCAvZW5vc3BjLywgL3RvbyBtYW55IG9wZW4gZmlsZXMvLCAva2lsbGVkLipzaWduYWwgOS8sXG4gICAgICAvamF2YXNjcmlwdCBoZWFwIG91dCBvZiBtZW1vcnkvLFxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBjYXRlZ29yeTogJ2RlcGxveW1lbnQnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvY2xvdWRmb3JtYXRpb24uKnJvbGxiYWNrLywgL3N0YWNrLipyb2xsYmFja19jb21wbGV0ZS8sIC9jcmVhdGVfZmFpbGVkLywgL3VwZGF0ZV9yb2xsYmFjay8sXG4gICAgICAvY2RrIGRlcGxveS4qZmFpbGVkLywgL2Vjcy4qZGVwbG95bWVudC4qZmFpbGVkLywgL2RlcGxveW1lbnQuKmNpcmN1aXQgYnJlYWtlci8sXG4gICAgICAvaGVhbHRoIGNoZWNrLipmYWlsZWQuKnRhcmdldCBncm91cC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnaW5mcmFzdHJ1Y3R1cmUnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvdGhyb3R0bC8sIC9yYXRlIGV4Y2VlZGVkLywgL2xpbWl0ZXhjZWVkZWQvLCAvc2VydmljZXF1b3RhZXhjZWVkZWQvLFxuICAgICAgL2NhcGFjaXR5LywgL2luc3VmZmljaWVudGluc3RhbmNlY2FwYWNpdHkvLCAvaG9zdC4qdW5yZWFjaGFibGUvLFxuICAgICAgL2ludGVybmFsIHNlcnZpY2UgZXJyb3IvLCAvNVxcZFxcZC4qYXdzLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdleHRlcm5hbF9zZXJ2aWNlJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL2NvdWxkIG5vdCByZXNvbHZlIGhvc3QvLCAvZW5vdGZvdW5kLywgL2Vjb25ucmVmdXNlZC8sIC9lY29ubnJlc2V0LyxcbiAgICAgIC9nZXRhZGRyaW5mby8sIC9zb2NrZXQgaGFuZyB1cC8sIC9iYWQgZ2F0ZXdheS8sIC81MDJ8NTAzfDUwNC8sXG4gICAgICAvdXBzdHJlYW0uKnVuYXZhaWxhYmxlLywgL3JlZ2lzdHJ5Lip1bnJlYWNoYWJsZS8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9pcyBub3QgZGVmaW5lZC8sIC9ubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5LywgL2Vub2VudC8sIC9pbnZhbGlkLipjb25maWd1cmF0aW9uLyxcbiAgICAgIC9taXNzaW5nIHJlcXVpcmVkLiooPzp2YXJpYWJsZXxwYXJhbWV0ZXJ8aW5wdXQpLyxcbiAgICAgIC8vIEJvdGggb3JkZXJzOiBcInlhbWwgcGFyc2UgZXJyb3JcIiBhbmQgXCJlcnJvciBwYXJzaW5nIFlBTUxcIi5cbiAgICAgIC95YW1sLiooPzpwYXJzZXxwYXJzaW5nfHN5bnRheCkvLCAvKD86cGFyc2V8cGFyc2luZ3xzeW50YXgpLip5YW1sLyxcbiAgICAgIC91bmV4cGVjdGVkIHRva2VuLipqc29uLywgL2J1aWxkc3BlYy8sIC9jb21tYW5kIG5vdCBmb3VuZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnYnVpbGQnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvY29tcGlsYXRpb24gKD86ZmFpbGVkfGVycm9yKS8sIC9lcnJvciB0c1xcZCsvLCAvc3ludGF4IGVycm9yLywgL2Nhbm5vdCBmaW5kIG1vZHVsZS8sXG4gICAgICAvdW5kZWZpbmVkIHJlZmVyZW5jZS8sIC9idWlsZCBmYWlsZWQvLCAvd2VicGFjay4qZXJyb3IvLCAvdHNjLiplcnJvci8sXG4gICAgICAvZG9ja2VyIGJ1aWxkLipmYWlsZWQvLCAvZmFpbGVkIHRvIHNvbHZlLyxcbiAgICBdLFxuICB9LFxuXTtcblxuLyoqXG4gKiBUaGUgY2F0ZWdvcnkgZm9yIGEgZmFpbGVkIGFjdGlvbi5cbiAqXG4gKiBgbnVsbGAgZm9yIGFueXRoaW5nIHRoYXQgaXMgbm90IGEgZmFpbHVyZSDigJQgdGhlIGNhbGxlciBzdG9yZXMgbm90aGluZyByYXRoZXJcbiAqIHRoYW4gbGFiZWxsaW5nIGEgc3VjY2Vzcywgc28gYSBjYXRlZ29yeSdzIHByZXNlbmNlIGFsd2F5cyBtZWFucyBcInRoaXMgYnJva2VcIi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYXNzaWZ5RmFpbHVyZShpbnB1dDoge1xuICBzdGF0dXM6IHN0cmluZztcbiAgZXJyb3JNZXNzYWdlPzogc3RyaW5nIHwgbnVsbDtcbiAgYWN0aW9uTmFtZT86IHN0cmluZyB8IG51bGw7XG4gIHN0YWdlTmFtZT86IHN0cmluZyB8IG51bGw7XG59KTogRmFpbHVyZUNhdGVnb3J5IHwgbnVsbCB7XG4gIGNvbnN0IGZhaWxlZCA9IC9eKEZBSUxFRHxGQUlMVVJFfEVSUk9SfFRJTUVEX09VVCkkL2kudGVzdChpbnB1dC5zdGF0dXMpO1xuICBpZiAoIWZhaWxlZCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgdGV4dCA9IChpbnB1dC5lcnJvck1lc3NhZ2UgPz8gJycpLnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHdoZXJlID0gYCR7aW5wdXQuYWN0aW9uTmFtZSA/PyAnJ30gJHtpbnB1dC5zdGFnZU5hbWUgPz8gJyd9YDtcblxuICBmb3IgKGNvbnN0IHJ1bGUgb2YgUlVMRVMpIHtcbiAgICBpZiAocnVsZS5hY3Rpb24gJiYgIXJ1bGUuYWN0aW9uLnRlc3Qod2hlcmUpKSBjb250aW51ZTtcbiAgICBpZiAocnVsZS5wYXR0ZXJucy5zb21lKChwKSA9PiBwLnRlc3QodGV4dCkpKSByZXR1cm4gcnVsZS5jYXRlZ29yeTtcbiAgfVxuXG4gIC8vIE5vdGhpbmcgbWF0Y2hlZC4gYG90aGVyYCByYXRoZXIgdGhhbiBhIGd1ZXNzLCBhbmQgY291bnRlZCwgc28gdGhlIHNoYXJlIG9mXG4gIC8vIGBvdGhlcmAgbWVhc3VyZXMgaG93IGdvb2QgdGhlIHJ1bGVzIGFyZSBhbmQgbmFtZXMgdGhlIGdhcCB0byBjbG9zZS5cbiAgcmV0dXJuICdvdGhlcic7XG59XG5cbi8qKlxuICogQSBodW1hbiBsYWJlbCBmb3IgYSBjYXRlZ29yeSwgZm9yIHRoZSByZXBvcnQgYW5kIHRoZSBVSS5cbiAqXG4gKiBQaHJhc2VkIGFzIHdoYXQgYnJva2UgcmF0aGVyIHRoYW4gYXMgYW4gZW51bTogYSBtYW5hZ2VyIHJlYWRpbmdcbiAqIFwiRGVwZW5kZW5jeSByZXNvbHV0aW9uXCIgdW5kZXJzdGFuZHMgaXQsIGFuZCBgaW50ZWdyYXRpb25fdGVzdGAgZG9lcyBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBGQUlMVVJFX0NBVEVHT1JZX0xBQkVMUzogUmVjb3JkPEZhaWx1cmVDYXRlZ29yeSwgc3RyaW5nPiA9IHtcbiAgc291cmNlX2NoZWNrb3V0OiAnU291cmNlIGNoZWNrb3V0JyxcbiAgZGVwZW5kZW5jeTogJ0RlcGVuZGVuY3kgcmVzb2x1dGlvbicsXG4gIGJ1aWxkOiAnQnVpbGQgLyBjb21waWxlJyxcbiAgdW5pdF90ZXN0OiAnVW5pdCB0ZXN0cycsXG4gIGludGVncmF0aW9uX3Rlc3Q6ICdJbnRlZ3JhdGlvbiB0ZXN0cycsXG4gIHNlY3VyaXR5X3NjYW46ICdTZWN1cml0eSBzY2FuJyxcbiAgaW5mcmFzdHJ1Y3R1cmU6ICdDbG91ZCBpbmZyYXN0cnVjdHVyZScsXG4gIGRlcGxveW1lbnQ6ICdEZXBsb3ltZW50JyxcbiAgYXV0aGVudGljYXRpb246ICdBdXRoZW50aWNhdGlvbicsXG4gIHBlcm1pc3Npb25zOiAnUGVybWlzc2lvbnMnLFxuICBjb25maWd1cmF0aW9uOiAnQ29uZmlndXJhdGlvbicsXG4gIHRpbWVvdXQ6ICdUaW1lb3V0JyxcbiAgcmVzb3VyY2VfZXhoYXVzdGlvbjogJ091dCBvZiByZXNvdXJjZXMnLFxuICBleHRlcm5hbF9zZXJ2aWNlOiAnRXh0ZXJuYWwgc2VydmljZScsXG4gIG90aGVyOiAnVW5jbGFzc2lmaWVkJyxcbn07XG5cbi8qKlxuICogV2hldGhlciBhIGNhdGVnb3J5IGlzIHNvbWV0aGluZyB0aGUgVEVBTSBjYW4gYWN0IG9uLCBhcyBvcHBvc2VkIHRvIHNvbWV0aGluZ1xuICogdGhhdCBoYXBwZW5lZCB0byB0aGVtLlxuICpcbiAqIFVzZWQgYnkgdGhlIGZhaWx1cmUtYW5hbHlzaXMgc2VjdGlvbiB0byBzZXBhcmF0ZSB0aGUgdHdvLCBiZWNhdXNlIGEgd2VlayB3aG9zZVxuICogZmFpbHVyZXMgd2VyZSBhbGwgY2xvdWQgdGhyb3R0bGluZyBpcyBhIGRpZmZlcmVudCBjb252ZXJzYXRpb24gZnJvbSBvbmUgd2hvc2VcbiAqIGZhaWx1cmVzIHdlcmUgYWxsIGJyb2tlbiB0ZXN0cyDigJQgYW5kIHByZXNlbnRpbmcgdGhlbSBpbiBvbmUgcmFua2VkIGxpc3QgaW52aXRlc1xuICogZXhhY3RseSB0aGUgd3JvbmcgY29uY2x1c2lvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVGVhbUFjdGlvbmFibGUoY2F0ZWdvcnk6IEZhaWx1cmVDYXRlZ29yeSk6IGJvb2xlYW4ge1xuICByZXR1cm4gIVsnaW5mcmFzdHJ1Y3R1cmUnLCAnZXh0ZXJuYWxfc2VydmljZSddLmluY2x1ZGVzKGNhdGVnb3J5KTtcbn1cbiJdfQ==
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IngestEvent, IngestMetric, IngestResult } from './types.js';
|
|
1
|
+
import type { IngestCaller, IngestEvent, IngestMetric, IngestResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Resolve incoming events against the pipeline registry, batch-insert the
|
|
4
4
|
* matched ones, and invalidate reporting caches for affected orgs.
|
|
@@ -8,4 +8,4 @@ import type { IngestEvent, IngestMetric, IngestResult } from './types.js';
|
|
|
8
8
|
*
|
|
9
9
|
* Returns counts + a sample of unregistered pipeline ids for observability.
|
|
10
10
|
*/
|
|
11
|
-
export declare function ingestEvents(events: IngestEvent[], onMetric?: (m: IngestMetric) => void): Promise<IngestResult>;
|
|
11
|
+
export declare function ingestEvents(events: IngestEvent[], onMetric?: (m: IngestMetric) => void, caller?: IngestCaller): Promise<IngestResult>;
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
import { createLogger, errorMessage, scrubAwsIdentifiers } from '@pipeline-builder/api-core';
|
|
11
11
|
import { inArray } from 'drizzle-orm';
|
|
12
12
|
import { invalidateOrgReports } from './caches.js';
|
|
13
|
+
import { upsertDeployments } from './deploy-rollup.js';
|
|
14
|
+
import { classifyFailure } from './failure-classifier.js';
|
|
13
15
|
import { scrubOptional } from './sql-helpers.js';
|
|
14
16
|
import { schema } from '../../database/drizzle-schema.js';
|
|
15
17
|
import { withTenantTx } from '../../database/tenancy.js';
|
|
@@ -47,6 +49,50 @@ async function loadStepPlugins(tx, attributable) {
|
|
|
47
49
|
.where(inArray(schema.pipelineStepManifest.pipelineId, pipelineIds));
|
|
48
50
|
return new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m]));
|
|
49
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Allowance for clock skew between an AWS event's source clock and ours. A real
|
|
54
|
+
* CodePipeline event can carry a timestamp a little ahead of our `now`; without
|
|
55
|
+
* some tolerance the validation below would drop healthy events during normal
|
|
56
|
+
* NTP drift, which is far worse than admitting a few seconds of skew.
|
|
57
|
+
*/
|
|
58
|
+
const CLOCK_SKEW_TOLERANCE_MS = 5 * 60 * 1000;
|
|
59
|
+
/**
|
|
60
|
+
* Why this event's timestamps are impossible, or null when they are usable.
|
|
61
|
+
*
|
|
62
|
+
* Checked at INGEST — the durable boundary — rather than clamped when the metrics
|
|
63
|
+
* are computed. A negative duration or a future deploy used to be clamped to 0
|
|
64
|
+
* downstream, which reported a broken clock as an instant deploy and quietly
|
|
65
|
+
* moved deployment frequency, change-failure rate and lead time for the org.
|
|
66
|
+
*
|
|
67
|
+
* NOT checked here: commit time vs deploy completion. `commit_timestamp` rides the
|
|
68
|
+
* PIPELINE/source event while the deploy's `completed_at` is on a separate STAGE
|
|
69
|
+
* row, joined by `execution_id` only when DORA is queried — so no single event
|
|
70
|
+
* carries both, and that ordering can only be guarded where the two meet.
|
|
71
|
+
*/
|
|
72
|
+
function invalidEventTimes(event, nowMs) {
|
|
73
|
+
const ceiling = nowMs + CLOCK_SKEW_TOLERANCE_MS;
|
|
74
|
+
const parsed = [];
|
|
75
|
+
for (const field of ['startedAt', 'completedAt', 'commitTimestamp']) {
|
|
76
|
+
const raw = event[field];
|
|
77
|
+
if (raw === undefined || raw === null)
|
|
78
|
+
continue;
|
|
79
|
+
const ms = Date.parse(String(raw));
|
|
80
|
+
if (!Number.isFinite(ms))
|
|
81
|
+
return `${field} is not a parseable timestamp`;
|
|
82
|
+
if (ms > ceiling)
|
|
83
|
+
return `${field} is in the future`;
|
|
84
|
+
parsed.push([field, ms]);
|
|
85
|
+
}
|
|
86
|
+
const started = parsed.find(([f]) => f === 'startedAt')?.[1];
|
|
87
|
+
const completed = parsed.find(([f]) => f === 'completedAt')?.[1];
|
|
88
|
+
if (started !== undefined && completed !== undefined && completed < started) {
|
|
89
|
+
return 'completedAt is before startedAt';
|
|
90
|
+
}
|
|
91
|
+
if (event.durationMs !== undefined && event.durationMs !== null && event.durationMs < 0) {
|
|
92
|
+
return 'durationMs is negative';
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
50
96
|
/**
|
|
51
97
|
* The persisted row for one ingested event. This is the DURABLE persistence
|
|
52
98
|
* boundary: every user/AWS-derived free-form string is scrubbed here, and
|
|
@@ -87,6 +133,16 @@ function toEventRow(event, registry, plugin) {
|
|
|
87
133
|
pluginPublisherId: plugin?.pluginPublisherId ?? null,
|
|
88
134
|
pluginName: plugin?.pluginName ?? null,
|
|
89
135
|
pluginVersion: plugin?.pluginVersion ?? null,
|
|
136
|
+
// WHAT KIND of thing broke, classified here rather than at read time: the
|
|
137
|
+
// error text is scrubbed above and eventually swept by retention, so a
|
|
138
|
+
// category derived later would have nothing left to read. NULL for anything
|
|
139
|
+
// that is not a failure, so its presence always means "this broke".
|
|
140
|
+
failureCategory: classifyFailure({
|
|
141
|
+
status: event.status,
|
|
142
|
+
errorMessage: scrubOptional(event.errorMessage),
|
|
143
|
+
actionName: scrubOptional(event.actionName),
|
|
144
|
+
stageName: scrubOptional(event.stageName),
|
|
145
|
+
}),
|
|
90
146
|
detail: event.detail !== undefined ? scrubAwsIdentifiers(event.detail) : undefined,
|
|
91
147
|
};
|
|
92
148
|
}
|
|
@@ -118,7 +174,19 @@ function emitStageMetrics(rows, onMetric) {
|
|
|
118
174
|
*
|
|
119
175
|
* Returns counts + a sample of unregistered pipeline ids for observability.
|
|
120
176
|
*/
|
|
121
|
-
export async function ingestEvents(events, onMetric) {
|
|
177
|
+
export async function ingestEvents(events, onMetric, caller) {
|
|
178
|
+
// TENANCY. An event's org comes from the pipeline REGISTRY, not the token, so
|
|
179
|
+
// the scope check alone let any `reporting:ingest` holder post events for
|
|
180
|
+
// another org's pipeline id and have them attributed there. `caller` carries
|
|
181
|
+
// the org ids this token may write for; anything else is dropped below.
|
|
182
|
+
//
|
|
183
|
+
// `caller` is optional only so in-process callers that already run
|
|
184
|
+
// cross-tenant (tests, backfills) keep working — an ABSENT caller means "no
|
|
185
|
+
// restriction", and the route always supplies one. A caller with an EMPTY
|
|
186
|
+
// allow-list and no crossTenant flag therefore drops everything, which is the
|
|
187
|
+
// right answer when the route could not establish who is writing.
|
|
188
|
+
const unrestricted = caller === undefined || caller.crossTenant === true;
|
|
189
|
+
const allowed = new Set(caller?.allowedOrgIds ?? []);
|
|
122
190
|
// Multi-org batch insert: the caller resolves to multiple orgs via the
|
|
123
191
|
// pipeline-registry lookup below, so the route layer MUST establish a
|
|
124
192
|
// `runWithTenantContext({ isSuperAdmin: true }, ...)` scope before calling
|
|
@@ -129,7 +197,7 @@ export async function ingestEvents(events, onMetric) {
|
|
|
129
197
|
// Caches are invalidated AFTER the tx resolves: doing it inside held the pg
|
|
130
198
|
// locks open across unrelated cache round-trips. The TTL is 2-5 min, so a
|
|
131
199
|
// fire-and-forget post-commit invalidation is an acceptable trade.
|
|
132
|
-
const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, insertedRows } = await withTenantTx(async (tx) => {
|
|
200
|
+
const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime, insertedRows } = await withTenantTx(async (tx) => {
|
|
133
201
|
// Batch-resolve all unique pipeline ids in one query
|
|
134
202
|
const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
|
|
135
203
|
const registryRows = await tx
|
|
@@ -144,7 +212,14 @@ export async function ingestEvents(events, onMetric) {
|
|
|
144
212
|
// Build insert batch (skip events whose pipeline isn't registered)
|
|
145
213
|
const rows = [];
|
|
146
214
|
let skippedLocal = 0;
|
|
215
|
+
let foreignLocal = 0;
|
|
216
|
+
let invalidTimeLocal = 0;
|
|
217
|
+
const invalidTimeReasons = new Set();
|
|
218
|
+
const foreignOrgIds = new Set();
|
|
147
219
|
const unregisteredLocal = [];
|
|
220
|
+
// One `now` for the whole batch: per-event clocks would let an event pass or
|
|
221
|
+
// fail depending on where it sat in the loop.
|
|
222
|
+
const nowMs = Date.now();
|
|
148
223
|
for (const event of events) {
|
|
149
224
|
const registry = idMap.get(event.pipelineId);
|
|
150
225
|
if (!registry) {
|
|
@@ -152,6 +227,22 @@ export async function ingestEvents(events, onMetric) {
|
|
|
152
227
|
unregisteredLocal.push(event.pipelineId);
|
|
153
228
|
continue;
|
|
154
229
|
}
|
|
230
|
+
// The pipeline resolves to an org this caller may not write for. Counted
|
|
231
|
+
// separately from `skipped` (an unregistered id is a producer running
|
|
232
|
+
// ahead of registration; this is a tenancy refusal) and never inserted.
|
|
233
|
+
if (!unrestricted && !allowed.has(registry.orgId)) {
|
|
234
|
+
foreignLocal++;
|
|
235
|
+
foreignOrgIds.add(registry.orgId);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
// Impossible timestamps are refused at the boundary, so no downstream
|
|
239
|
+
// metric has to clamp a negative gap and call it zero.
|
|
240
|
+
const badTime = invalidEventTimes(event, nowMs);
|
|
241
|
+
if (badTime) {
|
|
242
|
+
invalidTimeLocal++;
|
|
243
|
+
invalidTimeReasons.add(badTime);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
155
246
|
const stageName = scrubOptional(event.stageName);
|
|
156
247
|
const actionName = scrubOptional(event.actionName);
|
|
157
248
|
const step = isAttributable(event) && stageName && actionName
|
|
@@ -176,18 +267,52 @@ export async function ingestEvents(events, onMetric) {
|
|
|
176
267
|
status: schema.pipelineEvent.status,
|
|
177
268
|
stageName: schema.pipelineEvent.stageName,
|
|
178
269
|
environment: schema.pipelineEvent.environment,
|
|
270
|
+
// For the per-deploy rollup below: everything `dora_deployments` needs,
|
|
271
|
+
// taken from the rows that ACTUALLY landed so a re-delivery cannot
|
|
272
|
+
// produce a second deploy.
|
|
273
|
+
executionId: schema.pipelineEvent.executionId,
|
|
274
|
+
commitSha: schema.pipelineEvent.commitSha,
|
|
275
|
+
commitTimestamp: schema.pipelineEvent.commitTimestamp,
|
|
276
|
+
commitCount: schema.pipelineEvent.commitCount,
|
|
277
|
+
completedAt: schema.pipelineEvent.completedAt,
|
|
278
|
+
startedAt: schema.pipelineEvent.startedAt,
|
|
279
|
+
createdAt: schema.pipelineEvent.createdAt,
|
|
280
|
+
detail: schema.pipelineEvent.detail,
|
|
179
281
|
})
|
|
180
282
|
: [];
|
|
283
|
+
// Log inside the tx scope while the org set is in hand. WARN, not error:
|
|
284
|
+
// a misrouted producer is the common cause, but the same line is the only
|
|
285
|
+
// signal of an injection attempt, so it names the orgs it refused.
|
|
286
|
+
if (foreignLocal > 0) {
|
|
287
|
+
logger.warn('Dropped ingest events for orgs the caller may not write for', {
|
|
288
|
+
dropped: foreignLocal,
|
|
289
|
+
foreignOrgIds: [...foreignOrgIds],
|
|
290
|
+
allowedOrgIds: [...allowed],
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (invalidTimeLocal > 0) {
|
|
294
|
+
logger.warn('Dropped ingest events with impossible timestamps', {
|
|
295
|
+
dropped: invalidTimeLocal,
|
|
296
|
+
reasons: [...invalidTimeReasons],
|
|
297
|
+
});
|
|
298
|
+
}
|
|
181
299
|
return {
|
|
182
300
|
inserted: landed.length,
|
|
183
301
|
skipped: skippedLocal,
|
|
184
302
|
unregisteredPipelineIds: unregisteredLocal,
|
|
185
303
|
affectedOrgs: [...new Set(landed.map(r => r.orgId))],
|
|
304
|
+
droppedForeignOrg: foreignLocal,
|
|
305
|
+
droppedInvalidTime: invalidTimeLocal,
|
|
186
306
|
insertedRows: landed,
|
|
187
307
|
};
|
|
188
308
|
});
|
|
189
309
|
if (onMetric)
|
|
190
310
|
emitStageMetrics(insertedRows, onMetric);
|
|
311
|
+
// Per-deploy rollup. AFTER the events commit and outside their transaction: the
|
|
312
|
+
// events are the durable record and `dora_deployments` is derived from them, so
|
|
313
|
+
// a rollup failure must not roll back an ingest that succeeded. Rebuildable
|
|
314
|
+
// either way. `upsertDeployments` never throws for that reason.
|
|
315
|
+
await upsertDeployments(insertedRows);
|
|
191
316
|
// Surface the silent skip: an unregistered pipeline id usually means the
|
|
192
317
|
// pipeline hasn't called POST /pipelines/registry yet (or its
|
|
193
318
|
// pb.pipeline-id tag is missing/unreadable by the Lambda). Logging it
|
|
@@ -205,6 +330,6 @@ export async function ingestEvents(events, onMetric) {
|
|
|
205
330
|
logger.warn('Reporting cache invalidation failed', { orgId: org, error: errorMessage(err) });
|
|
206
331
|
})));
|
|
207
332
|
}
|
|
208
|
-
return { inserted, skipped, unregisteredPipelineIds, affectedOrgs };
|
|
333
|
+
return { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime };
|
|
209
334
|
}
|
|
210
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvaW5nZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUd6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQWNoRCxxRUFBcUU7QUFDckUsU0FBUyxjQUFjLENBQUMsQ0FBYztJQUNwQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUM7V0FDdkQsQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLGNBQWMsSUFBSSxDQUFDLENBQUMsV0FBVyxLQUFLLFdBQVcsQ0FBQztXQUNuRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUN2QyxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsVUFBa0IsRUFBRSxTQUFpQixFQUFFLFVBQWtCO0lBQ3hFLE9BQU8sR0FBRyxVQUFVLFNBQVMsU0FBUyxTQUFTLFVBQVUsRUFBRSxDQUFDO0FBQzlELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLGVBQWUsQ0FBQyxF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QUFDLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUV2RCx5RUFBeUU7SUFDekUsOERBQThEO0lBQzlELHNFQUFzRTtJQUN0RSxxRUFBcUU7SUFDckUsSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdkMsTUFBTSxDQUFDLElBQUksQ0FBQyw0REFBNEQsRUFBRTtZQUN4RSxLQUFLLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtZQUNyQyxNQUFNLEVBQUUsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDNUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxzREFBc0Q7SUFDdEQsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVCLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDeEMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0YsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFlBQVksRUFBRSxDQUFDO0FBQ3RFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBFdmVudCBpbmdlc3Q6IHRoZSBXUklURSBoYWxmIG9mIHJlcG9ydGluZy4gUmVzb2x2ZXMgaW5jb21pbmcgcGlwZWxpbmUgZXZlbnRzXG4gKiBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgc2NydWJzIGV2ZXJ5IGZyZWUtZm9ybSBzdHJpbmcsIGJhdGNoLWluc2VydHNcbiAqIHRoZSBtYXRjaGVkIHJvd3MgaWRlbXBvdGVudGx5LCBhbmQgaW52YWxpZGF0ZXMgdGhlIGFmZmVjdGVkIG9yZ3MnIHJlcG9ydFxuICogY2FjaGVzLiBTZXBhcmF0ZSBmcm9tIHRoZSByZXBvcnQgcXVlcmllcyBiZWNhdXNlIHRoaXMgaXMgcmVwb3J0aW5nJ3Mgb25seVxuICogZHVyYWJsZSBwZXJzaXN0ZW5jZSBib3VuZGFyeSDigJQgZXZlcnl0aGluZyBlbHNlIGluIHRoZSBzZXJ2aWNlIG9ubHkgcmVhZHMuXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlcnJvck1lc3NhZ2UsIHNjcnViQXdzSWRlbnRpZmllcnMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBpbkFycmF5IH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgaW52YWxpZGF0ZU9yZ1JlcG9ydHMgfSBmcm9tICcuL2NhY2hlcy5qcyc7XG5pbXBvcnQgeyBzY3J1Yk9wdGlvbmFsIH0gZnJvbSAnLi9zcWwtaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7IEluZ2VzdEV2ZW50LCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5pbXBvcnQgdHlwZSB7IENydWRUeCB9IGZyb20gJy4uL2NydWQtc2VydmljZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLWluZ2VzdCcpO1xuXG50eXBlIFBpcGVsaW5lRXZlbnRJbnNlcnQgPSB0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0O1xuXG5cbi8qKiBUaGUgcGx1Z2luIGEgcGlwZWxpbmUgc3RlcCBydW5zLCBmcm9tIHRoZSBzdGVwIG1hbmlmZXN0IGl0cyBsYXN0IGRlcGxveSByZWdpc3RlcmVkLiAqL1xuaW50ZXJmYWNlIFN0ZXBQbHVnaW4ge1xuICBvcmdJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblB1Ymxpc2hlcklkOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKiogQW4gYWN0aW9uL2J1aWxkIGV2ZW50IHRoYXQgY2FuIGJlIGF0dHJpYnV0ZWQgdG8gYSBwbHVnaW4gc3RlcC4gKi9cbmZ1bmN0aW9uIGlzQXR0cmlidXRhYmxlKGU6IEluZ2VzdEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiAoZS5ldmVudFR5cGUgPT09ICdBQ1RJT04nIHx8IGUuZXZlbnRUeXBlID09PSAnQlVJTEQnKVxuICAgICYmIChlLmV2ZW50U291cmNlID09PSAnY29kZXBpcGVsaW5lJyB8fCBlLmV2ZW50U291cmNlID09PSAnY29kZWJ1aWxkJylcbiAgICAmJiAhIWUuc3RhZ2VOYW1lICYmICEhZS5hY3Rpb25OYW1lO1xufVxuXG5mdW5jdGlvbiBzdGVwS2V5KHBpcGVsaW5lSWQ6IHN0cmluZywgc3RhZ2VOYW1lOiBzdHJpbmcsIGFjdGlvbk5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtwaXBlbGluZUlkfVxcdTAwMDAke3N0YWdlTmFtZX1cXHUwMDAwJHthY3Rpb25OYW1lfWA7XG59XG5cbi8qKlxuICogUGx1Z2luIGF0dHJpYnV0aW9uOiB0aGUgc3RlcCBtYW5pZmVzdHMgb2YgZXZlcnkgcGlwZWxpbmUgd2l0aCBhbiBhdHRyaWJ1dGFibGVcbiAqIGV2ZW50LCBpbiBPTkUgcmVhZCBwZXIgYmF0Y2gsIGtleWVkIGZvciBhbiBpbi1tZW1vcnkgam9pbi4gTmFtZXMgYXJlIGNvbXBhcmVkXG4gKiBwb3N0LXNjcnViIG9uIGJvdGggc2lkZXMgKHRoZSBtYW5pZmVzdCBzdG9yZXMgdGhlbSBzY3J1YmJlZCB0aGUgc2FtZSB3YXkpLlxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkU3RlcFBsdWdpbnModHg6IENydWRUeCwgYXR0cmlidXRhYmxlOiBJbmdlc3RFdmVudFtdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBTdGVwUGx1Z2luPj4ge1xuICBjb25zdCBwaXBlbGluZUlkcyA9IFsuLi5uZXcgU2V0KGF0dHJpYnV0YWJsZS5tYXAoKGUpID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgaWYgKHBpcGVsaW5lSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBNYXAoKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHR4XG4gICAgLnNlbGVjdCh7XG4gICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Qub3JnSWQsXG4gICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5zdGFnZU5hbWUsXG4gICAgICBhY3Rpb25OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QuYWN0aW9uTmFtZSxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcixcbiAgICAgIHBsdWdpblB1Ymxpc2hlcklkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVySWQsXG4gICAgICBwbHVnaW5OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5WZXJzaW9uLFxuICAgIH0pXG4gICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0KVxuICAgIC53aGVyZShpbkFycmF5KHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLCBwaXBlbGluZUlkcykpO1xuICByZXR1cm4gbmV3IE1hcChyb3dzLm1hcCgobSkgPT4gW3N0ZXBLZXkobS5waXBlbGluZUlkLCBtLnN0YWdlTmFtZSwgbS5hY3Rpb25OYW1lKSwgbV0pKTtcbn1cblxuLyoqXG4gKiBUaGUgcGVyc2lzdGVkIHJvdyBmb3Igb25lIGluZ2VzdGVkIGV2ZW50LiBUaGlzIGlzIHRoZSBEVVJBQkxFIHBlcnNpc3RlbmNlXG4gKiBib3VuZGFyeTogZXZlcnkgdXNlci9BV1MtZGVyaXZlZCBmcmVlLWZvcm0gc3RyaW5nIGlzIHNjcnViYmVkIGhlcmUsIGFuZFxuICogdGVuYW5jeSBjb21lcyBmcm9tIHRoZSBwaXBlbGluZSByZWdpc3RyeSwgbmV2ZXIgdGhlIGNhbGxlcidzIGNsYWltZWQgb3JnLlxuICovXG5mdW5jdGlvbiB0b0V2ZW50Um93KGV2ZW50OiBJbmdlc3RFdmVudCwgcmVnaXN0cnk6IHsgcGlwZWxpbmVJZDogc3RyaW5nOyBvcmdJZDogc3RyaW5nIH0sIHBsdWdpbjogU3RlcFBsdWdpbiB8IHVuZGVmaW5lZCk6IFBpcGVsaW5lRXZlbnRJbnNlcnQge1xuICByZXR1cm4ge1xuICAgIC8vIHJlZ2lzdHJ5LnBpcGVsaW5lSWQgPT09IGV2ZW50LnBpcGVsaW5lSWQ7IHRoZSByZWdpc3RyeSdzIGlzIGFsd2F5cyBhIHJvd1xuICAgIC8vIHRoYXQgZXhpc3RzIChGSykgYW5kIGl0cyBvcmdJZCBpcyB0aGUgdHJ1c3RlZCB0ZW5hbnQuXG4gICAgcGlwZWxpbmVJZDogcmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICBvcmdJZDogcmVnaXN0cnkub3JnSWQsXG4gICAgZXZlbnRTb3VyY2U6IGV2ZW50LmV2ZW50U291cmNlLFxuICAgIGV2ZW50VHlwZTogZXZlbnQuZXZlbnRUeXBlLFxuICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgIC8vIEFuIEFXUy1BU1NJR05FRCBVVUlELCBub3QgZnJlZS1mb3JtIHRleHQ6IGl0IGNhbid0IGNhcnJ5IGFuIGFjY291bnQgaWQsXG4gICAgLy8gYW5kIHNjcnViYmluZyBhIDEyLWRpZ2l0IHJ1biBpbnNpZGUgaXQgd291bGQgY29ycnVwdCB0aGUgY29ycmVsYXRpb24ga2V5LlxuICAgIGV4ZWN1dGlvbklkOiBldmVudC5leGVjdXRpb25JZCxcbiAgICAvLyBVU0VSLUFVVEhPUkVEIHBpcGVsaW5lLXN0cnVjdHVyZSBuYW1lcyDigJQgc2FtZSB1bnRydXN0ZWQgb3JpZ2luIGFzXG4gICAgLy8gZXJyb3JNZXNzYWdlLCBzbyBzY3J1YmJlZCAoYSBzdGFnZSBuYW1lZCB3aXRoIGFuIEFSTiBtdXN0IG5vdCBwZXJzaXN0KS5cbiAgICBzdGFnZU5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKSxcbiAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgIC8vIEhBUkQgQ09OU1RSQUlOVDogYW4gQVdTIGFjY291bnQgaWQgbXVzdCBORVZFUiBiZSBwZXJzaXN0ZWQuIEZhaWx1cmUgZGV0YWlsXG4gICAgLy8gYW5kIG1lc3NhZ2VzIHJvdXRpbmVseSBjYXJyeSBBUk5zIGFuZCBiYXJlIDEyLWRpZ2l0IGFjY291bnQgaWRzLlxuICAgIGVycm9yTWVzc2FnZTogc2NydWJPcHRpb25hbChldmVudC5lcnJvck1lc3NhZ2UpLFxuICAgIHN0YXJ0ZWRBdDogZXZlbnQuc3RhcnRlZEF0ID8gbmV3IERhdGUoZXZlbnQuc3RhcnRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBjb21wbGV0ZWRBdDogZXZlbnQuY29tcGxldGVkQXQgPyBuZXcgRGF0ZShldmVudC5jb21wbGV0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgZHVyYXRpb25NczogZXZlbnQuZHVyYXRpb25NcyxcbiAgICAvLyBEZXBsb3kgYXR0cmlidXRpb24g4oCUIHNjcnViYmVkIGxpa2UgdGhlIG90aGVyIGZyZWUtZm9ybSBzdHJpbmdzLlxuICAgIGNvbW1pdFNoYTogc2NydWJPcHRpb25hbChldmVudC5jb21taXRTaGEpLFxuICAgIGNvbW1pdFJlZjogc2NydWJPcHRpb25hbChldmVudC5jb21taXRSZWYpLFxuICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVudmlyb25tZW50KSxcbiAgICAvLyBNZWFzdXJlZCBsZWFkIHRpbWU6IHRoZSBvbGRlc3QgdW5zaGlwcGVkIGNvbW1pdCdzIHRpbWUgKyB0aGUgY291bnQuIEFuXG4gICAgLy8gU0NNLWRlcml2ZWQgaW5zdGFudCBhbmQgYSBwbGFpbiBpbnRlZ2VyIOKAlCBub3RoaW5nIHRvIHNjcnViLlxuICAgIGNvbW1pdFRpbWVzdGFtcDogZXZlbnQuY29tbWl0VGltZXN0YW1wID8gbmV3IERhdGUoZXZlbnQuY29tbWl0VGltZXN0YW1wKSA6IHVuZGVmaW5lZCxcbiAgICBjb21taXRDb3VudDogZXZlbnQuY29tbWl0Q291bnQsXG4gICAgLy8gTlVMTCBmb3Igbm9uLXBsdWdpbiBhY3Rpb25zIGFuZCBmb3IgcGlwZWxpbmVzIGRlcGxveWVkIHdpdGhvdXQgYSBtYW5pZmVzdC5cbiAgICBwbHVnaW5QdWJsaXNoZXI6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVyID8/IG51bGwsXG4gICAgcGx1Z2luUHVibGlzaGVySWQ6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVySWQgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBwbHVnaW4/LnBsdWdpbk5hbWUgPz8gbnVsbCxcbiAgICBwbHVnaW5WZXJzaW9uOiBwbHVnaW4/LnBsdWdpblZlcnNpb24gPz8gbnVsbCxcbiAgICBkZXRhaWw6IGV2ZW50LmRldGFpbCAhPT0gdW5kZWZpbmVkID8gc2NydWJBd3NJZGVudGlmaWVycyhldmVudC5kZXRhaWwpIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEZhbiB0ZXJtaW5hbCBTVEFHRSBvdXRjb21lcyBpbnRvIHRoZSByb3V0ZSdzIG1ldHJpYyBob29rIChwaXBlbGluZS1kYXRhIGNhbid0XG4gKiBpbXBvcnQgYXBpLXNlcnZlcidzIHJlZ2lzdHJ5KSBhZnRlciB0aGUgaW5zZXJ0IGNvbW1pdHMuIERyaXZlbiBvZmYgdGhlXG4gKiBJTlNFUlRFRCByb3dzLCBzbyBhIHJlLWRlbGl2ZXJlZCBldmVudCB0aGUgZGVkdXAgaW5kZXggc3dhbGxvd2VkIGlzIG5ldmVyXG4gKiBjb3VudGVkIHR3aWNlLiBBIG5vbi1udWxsIGVudmlyb25tZW50IG1hcmtzIGEgZGVwbG95LlxuICovXG5mdW5jdGlvbiBlbWl0U3RhZ2VNZXRyaWNzKFxuICByb3dzOiBSZWFkb25seUFycmF5PHsgb3JnSWQ6IHN0cmluZzsgcGlwZWxpbmVJZDogc3RyaW5nIHwgbnVsbDsgZXZlbnRUeXBlOiBzdHJpbmc7IHN0YXR1czogc3RyaW5nOyBzdGFnZU5hbWU6IHN0cmluZyB8IG51bGw7IGVudmlyb25tZW50OiBzdHJpbmcgfCBudWxsIH0+LFxuICBvbk1ldHJpYzogKG06IEluZ2VzdE1ldHJpYykgPT4gdm9pZCxcbik6IHZvaWQge1xuICBmb3IgKGNvbnN0IHIgb2Ygcm93cykge1xuICAgIGlmIChyLmV2ZW50VHlwZSAhPT0gJ1NUQUdFJyB8fCAoci5zdGF0dXMgIT09ICdTVUNDRUVERUQnICYmIHIuc3RhdHVzICE9PSAnRkFJTEVEJykgfHwgIXIucGlwZWxpbmVJZCkgY29udGludWU7XG4gICAgb25NZXRyaWMoe1xuICAgICAgcGlwZWxpbmVJZDogci5waXBlbGluZUlkLFxuICAgICAgb3JnSWQ6IHIub3JnSWQsXG4gICAgICBzdGFnZTogci5zdGFnZU5hbWUgPz8gJycsXG4gICAgICBlbnZpcm9ubWVudDogci5lbnZpcm9ubWVudCA/PyBudWxsLFxuICAgICAgcmVzdWx0OiByLnN0YXR1cyA9PT0gJ1NVQ0NFRURFRCcgPyAnc3VjY2VlZGVkJyA6ICdmYWlsZWQnLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZSBpbmNvbWluZyBldmVudHMgYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIGJhdGNoLWluc2VydCB0aGVcbiAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gKiB3aXRoIHNhbXBsZSBpZHMgc28gYW4gb3BlcmF0b3IgY2FuIHNlZSB3aGVuIEV2ZW50QnJpZGdlIGlzIGRlbGl2ZXJpbmdcbiAqIGV2ZW50cyBmb3IgcGlwZWxpbmVzIHRoYXQgaGF2ZW4ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCkuXG4gKlxuICogUmV0dXJucyBjb3VudHMgKyBhIHNhbXBsZSBvZiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWRzIGZvciBvYnNlcnZhYmlsaXR5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5nZXN0RXZlbnRzKGV2ZW50czogSW5nZXN0RXZlbnRbXSwgb25NZXRyaWM/OiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkKTogUHJvbWlzZTxJbmdlc3RSZXN1bHQ+IHtcbiAgLy8gTXVsdGktb3JnIGJhdGNoIGluc2VydDogdGhlIGNhbGxlciByZXNvbHZlcyB0byBtdWx0aXBsZSBvcmdzIHZpYSB0aGVcbiAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAvLyBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgLi4uKWAgc2NvcGUgYmVmb3JlIGNhbGxpbmdcbiAgLy8gdGhpcyBmdW5jdGlvbi4gVW5kZXIgRk9SQ0UnZCBSTFMsIGEgc2luZ2xlIHR4IHdpdGggYGFwcC5vcmdfaWQgPSA8b25lXG4gIC8vIG9yZz5gIGNvdWxkIG9ubHkgd3JpdGUgZXZlbnRzIGZvciB0aGF0IG9yZzsgYnlwYXNzIHZpYSBzeXNhZG1pbiBpc1xuICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgLy8gYXBpL3JlcG9ydGluZy9zcmMvcm91dGVzL2V2ZW50LWluZ2VzdC50cyBmb3IgdGhlIHdyYXBwZXIuXG4gIC8vIENhY2hlcyBhcmUgaW52YWxpZGF0ZWQgQUZURVIgdGhlIHR4IHJlc29sdmVzOiBkb2luZyBpdCBpbnNpZGUgaGVsZCB0aGUgcGdcbiAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBvc3QtY29tbWl0IGludmFsaWRhdGlvbiBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLlxuICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgIGNvbnN0IHVuaXF1ZUlkcyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICBjb25zdCBzdGVwUGx1Z2lucyA9IGF3YWl0IGxvYWRTdGVwUGx1Z2lucyh0eCwgZXZlbnRzLmZpbHRlcigoZSkgPT4gaXNBdHRyaWJ1dGFibGUoZSkgJiYgaWRNYXAuaGFzKGUucGlwZWxpbmVJZCkpKTtcblxuICAgIC8vIEJ1aWxkIGluc2VydCBiYXRjaCAoc2tpcCBldmVudHMgd2hvc2UgcGlwZWxpbmUgaXNuJ3QgcmVnaXN0ZXJlZClcbiAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICBsZXQgc2tpcHBlZExvY2FsID0gMDtcbiAgICBjb25zdCB1bnJlZ2lzdGVyZWRMb2NhbDogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGlkTWFwLmdldChldmVudC5waXBlbGluZUlkKTtcbiAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgIHVucmVnaXN0ZXJlZExvY2FsLnB1c2goZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSk7XG4gICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgID8gc3RlcFBsdWdpbnMuZ2V0KHN0ZXBLZXkocmVnaXN0cnkucGlwZWxpbmVJZCwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAvLyBvd25zIHRoZSBwaXBlbGluZSwgYnV0IHRoZSBpbmdlc3QgcnVucyBjcm9zcy10ZW5hbnQsIHNvIGRvbid0IGxlYW4gb24gaXQuXG4gICAgICByb3dzLnB1c2godG9FdmVudFJvdyhldmVudCwgcmVnaXN0cnksIHN0ZXAgJiYgc3RlcC5vcmdJZCA9PT0gcmVnaXN0cnkub3JnSWQgPyBzdGVwIDogdW5kZWZpbmVkKSk7XG4gICAgfVxuXG4gICAgLy8gU1FTIGlzIGF0LWxlYXN0LW9uY2UsIHNvIEV2ZW50QnJpZGdlIGNhbiBkZWxpdmVyIHRoZSBzYW1lIHN0YXRlLWNoYW5nZVxuICAgIC8vIHR3aWNlLiBgb25Db25mbGljdERvTm90aGluZ2AgKyB0aGUgcGFydGlhbCB1bmlxdWUgaW5kZXggb25cbiAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAvLyBtYWtlcyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAvLyBjb3VudHMsIG1ldHJpY3MgYW5kIGNhY2hlIGludmFsaWRhdGlvbiBhbGwgaWdub3JlIGR1cGxpY2F0ZXMuXG4gICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgIC5vbkNvbmZsaWN0RG9Ob3RoaW5nKClcbiAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkLFxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnBpcGVsaW5lSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGF0dXMsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICB9KVxuICAgICAgOiBbXTtcblxuICAgIHJldHVybiB7XG4gICAgICBpbnNlcnRlZDogbGFuZGVkLmxlbmd0aCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWRMb2NhbCxcbiAgICAgIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiB1bnJlZ2lzdGVyZWRMb2NhbCxcbiAgICAgIGFmZmVjdGVkT3JnczogWy4uLm5ldyBTZXQobGFuZGVkLm1hcChyID0+IHIub3JnSWQpKV0sXG4gICAgICBpbnNlcnRlZFJvd3M6IGxhbmRlZCxcbiAgICB9O1xuICB9KTtcblxuICBpZiAob25NZXRyaWMpIGVtaXRTdGFnZU1ldHJpY3MoaW5zZXJ0ZWRSb3dzLCBvbk1ldHJpYyk7XG5cbiAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAvLyBwaXBlbGluZSBoYXNuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQgKG9yIGl0c1xuICAvLyBwYi5waXBlbGluZS1pZCB0YWcgaXMgbWlzc2luZy91bnJlYWRhYmxlIGJ5IHRoZSBMYW1iZGEpLiBMb2dnaW5nIGl0XG4gIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gIGlmICh1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5sZW5ndGggPiAwKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1BpcGVsaW5lIGV2ZW50cyBza2lwcGVkOiBwaXBlbGluZSBpZCBub3QgZm91bmQgaW4gcmVnaXN0cnknLCB7XG4gICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgc2FtcGxlOiB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5zbGljZSgwLCAzKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFBvc3QtY29tbWl0IGNhY2hlIGludmFsaWRhdGlvbi4gRmlyZS1hbmQtZm9yZ2V0IHdpdGggbG9nZ2luZyDigJQgVFRMIGlzXG4gIC8vIHNob3J0IGVub3VnaCB0aGF0IGEgbWlzc2VkIGludmFsaWRhdGlvbiBzZWxmLWhlYWxzLlxuICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICB2b2lkIFByb21pc2UuYWxsKGFmZmVjdGVkT3Jncy5tYXAoKG9yZykgPT5cbiAgICAgIGludmFsaWRhdGVPcmdSZXBvcnRzKG9yZykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkOiBvcmcsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICAgIH0pLFxuICAgICkpO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfTtcbn1cbiJdfQ==
|
|
335
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvaW5nZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFjaEQscUVBQXFFO0FBQ3JFLFNBQVMsY0FBYyxDQUFDLENBQWM7SUFDcEMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxTQUFTLEtBQUssT0FBTyxDQUFDO1dBQ3ZELENBQUMsQ0FBQyxDQUFDLFdBQVcsS0FBSyxjQUFjLElBQUksQ0FBQyxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUM7V0FDbkUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7QUFDdkMsQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFDLFVBQWtCLEVBQUUsU0FBaUIsRUFBRSxVQUFrQjtJQUN4RSxPQUFPLEdB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LEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzVDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsc0RBQXNEO0lBQ3RELElBQUksWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QixLQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQ3hDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sQ0FBQyxJQUFJLENBQUMscUNBQXFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9GLENBQUMsQ0FBQyxDQUNILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQztBQUM3RyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogRXZlbnQgaW5nZXN0OiB0aGUgV1JJVEUgaGFsZiBvZiByZXBvcnRpbmcuIFJlc29sdmVzIGluY29taW5nIHBpcGVsaW5lIGV2ZW50c1xuICogYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIHNjcnVicyBldmVyeSBmcmVlLWZvcm0gc3RyaW5nLCBiYXRjaC1pbnNlcnRzXG4gKiB0aGUgbWF0Y2hlZCByb3dzIGlkZW1wb3RlbnRseSwgYW5kIGludmFsaWRhdGVzIHRoZSBhZmZlY3RlZCBvcmdzJyByZXBvcnRcbiAqIGNhY2hlcy4gU2VwYXJhdGUgZnJvbSB0aGUgcmVwb3J0IHF1ZXJpZXMgYmVjYXVzZSB0aGlzIGlzIHJlcG9ydGluZydzIG9ubHlcbiAqIGR1cmFibGUgcGVyc2lzdGVuY2UgYm91bmRhcnkg4oCUIGV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgc2VydmljZSBvbmx5IHJlYWRzLlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBzY3J1YkF3c0lkZW50aWZpZXJzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgaW5BcnJheSB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGludmFsaWRhdGVPcmdSZXBvcnRzIH0gZnJvbSAnLi9jYWNoZXMuanMnO1xuaW1wb3J0IHsgdXBzZXJ0RGVwbG95bWVudHMgfSBmcm9tICcuL2RlcGxveS1yb2xsdXAuanMnO1xuaW1wb3J0IHsgY2xhc3NpZnlGYWlsdXJlIH0gZnJvbSAnLi9mYWlsdXJlLWNsYXNzaWZpZXIuanMnO1xuaW1wb3J0IHsgc2NydWJPcHRpb25hbCB9IGZyb20gJy4vc3FsLWhlbHBlcnMuanMnO1xuaW1wb3J0IHR5cGUgeyBJbmdlc3RDYWxsZXIsIEluZ2VzdEV2ZW50LCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5pbXBvcnQgdHlwZSB7IENydWRUeCB9IGZyb20gJy4uL2NydWQtc2VydmljZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLWluZ2VzdCcpO1xuXG50eXBlIFBpcGVsaW5lRXZlbnRJbnNlcnQgPSB0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0O1xuXG5cbi8qKiBUaGUgcGx1Z2luIGEgcGlwZWxpbmUgc3RlcCBydW5zLCBmcm9tIHRoZSBzdGVwIG1hbmlmZXN0IGl0cyBsYXN0IGRlcGxveSByZWdpc3RlcmVkLiAqL1xuaW50ZXJmYWNlIFN0ZXBQbHVnaW4ge1xuICBvcmdJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblB1Ymxpc2hlcklkOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKiogQW4gYWN0aW9uL2J1aWxkIGV2ZW50IHRoYXQgY2FuIGJlIGF0dHJpYnV0ZWQgdG8gYSBwbHVnaW4gc3RlcC4gKi9cbmZ1bmN0aW9uIGlzQXR0cmlidXRhYmxlKGU6IEluZ2VzdEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiAoZS5ldmVudFR5cGUgPT09ICdBQ1RJT04nIHx8IGUuZXZlbnRUeXBlID09PSAnQlVJTEQnKVxuICAgICYmIChlLmV2ZW50U291cmNlID09PSAnY29kZXBpcGVsaW5lJyB8fCBlLmV2ZW50U291cmNlID09PSAnY29kZWJ1aWxkJylcbiAgICAmJiAhIWUuc3RhZ2VOYW1lICYmICEhZS5hY3Rpb25OYW1lO1xufVxuXG5mdW5jdGlvbiBzdGVwS2V5KHBpcGVsaW5lSWQ6IHN0cmluZywgc3RhZ2VOYW1lOiBzdHJpbmcsIGFjdGlvbk5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtwaXBlbGluZUlkfVxcdTAwMDAke3N0YWdlTmFtZX1cXHUwMDAwJHthY3Rpb25OYW1lfWA7XG59XG5cbi8qKlxuICogUGx1Z2luIGF0dHJpYnV0aW9uOiB0aGUgc3RlcCBtYW5pZmVzdHMgb2YgZXZlcnkgcGlwZWxpbmUgd2l0aCBhbiBhdHRyaWJ1dGFibGVcbiAqIGV2ZW50LCBpbiBPTkUgcmVhZCBwZXIgYmF0Y2gsIGtleWVkIGZvciBhbiBpbi1tZW1vcnkgam9pbi4gTmFtZXMgYXJlIGNvbXBhcmVkXG4gKiBwb3N0LXNjcnViIG9uIGJvdGggc2lkZXMgKHRoZSBtYW5pZmVzdCBzdG9yZXMgdGhlbSBzY3J1YmJlZCB0aGUgc2FtZSB3YXkpLlxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkU3RlcFBsdWdpbnModHg6IENydWRUeCwgYXR0cmlidXRhYmxlOiBJbmdlc3RFdmVudFtdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBTdGVwUGx1Z2luPj4ge1xuICBjb25zdCBwaXBlbGluZUlkcyA9IFsuLi5uZXcgU2V0KGF0dHJpYnV0YWJsZS5tYXAoKGUpID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgaWYgKHBpcGVsaW5lSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBNYXAoKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHR4XG4gICAgLnNlbGVjdCh7XG4gICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Qub3JnSWQsXG4gICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5zdGFnZU5hbWUsXG4gICAgICBhY3Rpb25OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QuYWN0aW9uTmFtZSxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcixcbiAgICAgIHBsdWdpblB1Ymxpc2hlcklkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVySWQsXG4gICAgICBwbHVnaW5OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5WZXJzaW9uLFxuICAgIH0pXG4gICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0KVxuICAgIC53aGVyZShpbkFycmF5KHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLCBwaXBlbGluZUlkcykpO1xuICByZXR1cm4gbmV3IE1hcChyb3dzLm1hcCgobSkgPT4gW3N0ZXBLZXkobS5waXBlbGluZUlkLCBtLnN0YWdlTmFtZSwgbS5hY3Rpb25OYW1lKSwgbV0pKTtcbn1cblxuLyoqXG4gKiBBbGxvd2FuY2UgZm9yIGNsb2NrIHNrZXcgYmV0d2VlbiBhbiBBV1MgZXZlbnQncyBzb3VyY2UgY2xvY2sgYW5kIG91cnMuIEEgcmVhbFxuICogQ29kZVBpcGVsaW5lIGV2ZW50IGNhbiBjYXJyeSBhIHRpbWVzdGFtcCBhIGxpdHRsZSBhaGVhZCBvZiBvdXIgYG5vd2A7IHdpdGhvdXRcbiAqIHNvbWUgdG9sZXJhbmNlIHRoZSB2YWxpZGF0aW9uIGJlbG93IHdvdWxkIGRyb3AgaGVhbHRoeSBldmVudHMgZHVyaW5nIG5vcm1hbFxuICogTlRQIGRyaWZ0LCB3aGljaCBpcyBmYXIgd29yc2UgdGhhbiBhZG1pdHRpbmcgYSBmZXcgc2Vjb25kcyBvZiBza2V3LlxuICovXG5jb25zdCBDTE9DS19TS0VXX1RPTEVSQU5DRV9NUyA9IDUgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogV2h5IHRoaXMgZXZlbnQncyB0aW1lc3RhbXBzIGFyZSBpbXBvc3NpYmxlLCBvciBudWxsIHdoZW4gdGhleSBhcmUgdXNhYmxlLlxuICpcbiAqIENoZWNrZWQgYXQgSU5HRVNUIOKAlCB0aGUgZHVyYWJsZSBib3VuZGFyeSDigJQgcmF0aGVyIHRoYW4gY2xhbXBlZCB3aGVuIHRoZSBtZXRyaWNzXG4gKiBhcmUgY29tcHV0ZWQuIEEgbmVnYXRpdmUgZHVyYXRpb24gb3IgYSBmdXR1cmUgZGVwbG95IHVzZWQgdG8gYmUgY2xhbXBlZCB0byAwXG4gKiBkb3duc3RyZWFtLCB3aGljaCByZXBvcnRlZCBhIGJyb2tlbiBjbG9jayBhcyBhbiBpbnN0YW50IGRlcGxveSBhbmQgcXVpZXRseVxuICogbW92ZWQgZGVwbG95bWVudCBmcmVxdWVuY3ksIGNoYW5nZS1mYWlsdXJlIHJhdGUgYW5kIGxlYWQgdGltZSBmb3IgdGhlIG9yZy5cbiAqXG4gKiBOT1QgY2hlY2tlZCBoZXJlOiBjb21taXQgdGltZSB2cyBkZXBsb3kgY29tcGxldGlvbi4gYGNvbW1pdF90aW1lc3RhbXBgIHJpZGVzIHRoZVxuICogUElQRUxJTkUvc291cmNlIGV2ZW50IHdoaWxlIHRoZSBkZXBsb3kncyBgY29tcGxldGVkX2F0YCBpcyBvbiBhIHNlcGFyYXRlIFNUQUdFXG4gKiByb3csIGpvaW5lZCBieSBgZXhlY3V0aW9uX2lkYCBvbmx5IHdoZW4gRE9SQSBpcyBxdWVyaWVkIOKAlCBzbyBubyBzaW5nbGUgZXZlbnRcbiAqIGNhcnJpZXMgYm90aCwgYW5kIHRoYXQgb3JkZXJpbmcgY2FuIG9ubHkgYmUgZ3VhcmRlZCB3aGVyZSB0aGUgdHdvIG1lZXQuXG4gKi9cbmZ1bmN0aW9uIGludmFsaWRFdmVudFRpbWVzKGV2ZW50OiBJbmdlc3RFdmVudCwgbm93TXM6IG51bWJlcik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjZWlsaW5nID0gbm93TXMgKyBDTE9DS19TS0VXX1RPTEVSQU5DRV9NUztcbiAgY29uc3QgcGFyc2VkOiBBcnJheTxbc3RyaW5nLCBudW1iZXJdPiA9IFtdO1xuICBmb3IgKGNvbnN0IGZpZWxkIG9mIFsnc3RhcnRlZEF0JywgJ2NvbXBsZXRlZEF0JywgJ2NvbW1pdFRpbWVzdGFtcCddIGFzIGNvbnN0KSB7XG4gICAgY29uc3QgcmF3ID0gZXZlbnRbZmllbGRdO1xuICAgIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09IG51bGwpIGNvbnRpbnVlO1xuICAgIGNvbnN0IG1zID0gRGF0ZS5wYXJzZShTdHJpbmcocmF3KSk7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobXMpKSByZXR1cm4gYCR7ZmllbGR9IGlzIG5vdCBhIHBhcnNlYWJsZSB0aW1lc3RhbXBgO1xuICAgIGlmIChtcyA+IGNlaWxpbmcpIHJldHVybiBgJHtmaWVsZH0gaXMgaW4gdGhlIGZ1dHVyZWA7XG4gICAgcGFyc2VkLnB1c2goW2ZpZWxkLCBtc10pO1xuICB9XG4gIGNvbnN0IHN0YXJ0ZWQgPSBwYXJzZWQuZmluZCgoW2ZdKSA9PiBmID09PSAnc3RhcnRlZEF0Jyk/LlsxXTtcbiAgY29uc3QgY29tcGxldGVkID0gcGFyc2VkLmZpbmQoKFtmXSkgPT4gZiA9PT0gJ2NvbXBsZXRlZEF0Jyk/LlsxXTtcbiAgaWYgKHN0YXJ0ZWQgIT09IHVuZGVmaW5lZCAmJiBjb21wbGV0ZWQgIT09IHVuZGVmaW5lZCAmJiBjb21wbGV0ZWQgPCBzdGFydGVkKSB7XG4gICAgcmV0dXJuICdjb21wbGV0ZWRBdCBpcyBiZWZvcmUgc3RhcnRlZEF0JztcbiAgfVxuICBpZiAoZXZlbnQuZHVyYXRpb25NcyAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmR1cmF0aW9uTXMgIT09IG51bGwgJiYgZXZlbnQuZHVyYXRpb25NcyA8IDApIHtcbiAgICByZXR1cm4gJ2R1cmF0aW9uTXMgaXMgbmVnYXRpdmUnO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFRoZSBwZXJzaXN0ZWQgcm93IGZvciBvbmUgaW5nZXN0ZWQgZXZlbnQuIFRoaXMgaXMgdGhlIERVUkFCTEUgcGVyc2lzdGVuY2VcbiAqIGJvdW5kYXJ5OiBldmVyeSB1c2VyL0FXUy1kZXJpdmVkIGZyZWUtZm9ybSBzdHJpbmcgaXMgc2NydWJiZWQgaGVyZSwgYW5kXG4gKiB0ZW5hbmN5IGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBuZXZlciB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcuXG4gKi9cbmZ1bmN0aW9uIHRvRXZlbnRSb3coZXZlbnQ6IEluZ2VzdEV2ZW50LCByZWdpc3RyeTogeyBwaXBlbGluZUlkOiBzdHJpbmc7IG9yZ0lkOiBzdHJpbmcgfSwgcGx1Z2luOiBTdGVwUGx1Z2luIHwgdW5kZWZpbmVkKTogUGlwZWxpbmVFdmVudEluc2VydCB7XG4gIHJldHVybiB7XG4gICAgLy8gcmVnaXN0cnkucGlwZWxpbmVJZCA9PT0gZXZlbnQucGlwZWxpbmVJZDsgdGhlIHJlZ2lzdHJ5J3MgaXMgYWx3YXlzIGEgcm93XG4gICAgLy8gdGhhdCBleGlzdHMgKEZLKSBhbmQgaXRzIG9yZ0lkIGlzIHRoZSB0cnVzdGVkIHRlbmFudC5cbiAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgIG9yZ0lkOiByZWdpc3RyeS5vcmdJZCxcbiAgICBldmVudFNvdXJjZTogZXZlbnQuZXZlbnRTb3VyY2UsXG4gICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgLy8gQW4gQVdTLUFTU0lHTkVEIFVVSUQsIG5vdCBmcmVlLWZvcm0gdGV4dDogaXQgY2FuJ3QgY2FycnkgYW4gYWNjb3VudCBpZCxcbiAgICAvLyBhbmQgc2NydWJiaW5nIGEgMTItZGlnaXQgcnVuIGluc2lkZSBpdCB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvbiBrZXkuXG4gICAgZXhlY3V0aW9uSWQ6IGV2ZW50LmV4ZWN1dGlvbklkLFxuICAgIC8vIFVTRVItQVVUSE9SRUQgcGlwZWxpbmUtc3RydWN0dXJlIG5hbWVzIOKAlCBzYW1lIHVudHJ1c3RlZCBvcmlnaW4gYXNcbiAgICAvLyBlcnJvck1lc3NhZ2UsIHNvIHNjcnViYmVkIChhIHN0YWdlIG5hbWVkIHdpdGggYW4gQVJOIG11c3Qgbm90IHBlcnNpc3QpLlxuICAgIHN0YWdlTmFtZTogc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpLFxuICAgIGFjdGlvbk5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSksXG4gICAgLy8gSEFSRCBDT05TVFJBSU5UOiBhbiBBV1MgYWNjb3VudCBpZCBtdXN0IE5FVkVSIGJlIHBlcnNpc3RlZC4gRmFpbHVyZSBkZXRhaWxcbiAgICAvLyBhbmQgbWVzc2FnZXMgcm91dGluZWx5IGNhcnJ5IEFSTnMgYW5kIGJhcmUgMTItZGlnaXQgYWNjb3VudCBpZHMuXG4gICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgc3RhcnRlZEF0OiBldmVudC5zdGFydGVkQXQgPyBuZXcgRGF0ZShldmVudC5zdGFydGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIGNvbXBsZXRlZEF0OiBldmVudC5jb21wbGV0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LmNvbXBsZXRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgIC8vIERlcGxveSBhdHRyaWJ1dGlvbiDigJQgc2NydWJiZWQgbGlrZSB0aGUgb3RoZXIgZnJlZS1mb3JtIHN0cmluZ3MuXG4gICAgY29tbWl0U2hhOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFNoYSksXG4gICAgY29tbWl0UmVmOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFJlZiksXG4gICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoZXZlbnQuZW52aXJvbm1lbnQpLFxuICAgIC8vIE1lYXN1cmVkIGxlYWQgdGltZTogdGhlIG9sZGVzdCB1bnNoaXBwZWQgY29tbWl0J3MgdGltZSArIHRoZSBjb3VudC4gQW5cbiAgICAvLyBTQ00tZGVyaXZlZCBpbnN0YW50IGFuZCBhIHBsYWluIGludGVnZXIg4oCUIG5vdGhpbmcgdG8gc2NydWIuXG4gICAgY29tbWl0VGltZXN0YW1wOiBldmVudC5jb21taXRUaW1lc3RhbXAgPyBuZXcgRGF0ZShldmVudC5jb21taXRUaW1lc3RhbXApIDogdW5kZWZpbmVkLFxuICAgIGNvbW1pdENvdW50OiBldmVudC5jb21taXRDb3VudCxcbiAgICAvLyBOVUxMIGZvciBub24tcGx1Z2luIGFjdGlvbnMgYW5kIGZvciBwaXBlbGluZXMgZGVwbG95ZWQgd2l0aG91dCBhIG1hbmlmZXN0LlxuICAgIHBsdWdpblB1Ymxpc2hlcjogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5QdWJsaXNoZXJJZDogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXJJZCA/PyBudWxsLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbj8ucGx1Z2luTmFtZSA/PyBudWxsLFxuICAgIHBsdWdpblZlcnNpb246IHBsdWdpbj8ucGx1Z2luVmVyc2lvbiA/PyBudWxsLFxuICAgIC8vIFdIQVQgS0lORCBvZiB0aGluZyBicm9rZSwgY2xhc3NpZmllZCBoZXJlIHJhdGhlciB0aGFuIGF0IHJlYWQgdGltZTogdGhlXG4gICAgLy8gZXJyb3IgdGV4dCBpcyBzY3J1YmJlZCBhYm92ZSBhbmQgZXZlbnR1YWxseSBzd2VwdCBieSByZXRlbnRpb24sIHNvIGFcbiAgICAvLyBjYXRlZ29yeSBkZXJpdmVkIGxhdGVyIHdvdWxkIGhhdmUgbm90aGluZyBsZWZ0IHRvIHJlYWQuIE5VTEwgZm9yIGFueXRoaW5nXG4gICAgLy8gdGhhdCBpcyBub3QgYSBmYWlsdXJlLCBzbyBpdHMgcHJlc2VuY2UgYWx3YXlzIG1lYW5zIFwidGhpcyBicm9rZVwiLlxuICAgIGZhaWx1cmVDYXRlZ29yeTogY2xhc3NpZnlGYWlsdXJlKHtcbiAgICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgICAgc3RhZ2VOYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LnN0YWdlTmFtZSksXG4gICAgfSksXG4gICAgZGV0YWlsOiBldmVudC5kZXRhaWwgIT09IHVuZGVmaW5lZCA/IHNjcnViQXdzSWRlbnRpZmllcnMoZXZlbnQuZGV0YWlsKSA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBGYW4gdGVybWluYWwgU1RBR0Ugb3V0Y29tZXMgaW50byB0aGUgcm91dGUncyBtZXRyaWMgaG9vayAocGlwZWxpbmUtZGF0YSBjYW4ndFxuICogaW1wb3J0IGFwaS1zZXJ2ZXIncyByZWdpc3RyeSkgYWZ0ZXIgdGhlIGluc2VydCBjb21taXRzLiBEcml2ZW4gb2ZmIHRoZVxuICogSU5TRVJURUQgcm93cywgc28gYSByZS1kZWxpdmVyZWQgZXZlbnQgdGhlIGRlZHVwIGluZGV4IHN3YWxsb3dlZCBpcyBuZXZlclxuICogY291bnRlZCB0d2ljZS4gQSBub24tbnVsbCBlbnZpcm9ubWVudCBtYXJrcyBhIGRlcGxveS5cbiAqL1xuZnVuY3Rpb24gZW1pdFN0YWdlTWV0cmljcyhcbiAgcm93czogUmVhZG9ubHlBcnJheTx7IG9yZ0lkOiBzdHJpbmc7IHBpcGVsaW5lSWQ6IHN0cmluZyB8IG51bGw7IGV2ZW50VHlwZTogc3RyaW5nOyBzdGF0dXM6IHN0cmluZzsgc3RhZ2VOYW1lOiBzdHJpbmcgfCBudWxsOyBlbnZpcm9ubWVudDogc3RyaW5nIHwgbnVsbCB9PixcbiAgb25NZXRyaWM6IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQsXG4pOiB2b2lkIHtcbiAgZm9yIChjb25zdCByIG9mIHJvd3MpIHtcbiAgICBpZiAoci5ldmVudFR5cGUgIT09ICdTVEFHRScgfHwgKHIuc3RhdHVzICE9PSAnU1VDQ0VFREVEJyAmJiByLnN0YXR1cyAhPT0gJ0ZBSUxFRCcpIHx8ICFyLnBpcGVsaW5lSWQpIGNvbnRpbnVlO1xuICAgIG9uTWV0cmljKHtcbiAgICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiByLm9yZ0lkLFxuICAgICAgc3RhZ2U6IHIuc3RhZ2VOYW1lID8/ICcnLFxuICAgICAgZW52aXJvbm1lbnQ6IHIuZW52aXJvbm1lbnQgPz8gbnVsbCxcbiAgICAgIHJlc3VsdDogci5zdGF0dXMgPT09ICdTVUNDRUVERUQnID8gJ3N1Y2NlZWRlZCcgOiAnZmFpbGVkJyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmUgaW5jb21pbmcgZXZlbnRzIGFnYWluc3QgdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBiYXRjaC1pbnNlcnQgdGhlXG4gKiBtYXRjaGVkIG9uZXMsIGFuZCBpbnZhbGlkYXRlIHJlcG9ydGluZyBjYWNoZXMgZm9yIGFmZmVjdGVkIG9yZ3MuXG4gKiBFdmVudHMgZm9yIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgYXJlIGRyb3BwZWQgKGFuZCBsb2dnZWQgYXQgV0FSTlxuICogd2l0aCBzYW1wbGUgaWRzIHNvIGFuIG9wZXJhdG9yIGNhbiBzZWUgd2hlbiBFdmVudEJyaWRnZSBpcyBkZWxpdmVyaW5nXG4gKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICpcbiAqIFJldHVybnMgY291bnRzICsgYSBzYW1wbGUgb2YgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBmb3Igb2JzZXJ2YWJpbGl0eS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluZ2VzdEV2ZW50cyhcbiAgZXZlbnRzOiBJbmdlc3RFdmVudFtdLFxuICBvbk1ldHJpYz86IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQsXG4gIGNhbGxlcj86IEluZ2VzdENhbGxlcixcbik6IFByb21pc2U8SW5nZXN0UmVzdWx0PiB7XG4gIC8vIFRFTkFOQ1kuIEFuIGV2ZW50J3Mgb3JnIGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIFJFR0lTVFJZLCBub3QgdGhlIHRva2VuLCBzb1xuICAvLyB0aGUgc2NvcGUgY2hlY2sgYWxvbmUgbGV0IGFueSBgcmVwb3J0aW5nOmluZ2VzdGAgaG9sZGVyIHBvc3QgZXZlbnRzIGZvclxuICAvLyBhbm90aGVyIG9yZydzIHBpcGVsaW5lIGlkIGFuZCBoYXZlIHRoZW0gYXR0cmlidXRlZCB0aGVyZS4gYGNhbGxlcmAgY2Fycmllc1xuICAvLyB0aGUgb3JnIGlkcyB0aGlzIHRva2VuIG1heSB3cml0ZSBmb3I7IGFueXRoaW5nIGVsc2UgaXMgZHJvcHBlZCBiZWxvdy5cbiAgLy9cbiAgLy8gYGNhbGxlcmAgaXMgb3B0aW9uYWwgb25seSBzbyBpbi1wcm9jZXNzIGNhbGxlcnMgdGhhdCBhbHJlYWR5IHJ1blxuICAvLyBjcm9zcy10ZW5hbnQgKHRlc3RzLCBiYWNrZmlsbHMpIGtlZXAgd29ya2luZyDigJQgYW4gQUJTRU5UIGNhbGxlciBtZWFucyBcIm5vXG4gIC8vIHJlc3RyaWN0aW9uXCIsIGFuZCB0aGUgcm91dGUgYWx3YXlzIHN1cHBsaWVzIG9uZS4gQSBjYWxsZXIgd2l0aCBhbiBFTVBUWVxuICAvLyBhbGxvdy1saXN0IGFuZCBubyBjcm9zc1RlbmFudCBmbGFnIHRoZXJlZm9yZSBkcm9wcyBldmVyeXRoaW5nLCB3aGljaCBpcyB0aGVcbiAgLy8gcmlnaHQgYW5zd2VyIHdoZW4gdGhlIHJvdXRlIGNvdWxkIG5vdCBlc3RhYmxpc2ggd2hvIGlzIHdyaXRpbmcuXG4gIGNvbnN0IHVucmVzdHJpY3RlZCA9IGNhbGxlciA9PT0gdW5kZWZpbmVkIHx8IGNhbGxlci5jcm9zc1RlbmFudCA9PT0gdHJ1ZTtcbiAgY29uc3QgYWxsb3dlZCA9IG5ldyBTZXQoY2FsbGVyPy5hbGxvd2VkT3JnSWRzID8/IFtdKTtcbiAgLy8gTXVsdGktb3JnIGJhdGNoIGluc2VydDogdGhlIGNhbGxlciByZXNvbHZlcyB0byBtdWx0aXBsZSBvcmdzIHZpYSB0aGVcbiAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAvLyBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgLi4uKWAgc2NvcGUgYmVmb3JlIGNhbGxpbmdcbiAgLy8gdGhpcyBmdW5jdGlvbi4gVW5kZXIgRk9SQ0UnZCBSTFMsIGEgc2luZ2xlIHR4IHdpdGggYGFwcC5vcmdfaWQgPSA8b25lXG4gIC8vIG9yZz5gIGNvdWxkIG9ubHkgd3JpdGUgZXZlbnRzIGZvciB0aGF0IG9yZzsgYnlwYXNzIHZpYSBzeXNhZG1pbiBpc1xuICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgLy8gYXBpL3JlcG9ydGluZy9zcmMvcm91dGVzL2V2ZW50LWluZ2VzdC50cyBmb3IgdGhlIHdyYXBwZXIuXG4gIC8vIENhY2hlcyBhcmUgaW52YWxpZGF0ZWQgQUZURVIgdGhlIHR4IHJlc29sdmVzOiBkb2luZyBpdCBpbnNpZGUgaGVsZCB0aGUgcGdcbiAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBvc3QtY29tbWl0IGludmFsaWRhdGlvbiBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLlxuICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzLCBkcm9wcGVkRm9yZWlnbk9yZywgZHJvcHBlZEludmFsaWRUaW1lLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgIGNvbnN0IHVuaXF1ZUlkcyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICBjb25zdCBzdGVwUGx1Z2lucyA9IGF3YWl0IGxvYWRTdGVwUGx1Z2lucyh0eCwgZXZlbnRzLmZpbHRlcigoZSkgPT4gaXNBdHRyaWJ1dGFibGUoZSkgJiYgaWRNYXAuaGFzKGUucGlwZWxpbmVJZCkpKTtcblxuICAgIC8vIEJ1aWxkIGluc2VydCBiYXRjaCAoc2tpcCBldmVudHMgd2hvc2UgcGlwZWxpbmUgaXNuJ3QgcmVnaXN0ZXJlZClcbiAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICBsZXQgc2tpcHBlZExvY2FsID0gMDtcbiAgICBsZXQgZm9yZWlnbkxvY2FsID0gMDtcbiAgICBsZXQgaW52YWxpZFRpbWVMb2NhbCA9IDA7XG4gICAgY29uc3QgaW52YWxpZFRpbWVSZWFzb25zID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgZm9yZWlnbk9yZ0lkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHVucmVnaXN0ZXJlZExvY2FsOiBzdHJpbmdbXSA9IFtdO1xuICAgIC8vIE9uZSBgbm93YCBmb3IgdGhlIHdob2xlIGJhdGNoOiBwZXItZXZlbnQgY2xvY2tzIHdvdWxkIGxldCBhbiBldmVudCBwYXNzIG9yXG4gICAgLy8gZmFpbCBkZXBlbmRpbmcgb24gd2hlcmUgaXQgc2F0IGluIHRoZSBsb29wLlxuICAgIGNvbnN0IG5vd01zID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGlkTWFwLmdldChldmVudC5waXBlbGluZUlkKTtcbiAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgIHVucmVnaXN0ZXJlZExvY2FsLnB1c2goZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHBpcGVsaW5lIHJlc29sdmVzIHRvIGFuIG9yZyB0aGlzIGNhbGxlciBtYXkgbm90IHdyaXRlIGZvci4gQ291bnRlZFxuICAgICAgLy8gc2VwYXJhdGVseSBmcm9tIGBza2lwcGVkYCAoYW4gdW5yZWdpc3RlcmVkIGlkIGlzIGEgcHJvZHVjZXIgcnVubmluZ1xuICAgICAgLy8gYWhlYWQgb2YgcmVnaXN0cmF0aW9uOyB0aGlzIGlzIGEgdGVuYW5jeSByZWZ1c2FsKSBhbmQgbmV2ZXIgaW5zZXJ0ZWQuXG4gICAgICBpZiAoIXVucmVzdHJpY3RlZCAmJiAhYWxsb3dlZC5oYXMocmVnaXN0cnkub3JnSWQpKSB7XG4gICAgICAgIGZvcmVpZ25Mb2NhbCsrO1xuICAgICAgICBmb3JlaWduT3JnSWRzLmFkZChyZWdpc3RyeS5vcmdJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gSW1wb3NzaWJsZSB0aW1lc3RhbXBzIGFyZSByZWZ1c2VkIGF0IHRoZSBib3VuZGFyeSwgc28gbm8gZG93bnN0cmVhbVxuICAgICAgLy8gbWV0cmljIGhhcyB0byBjbGFtcCBhIG5lZ2F0aXZlIGdhcCBhbmQgY2FsbCBpdCB6ZXJvLlxuICAgICAgY29uc3QgYmFkVGltZSA9IGludmFsaWRFdmVudFRpbWVzKGV2ZW50LCBub3dNcyk7XG4gICAgICBpZiAoYmFkVGltZSkge1xuICAgICAgICBpbnZhbGlkVGltZUxvY2FsKys7XG4gICAgICAgIGludmFsaWRUaW1lUmVhc29ucy5hZGQoYmFkVGltZSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSk7XG4gICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgID8gc3RlcFBsdWdpbnMuZ2V0KHN0ZXBLZXkocmVnaXN0cnkucGlwZWxpbmVJZCwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAvLyBvd25zIHRoZSBwaXBlbGluZSwgYnV0IHRoZSBpbmdlc3QgcnVucyBjcm9zcy10ZW5hbnQsIHNvIGRvbid0IGxlYW4gb24gaXQuXG4gICAgICByb3dzLnB1c2godG9FdmVudFJvdyhldmVudCwgcmVnaXN0cnksIHN0ZXAgJiYgc3RlcC5vcmdJZCA9PT0gcmVnaXN0cnkub3JnSWQgPyBzdGVwIDogdW5kZWZpbmVkKSk7XG4gICAgfVxuXG4gICAgLy8gU1FTIGlzIGF0LWxlYXN0LW9uY2UsIHNvIEV2ZW50QnJpZGdlIGNhbiBkZWxpdmVyIHRoZSBzYW1lIHN0YXRlLWNoYW5nZVxuICAgIC8vIHR3aWNlLiBgb25Db25mbGljdERvTm90aGluZ2AgKyB0aGUgcGFydGlhbCB1bmlxdWUgaW5kZXggb25cbiAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAvLyBtYWtlcyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAvLyBjb3VudHMsIG1ldHJpY3MgYW5kIGNhY2hlIGludmFsaWRhdGlvbiBhbGwgaWdub3JlIGR1cGxpY2F0ZXMuXG4gICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgIC5vbkNvbmZsaWN0RG9Ob3RoaW5nKClcbiAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkLFxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnBpcGVsaW5lSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGF0dXMsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICAgIC8vIEZvciB0aGUgcGVyLWRlcGxveSByb2xsdXAgYmVsb3c6IGV2ZXJ5dGhpbmcgYGRvcmFfZGVwbG95bWVudHNgIG5lZWRzLFxuICAgICAgICAgIC8vIHRha2VuIGZyb20gdGhlIHJvd3MgdGhhdCBBQ1RVQUxMWSBsYW5kZWQgc28gYSByZS1kZWxpdmVyeSBjYW5ub3RcbiAgICAgICAgICAvLyBwcm9kdWNlIGEgc2Vjb25kIGRlcGxveS5cbiAgICAgICAgICBleGVjdXRpb25JZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuZXhlY3V0aW9uSWQsXG4gICAgICAgICAgY29tbWl0U2hhOiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21taXRTaGEsXG4gICAgICAgICAgY29tbWl0VGltZXN0YW1wOiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21taXRUaW1lc3RhbXAsXG4gICAgICAgICAgY29tbWl0Q291bnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNvbW1pdENvdW50LFxuICAgICAgICAgIGNvbXBsZXRlZEF0OiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21wbGV0ZWRBdCxcbiAgICAgICAgICBzdGFydGVkQXQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXJ0ZWRBdCxcbiAgICAgICAgICBjcmVhdGVkQXQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNyZWF0ZWRBdCxcbiAgICAgICAgICBkZXRhaWw6IHNjaGVtYS5waXBlbGluZUV2ZW50LmRldGFpbCxcbiAgICAgICAgfSlcbiAgICAgIDogW107XG5cbiAgICAvLyBMb2cgaW5zaWRlIHRoZSB0eCBzY29wZSB3aGlsZSB0aGUgb3JnIHNldCBpcyBpbiBoYW5kLiBXQVJOLCBub3QgZXJyb3I6XG4gICAgLy8gYSBtaXNyb3V0ZWQgcHJvZHVjZXIgaXMgdGhlIGNvbW1vbiBjYXVzZSwgYnV0IHRoZSBzYW1lIGxpbmUgaXMgdGhlIG9ubHlcbiAgICAvLyBzaWduYWwgb2YgYW4gaW5qZWN0aW9uIGF0dGVtcHQsIHNvIGl0IG5hbWVzIHRoZSBvcmdzIGl0IHJlZnVzZWQuXG4gICAgaWYgKGZvcmVpZ25Mb2NhbCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdEcm9wcGVkIGluZ2VzdCBldmVudHMgZm9yIG9yZ3MgdGhlIGNhbGxlciBtYXkgbm90IHdyaXRlIGZvcicsIHtcbiAgICAgICAgZHJvcHBlZDogZm9yZWlnbkxvY2FsLFxuICAgICAgICBmb3JlaWduT3JnSWRzOiBbLi4uZm9yZWlnbk9yZ0lkc10sXG4gICAgICAgIGFsbG93ZWRPcmdJZHM6IFsuLi5hbGxvd2VkXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkVGltZUxvY2FsID4gMCkge1xuICAgICAgbG9nZ2VyLndhcm4oJ0Ryb3BwZWQgaW5nZXN0IGV2ZW50cyB3aXRoIGltcG9zc2libGUgdGltZXN0YW1wcycsIHtcbiAgICAgICAgZHJvcHBlZDogaW52YWxpZFRpbWVMb2NhbCxcbiAgICAgICAgcmVhc29uczogWy4uLmludmFsaWRUaW1lUmVhc29uc10sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zZXJ0ZWQ6IGxhbmRlZC5sZW5ndGgsXG4gICAgICBza2lwcGVkOiBza2lwcGVkTG9jYWwsXG4gICAgICB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkczogdW5yZWdpc3RlcmVkTG9jYWwsXG4gICAgICBhZmZlY3RlZE9yZ3M6IFsuLi5uZXcgU2V0KGxhbmRlZC5tYXAociA9PiByLm9yZ0lkKSldLFxuICAgICAgZHJvcHBlZEZvcmVpZ25Pcmc6IGZvcmVpZ25Mb2NhbCxcbiAgICAgIGRyb3BwZWRJbnZhbGlkVGltZTogaW52YWxpZFRpbWVMb2NhbCxcbiAgICAgIGluc2VydGVkUm93czogbGFuZGVkLFxuICAgIH07XG4gIH0pO1xuXG4gIGlmIChvbk1ldHJpYykgZW1pdFN0YWdlTWV0cmljcyhpbnNlcnRlZFJvd3MsIG9uTWV0cmljKTtcblxuICAvLyBQZXItZGVwbG95IHJvbGx1cC4gQUZURVIgdGhlIGV2ZW50cyBjb21taXQgYW5kIG91dHNpZGUgdGhlaXIgdHJhbnNhY3Rpb246IHRoZVxuICAvLyBldmVudHMgYXJlIHRoZSBkdXJhYmxlIHJlY29yZCBhbmQgYGRvcmFfZGVwbG95bWVudHNgIGlzIGRlcml2ZWQgZnJvbSB0aGVtLCBzb1xuICAvLyBhIHJvbGx1cCBmYWlsdXJlIG11c3Qgbm90IHJvbGwgYmFjayBhbiBpbmdlc3QgdGhhdCBzdWNjZWVkZWQuIFJlYnVpbGRhYmxlXG4gIC8vIGVpdGhlciB3YXkuIGB1cHNlcnREZXBsb3ltZW50c2AgbmV2ZXIgdGhyb3dzIGZvciB0aGF0IHJlYXNvbi5cbiAgYXdhaXQgdXBzZXJ0RGVwbG95bWVudHMoaW5zZXJ0ZWRSb3dzKTtcblxuICAvLyBTdXJmYWNlIHRoZSBzaWxlbnQgc2tpcDogYW4gdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkIHVzdWFsbHkgbWVhbnMgdGhlXG4gIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gIC8vIHBiLnBpcGVsaW5lLWlkIHRhZyBpcyBtaXNzaW5nL3VucmVhZGFibGUgYnkgdGhlIExhbWJkYSkuIExvZ2dpbmcgaXRcbiAgLy8gbWFrZXMgYSBicm9rZW4gam9pbiB2aXNpYmxlIGluc3RlYWQgb2YgbG9va2luZyBsaWtlIFwibm8gYWN0aXZpdHlcIi5cbiAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICBsb2dnZXIud2FybignUGlwZWxpbmUgZXZlbnRzIHNraXBwZWQ6IHBpcGVsaW5lIGlkIG5vdCBmb3VuZCBpbiByZWdpc3RyeScsIHtcbiAgICAgIGNvdW50OiB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5sZW5ndGgsXG4gICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgLy8gc2hvcnQgZW5vdWdoIHRoYXQgYSBtaXNzZWQgaW52YWxpZGF0aW9uIHNlbGYtaGVhbHMuXG4gIGlmIChhZmZlY3RlZE9yZ3MubGVuZ3RoID4gMCkge1xuICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgaW52YWxpZGF0ZU9yZ1JlcG9ydHMob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQ6IG9yZywgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgfSksXG4gICAgKSk7XG4gIH1cblxuICByZXR1cm4geyBpbnNlcnRlZCwgc2tpcHBlZCwgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMsIGFmZmVjdGVkT3JncywgZHJvcHBlZEZvcmVpZ25PcmcsIGRyb3BwZWRJbnZhbGlkVGltZSB9O1xufVxuIl19
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IngestCaller } from './types.js';
|
|
2
|
+
/** The bound, or nulls when this pipeline has no recorded deploy carrying a commit. */
|
|
3
|
+
export interface LastDeployedCommit {
|
|
4
|
+
/** Commit sha of the most recent successful deploy to the environment. */
|
|
5
|
+
commitSha: string | null;
|
|
6
|
+
/** When that deploy completed, ISO text — for the caller's own logging. */
|
|
7
|
+
deployedAt: string | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The commit sha of the most recent SUCCEEDED deploy-stage execution for this
|
|
11
|
+
* pipeline — narrowed to one `environment` when given.
|
|
12
|
+
*
|
|
13
|
+
* Two steps, because the two facts live on different rows: `environment` is
|
|
14
|
+
* stamped on the deploy STAGE event, while `commit_sha` rides the source
|
|
15
|
+
* ACTION/PIPELINE event of the same execution. They are joined by `execution_id`,
|
|
16
|
+
* exactly as the DORA lead-time query does it.
|
|
17
|
+
*
|
|
18
|
+
* `environment` is OPTIONAL because of who asks. The events Lambda resolves a
|
|
19
|
+
* commit while handling the SOURCE event, and a source stage carries no
|
|
20
|
+
* environment — the execution has not reached a deploy stage yet, so at that
|
|
21
|
+
* moment the environment is genuinely unknown. Omitting it answers "what did this
|
|
22
|
+
* pipeline last ship anywhere", which is the right lower bound for an SCM range;
|
|
23
|
+
* passing it answers per-environment, for callers that know.
|
|
24
|
+
*
|
|
25
|
+
* TENANCY. `caller` is enforced the same way as {@link ingestEvents}: the org
|
|
26
|
+
* comes from the pipeline REGISTRY, never from the caller, and a pipeline outside
|
|
27
|
+
* the caller's allow-list returns nothing. Without this the endpoint would hand
|
|
28
|
+
* any `reporting:ingest` holder another tenant's commit history — the same hole
|
|
29
|
+
* the ingest tenancy check closes on the write side.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getLastDeployedCommit(pipelineId: string, environment?: string, caller?: IngestCaller): Promise<LastDeployedCommit>;
|