velocious 1.0.559 → 1.0.561
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/build/background-jobs/worker.js +39 -11
- package/build/database/drivers/base.js +9 -2
- package/build/database/drivers/mysql/index.js +11 -2
- package/build/database/drivers/mysql/query.js +198 -22
- package/build/database/query/index.js +16 -1
- package/build/database/query/model-class-query.js +3 -2
- package/build/database/query/query-data.js +75 -7
- package/build/database/query/with-count.js +64 -28
- package/build/database/query-aborted-error.js +24 -0
- package/build/http-server/client/websocket-session.js +134 -28
- package/build/src/background-jobs/worker.d.ts +15 -1
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +35 -13
- package/build/src/database/drivers/base.d.ts +6 -1
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +10 -3
- package/build/src/database/drivers/mssql/index.d.ts +6 -0
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +12 -3
- package/build/src/database/drivers/mysql/query.d.ts +13 -3
- package/build/src/database/drivers/mysql/query.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/query.js +172 -23
- package/build/src/database/drivers/pgsql/index.d.ts +6 -0
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.d.ts +6 -0
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.native.d.ts +6 -0
- package/build/src/database/drivers/sqlite/index.native.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.web.d.ts +6 -0
- package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
- package/build/src/database/query/index.d.ts +13 -1
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +15 -3
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +4 -3
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +69 -8
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +60 -26
- package/build/src/database/query-aborted-error.d.ts +23 -0
- package/build/src/database/query-aborted-error.d.ts.map +1 -0
- package/build/src/database/query-aborted-error.js +23 -0
- package/build/src/http-server/client/websocket-session.d.ts +31 -3
- package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-session.js +112 -26
- package/build/src/tenants/tenant-aggregator.d.ts +4 -0
- package/build/src/tenants/tenant-aggregator.d.ts.map +1 -1
- package/build/src/tenants/tenant-aggregator.js +4 -3
- package/build/tenants/tenant-aggregator.js +3 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/src/background-jobs/worker.js +39 -11
- package/src/database/drivers/base.js +9 -2
- package/src/database/drivers/mysql/index.js +11 -2
- package/src/database/drivers/mysql/query.js +198 -22
- package/src/database/query/index.js +16 -1
- package/src/database/query/model-class-query.js +3 -2
- package/src/database/query/query-data.js +75 -7
- package/src/database/query/with-count.js +64 -28
- package/src/database/query-aborted-error.js +24 -0
- package/src/http-server/client/websocket-session.js +134 -28
- package/src/tenants/tenant-aggregator.js +3 -2
|
@@ -163,6 +163,10 @@ export type TenantAggregateOptions = {
|
|
|
163
163
|
* - Output column name to aggregate. `"SUM"` is shorthand for `{op: "SUM", column: <output name>}`; use `{op: "COUNT", column: "*"}` for `COUNT(*)`.
|
|
164
164
|
*/
|
|
165
165
|
aggregates: Record<string, AggregateSpec>;
|
|
166
|
+
/**
|
|
167
|
+
* - Signal passed to each aggregate database query.
|
|
168
|
+
*/
|
|
169
|
+
signal?: AbortSignal | undefined;
|
|
166
170
|
/**
|
|
167
171
|
* - Builds one tenant's inner `SELECT`, which must select every `keyColumns` entry plus every aggregate source column.
|
|
168
172
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-aggregator.d.ts","sourceRoot":"","sources":["../../../src/tenants/tenant-aggregator.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tenant-aggregator.d.ts","sourceRoot":"","sources":["../../../src/tenants/tenant-aggregator.js"],"names":[],"mappings":"AAuCA;;;;;;;;;GASG;AACH;IACE;;;OAGG;IACH,qBAFW,sBAAsB,EAOhC;IAJC,gCAAsB;IACtB,qDAAqE;IACrE,qBAA0C;IAC1C;YAmR+B,kBAAkB;gBAAU,MAAM;OAnRF;IAGjE;;;OAGG;IACH,OAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAAC,CAAC,CAiB7C;IAED;;;;OAIG;IACH,mBAFa,OAAO,CAAC,cAAc,EAAE,CAAC,CA0BrC;IAED;;;OAGG;IACH,wBAFa,OAAO,CAAC,MAAM,EAAE,CAAC,CAc7B;IAED;;;;OAIG;IACH,gCAHW,cAAc,EAAE,GACd,cAAc,EAAE,EAAE,CAiB9B;IAED;;;;;;;OAOG;IACH,qBAHW,cAAc,EAAE,GACd,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAAC,CAAC,CA+B7C;IAED;;;;;;;OAOG;IACH,YALa,CAAC,UACH,MAAM,YACN,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACxF,OAAO,CAAC,CAAC,CAAC,CAItB;IAED;;;;OAIG;IACH,sDAHW;QAAC,UAAU,EAAE,OAAO,6BAA6B,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,cAAc,EAAE,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAC,GACxG,MAAM,CA+BlB;IAED;;;;;;;;OAQG;IACH,iBAHW,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAAC,GACtB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAAC,CAoCpC;IAED;;;;;;OAMG;IACH,aALW,kBAAkB,WAClB,MAAM,SACN,MAAM,GACJ,MAAM,CAOlB;IAED;;;;;;;;OAQG;IACH,yBAHW,OAAC,GACC,MAAM,CAUlB;IAED;;;;OAIG;IACH,wBAHW,OAAO,6BAA6B,EAAE,OAAO,GAC3C,CAAC,CAAC,KAAK,EAAE,OAAC,KAAK,MAAM,CAAC,GAAG;QAAC,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,OAAC,CAAC,KAAK,MAAM,CAAA;KAAC,CAOzE;IAED;;;;OAIG;IACH,iCAHW,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE;QAAC,EAAE,EAAE,kBAAkB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC,CAiBpE;CACF;iCA1VY,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK;4BAI/B,kBAAkB,GAAG;IAAC,EAAE,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC;;;;;WAK5D,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM;;;;WAC7B,CAAC,CAAC,KAAK,EAAE,OAAC,KAAK,MAAM,CAAC,GAAG;QAAC,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,OAAC,CAAC,KAAK,MAAM,CAAA;KAAC;;;;YAC7D,MAAM;;;;gBACN,OAAO,6BAA6B,EAAE,OAAO;;;;;;gBAK7C,MAAM;;;;;;;;uBAEG,OAAC,KAAK,OAAO;;;;;;;;gBAEtB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;;;;;;;;cAE7B,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM;;;;;;6BAKrC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC"}
|
|
@@ -20,6 +20,7 @@ import Current from "../current.js";
|
|
|
20
20
|
* @property {(tenant: ?) => boolean} [filter] - Optional filter applied to the resolved tenant list.
|
|
21
21
|
* @property {string[]} [keyColumns] - Columns the aggregate is grouped by (for example `["docker_server_id"]`). Empty means a single grand-total row.
|
|
22
22
|
* @property {Record<string, AggregateSpec>} aggregates - Output column name to aggregate. `"SUM"` is shorthand for `{op: "SUM", column: <output name>}`; use `{op: "COUNT", column: "*"}` for `COUNT(*)`.
|
|
23
|
+
* @property {AbortSignal} [signal] - Signal passed to each aggregate database query.
|
|
23
24
|
* @property {(context: SubqueryContext) => string} subquery - Builds one tenant's inner `SELECT`, which must select every `keyColumns` entry plus every aggregate source column.
|
|
24
25
|
* @property {import("../configuration.js").default} [configuration] - Configuration to run against. Defaults to the current configuration.
|
|
25
26
|
*/
|
|
@@ -138,7 +139,7 @@ export default class TenantAggregator {
|
|
|
138
139
|
if (supportsCrossDatabaseReferences) {
|
|
139
140
|
return await this._withTenant(firstTenant.tenant, async (connections) => {
|
|
140
141
|
const connection = connections[this.options.identifier];
|
|
141
|
-
return await connection.query(this.buildAggregateSql({ connection, entries: group, qualified: true }));
|
|
142
|
+
return await connection.query(this.buildAggregateSql({ connection, entries: group, qualified: true }), { signal: this.options.signal });
|
|
142
143
|
});
|
|
143
144
|
}
|
|
144
145
|
/** @type {Array<Record<string, ?>>} */
|
|
@@ -146,7 +147,7 @@ export default class TenantAggregator {
|
|
|
146
147
|
for (const resolvedTenant of group) {
|
|
147
148
|
const tenantRows = await this._withTenant(resolvedTenant.tenant, async (connections) => {
|
|
148
149
|
const connection = connections[this.options.identifier];
|
|
149
|
-
return await connection.query(this.buildAggregateSql({ connection, entries: [resolvedTenant], qualified: false }));
|
|
150
|
+
return await connection.query(this.buildAggregateSql({ connection, entries: [resolvedTenant], qualified: false }), { signal: this.options.signal });
|
|
150
151
|
});
|
|
151
152
|
rows.push(...tenantRows);
|
|
152
153
|
}
|
|
@@ -282,4 +283,4 @@ export default class TenantAggregator {
|
|
|
282
283
|
return normalized;
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWFnZ3JlZ2F0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVuYW50cy90ZW5hbnQtYWdncmVnYXRvci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxPQUFPLE1BQU0sZUFBZSxDQUFBO0FBRW5DOztHQUVHO0FBRUg7O0dBRUc7QUFFSDs7Ozs7O0dBTUc7QUFFSDs7Ozs7Ozs7O0dBU0c7QUFFSDs7R0FFRztBQUVILE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBQ3BFLE1BQU0sbUJBQW1CLEdBQUcsNEJBQTRCLENBQUE7QUFFeEQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxnQkFBZ0I7SUFDbkM7OztPQUdHO0lBQ0gsWUFBWSxPQUFPO1FBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUE7UUFDckUsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQTtRQUMxQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDakUsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxHQUFHO1FBQ1AsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7UUFFcEQsSUFBSSxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUUzQyx1Q0FBdUM7UUFDdkMsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBRWYsS0FBSyxNQUFNLEtBQUss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QUFJLEVBQUUsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3RELE1BQU0sRUFBRSxHQUFHLGlDQUFpQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUE7WUFFeEcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxJQUFJLEtBQUssRUFBRSxnQkFBZ0IsS0FBSyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDbkksQ0FBQztZQUVELFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDLE1BQU0sRUFBRSxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUMsQ0FBQTtRQUNoRixDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUE7SUFDbkIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBDdXJyZW50IGZyb20gXCIuLi9jdXJyZW50LmpzXCJcblxuLyoqXG4gKiBAdHlwZWRlZiB7XCJTVU1cIiB8IFwiQ09VTlRcIiB8IFwiTUFYXCIgfCBcIk1JTlwifSBBZ2dyZWdhdGVPcGVyYXRpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtBZ2dyZWdhdGVPcGVyYXRpb24gfCB7b3A6IEFnZ3JlZ2F0ZU9wZXJhdGlvbiwgY29sdW1uOiBzdHJpbmd9fSBBZ2dyZWdhdGVTcGVjXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBTdWJxdWVyeUNvbnRleHRcbiAqIEBwcm9wZXJ0eSB7KHRhYmxlTmFtZTogc3RyaW5nKSA9PiBzdHJpbmd9IHRhYmxlIC0gUXVvdGVzIGEgdGFibGUgZm9yIHRoaXMgdGVuYW50LiBJbiBhIGNyb3NzLWRhdGFiYXNlIGBVTklPTiBBTExgIGl0IHJldHVybnMgYSBgZGF0YWJhc2VgLmB0YWJsZWAgcXVhbGlmaWVkIGlkZW50aWZpZXI7IHdoZW4gZWFjaCB0ZW5hbnQgcnVucyBvbiBpdHMgb3duIGNvbm5lY3Rpb24gaXQgcmV0dXJucyB0aGUgcGxhaW4gcXVvdGVkIHRhYmxlIG5hbWUuIFVzZSBpdCBmb3IgZXZlcnkgdGFibGUgdGhlIHN1YnF1ZXJ5IHJlYWRzIHNvIHRoZSBzYW1lIHN1YnF1ZXJ5IHdvcmtzIG9uIGJvdGggZXhlY3V0aW9uIHBhdGhzLlxuICogQHByb3BlcnR5IHsoKHZhbHVlOiA/KSA9PiBzdHJpbmcpICYge2xpc3Q6ICh2YWx1ZXM6IEFycmF5PD8+KSA9PiBzdHJpbmd9fSBxdW90ZSAtIFF1b3RlcyBhIHZhbHVlIGZvciB0aGUgYWN0aXZlIGNvbm5lY3Rpb24uIGBxdW90ZS5saXN0KHZhbHVlcylgIHF1b3RlcyBhbmQgY29tbWEtam9pbnMgYW4gYXJyYXkgZm9yIGBJTiAoLi4uKWAgY2xhdXNlcy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSB0ZW5hbnQgLSBUaGUgdGVuYW50IGRlc2NyaXB0b3IgdGhpcyBzdWJxdWVyeSBpcyBiZWluZyBidWlsdCBmb3IuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gVGhlIGRyaXZlciB0aGUgcXVlcnkgd2lsbCBydW4gb24uXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZW5hbnRBZ2dyZWdhdGVPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIgd2hvc2UgdGVuYW50cyBhcmUgYWdncmVnYXRlZCAoZm9yIGV4YW1wbGUgYFwicHJvamVjdFRlbmFudFwiYCkuXG4gKiBAcHJvcGVydHkge29iamVjdFtdfSBbdGVuYW50c10gLSBFeHBsaWNpdCB0ZW5hbnQgZGVzY3JpcHRvcnMgdG8gYWdncmVnYXRlLiBEZWZhdWx0cyB0byBldmVyeSB0ZW5hbnQgdGhlIGlkZW50aWZpZXIncyBwcm92aWRlciBgbGlzdFRlbmFudHNgIHJldHVybnMuXG4gKiBAcHJvcGVydHkgeyh0ZW5hbnQ6ID8pID0+IGJvb2xlYW59IFtmaWx0ZXJdIC0gT3B0aW9uYWwgZmlsdGVyIGFwcGxpZWQgdG8gdGhlIHJlc29sdmVkIHRlbmFudCBsaXN0LlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gW2tleUNvbHVtbnNdIC0gQ29sdW1ucyB0aGUgYWdncmVnYXRlIGlzIGdyb3VwZWQgYnkgKGZvciBleGFtcGxlIGBbXCJkb2NrZXJfc2VydmVyX2lkXCJdYCkuIEVtcHR5IG1lYW5zIGEgc2luZ2xlIGdyYW5kLXRvdGFsIHJvdy5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgQWdncmVnYXRlU3BlYz59IGFnZ3JlZ2F0ZXMgLSBPdXRwdXQgY29sdW1uIG5hbWUgdG8gYWdncmVnYXRlLiBgXCJTVU1cImAgaXMgc2hvcnRoYW5kIGZvciBge29wOiBcIlNVTVwiLCBjb2x1bW46IDxvdXRwdXQgbmFtZT59YDsgdXNlIGB7b3A6IFwiQ09VTlRcIiwgY29sdW1uOiBcIipcIn1gIGZvciBgQ09VTlQoKilgLlxuICogQHByb3BlcnR5IHsoY29udGV4dDogU3VicXVlcnlDb250ZXh0KSA9PiBzdHJpbmd9IHN1YnF1ZXJ5IC0gQnVpbGRzIG9uZSB0ZW5hbnQncyBpbm5lciBgU0VMRUNUYCwgd2hpY2ggbXVzdCBzZWxlY3QgZXZlcnkgYGtleUNvbHVtbnNgIGVudHJ5IHBsdXMgZXZlcnkgYWdncmVnYXRlIHNvdXJjZSBjb2x1bW4uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gW2NvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiB0byBydW4gYWdhaW5zdC4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbi5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHt7dGVuYW50OiBvYmplY3QsIGRhdGFiYXNlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHNlcnZlcktleTogc3RyaW5nfX0gUmVzb2x2ZWRUZW5hbnRcbiAqL1xuXG5jb25zdCBBR0dSRUdBVEVfT1BFUkFUSU9OUyA9IG5ldyBTZXQoW1wiU1VNXCIsIFwiQ09VTlRcIiwgXCJNQVhcIiwgXCJNSU5cIl0pXG5jb25zdCBERVJJVkVEX1RBQkxFX0FMSUFTID0gXCJ2ZWxvY2lvdXNfdGVuYW50X2FnZ3JlZ2F0ZVwiXG5cbi8qKlxuICogUnVucyBvbmUgYWdncmVnYXRlIHF1ZXJ5IGFjcm9zcyBtYW55IHRlbmFudCBkYXRhYmFzZXMgYW5kIG1lcmdlcyB0aGUgcmVzdWx0LiBUZW5hbnQgZGF0YWJhc2VzIG1heVxuICogYmUgY28tbG9jYXRlZCBvbiB0aGUgZGVmYXVsdCBzZXJ2ZXIgb3Igc3ByZWFkIGFjcm9zcyBvdGhlciBzZXJ2ZXJzLCBhbmQgdGhleSBjYW4gYXBwZWFyIG9yXG4gKiBkaXNhcHBlYXIgYXQgcnVudGltZTsgdGhpcyByZXNvbHZlcyB0aGUgbGl2ZSB0ZW5hbnQgbGlzdCwgZ3JvdXBzIHRlbmFudHMgYnkgdGhlIHNlcnZlciB0aGV5IGxpdmVcbiAqIG9uLCBhbmQg4oCUIHBlciBzZXJ2ZXIg4oCUIGVtaXRzIGEgc2luZ2xlIGNyb3NzLWRhdGFiYXNlIGBVTklPTiBBTExgIHdoZW4gdGhlIGRyaXZlciBzdXBwb3J0cyBxdWFsaWZpZWRcbiAqIGNyb3NzLWRhdGFiYXNlIHJlZmVyZW5jZXMgKE15U1FML01TU1FMKSBvciBmYWxscyBiYWNrIHRvIG9uZSBxdWVyeSBwZXIgdGVuYW50IG90aGVyd2lzZVxuICogKFBvc3RncmVTUUwvU1FMaXRlKS4gUmVzdWx0cyBmcm9tIGV2ZXJ5IHNlcnZlciBhcmUgbWVyZ2VkIHdpdGggdGhlIGFnZ3JlZ2F0ZSdzIG93biBvcGVyYXRpb24sIHNvXG4gKiBjYWxsZXJzIGdldCBvbmUgY29tYmluZWQgcmVzdWx0IHNldCByZWdhcmRsZXNzIG9mIGhvdyB0aGUgdGVuYW50cyBhcmUgZGlzdHJpYnV0ZWQuIFJlYWNoZWQgdGhyb3VnaFxuICogYFRlbmFudC5hZ2dyZWdhdGVBY3Jvc3NgLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZW5hbnRBZ2dyZWdhdG9yIHtcbiAgLyoqXG4gICAqIFByZXBhcmVzIGFuIGFnZ3JlZ2F0ZSBydW4sIG5vcm1hbGl6aW5nIHRoZSBhZ2dyZWdhdGUgc3BlY3MgdXAgZnJvbnQuXG4gICAqIEBwYXJhbSB7VGVuYW50QWdncmVnYXRlT3B0aW9uc30gb3B0aW9ucyAtIEFnZ3JlZ2F0ZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBvcHRpb25zLmNvbmZpZ3VyYXRpb24gPz8gQ3VycmVudC5jb25maWd1cmF0aW9uKClcbiAgICB0aGlzLmtleUNvbHVtbnMgPSBvcHRpb25zLmtleUNvbHVtbnMgPz8gW11cbiAgICB0aGlzLmFnZ3JlZ2F0ZXMgPSB0aGlzLl9ub3JtYWxpemVBZ2dyZWdhdGVzKG9wdGlvbnMuYWdncmVnYXRlcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgdGVuYW50IGxpc3QsIHJ1bnMgdGhlIGFnZ3JlZ2F0ZSBwZXIgc2VydmVyLCBhbmQgbWVyZ2VzIGV2ZXJ5dGhpbmcuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pj59IC0gT25lIG1lcmdlZCByb3cgcGVyIGRpc3RpbmN0IGtleS1jb2x1bW4gY29tYmluYXRpb24uXG4gICAqL1xuICBhc3luYyBydW4oKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRUZW5hbnRzID0gYXdhaXQgdGhpcy5fcmVzb2x2ZVRlbmFudHMoKVxuXG4gICAgaWYgKHJlc29sdmVkVGVuYW50cy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuXG4gICAgLyoqIEB0eXBlIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59ICovXG4gICAgY29uc3Qgcm93cyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMuX2dyb3VwQnlTZXJ2ZXIocmVzb2x2ZWRUZW5hbnRzKSkge1xuICAgICAgY29uc3QgZ3JvdXBSb3dzID0gYXdhaXQgdGhpcy5fcnVuRm9yU2VydmVyKGdyb3VwKVxuXG4gICAgICByb3dzLnB1c2goLi4uZ3JvdXBSb3dzKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9tZXJnZVJvd3Mocm93cylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgdGVuYW50IGxpc3QgKGV4cGxpY2l0IG9yIGZyb20gdGhlIHByb3ZpZGVyKSwgdGhlbiBtYXBzIGVhY2ggdG8gaXRzIHNlcnZlciBhbmRcbiAgICogZGF0YWJhc2UgdmlhIHRoZSB0ZW5hbnQgZGF0YWJhc2UgcmVzb2x2ZXIuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlc29sdmVkVGVuYW50W10+fSAtIFRlbmFudHMgdG8gYWdncmVnYXRlLCBlYWNoIHJlc29sdmVkIHRvIGl0cyBzZXJ2ZXIgKyBkYXRhYmFzZS5cbiAgICovXG4gIGFzeW5jIF9yZXNvbHZlVGVuYW50cygpIHtcbiAgICBjb25zdCB0ZW5hbnRzID0gdGhpcy5vcHRpb25zLnRlbmFudHMgPz8gYXdhaXQgdGhpcy5fbGlzdFByb3ZpZGVyVGVuYW50cygpXG4gICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLm9wdGlvbnMuZmlsdGVyID8gdGVuYW50cy5maWx0ZXIodGhpcy5vcHRpb25zLmZpbHRlcikgOiB0ZW5hbnRzXG5cbiAgICByZXR1cm4gZmlsdGVyZWQubWFwKCh0ZW5hbnQpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5yZXNvbHZlRGF0YWJhc2VDb25maWd1cmF0aW9uKHRoaXMub3B0aW9ucy5pZGVudGlmaWVyLCB0ZW5hbnQpXG5cbiAgICAgIC8vIFRoZSBzZXJ2ZXIga2V5IGdyb3VwcyB0ZW5hbnRzIHRoYXQgc2hhcmUgYSBjb25uZWN0aW9uIGVuZHBvaW50IHNvIGNvLWxvY2F0ZWQgdGVuYW50cyBjYW4gYmVcbiAgICAgIC8vIFVOSU9OLWVkIG9uIG9uZSBjb25uZWN0aW9uLiBJdCBvbmx5IG5lZWRzIHRvIGJlIGV4YWN0IGZvciB0aGUgY3Jvc3MtZGF0YWJhc2UgYFVOSU9OIEFMTGBcbiAgICAgIC8vIHBhdGgsIHdoaWNoIGlzIE15U1FMLW9ubHksIHdoZXJlIGhvc3QvcG9ydC91c2VybmFtZS90eXBlIGZ1bGx5IGlkZW50aWZ5IHRoZSBzZXJ2ZXIuIEV2ZXJ5XG4gICAgICAvLyBvdGhlciBkcml2ZXIgdGFrZXMgdGhlIGZhbi1vdXQgcGF0aCAob25lIGNvbm5lY3Rpb24gcGVyIHRlbmFudCksIHNvIGEgY29hcnNlIGtleSB0aGVyZSBqdXN0XG4gICAgICAvLyBncm91cHMgdGVuYW50cyB0aGF0IGFyZSB0aGVuIHF1ZXJpZWQgaW5kaXZpZHVhbGx5IGFueXdheSDigJQgaXQgY2FuIG5ldmVyIHJvdXRlIGEgcXVlcnkgdG8gdGhlXG4gICAgICAvLyB3cm9uZyBzZXJ2ZXIuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhYmFzZTogZGF0YWJhc2VDb25maWd1cmF0aW9uLmRhdGFiYXNlLFxuICAgICAgICBzZXJ2ZXJLZXk6IEpTT04uc3RyaW5naWZ5KFtcbiAgICAgICAgICBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udHlwZSA/PyBudWxsLFxuICAgICAgICAgIGRhdGFiYXNlQ29uZmlndXJhdGlvbi5ob3N0ID8/IG51bGwsXG4gICAgICAgICAgZGF0YWJhc2VDb25maWd1cmF0aW9uLnBvcnQgPz8gbnVsbCxcbiAgICAgICAgICBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udXNlcm5hbWUgPz8gbnVsbFxuICAgICAgICBdKSxcbiAgICAgICAgdGVuYW50XG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyBldmVyeSB0ZW5hbnQgZm9yIHRoZSBpZGVudGlmaWVyIHRocm91Z2ggaXRzIHByb3ZpZGVyJ3MgYGxpc3RUZW5hbnRzYCBob29rLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxvYmplY3RbXT59IC0gRXZlcnkgdGVuYW50IHRoZSBwcm92aWRlciBsaXN0cyBmb3IgdGhlIGlkZW50aWZpZXIuXG4gICAqL1xuICBhc3luYyBfbGlzdFByb3ZpZGVyVGVuYW50cygpIHtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXRUZW5hbnREYXRhYmFzZVByb3ZpZGVyKHRoaXMub3B0aW9ucy5pZGVudGlmaWVyKVxuICAgIGNvbnN0IGxpc3RlZFRlbmFudHMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoXG4gICAgICB7bmFtZTogYFRlbmFudC5hZ2dyZWdhdGVBY3Jvc3M6ICR7dGhpcy5vcHRpb25zLmlkZW50aWZpZXJ9YH0sXG4gICAgICBhc3luYyAoKSA9PiBhd2FpdCBwcm92aWRlci5saXN0VGVuYW50cyh7Y29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLCBpZGVudGlmaWVyOiB0aGlzLm9wdGlvbnMuaWRlbnRpZmllcn0pXG4gICAgKVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3RlZFRlbmFudHMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbmFudCBkYXRhYmFzZSBwcm92aWRlciBmb3IgJHt0aGlzLm9wdGlvbnMuaWRlbnRpZmllcn0gbXVzdCByZXR1cm4gYW4gYXJyYXkgZnJvbSBsaXN0VGVuYW50c2ApXG4gICAgfVxuXG4gICAgcmV0dXJuIGxpc3RlZFRlbmFudHNcbiAgfVxuXG4gIC8qKlxuICAgKiBHcm91cHMgdGVuYW50cyBieSB0aGUgc2VydmVyIHRoZXkgbGl2ZSBvbiBzbyBjby1sb2NhdGVkIHRlbmFudHMgY2FuIHNoYXJlIG9uZSBxdWVyeS5cbiAgICogQHBhcmFtIHtSZXNvbHZlZFRlbmFudFtdfSByZXNvbHZlZFRlbmFudHMgLSBUZW5hbnRzIHJlc29sdmVkIHRvIHRoZWlyIHNlcnZlci5cbiAgICogQHJldHVybnMge1Jlc29sdmVkVGVuYW50W11bXX0gLSBUZW5hbnRzIGdyb3VwZWQgYnkgdGhlIHNlcnZlciB0aGV5IGxpdmUgb24uXG4gICAqL1xuICBfZ3JvdXBCeVNlcnZlcihyZXNvbHZlZFRlbmFudHMpIHtcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFJlc29sdmVkVGVuYW50W10+fSAqL1xuICAgIGNvbnN0IGdyb3VwcyA9IG5ldyBNYXAoKVxuXG4gICAgZm9yIChjb25zdCByZXNvbHZlZFRlbmFudCBvZiByZXNvbHZlZFRlbmFudHMpIHtcbiAgICAgIGNvbnN0IGdyb3VwID0gZ3JvdXBzLmdldChyZXNvbHZlZFRlbmFudC5zZXJ2ZXJLZXkpXG5cbiAgICAgIGlmIChncm91cCkge1xuICAgICAgICBncm91cC5wdXNoKHJlc29sdmVkVGVuYW50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ3JvdXBzLnNldChyZXNvbHZlZFRlbmFudC5zZXJ2ZXJLZXksIFtyZXNvbHZlZFRlbmFudF0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIEFycmF5LmZyb20oZ3JvdXBzLnZhbHVlcygpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdGhlIGFnZ3JlZ2F0ZSBmb3Igb25lIHNlcnZlcidzIHRlbmFudHMsIHVzaW5nIGEgc2luZ2xlIGNyb3NzLWRhdGFiYXNlIGBVTklPTiBBTExgIHdoZW4gdGhlXG4gICAqIGRyaXZlciBzdXBwb3J0cyBpdCBvciBvbmUgcXVlcnkgcGVyIHRlbmFudCBvdGhlcndpc2UuIFRoZSBkcml2ZXIgY2FwYWJpbGl0eSBpcyBwcm9iZWQgaW4gaXRzIG93blxuICAgKiBjb25uZWN0aW9uIHNjb3BlIHRoYXQgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBmYW4tb3V0IHJ1bnMsIHNvIGEgYG1heDogMWAgdGVuYW50IHBvb2wgaXMgbmV2ZXJcbiAgICogYXNrZWQgZm9yIGEgc2Vjb25kIGNvbm5lY3Rpb24gd2hpbGUgdGhlIGZpcnN0IGlzIHN0aWxsIGhlbGQgKHdoaWNoIHdvdWxkIGRlYWRsb2NrKS5cbiAgICogQHBhcmFtIHtSZXNvbHZlZFRlbmFudFtdfSBncm91cCAtIFRlbmFudHMgc2hhcmluZyBvbmUgc2VydmVyLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4+fSAtIFJvd3MgcHJvZHVjZWQgZm9yIHRoaXMgc2VydmVyLlxuICAgKi9cbiAgYXN5bmMgX3J1bkZvclNlcnZlcihncm91cCkge1xuICAgIGNvbnN0IFtmaXJzdFRlbmFudF0gPSBncm91cFxuICAgIGNvbnN0IHN1cHBvcnRzQ3Jvc3NEYXRhYmFzZVJlZmVyZW5jZXMgPSBhd2FpdCB0aGlzLl93aXRoVGVuYW50KFxuICAgICAgZmlyc3RUZW5hbnQudGVuYW50LFxuICAgICAgYXN5bmMgKGNvbm5lY3Rpb25zKSA9PiBjb25uZWN0aW9uc1t0aGlzLm9wdGlvbnMuaWRlbnRpZmllcl0uc3VwcG9ydHNDcm9zc0RhdGFiYXNlUmVmZXJlbmNlcygpXG4gICAgKVxuXG4gICAgaWYgKHN1cHBvcnRzQ3Jvc3NEYXRhYmFzZVJlZmVyZW5jZXMpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLl93aXRoVGVuYW50KGZpcnN0VGVuYW50LnRlbmFudCwgYXN5bmMgKGNvbm5lY3Rpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb25uZWN0aW9uc1t0aGlzLm9wdGlvbnMuaWRlbnRpZmllcl1cblxuICAgICAgICByZXR1cm4gYXdhaXQgY29ubmVjdGlvbi5xdWVyeSh0aGlzLmJ1aWxkQWdncmVnYXRlU3FsKHtjb25uZWN0aW9uLCBlbnRyaWVzOiBncm91cCwgcXVhbGlmaWVkOiB0cnVlfSkpXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAqL1xuICAgIGNvbnN0IHJvd3MgPSBbXVxuXG4gICAgZm9yIChjb25zdCByZXNvbHZlZFRlbmFudCBvZiBncm91cCkge1xuICAgICAgY29uc3QgdGVuYW50Um93cyA9IGF3YWl0IHRoaXMuX3dpdGhUZW5hbnQocmVzb2x2ZWRUZW5hbnQudGVuYW50LCBhc3luYyAoY29ubmVjdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zW3RoaXMub3B0aW9ucy5pZGVudGlmaWVyXVxuXG4gICAgICAgIHJldHVybiBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KHRoaXMuYnVpbGRBZ2dyZWdhdGVTcWwoe2Nvbm5lY3Rpb24sIGVudHJpZXM6IFtyZXNvbHZlZFRlbmFudF0sIHF1YWxpZmllZDogZmFsc2V9KSlcbiAgICAgIH0pXG5cbiAgICAgIHJvd3MucHVzaCguLi50ZW5hbnRSb3dzKVxuICAgIH1cblxuICAgIHJldHVybiByb3dzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBgY2FsbGJhY2tgIGluc2lkZSBhIHRlbmFudCdzIGNvbnRleHQgd2l0aCBpdHMgY29ubmVjdGlvbnMgZXN0YWJsaXNoZWQsIG1pcnJvcmluZ1xuICAgKiBgVGVuYW50LndpdGhgIHdpdGhvdXQgaW1wb3J0aW5nIGl0ICh3aGljaCB3b3VsZCBjcmVhdGUgYW4gaW1wb3J0IGN5Y2xlKS5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtvYmplY3R9IHRlbmFudCAtIFRlbmFudCBkZXNjcmlwdG9yIHRvIHN3aXRjaCBpbnRvLlxuICAgKiBAcGFyYW0geyhjb25uZWN0aW9uczogUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIE9wZXJhdGlvbiB0byBydW4gd2l0aCB0aGUgdGVuYW50J3MgYWN0aXZlIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBDYWxsYmFjayByZXN1bHQgZnJvbSB3aXRoaW4gdGhlIHRlbmFudCBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgX3dpdGhUZW5hbnQodGVuYW50LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24ucnVuV2l0aFRlbmFudCh0ZW5hbnQsIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyhjYWxsYmFjaykpXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBhZ2dyZWdhdGUgU1FMOiBhbiBvdXRlciBgR1JPVVAgQllgIG92ZXIgYSBgVU5JT04gQUxMYCBvZiBlYWNoIGVudHJ5J3Mgc3VicXVlcnkuXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBlbnRyaWVzOiBSZXNvbHZlZFRlbmFudFtdLCBxdWFsaWZpZWQ6IGJvb2xlYW59fSBhcmdzIC0gQ29ubmVjdGlvbiwgdGVuYW50cywgYW5kIHdoZXRoZXIgdG8gcXVhbGlmeSB0YWJsZXMgd2l0aCB0aGVpciBkYXRhYmFzZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIEV4ZWN1dGFibGUgYWdncmVnYXRlIFNRTC5cbiAgICovXG4gIGJ1aWxkQWdncmVnYXRlU3FsKHtjb25uZWN0aW9uLCBlbnRyaWVzLCBxdWFsaWZpZWR9KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNvbm5lY3Rpb24ub3B0aW9ucygpXG4gICAgY29uc3QgcXVvdGUgPSB0aGlzLl9idWlsZFF1b3RlKGNvbm5lY3Rpb24pXG4gICAgY29uc3Qgc3VicXVlcmllcyA9IGVudHJpZXMubWFwKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKHF1YWxpZmllZCAmJiAhZW50cnkuZGF0YWJhc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgYnVpbGQgYSBjcm9zcy1kYXRhYmFzZSBxdWVyeSBmb3IgYSB0ZW5hbnQgd2l0aG91dCBhIHJlc29sdmVkIGRhdGFiYXNlIG5hbWUgKGlkZW50aWZpZXI6ICR7dGhpcy5vcHRpb25zLmlkZW50aWZpZXJ9KS5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB0YWJsZSA9ICgvKiogQHR5cGUge3N0cmluZ30gKi8gdGFibGVOYW1lKSA9PiBxdWFsaWZpZWRcbiAgICAgICAgPyBgJHtvcHRpb25zLnF1b3RlRGF0YWJhc2VOYW1lKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZW50cnkuZGF0YWJhc2UpKX0uJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKHRhYmxlTmFtZSl9YFxuICAgICAgICA6IG9wdGlvbnMucXVvdGVUYWJsZU5hbWUodGFibGVOYW1lKVxuXG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnN1YnF1ZXJ5KHtjb25uZWN0aW9uLCBxdW90ZSwgdGFibGUsIHRlbmFudDogZW50cnkudGVuYW50fSlcbiAgICB9KVxuXG4gICAgY29uc3Qgc2VsZWN0UGFydHMgPSB0aGlzLmtleUNvbHVtbnMubWFwKChrZXlDb2x1bW4pID0+IG9wdGlvbnMucXVvdGVDb2x1bW5OYW1lKGtleUNvbHVtbikpXG5cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBzcGVjXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmFnZ3JlZ2F0ZXMpKSB7XG4gICAgICBjb25zdCBhZ2dyZWdhdGVBcmd1bWVudCA9IHNwZWMuY29sdW1uID09PSBcIipcIiA/IFwiKlwiIDogb3B0aW9ucy5xdW90ZUNvbHVtbk5hbWUoc3BlYy5jb2x1bW4pXG5cbiAgICAgIHNlbGVjdFBhcnRzLnB1c2goYCR7c3BlYy5vcH0oJHthZ2dyZWdhdGVBcmd1bWVudH0pIEFTICR7b3B0aW9ucy5xdW90ZUNvbHVtbk5hbWUobmFtZSl9YClcbiAgICB9XG5cbiAgICBjb25zdCB1bmlvblNxbCA9IHN1YnF1ZXJpZXMubWFwKChzdWJxdWVyeSkgPT4gYFNFTEVDVCAqIEZST00gKCR7c3VicXVlcnl9KSAke29wdGlvbnMucXVvdGVUYWJsZU5hbWUoYCR7REVSSVZFRF9UQUJMRV9BTElBU31fc291cmNlYCl9YCkuam9pbihcIlxcblVOSU9OIEFMTFxcblwiKVxuICAgIGNvbnN0IGdyb3VwQnlTcWwgPSB0aGlzLmtleUNvbHVtbnMubGVuZ3RoID4gMFxuICAgICAgPyBgXFxuR1JPVVAgQlkgJHt0aGlzLmtleUNvbHVtbnMubWFwKChrZXlDb2x1bW4pID0+IG9wdGlvbnMucXVvdGVDb2x1bW5OYW1lKGtleUNvbHVtbikpLmpvaW4oXCIsIFwiKX1gXG4gICAgICA6IFwiXCJcblxuICAgIHJldHVybiBgU0VMRUNUICR7c2VsZWN0UGFydHMuam9pbihcIiwgXCIpfVxcbkZST00gKFxcbiR7dW5pb25TcWx9XFxuKSAke29wdGlvbnMucXVvdGVUYWJsZU5hbWUoREVSSVZFRF9UQUJMRV9BTElBUyl9JHtncm91cEJ5U3FsfWBcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgcm93cyBmcm9tIGV2ZXJ5IHNlcnZlciBieSBjb21iaW5pbmcgZWFjaCBhZ2dyZWdhdGUgd2l0aCBpdHMgb3duIG9wZXJhdGlvbi4gQSBgTlVMTGBcbiAgICogYWdncmVnYXRlIHZhbHVlIChhbiBlbXB0eSB0ZW5hbnQncyBgU1VNYC9gTUFYYC9gTUlOYCByZXR1cm5zIGBOVUxMYCBvbiB0aGUgZmFuLW91dCBwYXRoKSBpc1xuICAgKiB0cmVhdGVkIGFzIFwibm8gY29udHJpYnV0aW9uXCIgYW5kIHNraXBwZWQsIG5vdCBjb2VyY2VkIHRvIGAwYCDigJQgb3RoZXJ3aXNlIGFuIGVtcHR5IHRlbmFudCB3b3VsZFxuICAgKiBkcmFnIGEgYE1BWGAgb2YgbmVnYXRpdmVzIG9yIGEgYE1JTmAgb2YgcG9zaXRpdmVzIHRvIGAwYC4gQSBrZXkgd2hvc2UgZXZlcnkgdGVuYW50IGNvbnRyaWJ1dGVkXG4gICAqIGBOVUxMYCBzdGF5cyBgTlVMTGAsIG1hdGNoaW5nIFNRTCBhZ2dyZWdhdGUgc2VtYW50aWNzIG92ZXIgbm8gcm93cy5cbiAgICogQHBhcmFtIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59IHJvd3MgLSBSb3dzIGNvbGxlY3RlZCBmcm9tIGFsbCBzZXJ2ZXJzL3RlbmFudHMuXG4gICAqIEByZXR1cm5zIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59IC0gT25lIG1lcmdlZCByb3cgcGVyIGRpc3RpbmN0IGtleS1jb2x1bW4gY29tYmluYXRpb24uXG4gICAqL1xuICBfbWVyZ2VSb3dzKHJvd3MpIHtcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsID8+Pn0gKi9cbiAgICBjb25zdCBtZXJnZWQgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGNvbnN0IG1hcEtleSA9IEpTT04uc3RyaW5naWZ5KHRoaXMua2V5Q29sdW1ucy5tYXAoKGtleUNvbHVtbikgPT4gcm93W2tleUNvbHVtbl0pKVxuICAgICAgbGV0IGFjY3VtdWxhdG9yID0gbWVyZ2VkLmdldChtYXBLZXkpXG5cbiAgICAgIGlmICghYWNjdW11bGF0b3IpIHtcbiAgICAgICAgYWNjdW11bGF0b3IgPSB7fVxuXG4gICAgICAgIGZvciAoY29uc3Qga2V5Q29sdW1uIG9mIHRoaXMua2V5Q29sdW1ucykge1xuICAgICAgICAgIGFjY3VtdWxhdG9yW2tleUNvbHVtbl0gPSByb3dba2V5Q29sdW1uXVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHRoaXMuYWdncmVnYXRlcykpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvcltuYW1lXSA9IG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIG1lcmdlZC5zZXQobWFwS2V5LCBhY2N1bXVsYXRvcilcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBbbmFtZSwgc3BlY10gb2YgT2JqZWN0LmVudHJpZXModGhpcy5hZ2dyZWdhdGVzKSkge1xuICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHJvd1tuYW1lXVxuXG4gICAgICAgIGlmIChyYXdWYWx1ZSA9PT0gbnVsbCB8fCByYXdWYWx1ZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZVxuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fdG9FeGFjdE51bWJlcihyYXdWYWx1ZSlcblxuICAgICAgICBhY2N1bXVsYXRvcltuYW1lXSA9IGFjY3VtdWxhdG9yW25hbWVdID09PSBudWxsID8gdmFsdWUgOiB0aGlzLl9jb21iaW5lKHNwZWMub3AsIGFjY3VtdWxhdG9yW25hbWVdLCB2YWx1ZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbShtZXJnZWQudmFsdWVzKCkpXG4gIH1cblxuICAvKipcbiAgICogQ29tYmluZXMgdHdvIG5vbi1udWxsIHBlci1zZXJ2ZXIgYWdncmVnYXRlIHZhbHVlcyB3aXRoIHRoZSBhZ2dyZWdhdGUncyBvd24gb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge0FnZ3JlZ2F0ZU9wZXJhdGlvbn0gb3AgLSBBZ2dyZWdhdGUgb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY3VycmVudCAtIEFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgLSBJbmNvbWluZyBwZXItc2VydmVyIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIENvbWJpbmVkIHZhbHVlLlxuICAgKi9cbiAgX2NvbWJpbmUob3AsIGN1cnJlbnQsIHZhbHVlKSB7XG4gICAgaWYgKG9wID09PSBcIk1BWFwiKSByZXR1cm4gTWF0aC5tYXgoY3VycmVudCwgdmFsdWUpXG4gICAgaWYgKG9wID09PSBcIk1JTlwiKSByZXR1cm4gTWF0aC5taW4oY3VycmVudCwgdmFsdWUpXG5cbiAgICByZXR1cm4gY3VycmVudCArIHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkcml2ZXItcmV0dXJuZWQgYWdncmVnYXRlIHZhbHVlIHRvIGEgbnVtYmVyLCBmYWlsaW5nIGxvdWRseSByYXRoZXIgdGhhbiBzaWxlbnRseVxuICAgKiBsb3NpbmcgcHJlY2lzaW9uLiBEcml2ZXJzIHJldHVybiBleGFjdCBpbnRlZ2VyIGFnZ3JlZ2F0ZXMgKE15U1FMIGBTVU1gL2BDT1VOVGAsIFBvc3RncmVTUUxcbiAgICogYGJpZ2ludGApIGFzIHN0cmluZ3M7IGFuIGludGVnZXIgYmV5b25kIGBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUmAgY2Fubm90IGJlIHJlcHJlc2VudGVkIGV4YWN0bHlcbiAgICogYXMgYSBKUyBudW1iZXIsIHNvIGNyb3NzLXNlcnZlciBtZXJnaW5nIHdvdWxkIGNvcnJ1cHQgdGhlIHJlc3VsdCDigJQgdGhyb3cgaW5zdGVhZC4gKEZyYWN0aW9uYWxcbiAgICogYERFQ0lNQUxgL2BOVU1FUklDYCB2YWx1ZXMgYXJlIHN0aWxsIHN1YmplY3QgdG8gbm9ybWFsIGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uLilcbiAgICogQHBhcmFtIHs/fSByYXdWYWx1ZSAtIFZhbHVlIHJldHVybmVkIGJ5IHRoZSBkcml2ZXIgZm9yIGFuIGFnZ3JlZ2F0ZSBjb2x1bW4uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHZhbHVlIGFzIGEgbnVtYmVyLlxuICAgKi9cbiAgX3RvRXhhY3ROdW1iZXIocmF3VmFsdWUpIHtcbiAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihyYXdWYWx1ZSlcblxuICAgIGlmICh0eXBlb2YgcmF3VmFsdWUgPT09IFwic3RyaW5nXCIgJiYgL14tP1xcZCskLy50ZXN0KHJhd1ZhbHVlLnRyaW0oKSkgJiYgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBZ2dyZWdhdGUgdmFsdWUgJHtyYXdWYWx1ZX0gZXhjZWVkcyB0aGUgc2FmZS1pbnRlZ2VyIHJhbmdlIGFuZCBjYW5ub3QgYmUgbWVyZ2VkIHdpdGhvdXQgbG9zaW5nIHByZWNpc2lvbi5gKVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgdmFsdWUgcXVvdGVyIHBhc3NlZCB0byBzdWJxdWVyaWVzLCB3aXRoIGEgYC5saXN0YCBoZWxwZXIgZm9yIGBJTiAoLi4uKWAgY2xhdXNlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIERyaXZlciB3aG9zZSBxdW90aW5nIGlzIHVzZWQuXG4gICAqIEByZXR1cm5zIHsoKHZhbHVlOiA/KSA9PiBzdHJpbmcpICYge2xpc3Q6ICh2YWx1ZXM6IEFycmF5PD8+KSA9PiBzdHJpbmd9fSAtIFZhbHVlIHF1b3RlciB3aXRoIGEgYC5saXN0YCBoZWxwZXIuXG4gICAqL1xuICBfYnVpbGRRdW90ZShjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oXG4gICAgICAoLyoqIEB0eXBlIHs/fSAqLyB2YWx1ZSkgPT4gU3RyaW5nKGNvbm5lY3Rpb24ucXVvdGUodmFsdWUpKSxcbiAgICAgIHtsaXN0OiAoLyoqIEB0eXBlIHtBcnJheTw/Pn0gKi8gdmFsdWVzKSA9PiB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4gU3RyaW5nKGNvbm5lY3Rpb24ucXVvdGUodmFsdWUpKSkuam9pbihcIiwgXCIpfVxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIHRoZSBhZ2dyZWdhdGUgc3BlY3MgKHN0cmluZyBzaG9ydGhhbmQgb3Igb2JqZWN0KSBhbmQgdmFsaWRhdGVzIGVhY2ggb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIEFnZ3JlZ2F0ZVNwZWM+fSBhZ2dyZWdhdGVzIC0gUmF3IGFnZ3JlZ2F0ZSBzcGVjcy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHtvcDogQWdncmVnYXRlT3BlcmF0aW9uLCBjb2x1bW46IHN0cmluZ30+fSAtIE5vcm1hbGl6ZWQgYWdncmVnYXRlIHNwZWNzLlxuICAgKi9cbiAgX25vcm1hbGl6ZUFnZ3JlZ2F0ZXMoYWdncmVnYXRlcykge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywge29wOiBBZ2dyZWdhdGVPcGVyYXRpb24sIGNvbHVtbjogc3RyaW5nfT59ICovXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBzcGVjXSBvZiBPYmplY3QuZW50cmllcyhhZ2dyZWdhdGVzKSkge1xuICAgICAgY29uc3Qgb3AgPSAvKiogQHR5cGUge0FnZ3JlZ2F0ZU9wZXJhdGlvbn0gKi8gKCh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIiA/IHNwZWMgOiBzcGVjLm9wKS50b1VwcGVyQ2FzZSgpKVxuXG4gICAgICBpZiAoIUFHR1JFR0FURV9PUEVSQVRJT05TLmhhcyhvcCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBhZ2dyZWdhdGUgb3BlcmF0aW9uIGZvciAke25hbWV9OiAke29wfS4gU3VwcG9ydGVkOiAke0FycmF5LmZyb20oQUdHUkVHQVRFX09QRVJBVElPTlMpLmpvaW4oXCIsIFwiKX0uYClcbiAgICAgIH1cblxuICAgICAgbm9ybWFsaXplZFtuYW1lXSA9IHtjb2x1bW46IHR5cGVvZiBzcGVjID09PSBcInN0cmluZ1wiID8gbmFtZSA6IHNwZWMuY29sdW1uLCBvcH1cbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFxuICB9XG59XG4iXX0=
|
|
286
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWFnZ3JlZ2F0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVuYW50cy90ZW5hbnQtYWdncmVnYXRvci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxPQUFPLE1BQU0sZUFBZSxDQUFBO0FBRW5DOztHQUVHO0FBRUg7O0dBRUc7QUFFSDs7Ozs7O0dBTUc7QUFFSDs7Ozs7Ozs7OztHQVVHO0FBRUg7O0dBRUc7QUFFSCxNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQTtBQUNwRSxNQUFNLG1CQUFtQixHQUFHLDRCQUE0QixDQUFBO0FBRXhEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sZ0JBQWdCO0lBQ25DOzs7T0FHRztJQUNILFlBQVksT0FBTztRQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTtRQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBQ3JFLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUE7UUFDMUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ2pFLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsR0FBRztRQUNQLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO1FBRXBELElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUE7UUFFM0MsdUNBQXVDO1FBQ3ZDLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUVmLEtBQUssTUFBTSxLQUFL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SUFFRDs7OztPQUlHO0lBQ0gsb0JBQW9CLENBQUMsVUFBVTtRQUM3Qix1RUFBdUU7UUFDdkUsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFBO1FBRXJCLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDdEQsTUFBTSxFQUFFLEdBQUcsaUNBQWlDLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtZQUV4RyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLElBQUksS0FBSyxFQUFFLGdCQUFnQixLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNuSSxDQUFDO1lBRUQsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUMsTUFBTSxFQUFFLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBQyxDQUFBO1FBQ2hGLENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQTtJQUNuQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEN1cnJlbnQgZnJvbSBcIi4uL2N1cnJlbnQuanNcIlxuXG4vKipcbiAqIEB0eXBlZGVmIHtcIlNVTVwiIHwgXCJDT1VOVFwiIHwgXCJNQVhcIiB8IFwiTUlOXCJ9IEFnZ3JlZ2F0ZU9wZXJhdGlvblxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0FnZ3JlZ2F0ZU9wZXJhdGlvbiB8IHtvcDogQWdncmVnYXRlT3BlcmF0aW9uLCBjb2x1bW46IHN0cmluZ319IEFnZ3JlZ2F0ZVNwZWNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN1YnF1ZXJ5Q29udGV4dFxuICogQHByb3BlcnR5IHsodGFibGVOYW1lOiBzdHJpbmcpID0+IHN0cmluZ30gdGFibGUgLSBRdW90ZXMgYSB0YWJsZSBmb3IgdGhpcyB0ZW5hbnQuIEluIGEgY3Jvc3MtZGF0YWJhc2UgYFVOSU9OIEFMTGAgaXQgcmV0dXJucyBhIGBkYXRhYmFzZWAuYHRhYmxlYCBxdWFsaWZpZWQgaWRlbnRpZmllcjsgd2hlbiBlYWNoIHRlbmFudCBydW5zIG9uIGl0cyBvd24gY29ubmVjdGlvbiBpdCByZXR1cm5zIHRoZSBwbGFpbiBxdW90ZWQgdGFibGUgbmFtZS4gVXNlIGl0IGZvciBldmVyeSB0YWJsZSB0aGUgc3VicXVlcnkgcmVhZHMgc28gdGhlIHNhbWUgc3VicXVlcnkgd29ya3Mgb24gYm90aCBleGVjdXRpb24gcGF0aHMuXG4gKiBAcHJvcGVydHkgeygodmFsdWU6ID8pID0+IHN0cmluZykgJiB7bGlzdDogKHZhbHVlczogQXJyYXk8Pz4pID0+IHN0cmluZ319IHF1b3RlIC0gUXVvdGVzIGEgdmFsdWUgZm9yIHRoZSBhY3RpdmUgY29ubmVjdGlvbi4gYHF1b3RlLmxpc3QodmFsdWVzKWAgcXVvdGVzIGFuZCBjb21tYS1qb2lucyBhbiBhcnJheSBmb3IgYElOICguLi4pYCBjbGF1c2VzLlxuICogQHByb3BlcnR5IHtvYmplY3R9IHRlbmFudCAtIFRoZSB0ZW5hbnQgZGVzY3JpcHRvciB0aGlzIHN1YnF1ZXJ5IGlzIGJlaW5nIGJ1aWx0IGZvci5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBUaGUgZHJpdmVyIHRoZSBxdWVyeSB3aWxsIHJ1biBvbi5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlbmFudEFnZ3JlZ2F0ZU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllciB3aG9zZSB0ZW5hbnRzIGFyZSBhZ2dyZWdhdGVkIChmb3IgZXhhbXBsZSBgXCJwcm9qZWN0VGVuYW50XCJgKS5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0W119IFt0ZW5hbnRzXSAtIEV4cGxpY2l0IHRlbmFudCBkZXNjcmlwdG9ycyB0byBhZ2dyZWdhdGUuIERlZmF1bHRzIHRvIGV2ZXJ5IHRlbmFudCB0aGUgaWRlbnRpZmllcidzIHByb3ZpZGVyIGBsaXN0VGVuYW50c2AgcmV0dXJucy5cbiAqIEBwcm9wZXJ0eSB7KHRlbmFudDogPykgPT4gYm9vbGVhbn0gW2ZpbHRlcl0gLSBPcHRpb25hbCBmaWx0ZXIgYXBwbGllZCB0byB0aGUgcmVzb2x2ZWQgdGVuYW50IGxpc3QuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBba2V5Q29sdW1uc10gLSBDb2x1bW5zIHRoZSBhZ2dyZWdhdGUgaXMgZ3JvdXBlZCBieSAoZm9yIGV4YW1wbGUgYFtcImRvY2tlcl9zZXJ2ZXJfaWRcIl1gKS4gRW1wdHkgbWVhbnMgYSBzaW5nbGUgZ3JhbmQtdG90YWwgcm93LlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBBZ2dyZWdhdGVTcGVjPn0gYWdncmVnYXRlcyAtIE91dHB1dCBjb2x1bW4gbmFtZSB0byBhZ2dyZWdhdGUuIGBcIlNVTVwiYCBpcyBzaG9ydGhhbmQgZm9yIGB7b3A6IFwiU1VNXCIsIGNvbHVtbjogPG91dHB1dCBuYW1lPn1gOyB1c2UgYHtvcDogXCJDT1VOVFwiLCBjb2x1bW46IFwiKlwifWAgZm9yIGBDT1VOVCgqKWAuXG4gKiBAcHJvcGVydHkge0Fib3J0U2lnbmFsfSBbc2lnbmFsXSAtIFNpZ25hbCBwYXNzZWQgdG8gZWFjaCBhZ2dyZWdhdGUgZGF0YWJhc2UgcXVlcnkuXG4gKiBAcHJvcGVydHkgeyhjb250ZXh0OiBTdWJxdWVyeUNvbnRleHQpID0+IHN0cmluZ30gc3VicXVlcnkgLSBCdWlsZHMgb25lIHRlbmFudCdzIGlubmVyIGBTRUxFQ1RgLCB3aGljaCBtdXN0IHNlbGVjdCBldmVyeSBga2V5Q29sdW1uc2AgZW50cnkgcGx1cyBldmVyeSBhZ2dyZWdhdGUgc291cmNlIGNvbHVtbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIHRvIHJ1biBhZ2FpbnN0LiBEZWZhdWx0cyB0byB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge3t0ZW5hbnQ6IG9iamVjdCwgZGF0YWJhc2U6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2VydmVyS2V5OiBzdHJpbmd9fSBSZXNvbHZlZFRlbmFudFxuICovXG5cbmNvbnN0IEFHR1JFR0FURV9PUEVSQVRJT05TID0gbmV3IFNldChbXCJTVU1cIiwgXCJDT1VOVFwiLCBcIk1BWFwiLCBcIk1JTlwiXSlcbmNvbnN0IERFUklWRURfVEFCTEVfQUxJQVMgPSBcInZlbG9jaW91c190ZW5hbnRfYWdncmVnYXRlXCJcblxuLyoqXG4gKiBSdW5zIG9uZSBhZ2dyZWdhdGUgcXVlcnkgYWNyb3NzIG1hbnkgdGVuYW50IGRhdGFiYXNlcyBhbmQgbWVyZ2VzIHRoZSByZXN1bHQuIFRlbmFudCBkYXRhYmFzZXMgbWF5XG4gKiBiZSBjby1sb2NhdGVkIG9uIHRoZSBkZWZhdWx0IHNlcnZlciBvciBzcHJlYWQgYWNyb3NzIG90aGVyIHNlcnZlcnMsIGFuZCB0aGV5IGNhbiBhcHBlYXIgb3JcbiAqIGRpc2FwcGVhciBhdCBydW50aW1lOyB0aGlzIHJlc29sdmVzIHRoZSBsaXZlIHRlbmFudCBsaXN0LCBncm91cHMgdGVuYW50cyBieSB0aGUgc2VydmVyIHRoZXkgbGl2ZVxuICogb24sIGFuZCDigJQgcGVyIHNlcnZlciDigJQgZW1pdHMgYSBzaW5nbGUgY3Jvc3MtZGF0YWJhc2UgYFVOSU9OIEFMTGAgd2hlbiB0aGUgZHJpdmVyIHN1cHBvcnRzIHF1YWxpZmllZFxuICogY3Jvc3MtZGF0YWJhc2UgcmVmZXJlbmNlcyAoTXlTUUwvTVNTUUwpIG9yIGZhbGxzIGJhY2sgdG8gb25lIHF1ZXJ5IHBlciB0ZW5hbnQgb3RoZXJ3aXNlXG4gKiAoUG9zdGdyZVNRTC9TUUxpdGUpLiBSZXN1bHRzIGZyb20gZXZlcnkgc2VydmVyIGFyZSBtZXJnZWQgd2l0aCB0aGUgYWdncmVnYXRlJ3Mgb3duIG9wZXJhdGlvbiwgc29cbiAqIGNhbGxlcnMgZ2V0IG9uZSBjb21iaW5lZCByZXN1bHQgc2V0IHJlZ2FyZGxlc3Mgb2YgaG93IHRoZSB0ZW5hbnRzIGFyZSBkaXN0cmlidXRlZC4gUmVhY2hlZCB0aHJvdWdoXG4gKiBgVGVuYW50LmFnZ3JlZ2F0ZUFjcm9zc2AuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlbmFudEFnZ3JlZ2F0b3Ige1xuICAvKipcbiAgICogUHJlcGFyZXMgYW4gYWdncmVnYXRlIHJ1biwgbm9ybWFsaXppbmcgdGhlIGFnZ3JlZ2F0ZSBzcGVjcyB1cCBmcm9udC5cbiAgICogQHBhcmFtIHtUZW5hbnRBZ2dyZWdhdGVPcHRpb25zfSBvcHRpb25zIC0gQWdncmVnYXRlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IG9wdGlvbnMuY29uZmlndXJhdGlvbiA/PyBDdXJyZW50LmNvbmZpZ3VyYXRpb24oKVxuICAgIHRoaXMua2V5Q29sdW1ucyA9IG9wdGlvbnMua2V5Q29sdW1ucyA/PyBbXVxuICAgIHRoaXMuYWdncmVnYXRlcyA9IHRoaXMuX25vcm1hbGl6ZUFnZ3JlZ2F0ZXMob3B0aW9ucy5hZ2dyZWdhdGVzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSB0ZW5hbnQgbGlzdCwgcnVucyB0aGUgYWdncmVnYXRlIHBlciBzZXJ2ZXIsIGFuZCBtZXJnZXMgZXZlcnl0aGluZy5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+Pn0gLSBPbmUgbWVyZ2VkIHJvdyBwZXIgZGlzdGluY3Qga2V5LWNvbHVtbiBjb21iaW5hdGlvbi5cbiAgICovXG4gIGFzeW5jIHJ1bigpIHtcbiAgICBjb25zdCByZXNvbHZlZFRlbmFudHMgPSBhd2FpdCB0aGlzLl9yZXNvbHZlVGVuYW50cygpXG5cbiAgICBpZiAocmVzb2x2ZWRUZW5hbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdXG5cbiAgICAvKiogQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsID8+Pn0gKi9cbiAgICBjb25zdCByb3dzID0gW11cblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgdGhpcy5fZ3JvdXBCeVNlcnZlcihyZXNvbHZlZFRlbmFudHMpKSB7XG4gICAgICBjb25zdCBncm91cFJvd3MgPSBhd2FpdCB0aGlzLl9ydW5Gb3JTZXJ2ZXIoZ3JvdXApXG5cbiAgICAgIHJvd3MucHVzaCguLi5ncm91cFJvd3MpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX21lcmdlUm93cyhyb3dzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSB0ZW5hbnQgbGlzdCAoZXhwbGljaXQgb3IgZnJvbSB0aGUgcHJvdmlkZXIpLCB0aGVuIG1hcHMgZWFjaCB0byBpdHMgc2VydmVyIGFuZFxuICAgKiBkYXRhYmFzZSB2aWEgdGhlIHRlbmFudCBkYXRhYmFzZSByZXNvbHZlci5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVzb2x2ZWRUZW5hbnRbXT59IC0gVGVuYW50cyB0byBhZ2dyZWdhdGUsIGVhY2ggcmVzb2x2ZWQgdG8gaXRzIHNlcnZlciArIGRhdGFiYXNlLlxuICAgKi9cbiAgYXN5bmMgX3Jlc29sdmVUZW5hbnRzKCkge1xuICAgIGNvbnN0IHRlbmFudHMgPSB0aGlzLm9wdGlvbnMudGVuYW50cyA/PyBhd2FpdCB0aGlzLl9saXN0UHJvdmlkZXJUZW5hbnRzKClcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMub3B0aW9ucy5maWx0ZXIgPyB0ZW5hbnRzLmZpbHRlcih0aGlzLm9wdGlvbnMuZmlsdGVyKSA6IHRlbmFudHNcblxuICAgIHJldHVybiBmaWx0ZXJlZC5tYXAoKHRlbmFudCkgPT4ge1xuICAgICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLnJlc29sdmVEYXRhYmFzZUNvbmZpZ3VyYXRpb24odGhpcy5vcHRpb25zLmlkZW50aWZpZXIsIHRlbmFudClcblxuICAgICAgLy8gVGhlIHNlcnZlciBrZXkgZ3JvdXBzIHRlbmFudHMgdGhhdCBzaGFyZSBhIGNvbm5lY3Rpb24gZW5kcG9pbnQgc28gY28tbG9jYXRlZCB0ZW5hbnRzIGNhbiBiZVxuICAgICAgLy8gVU5JT04tZWQgb24gb25lIGNvbm5lY3Rpb24uIEl0IG9ubHkgbmVlZHMgdG8gYmUgZXhhY3QgZm9yIHRoZSBjcm9zcy1kYXRhYmFzZSBgVU5JT04gQUxMYFxuICAgICAgLy8gcGF0aCwgd2hpY2ggaXMgTXlTUUwtb25seSwgd2hlcmUgaG9zdC9wb3J0L3VzZXJuYW1lL3R5cGUgZnVsbHkgaWRlbnRpZnkgdGhlIHNlcnZlci4gRXZlcnlcbiAgICAgIC8vIG90aGVyIGRyaXZlciB0YWtlcyB0aGUgZmFuLW91dCBwYXRoIChvbmUgY29ubmVjdGlvbiBwZXIgdGVuYW50KSwgc28gYSBjb2Fyc2Uga2V5IHRoZXJlIGp1c3RcbiAgICAgIC8vIGdyb3VwcyB0ZW5hbnRzIHRoYXQgYXJlIHRoZW4gcXVlcmllZCBpbmRpdmlkdWFsbHkgYW55d2F5IOKAlCBpdCBjYW4gbmV2ZXIgcm91dGUgYSBxdWVyeSB0byB0aGVcbiAgICAgIC8vIHdyb25nIHNlcnZlci5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGFiYXNlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24uZGF0YWJhc2UsXG4gICAgICAgIHNlcnZlcktleTogSlNPTi5zdHJpbmdpZnkoW1xuICAgICAgICAgIGRhdGFiYXNlQ29uZmlndXJhdGlvbi50eXBlID8/IG51bGwsXG4gICAgICAgICAgZGF0YWJhc2VDb25maWd1cmF0aW9uLmhvc3QgPz8gbnVsbCxcbiAgICAgICAgICBkYXRhYmFzZUNvbmZpZ3VyYXRpb24ucG9ydCA/PyBudWxsLFxuICAgICAgICAgIGRhdGFiYXNlQ29uZmlndXJhdGlvbi51c2VybmFtZSA/PyBudWxsXG4gICAgICAgIF0pLFxuICAgICAgICB0ZW5hbnRcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIGV2ZXJ5IHRlbmFudCBmb3IgdGhlIGlkZW50aWZpZXIgdGhyb3VnaCBpdHMgcHJvdmlkZXIncyBgbGlzdFRlbmFudHNgIGhvb2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdFtdPn0gLSBFdmVyeSB0ZW5hbnQgdGhlIHByb3ZpZGVyIGxpc3RzIGZvciB0aGUgaWRlbnRpZmllci5cbiAgICovXG4gIGFzeW5jIF9saXN0UHJvdmlkZXJUZW5hbnRzKCkge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5jb25maWd1cmF0aW9uLmdldFRlbmFudERhdGFiYXNlUHJvdmlkZXIodGhpcy5vcHRpb25zLmlkZW50aWZpZXIpXG4gICAgY29uc3QgbGlzdGVkVGVuYW50cyA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyhcbiAgICAgIHtuYW1lOiBgVGVuYW50LmFnZ3JlZ2F0ZUFjcm9zczogJHt0aGlzLm9wdGlvbnMuaWRlbnRpZmllcn1gfSxcbiAgICAgIGFzeW5jICgpID0+IGF3YWl0IHByb3ZpZGVyLmxpc3RUZW5hbnRzKHtjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sIGlkZW50aWZpZXI6IHRoaXMub3B0aW9ucy5pZGVudGlmaWVyfSlcbiAgICApXG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdGVkVGVuYW50cykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuYW50IGRhdGFiYXNlIHByb3ZpZGVyIGZvciAke3RoaXMub3B0aW9ucy5pZGVudGlmaWVyfSBtdXN0IHJldHVybiBhbiBhcnJheSBmcm9tIGxpc3RUZW5hbnRzYClcbiAgICB9XG5cbiAgICByZXR1cm4gbGlzdGVkVGVuYW50c1xuICB9XG5cbiAgLyoqXG4gICAqIEdyb3VwcyB0ZW5hbnRzIGJ5IHRoZSBzZXJ2ZXIgdGhleSBsaXZlIG9uIHNvIGNvLWxvY2F0ZWQgdGVuYW50cyBjYW4gc2hhcmUgb25lIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge1Jlc29sdmVkVGVuYW50W119IHJlc29sdmVkVGVuYW50cyAtIFRlbmFudHMgcmVzb2x2ZWQgdG8gdGhlaXIgc2VydmVyLlxuICAgKiBAcmV0dXJucyB7UmVzb2x2ZWRUZW5hbnRbXVtdfSAtIFRlbmFudHMgZ3JvdXBlZCBieSB0aGUgc2VydmVyIHRoZXkgbGl2ZSBvbi5cbiAgICovXG4gIF9ncm91cEJ5U2VydmVyKHJlc29sdmVkVGVuYW50cykge1xuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgUmVzb2x2ZWRUZW5hbnRbXT59ICovXG4gICAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcCgpXG5cbiAgICBmb3IgKGNvbnN0IHJlc29sdmVkVGVuYW50IG9mIHJlc29sdmVkVGVuYW50cykge1xuICAgICAgY29uc3QgZ3JvdXAgPSBncm91cHMuZ2V0KHJlc29sdmVkVGVuYW50LnNlcnZlcktleSlcblxuICAgICAgaWYgKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnB1c2gocmVzb2x2ZWRUZW5hbnQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBncm91cHMuc2V0KHJlc29sdmVkVGVuYW50LnNlcnZlcktleSwgW3Jlc29sdmVkVGVuYW50XSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbShncm91cHMudmFsdWVzKCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgYWdncmVnYXRlIGZvciBvbmUgc2VydmVyJ3MgdGVuYW50cywgdXNpbmcgYSBzaW5nbGUgY3Jvc3MtZGF0YWJhc2UgYFVOSU9OIEFMTGAgd2hlbiB0aGVcbiAgICogZHJpdmVyIHN1cHBvcnRzIGl0IG9yIG9uZSBxdWVyeSBwZXIgdGVuYW50IG90aGVyd2lzZS4gVGhlIGRyaXZlciBjYXBhYmlsaXR5IGlzIHByb2JlZCBpbiBpdHMgb3duXG4gICAqIGNvbm5lY3Rpb24gc2NvcGUgdGhhdCBpcyByZWxlYXNlZCBiZWZvcmUgdGhlIGZhbi1vdXQgcnVucywgc28gYSBgbWF4OiAxYCB0ZW5hbnQgcG9vbCBpcyBuZXZlclxuICAgKiBhc2tlZCBmb3IgYSBzZWNvbmQgY29ubmVjdGlvbiB3aGlsZSB0aGUgZmlyc3QgaXMgc3RpbGwgaGVsZCAod2hpY2ggd291bGQgZGVhZGxvY2spLlxuICAgKiBAcGFyYW0ge1Jlc29sdmVkVGVuYW50W119IGdyb3VwIC0gVGVuYW50cyBzaGFyaW5nIG9uZSBzZXJ2ZXIuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pj59IC0gUm93cyBwcm9kdWNlZCBmb3IgdGhpcyBzZXJ2ZXIuXG4gICAqL1xuICBhc3luYyBfcnVuRm9yU2VydmVyKGdyb3VwKSB7XG4gICAgY29uc3QgW2ZpcnN0VGVuYW50XSA9IGdyb3VwXG4gICAgY29uc3Qgc3VwcG9ydHNDcm9zc0RhdGFiYXNlUmVmZXJlbmNlcyA9IGF3YWl0IHRoaXMuX3dpdGhUZW5hbnQoXG4gICAgICBmaXJzdFRlbmFudC50ZW5hbnQsXG4gICAgICBhc3luYyAoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zW3RoaXMub3B0aW9ucy5pZGVudGlmaWVyXS5zdXBwb3J0c0Nyb3NzRGF0YWJhc2VSZWZlcmVuY2VzKClcbiAgICApXG5cbiAgICBpZiAoc3VwcG9ydHNDcm9zc0RhdGFiYXNlUmVmZXJlbmNlcykge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3dpdGhUZW5hbnQoZmlyc3RUZW5hbnQudGVuYW50LCBhc3luYyAoY29ubmVjdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zW3RoaXMub3B0aW9ucy5pZGVudGlmaWVyXVxuXG4gICAgICAgIHJldHVybiBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KHRoaXMuYnVpbGRBZ2dyZWdhdGVTcWwoe2Nvbm5lY3Rpb24sIGVudHJpZXM6IGdyb3VwLCBxdWFsaWZpZWQ6IHRydWV9KSwge3NpZ25hbDogdGhpcy5vcHRpb25zLnNpZ25hbH0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAqL1xuICAgIGNvbnN0IHJvd3MgPSBbXVxuXG4gICAgZm9yIChjb25zdCByZXNvbHZlZFRlbmFudCBvZiBncm91cCkge1xuICAgICAgY29uc3QgdGVuYW50Um93cyA9IGF3YWl0IHRoaXMuX3dpdGhUZW5hbnQocmVzb2x2ZWRUZW5hbnQudGVuYW50LCBhc3luYyAoY29ubmVjdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zW3RoaXMub3B0aW9ucy5pZGVudGlmaWVyXVxuXG4gICAgICAgIHJldHVybiBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KHRoaXMuYnVpbGRBZ2dyZWdhdGVTcWwoe2Nvbm5lY3Rpb24sIGVudHJpZXM6IFtyZXNvbHZlZFRlbmFudF0sIHF1YWxpZmllZDogZmFsc2V9KSwge3NpZ25hbDogdGhpcy5vcHRpb25zLnNpZ25hbH0pXG4gICAgICB9KVxuXG4gICAgICByb3dzLnB1c2goLi4udGVuYW50Um93cylcbiAgICB9XG5cbiAgICByZXR1cm4gcm93c1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYGNhbGxiYWNrYCBpbnNpZGUgYSB0ZW5hbnQncyBjb250ZXh0IHdpdGggaXRzIGNvbm5lY3Rpb25zIGVzdGFibGlzaGVkLCBtaXJyb3JpbmdcbiAgICogYFRlbmFudC53aXRoYCB3aXRob3V0IGltcG9ydGluZyBpdCAod2hpY2ggd291bGQgY3JlYXRlIGFuIGltcG9ydCBjeWNsZSkuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7b2JqZWN0fSB0ZW5hbnQgLSBUZW5hbnQgZGVzY3JpcHRvciB0byBzd2l0Y2ggaW50by5cbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbnM6IFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0PikgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBPcGVyYXRpb24gdG8gcnVuIHdpdGggdGhlIHRlbmFudCdzIGFjdGl2ZSBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gQ2FsbGJhY2sgcmVzdWx0IGZyb20gd2l0aGluIHRoZSB0ZW5hbnQgY29udGV4dC5cbiAgICovXG4gIGFzeW5jIF93aXRoVGVuYW50KHRlbmFudCwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLnJ1bldpdGhUZW5hbnQodGVuYW50LCBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoY2FsbGJhY2spKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgYWdncmVnYXRlIFNRTDogYW4gb3V0ZXIgYEdST1VQIEJZYCBvdmVyIGEgYFVOSU9OIEFMTGAgb2YgZWFjaCBlbnRyeSdzIHN1YnF1ZXJ5LlxuICAgKiBAcGFyYW0ge3tjb25uZWN0aW9uOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZW50cmllczogUmVzb2x2ZWRUZW5hbnRbXSwgcXVhbGlmaWVkOiBib29sZWFufX0gYXJncyAtIENvbm5lY3Rpb24sIHRlbmFudHMsIGFuZCB3aGV0aGVyIHRvIHF1YWxpZnkgdGFibGVzIHdpdGggdGhlaXIgZGF0YWJhc2UgbmFtZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBFeGVjdXRhYmxlIGFnZ3JlZ2F0ZSBTUUwuXG4gICAqL1xuICBidWlsZEFnZ3JlZ2F0ZVNxbCh7Y29ubmVjdGlvbiwgZW50cmllcywgcXVhbGlmaWVkfSkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb25uZWN0aW9uLm9wdGlvbnMoKVxuICAgIGNvbnN0IHF1b3RlID0gdGhpcy5fYnVpbGRRdW90ZShjb25uZWN0aW9uKVxuICAgIGNvbnN0IHN1YnF1ZXJpZXMgPSBlbnRyaWVzLm1hcCgoZW50cnkpID0+IHtcbiAgICAgIGlmIChxdWFsaWZpZWQgJiYgIWVudHJ5LmRhdGFiYXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGJ1aWxkIGEgY3Jvc3MtZGF0YWJhc2UgcXVlcnkgZm9yIGEgdGVuYW50IHdpdGhvdXQgYSByZXNvbHZlZCBkYXRhYmFzZSBuYW1lIChpZGVudGlmaWVyOiAke3RoaXMub3B0aW9ucy5pZGVudGlmaWVyfSkuYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFibGUgPSAoLyoqIEB0eXBlIHtzdHJpbmd9ICovIHRhYmxlTmFtZSkgPT4gcXVhbGlmaWVkXG4gICAgICAgID8gYCR7b3B0aW9ucy5xdW90ZURhdGFiYXNlTmFtZSgvKiogQHR5cGUge3N0cmluZ30gKi8gKGVudHJ5LmRhdGFiYXNlKSl9LiR7b3B0aW9ucy5xdW90ZVRhYmxlTmFtZSh0YWJsZU5hbWUpfWBcbiAgICAgICAgOiBvcHRpb25zLnF1b3RlVGFibGVOYW1lKHRhYmxlTmFtZSlcblxuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zdWJxdWVyeSh7Y29ubmVjdGlvbiwgcXVvdGUsIHRhYmxlLCB0ZW5hbnQ6IGVudHJ5LnRlbmFudH0pXG4gICAgfSlcblxuICAgIGNvbnN0IHNlbGVjdFBhcnRzID0gdGhpcy5rZXlDb2x1bW5zLm1hcCgoa2V5Q29sdW1uKSA9PiBvcHRpb25zLnF1b3RlQ29sdW1uTmFtZShrZXlDb2x1bW4pKVxuXG4gICAgZm9yIChjb25zdCBbbmFtZSwgc3BlY10gb2YgT2JqZWN0LmVudHJpZXModGhpcy5hZ2dyZWdhdGVzKSkge1xuICAgICAgY29uc3QgYWdncmVnYXRlQXJndW1lbnQgPSBzcGVjLmNvbHVtbiA9PT0gXCIqXCIgPyBcIipcIiA6IG9wdGlvbnMucXVvdGVDb2x1bW5OYW1lKHNwZWMuY29sdW1uKVxuXG4gICAgICBzZWxlY3RQYXJ0cy5wdXNoKGAke3NwZWMub3B9KCR7YWdncmVnYXRlQXJndW1lbnR9KSBBUyAke29wdGlvbnMucXVvdGVDb2x1bW5OYW1lKG5hbWUpfWApXG4gICAgfVxuXG4gICAgY29uc3QgdW5pb25TcWwgPSBzdWJxdWVyaWVzLm1hcCgoc3VicXVlcnkpID0+IGBTRUxFQ1QgKiBGUk9NICgke3N1YnF1ZXJ5fSkgJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKGAke0RFUklWRURfVEFCTEVfQUxJQVN9X3NvdXJjZWApfWApLmpvaW4oXCJcXG5VTklPTiBBTExcXG5cIilcbiAgICBjb25zdCBncm91cEJ5U3FsID0gdGhpcy5rZXlDb2x1bW5zLmxlbmd0aCA+IDBcbiAgICAgID8gYFxcbkdST1VQIEJZICR7dGhpcy5rZXlDb2x1bW5zLm1hcCgoa2V5Q29sdW1uKSA9PiBvcHRpb25zLnF1b3RlQ29sdW1uTmFtZShrZXlDb2x1bW4pKS5qb2luKFwiLCBcIil9YFxuICAgICAgOiBcIlwiXG5cbiAgICByZXR1cm4gYFNFTEVDVCAke3NlbGVjdFBhcnRzLmpvaW4oXCIsIFwiKX1cXG5GUk9NIChcXG4ke3VuaW9uU3FsfVxcbikgJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKERFUklWRURfVEFCTEVfQUxJQVMpfSR7Z3JvdXBCeVNxbH1gXG4gIH1cblxuICAvKipcbiAgICogTWVyZ2VzIHJvd3MgZnJvbSBldmVyeSBzZXJ2ZXIgYnkgY29tYmluaW5nIGVhY2ggYWdncmVnYXRlIHdpdGggaXRzIG93biBvcGVyYXRpb24uIEEgYE5VTExgXG4gICAqIGFnZ3JlZ2F0ZSB2YWx1ZSAoYW4gZW1wdHkgdGVuYW50J3MgYFNVTWAvYE1BWGAvYE1JTmAgcmV0dXJucyBgTlVMTGAgb24gdGhlIGZhbi1vdXQgcGF0aCkgaXNcbiAgICogdHJlYXRlZCBhcyBcIm5vIGNvbnRyaWJ1dGlvblwiIGFuZCBza2lwcGVkLCBub3QgY29lcmNlZCB0byBgMGAg4oCUIG90aGVyd2lzZSBhbiBlbXB0eSB0ZW5hbnQgd291bGRcbiAgICogZHJhZyBhIGBNQVhgIG9mIG5lZ2F0aXZlcyBvciBhIGBNSU5gIG9mIHBvc2l0aXZlcyB0byBgMGAuIEEga2V5IHdob3NlIGV2ZXJ5IHRlbmFudCBjb250cmlidXRlZFxuICAgKiBgTlVMTGAgc3RheXMgYE5VTExgLCBtYXRjaGluZyBTUUwgYWdncmVnYXRlIHNlbWFudGljcyBvdmVyIG5vIHJvd3MuXG4gICAqIEBwYXJhbSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSByb3dzIC0gUm93cyBjb2xsZWN0ZWQgZnJvbSBhbGwgc2VydmVycy90ZW5hbnRzLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAtIE9uZSBtZXJnZWQgcm93IHBlciBkaXN0aW5jdCBrZXktY29sdW1uIGNvbWJpbmF0aW9uLlxuICAgKi9cbiAgX21lcmdlUm93cyhyb3dzKSB7XG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCA/Pj59ICovXG4gICAgY29uc3QgbWVyZ2VkID0gbmV3IE1hcCgpXG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICBjb25zdCBtYXBLZXkgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmtleUNvbHVtbnMubWFwKChrZXlDb2x1bW4pID0+IHJvd1trZXlDb2x1bW5dKSlcbiAgICAgIGxldCBhY2N1bXVsYXRvciA9IG1lcmdlZC5nZXQobWFwS2V5KVxuXG4gICAgICBpZiAoIWFjY3VtdWxhdG9yKSB7XG4gICAgICAgIGFjY3VtdWxhdG9yID0ge31cblxuICAgICAgICBmb3IgKGNvbnN0IGtleUNvbHVtbiBvZiB0aGlzLmtleUNvbHVtbnMpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvcltrZXlDb2x1bW5dID0gcm93W2tleUNvbHVtbl1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyh0aGlzLmFnZ3JlZ2F0ZXMpKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3JbbmFtZV0gPSBudWxsXG4gICAgICAgIH1cblxuICAgICAgICBtZXJnZWQuc2V0KG1hcEtleSwgYWNjdW11bGF0b3IpXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgW25hbWUsIHNwZWNdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuYWdncmVnYXRlcykpIHtcbiAgICAgICAgY29uc3QgcmF3VmFsdWUgPSByb3dbbmFtZV1cblxuICAgICAgICBpZiAocmF3VmFsdWUgPT09IG51bGwgfHwgcmF3VmFsdWUgPT09IHVuZGVmaW5lZCkgY29udGludWVcblxuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3RvRXhhY3ROdW1iZXIocmF3VmFsdWUpXG5cbiAgICAgICAgYWNjdW11bGF0b3JbbmFtZV0gPSBhY2N1bXVsYXRvcltuYW1lXSA9PT0gbnVsbCA/IHZhbHVlIDogdGhpcy5fY29tYmluZShzcGVjLm9wLCBhY2N1bXVsYXRvcltuYW1lXSwgdmFsdWUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIEFycmF5LmZyb20obWVyZ2VkLnZhbHVlcygpKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbWJpbmVzIHR3byBub24tbnVsbCBwZXItc2VydmVyIGFnZ3JlZ2F0ZSB2YWx1ZXMgd2l0aCB0aGUgYWdncmVnYXRlJ3Mgb3duIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtBZ2dyZWdhdGVPcGVyYXRpb259IG9wIC0gQWdncmVnYXRlIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGN1cnJlbnQgLSBBY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gSW5jb21pbmcgcGVyLXNlcnZlciB2YWx1ZS5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBDb21iaW5lZCB2YWx1ZS5cbiAgICovXG4gIF9jb21iaW5lKG9wLCBjdXJyZW50LCB2YWx1ZSkge1xuICAgIGlmIChvcCA9PT0gXCJNQVhcIikgcmV0dXJuIE1hdGgubWF4KGN1cnJlbnQsIHZhbHVlKVxuICAgIGlmIChvcCA9PT0gXCJNSU5cIikgcmV0dXJuIE1hdGgubWluKGN1cnJlbnQsIHZhbHVlKVxuXG4gICAgcmV0dXJuIGN1cnJlbnQgKyB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgZHJpdmVyLXJldHVybmVkIGFnZ3JlZ2F0ZSB2YWx1ZSB0byBhIG51bWJlciwgZmFpbGluZyBsb3VkbHkgcmF0aGVyIHRoYW4gc2lsZW50bHlcbiAgICogbG9zaW5nIHByZWNpc2lvbi4gRHJpdmVycyByZXR1cm4gZXhhY3QgaW50ZWdlciBhZ2dyZWdhdGVzIChNeVNRTCBgU1VNYC9gQ09VTlRgLCBQb3N0Z3JlU1FMXG4gICAqIGBiaWdpbnRgKSBhcyBzdHJpbmdzOyBhbiBpbnRlZ2VyIGJleW9uZCBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgIGNhbm5vdCBiZSByZXByZXNlbnRlZCBleGFjdGx5XG4gICAqIGFzIGEgSlMgbnVtYmVyLCBzbyBjcm9zcy1zZXJ2ZXIgbWVyZ2luZyB3b3VsZCBjb3JydXB0IHRoZSByZXN1bHQg4oCUIHRocm93IGluc3RlYWQuIChGcmFjdGlvbmFsXG4gICAqIGBERUNJTUFMYC9gTlVNRVJJQ2AgdmFsdWVzIGFyZSBzdGlsbCBzdWJqZWN0IHRvIG5vcm1hbCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbi4pXG4gICAqIEBwYXJhbSB7P30gcmF3VmFsdWUgLSBWYWx1ZSByZXR1cm5lZCBieSB0aGUgZHJpdmVyIGZvciBhbiBhZ2dyZWdhdGUgY29sdW1uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSB2YWx1ZSBhcyBhIG51bWJlci5cbiAgICovXG4gIF90b0V4YWN0TnVtYmVyKHJhd1ZhbHVlKSB7XG4gICAgY29uc3QgdmFsdWUgPSBOdW1iZXIocmF3VmFsdWUpXG5cbiAgICBpZiAodHlwZW9mIHJhd1ZhbHVlID09PSBcInN0cmluZ1wiICYmIC9eLT9cXGQrJC8udGVzdChyYXdWYWx1ZS50cmltKCkpICYmICFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQWdncmVnYXRlIHZhbHVlICR7cmF3VmFsdWV9IGV4Y2VlZHMgdGhlIHNhZmUtaW50ZWdlciByYW5nZSBhbmQgY2Fubm90IGJlIG1lcmdlZCB3aXRob3V0IGxvc2luZyBwcmVjaXNpb24uYClcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHZhbHVlIHF1b3RlciBwYXNzZWQgdG8gc3VicXVlcmllcywgd2l0aCBhIGAubGlzdGAgaGVscGVyIGZvciBgSU4gKC4uLilgIGNsYXVzZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBEcml2ZXIgd2hvc2UgcXVvdGluZyBpcyB1c2VkLlxuICAgKiBAcmV0dXJucyB7KCh2YWx1ZTogPykgPT4gc3RyaW5nKSAmIHtsaXN0OiAodmFsdWVzOiBBcnJheTw/PikgPT4gc3RyaW5nfX0gLSBWYWx1ZSBxdW90ZXIgd2l0aCBhIGAubGlzdGAgaGVscGVyLlxuICAgKi9cbiAgX2J1aWxkUXVvdGUoY29ubmVjdGlvbikge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKFxuICAgICAgKC8qKiBAdHlwZSB7P30gKi8gdmFsdWUpID0+IFN0cmluZyhjb25uZWN0aW9uLnF1b3RlKHZhbHVlKSksXG4gICAgICB7bGlzdDogKC8qKiBAdHlwZSB7QXJyYXk8Pz59ICovIHZhbHVlcykgPT4gdmFsdWVzLm1hcCgodmFsdWUpID0+IFN0cmluZyhjb25uZWN0aW9uLnF1b3RlKHZhbHVlKSkpLmpvaW4oXCIsIFwiKX1cbiAgICApXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyB0aGUgYWdncmVnYXRlIHNwZWNzIChzdHJpbmcgc2hvcnRoYW5kIG9yIG9iamVjdCkgYW5kIHZhbGlkYXRlcyBlYWNoIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBZ2dyZWdhdGVTcGVjPn0gYWdncmVnYXRlcyAtIFJhdyBhZ2dyZWdhdGUgc3BlY3MuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB7b3A6IEFnZ3JlZ2F0ZU9wZXJhdGlvbiwgY29sdW1uOiBzdHJpbmd9Pn0gLSBOb3JtYWxpemVkIGFnZ3JlZ2F0ZSBzcGVjcy5cbiAgICovXG4gIF9ub3JtYWxpemVBZ2dyZWdhdGVzKGFnZ3JlZ2F0ZXMpIHtcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHtvcDogQWdncmVnYXRlT3BlcmF0aW9uLCBjb2x1bW46IHN0cmluZ30+fSAqL1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fVxuXG4gICAgZm9yIChjb25zdCBbbmFtZSwgc3BlY10gb2YgT2JqZWN0LmVudHJpZXMoYWdncmVnYXRlcykpIHtcbiAgICAgIGNvbnN0IG9wID0gLyoqIEB0eXBlIHtBZ2dyZWdhdGVPcGVyYXRpb259ICovICgodHlwZW9mIHNwZWMgPT09IFwic3RyaW5nXCIgPyBzcGVjIDogc3BlYy5vcCkudG9VcHBlckNhc2UoKSlcblxuICAgICAgaWYgKCFBR0dSRUdBVEVfT1BFUkFUSU9OUy5oYXMob3ApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgYWdncmVnYXRlIG9wZXJhdGlvbiBmb3IgJHtuYW1lfTogJHtvcH0uIFN1cHBvcnRlZDogJHtBcnJheS5mcm9tKEFHR1JFR0FURV9PUEVSQVRJT05TKS5qb2luKFwiLCBcIil9LmApXG4gICAgICB9XG5cbiAgICAgIG5vcm1hbGl6ZWRbbmFtZV0gPSB7Y29sdW1uOiB0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIiA/IG5hbWUgOiBzcGVjLmNvbHVtbiwgb3B9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRcbiAgfVxufVxuIl19
|
|
@@ -25,6 +25,7 @@ import Current from "../current.js"
|
|
|
25
25
|
* @property {(tenant: ?) => boolean} [filter] - Optional filter applied to the resolved tenant list.
|
|
26
26
|
* @property {string[]} [keyColumns] - Columns the aggregate is grouped by (for example `["docker_server_id"]`). Empty means a single grand-total row.
|
|
27
27
|
* @property {Record<string, AggregateSpec>} aggregates - Output column name to aggregate. `"SUM"` is shorthand for `{op: "SUM", column: <output name>}`; use `{op: "COUNT", column: "*"}` for `COUNT(*)`.
|
|
28
|
+
* @property {AbortSignal} [signal] - Signal passed to each aggregate database query.
|
|
28
29
|
* @property {(context: SubqueryContext) => string} subquery - Builds one tenant's inner `SELECT`, which must select every `keyColumns` entry plus every aggregate source column.
|
|
29
30
|
* @property {import("../configuration.js").default} [configuration] - Configuration to run against. Defaults to the current configuration.
|
|
30
31
|
*/
|
|
@@ -169,7 +170,7 @@ export default class TenantAggregator {
|
|
|
169
170
|
return await this._withTenant(firstTenant.tenant, async (connections) => {
|
|
170
171
|
const connection = connections[this.options.identifier]
|
|
171
172
|
|
|
172
|
-
return await connection.query(this.buildAggregateSql({connection, entries: group, qualified: true}))
|
|
173
|
+
return await connection.query(this.buildAggregateSql({connection, entries: group, qualified: true}), {signal: this.options.signal})
|
|
173
174
|
})
|
|
174
175
|
}
|
|
175
176
|
|
|
@@ -180,7 +181,7 @@ export default class TenantAggregator {
|
|
|
180
181
|
const tenantRows = await this._withTenant(resolvedTenant.tenant, async (connections) => {
|
|
181
182
|
const connection = connections[this.options.identifier]
|
|
182
183
|
|
|
183
|
-
return await connection.query(this.buildAggregateSql({connection, entries: [resolvedTenant], qualified: false}))
|
|
184
|
+
return await connection.query(this.buildAggregateSql({connection, entries: [resolvedTenant], qualified: false}), {signal: this.options.signal})
|
|
184
185
|
})
|
|
185
186
|
|
|
186
187
|
rows.push(...tenantRows)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-graceful-shutdown.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/counts-channel.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/record-changes.js","../src/database/structure-sql-loader.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-deadline.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/testing/wait-for-event.js","../src/testing/factory/association-declaration.js","../src/testing/factory/declarations.js","../src/testing/factory/definition-builder.js","../src/testing/factory/errors.js","../src/testing/factory/evaluation-context.js","../src/testing/factory/events.js","../src/testing/factory/factory-definition.js","../src/testing/factory/factory-registry.js","../src/testing/factory/factory-runner.js","../src/testing/factory/index.js","../src/testing/factory/linter.js","../src/testing/factory/model-contract.js","../src/testing/factory/sequence.js","../src/testing/factory/trait-definition.js","../src/testing/factory/node/load-definitions.js","../src/testing/factory/strategies/attributes-for.js","../src/testing/factory/strategies/base.js","../src/testing/factory/strategies/build.js","../src/testing/factory/strategies/create.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/shutdown-lifecycle.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
|
|
1
|
+
{"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-graceful-shutdown.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/counts-channel.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/query-aborted-error.js","../src/database/record-changes.js","../src/database/structure-sql-loader.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-deadline.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/testing/wait-for-event.js","../src/testing/factory/association-declaration.js","../src/testing/factory/declarations.js","../src/testing/factory/definition-builder.js","../src/testing/factory/errors.js","../src/testing/factory/evaluation-context.js","../src/testing/factory/events.js","../src/testing/factory/factory-definition.js","../src/testing/factory/factory-registry.js","../src/testing/factory/factory-runner.js","../src/testing/factory/index.js","../src/testing/factory/linter.js","../src/testing/factory/model-contract.js","../src/testing/factory/sequence.js","../src/testing/factory/trait-definition.js","../src/testing/factory/node/load-definitions.js","../src/testing/factory/strategies/attributes-for.js","../src/testing/factory/strategies/base.js","../src/testing/factory/strategies/build.js","../src/testing/factory/strategies/create.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/shutdown-lifecycle.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"velocious": "build/bin/velocious.js"
|
|
4
4
|
},
|
|
5
5
|
"name": "velocious",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.561",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
9
|
"files": [
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
"benchmark:factory-plan-reuse": "node benchmark/factory-plan-reuse.js",
|
|
20
20
|
"benchmark:preloader-id-dedup": "node benchmark/preloader-id-dedup.js",
|
|
21
21
|
"benchmark:mysql-result-row-materialization": "node benchmark/mysql-result-row-materialization.js",
|
|
22
|
+
"benchmark:query-roundtrip-batching": "node benchmark/query-roundtrip-batching.js",
|
|
23
|
+
"benchmark:websocket-frame-buffering": "node benchmark/websocket-frame-buffering.js",
|
|
22
24
|
"build": "node scripts/clean-build.js && npm run compile",
|
|
23
25
|
"compile": "tsc -b && npm run copy:js && npm run copy:ejs && npm run copy:templates && node scripts/ensure-bin-executable.js",
|
|
24
26
|
"copy:js": "cpy \"index.js\" build && cpy \"bin/**/*.js\" build/bin && cpy \"src/**/*.js\" build --parents",
|
|
@@ -193,8 +193,11 @@ export default class BackgroundJobsWorker {
|
|
|
193
193
|
this.inflightPooledJobs = new Set()
|
|
194
194
|
/** @type {Set<import("node:child_process").ChildProcess>} */
|
|
195
195
|
this.pooledChildren = new Set()
|
|
196
|
-
/** @type {Map<import("node:child_process").ChildProcess, {createdAtMs: number, jobsRun: number, inflight: Map<string, {payload: import("./types.js").BackgroundJobPayload & {id: string}, resolve?: (value: void) => void, timeoutTimer?: ReturnType<typeof setTimeout> | null}>, retiring: boolean, settling?: boolean, timeoutSigkillTimer?: ReturnType<typeof setTimeout> | null}>} */
|
|
196
|
+
/** @type {Map<import("node:child_process").ChildProcess, {createdAtMs: number, jobsRun: number, inflight: Map<string, {payload: import("./types.js").BackgroundJobPayload & {id: string}, resolve?: (value: void) => void, timeoutTimer?: ReturnType<typeof setTimeout> | null}>, lastDispatchSeq: number, retiring: boolean, settling?: boolean, timeoutSigkillTimer?: ReturnType<typeof setTimeout> | null}>} */
|
|
197
197
|
this.pooledChildStates = new Map()
|
|
198
|
+
// Monotonic dispatch counter for round-robin child selection: each dispatch stamps
|
|
199
|
+
// the chosen child, and selection prefers the child dispatched least recently.
|
|
200
|
+
this._pooledDispatchSeq = 0
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
/**
|
|
@@ -666,18 +669,13 @@ export default class BackgroundJobsWorker {
|
|
|
666
669
|
* @returns {Promise<void>} - Resolves after the durable report.
|
|
667
670
|
*/
|
|
668
671
|
_runPooledJob(payload) {
|
|
669
|
-
|
|
670
|
-
for (const candidate of this.pooledChildren) {
|
|
671
|
-
const state = this.pooledChildStates.get(candidate)
|
|
672
|
-
if (state && !state.retiring && state.inflight.size < this.pooledRunnerConcurrency) {
|
|
673
|
-
child = candidate
|
|
674
|
-
break
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
if (!child) child = this._createPooledChild()
|
|
672
|
+
const child = this._selectPooledChild() || this._createPooledChild()
|
|
678
673
|
const state = this.pooledChildStates.get(child)
|
|
679
674
|
if (!state) throw new Error("Pooled runner state missing")
|
|
680
675
|
|
|
676
|
+
// Stamp the round-robin cursor so the next dispatch prefers a different child.
|
|
677
|
+
state.lastDispatchSeq = ++this._pooledDispatchSeq
|
|
678
|
+
|
|
681
679
|
return new Promise((resolve) => {
|
|
682
680
|
const timeoutTimer = this._armPooledJobTimeout({child, jobId: payload.id})
|
|
683
681
|
|
|
@@ -690,6 +688,36 @@ export default class BackgroundJobsWorker {
|
|
|
690
688
|
})
|
|
691
689
|
}
|
|
692
690
|
|
|
691
|
+
/**
|
|
692
|
+
* Selects a pooled child to run the next job, or undefined when every non-retiring
|
|
693
|
+
* child is already full (the caller then lazily spawns one). Among children with a
|
|
694
|
+
* free concurrency slot, picks the one dispatched least recently — a round-robin that
|
|
695
|
+
* spreads jobs (notably multi-minute RunBuildJobs, each pinning a tenant connection
|
|
696
|
+
* for its whole run) evenly across children instead of first-fit packing the earliest
|
|
697
|
+
* one until it is full. A freshly spawned or replacement child therefore takes its
|
|
698
|
+
* fair share one job at a time as its turn comes up, rather than absorbing a burst to
|
|
699
|
+
* "catch up" to the others.
|
|
700
|
+
* @returns {import("node:child_process").ChildProcess | undefined} - The chosen child, or undefined when all non-retiring children are full.
|
|
701
|
+
*/
|
|
702
|
+
_selectPooledChild() {
|
|
703
|
+
/** @type {import("node:child_process").ChildProcess | undefined} */
|
|
704
|
+
let selected
|
|
705
|
+
let selectedSeq = Infinity
|
|
706
|
+
|
|
707
|
+
for (const child of this.pooledChildren) {
|
|
708
|
+
const state = this.pooledChildStates.get(child)
|
|
709
|
+
|
|
710
|
+
if (!state || state.retiring || state.inflight.size >= this.pooledRunnerConcurrency) continue
|
|
711
|
+
|
|
712
|
+
if (state.lastDispatchSeq < selectedSeq) {
|
|
713
|
+
selected = child
|
|
714
|
+
selectedSeq = state.lastDispatchSeq
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return selected
|
|
719
|
+
}
|
|
720
|
+
|
|
693
721
|
/**
|
|
694
722
|
* Arms a per-job wall-clock backstop for a pooled job. A pooled child hosts many
|
|
695
723
|
* concurrent jobs, so a single genuinely-hung job would otherwise pin its
|
|
@@ -756,7 +784,7 @@ export default class BackgroundJobsWorker {
|
|
|
756
784
|
})
|
|
757
785
|
this.pooledChildren.add(child)
|
|
758
786
|
this.inflightProcessChildren.add(child)
|
|
759
|
-
this.pooledChildStates.set(child, {createdAtMs: Date.now(), jobsRun: 0, inflight: new Map(), retiring: false})
|
|
787
|
+
this.pooledChildStates.set(child, {createdAtMs: Date.now(), jobsRun: 0, inflight: new Map(), lastDispatchSeq: 0, retiring: false})
|
|
760
788
|
child.on("message", (message) => this._handlePooledChildMessage({child, message}))
|
|
761
789
|
child.once("exit", (code, signal) => this._handlePooledChildFailure({child, error: new Error(`Pooled background job runner exited: code=${code} signal=${signal || "none"}`)}))
|
|
762
790
|
child.once("error", (error) => this._handlePooledChildFailure({child, error}))
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
* @property {boolean} [processListComment] - Whether to add process-list comments to the query.
|
|
60
60
|
* @property {boolean} [retry] - Whether retryable errors may retry the query; defaults to true.
|
|
61
61
|
* @property {boolean} [sessionTimeZone] - Whether to ensure the configured database session time zone before the query.
|
|
62
|
+
* @property {AbortSignal} [signal] - Aborts the in-flight query (destroying its connection) when it fires.
|
|
62
63
|
* @property {string} [sourceStack] - Stack captured at the caller boundary.
|
|
63
64
|
*/
|
|
64
65
|
|
|
@@ -116,6 +117,7 @@ import { formatDateForDatabase } from "../datetime-storage.js"
|
|
|
116
117
|
import isDate from "../../utils/is-date.js"
|
|
117
118
|
import Logger from "../../logger.js"
|
|
118
119
|
import Query from "../query/index.js"
|
|
120
|
+
import QueryAbortedError from "../query-aborted-error.js"
|
|
119
121
|
import Handler from "../handler.js"
|
|
120
122
|
import Mutex from "epic-locks/build/mutex.js"
|
|
121
123
|
import UUID from "pure-uuid"
|
|
@@ -1170,6 +1172,10 @@ export default class VelociousDatabaseDriversBase {
|
|
|
1170
1172
|
} catch (error) {
|
|
1171
1173
|
if (!(error instanceof Error)) throw error
|
|
1172
1174
|
|
|
1175
|
+
// A deliberately-aborted query must never be silently re-run — its
|
|
1176
|
+
// connection was destroyed on purpose, so treat it as terminal.
|
|
1177
|
+
if (error instanceof QueryAbortedError) throw error
|
|
1178
|
+
|
|
1173
1179
|
const retryInfo = this.retryableDatabaseError(error)
|
|
1174
1180
|
|
|
1175
1181
|
if (options.retry !== false && tries < maxTries && retryInfo.retry) {
|
|
@@ -1274,7 +1280,7 @@ export default class VelociousDatabaseDriversBase {
|
|
|
1274
1280
|
await this.beforeQuery(sql, options)
|
|
1275
1281
|
|
|
1276
1282
|
try {
|
|
1277
|
-
return await this._queryActual(sql)
|
|
1283
|
+
return await this._queryActual(sql, options)
|
|
1278
1284
|
} finally {
|
|
1279
1285
|
await this.afterQuery(sql, options)
|
|
1280
1286
|
}
|
|
@@ -1463,9 +1469,10 @@ export default class VelociousDatabaseDriversBase {
|
|
|
1463
1469
|
* Runs query actual.
|
|
1464
1470
|
* @abstract
|
|
1465
1471
|
* @param {string} sql - SQL string.
|
|
1472
|
+
* @param {QueryOptions} [options] - Query options (carries the optional abort signal).
|
|
1466
1473
|
* @returns {Promise<QueryResultType>} - Resolves with the query actual.
|
|
1467
1474
|
*/
|
|
1468
|
-
_queryActual(sql) { // eslint-disable-line no-unused-vars
|
|
1475
|
+
_queryActual(sql, options) { // eslint-disable-line no-unused-vars
|
|
1469
1476
|
throw new Error(`queryActual not implemented`)
|
|
1470
1477
|
}
|
|
1471
1478
|
|
|
@@ -13,6 +13,7 @@ import Insert from "./sql/insert.js"
|
|
|
13
13
|
import Options from "./options.js"
|
|
14
14
|
import mysql from "mysql"
|
|
15
15
|
import query from "./query.js"
|
|
16
|
+
import QueryAbortedError from "../../query-aborted-error.js"
|
|
16
17
|
import QueryParser from "./query-parser.js"
|
|
17
18
|
import streamQuery from "./query-stream.js"
|
|
18
19
|
import RemoveIndex from "./sql/remove-index.js"
|
|
@@ -371,15 +372,23 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
371
372
|
/**
|
|
372
373
|
* Runs query actual.
|
|
373
374
|
* @param {string} sql - SQL string.
|
|
375
|
+
* @param {import("../base.js").QueryOptions} [options] - Query options (carries the optional abort signal).
|
|
374
376
|
* @returns {Promise<import("../base.js").QueryResultType>} - Resolves with the query actual.
|
|
375
377
|
*/
|
|
376
|
-
async _queryActual(sql) {
|
|
378
|
+
async _queryActual(sql, options = {}) {
|
|
377
379
|
if (!this.pool) await this.connect()
|
|
378
380
|
if (!this.pool) throw new Error("MySQL pool failed to initialize")
|
|
379
381
|
|
|
380
382
|
try {
|
|
381
|
-
return await query(this.pool, sql)
|
|
383
|
+
return await query(this.pool, sql, {signal: options.signal})
|
|
382
384
|
} catch (error) {
|
|
385
|
+
// Preserve an abort as-is so the retry loop can recognise it as terminal
|
|
386
|
+
// (wrapping it in a plain Error would lose the QueryAbortedError type).
|
|
387
|
+
if (error instanceof QueryAbortedError) {
|
|
388
|
+
if (error.connectionDestroyed) this.resetCurrentSessionTimeZone()
|
|
389
|
+
throw error
|
|
390
|
+
}
|
|
391
|
+
|
|
383
392
|
// Re-throw to un-corrupt stacktrace
|
|
384
393
|
if (error instanceof Error) {
|
|
385
394
|
throw new Error(`Query failed: ${error.message}`, {cause: error})
|