@antelopejs/postgres 0.3.0 → 0.4.1
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 +5 -5
- package/dist/config.d.ts +1 -1
- package/dist/config.js +51 -0
- package/dist/config.js.map +1 -1
- package/dist/implementations/database/external-access.d.ts +22 -0
- package/dist/implementations/database/external-access.js +59 -0
- package/dist/implementations/database/external-access.js.map +1 -0
- package/dist/implementations/database/external-catalog.d.ts +0 -1
- package/dist/implementations/database/external-catalog.js +2 -3
- package/dist/implementations/database/external-catalog.js.map +1 -1
- package/dist/implementations/database/external-discovery.d.ts +1 -15
- package/dist/implementations/database/external-discovery.js +4 -44
- package/dist/implementations/database/external-discovery.js.map +1 -1
- package/dist/implementations/database/external-profile.d.ts +1 -1
- package/dist/implementations/database/external-profile.js.map +1 -1
- package/dist/implementations/database/external-reference.js.map +1 -1
- package/dist/implementations/database/external-sample.d.ts +1 -1
- package/dist/implementations/database/member.js.map +1 -1
- package/dist/implementations/database/result.js +2 -3
- package/dist/implementations/database/result.js.map +1 -1
- package/dist/implementations/database/schema.d.ts +1 -0
- package/dist/implementations/database/schema.js +4 -0
- package/dist/implementations/database/schema.js.map +1 -1
- package/dist/pg-connection-parameters.d.ts +17 -0
- package/dist/pg-connection-parameters.js +8 -0
- package/dist/pg-connection-parameters.js.map +1 -0
- package/dist/probe-parameters.d.ts +5 -0
- package/dist/probe-parameters.js +44 -0
- package/dist/probe-parameters.js.map +1 -0
- package/dist/probe-url.d.ts +9 -0
- package/dist/probe-url.js +54 -0
- package/dist/probe-url.js.map +1 -0
- package/dist/probe.d.ts +2 -0
- package/dist/probe.js +188 -0
- package/dist/probe.js.map +1 -0
- package/dist/test/atomic.test.js +49 -32
- package/dist/test/atomic.test.js.map +1 -1
- package/dist/test/contention.test.js +20 -16
- package/dist/test/contention.test.js.map +1 -1
- package/dist/test/convergence.test.d.ts +1 -0
- package/dist/test/convergence.test.js +9 -0
- package/dist/test/convergence.test.js.map +1 -0
- package/dist/test/duplicate-key.test.js +38 -18
- package/dist/test/duplicate-key.test.js.map +1 -1
- package/dist/test/indexes.test.js +14 -13
- package/dist/test/indexes.test.js.map +1 -1
- package/dist/test/nested-paths.test.js +27 -18
- package/dist/test/nested-paths.test.js.map +1 -1
- package/dist/test/typed-operations.test.js +55 -38
- package/dist/test/typed-operations.test.js.map +1 -1
- package/dist/test/unit/config-fixture.d.ts +2 -0
- package/dist/test/unit/config-fixture.js +11 -0
- package/dist/test/unit/config-fixture.js.map +1 -0
- package/dist/test/unit/config.spec.js +2 -32
- package/dist/test/unit/config.spec.js.map +1 -1
- package/dist/test/unit/config.untyped.spec.d.ts +1 -0
- package/dist/test/unit/config.untyped.spec.js +34 -0
- package/dist/test/unit/config.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-array-walk.spec.js +0 -8
- package/dist/test/unit/expression-array-walk.spec.js.map +1 -1
- package/dist/test/unit/expression-array-walk.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-array-walk.untyped.spec.js +17 -0
- package/dist/test/unit/expression-array-walk.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-array.spec.js +0 -18
- package/dist/test/unit/expression-array.spec.js.map +1 -1
- package/dist/test/unit/expression-array.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-array.untyped.spec.js +32 -0
- package/dist/test/unit/expression-array.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-date.spec.js +0 -21
- package/dist/test/unit/expression-date.spec.js.map +1 -1
- package/dist/test/unit/expression-date.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-date.untyped.spec.js +33 -0
- package/dist/test/unit/expression-date.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-numeric.spec.js +0 -20
- package/dist/test/unit/expression-numeric.spec.js.map +1 -1
- package/dist/test/unit/expression-numeric.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-numeric.untyped.spec.js +31 -0
- package/dist/test/unit/expression-numeric.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-object.spec.js +0 -12
- package/dist/test/unit/expression-object.spec.js.map +1 -1
- package/dist/test/unit/expression-object.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-object.untyped.spec.js +23 -0
- package/dist/test/unit/expression-object.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression-string.spec.js +0 -5
- package/dist/test/unit/expression-string.spec.js.map +1 -1
- package/dist/test/unit/expression-string.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression-string.untyped.spec.js +14 -0
- package/dist/test/unit/expression-string.untyped.spec.js.map +1 -0
- package/dist/test/unit/expression.spec.js +0 -16
- package/dist/test/unit/expression.spec.js.map +1 -1
- package/dist/test/unit/expression.untyped.spec.d.ts +1 -0
- package/dist/test/unit/expression.untyped.spec.js +29 -0
- package/dist/test/unit/expression.untyped.spec.js.map +1 -0
- package/dist/test/unit/feeds-fixture.d.ts +30 -0
- package/dist/test/unit/feeds-fixture.js +65 -0
- package/dist/test/unit/feeds-fixture.js.map +1 -0
- package/dist/test/unit/feeds.spec.js +80 -143
- package/dist/test/unit/feeds.spec.js.map +1 -1
- package/dist/test/unit/feeds.untyped.spec.d.ts +1 -0
- package/dist/test/unit/feeds.untyped.spec.js +22 -0
- package/dist/test/unit/feeds.untyped.spec.js.map +1 -0
- package/dist/test/unit/fields.spec.js +0 -5
- package/dist/test/unit/fields.spec.js.map +1 -1
- package/dist/test/unit/fields.untyped.spec.d.ts +1 -0
- package/dist/test/unit/fields.untyped.spec.js +12 -0
- package/dist/test/unit/fields.untyped.spec.js.map +1 -0
- package/dist/test/unit/pipeline-fold-fixture.d.ts +10 -0
- package/dist/test/unit/pipeline-fold-fixture.js +46 -0
- package/dist/test/unit/pipeline-fold-fixture.js.map +1 -0
- package/dist/test/unit/pipeline-group.spec.js +0 -3
- package/dist/test/unit/pipeline-group.spec.js.map +1 -1
- package/dist/test/unit/pipeline-group.untyped.spec.d.ts +1 -0
- package/dist/test/unit/pipeline-group.untyped.spec.js +11 -0
- package/dist/test/unit/pipeline-group.untyped.spec.js.map +1 -0
- package/dist/test/unit/pipeline-lambda-ids.untyped.spec.d.ts +1 -0
- package/dist/test/unit/{pipeline-lambda-ids.spec.js → pipeline-lambda-ids.untyped.spec.js} +7 -7
- package/dist/test/unit/pipeline-lambda-ids.untyped.spec.js.map +1 -0
- package/dist/test/unit/pipeline-projection.spec.js +0 -7
- package/dist/test/unit/pipeline-projection.spec.js.map +1 -1
- package/dist/test/unit/pipeline-projection.untyped.spec.d.ts +1 -0
- package/dist/test/unit/pipeline-projection.untyped.spec.js +16 -0
- package/dist/test/unit/pipeline-projection.untyped.spec.js.map +1 -0
- package/dist/test/unit/pipeline-selection.spec.js +0 -31
- package/dist/test/unit/pipeline-selection.spec.js.map +1 -1
- package/dist/test/unit/pipeline-selection.untyped.spec.d.ts +1 -0
- package/dist/test/unit/pipeline-selection.untyped.spec.js +44 -0
- package/dist/test/unit/pipeline-selection.untyped.spec.js.map +1 -0
- package/dist/test/unit/pipeline.spec.js +6 -54
- package/dist/test/unit/pipeline.spec.js.map +1 -1
- package/dist/test/unit/pipeline.untyped.spec.d.ts +1 -0
- package/dist/test/unit/pipeline.untyped.spec.js +21 -0
- package/dist/test/unit/pipeline.untyped.spec.js.map +1 -0
- package/dist/test/unit/probe-parameters.spec.d.ts +1 -0
- package/dist/test/unit/probe-parameters.spec.js +17 -0
- package/dist/test/unit/probe-parameters.spec.js.map +1 -0
- package/dist/test/unit/selection-fixture.d.ts +15 -0
- package/dist/test/unit/selection-fixture.js +41 -0
- package/dist/test/unit/selection-fixture.js.map +1 -0
- package/dist/test/unit/selection.spec.js +45 -83
- package/dist/test/unit/selection.spec.js.map +1 -1
- package/dist/test/unit/selection.untyped.spec.d.ts +1 -0
- package/dist/test/unit/selection.untyped.spec.js +19 -0
- package/dist/test/unit/selection.untyped.spec.js.map +1 -0
- package/dist/test/unit/ssl-url.spec.d.ts +1 -0
- package/dist/test/unit/ssl-url.spec.js +147 -0
- package/dist/test/unit/ssl-url.spec.js.map +1 -0
- package/dist/test/unit/utils.spec.js +0 -13
- package/dist/test/unit/utils.spec.js.map +1 -1
- package/dist/test/unit/utils.untyped.spec.d.ts +1 -0
- package/dist/test/unit/utils.untyped.spec.js +21 -0
- package/dist/test/unit/utils.untyped.spec.js.map +1 -0
- package/dist/test/unit/value.spec.js +0 -4
- package/dist/test/unit/value.spec.js.map +1 -1
- package/dist/test/unit/value.untyped.spec.d.ts +1 -0
- package/dist/test/unit/value.untyped.spec.js +12 -0
- package/dist/test/unit/value.untyped.spec.js.map +1 -0
- package/dist/test/unit/writes-insert.spec.js +0 -9
- package/dist/test/unit/writes-insert.spec.js.map +1 -1
- package/dist/test/unit/writes-insert.untyped.spec.d.ts +1 -0
- package/dist/test/unit/writes-insert.untyped.spec.js +18 -0
- package/dist/test/unit/writes-insert.untyped.spec.js.map +1 -0
- package/dist/test/unit/writes-replace.spec.js +0 -3
- package/dist/test/unit/writes-replace.spec.js.map +1 -1
- package/dist/test/unit/writes-replace.untyped.spec.d.ts +1 -0
- package/dist/test/unit/writes-replace.untyped.spec.js +12 -0
- package/dist/test/unit/writes-replace.untyped.spec.js.map +1 -0
- package/dist/test/unit/writes-update.spec.js +0 -6
- package/dist/test/unit/writes-update.spec.js.map +1 -1
- package/dist/test/unit/writes-update.untyped.spec.d.ts +1 -0
- package/dist/test/unit/writes-update.untyped.spec.js +13 -0
- package/dist/test/unit/writes-update.untyped.spec.js.map +1 -0
- package/dist/test-external/catalog.test.js +1 -4
- package/dist/test-external/catalog.test.js.map +1 -1
- package/dist/test-external/native.test.js +19 -10
- package/dist/test-external/native.test.js.map +1 -1
- package/dist/test-external/probe-access.test.js +90 -0
- package/dist/test-external/probe-access.test.js.map +1 -0
- package/dist/test-external/probe-closing.test.d.ts +1 -0
- package/dist/test-external/probe-closing.test.js +111 -0
- package/dist/test-external/probe-closing.test.js.map +1 -0
- package/dist/test-external/probe-fixture.d.ts +36 -0
- package/dist/test-external/probe-fixture.js +166 -0
- package/dist/test-external/probe-fixture.js.map +1 -0
- package/dist/test-external/probe-refusals.test.d.ts +1 -0
- package/dist/test-external/probe-refusals.test.js +110 -0
- package/dist/test-external/probe-refusals.test.js.map +1 -0
- package/dist/test-external/probe-url.test.d.ts +1 -0
- package/dist/test-external/probe-url.test.js +242 -0
- package/dist/test-external/probe-url.test.js.map +1 -0
- package/dist/test-external/reads.test.js +51 -26
- package/dist/test-external/reads.test.js.map +1 -1
- package/dist/test-external/refusals.test.js +12 -7
- package/dist/test-external/refusals.test.js.map +1 -1
- package/dist/test-external/registration.test.js +8 -0
- package/dist/test-external/registration.test.js.map +1 -1
- package/dist/test-external/relays.d.ts +27 -0
- package/dist/test-external/relays.js +176 -0
- package/dist/test-external/relays.js.map +1 -0
- package/dist/test-external/sales.d.ts +4 -1
- package/dist/test-external/sales.js +38 -1
- package/dist/test-external/sales.js.map +1 -1
- package/dist/test-external/writes.test.js +84 -48
- package/dist/test-external/writes.test.js.map +1 -1
- package/package.json +11 -9
- package/dist/test/unit/pipeline-lambda-ids.spec.js.map +0 -1
- /package/dist/{test/unit/pipeline-lambda-ids.spec.d.ts → test-external/probe-access.test.d.ts} +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IsUnusableSsl = IsUnusableSsl;
|
|
4
|
+
const UNUSABLE_SSL_KINDS = new Set(["string", "number", "bigint", "symbol"]);
|
|
5
|
+
function IsUnusableSsl(ssl) {
|
|
6
|
+
return Boolean(ssl) && UNUSABLE_SSL_KINDS.has(typeof ssl);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=pg-connection-parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-connection-parameters.js","sourceRoot":"","sources":["../src/pg-connection-parameters.ts"],"names":[],"mappings":";;AA8CA,sCAEC;AARD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAM7E,SAAgB,aAAa,CAAC,GAAkB;IAC9C,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Client } from "pg";
|
|
2
|
+
export type ParameterHandling = "url" | "probe" | "inert";
|
|
3
|
+
export declare const CONNECTION_PARAMETERS: ReadonlyMap<string, ParameterHandling>;
|
|
4
|
+
export declare function OverrideParameters(client: Client, timeoutMs: number): void;
|
|
5
|
+
export declare function SslRefusal(client: Client): string | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONNECTION_PARAMETERS = void 0;
|
|
4
|
+
exports.OverrideParameters = OverrideParameters;
|
|
5
|
+
exports.SslRefusal = SslRefusal;
|
|
6
|
+
const pg_connection_parameters_1 = require("./pg-connection-parameters");
|
|
7
|
+
exports.CONNECTION_PARAMETERS = new Map([
|
|
8
|
+
["user", "url"],
|
|
9
|
+
["database", "url"],
|
|
10
|
+
["port", "url"],
|
|
11
|
+
["host", "url"],
|
|
12
|
+
["isDomainSocket", "url"],
|
|
13
|
+
["password", "url"],
|
|
14
|
+
["options", "url"],
|
|
15
|
+
["ssl", "url"],
|
|
16
|
+
["sslnegotiation", "url"],
|
|
17
|
+
["client_encoding", "url"],
|
|
18
|
+
["application_name", "url"],
|
|
19
|
+
["fallback_application_name", "url"],
|
|
20
|
+
["query_timeout", "probe"],
|
|
21
|
+
["statement_timeout", "probe"],
|
|
22
|
+
["lock_timeout", "probe"],
|
|
23
|
+
["idle_in_transaction_session_timeout", "probe"],
|
|
24
|
+
["replication", "probe"],
|
|
25
|
+
["binary", "inert"],
|
|
26
|
+
["connect_timeout", "inert"],
|
|
27
|
+
["keepalives", "inert"],
|
|
28
|
+
["keepalives_idle", "inert"],
|
|
29
|
+
]);
|
|
30
|
+
function OverrideParameters(client, timeoutMs) {
|
|
31
|
+
Object.assign(client.connectionParameters, {
|
|
32
|
+
query_timeout: timeoutMs,
|
|
33
|
+
statement_timeout: timeoutMs,
|
|
34
|
+
lock_timeout: timeoutMs,
|
|
35
|
+
idle_in_transaction_session_timeout: timeoutMs,
|
|
36
|
+
replication: undefined,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const SSL_TEXT = "the URL's ssl value is none of true, 1, 0, empty or no-verify, and pg fails on it once the server accepts TLS";
|
|
40
|
+
function SslRefusal(client) {
|
|
41
|
+
const { ssl } = client.connectionParameters;
|
|
42
|
+
return (0, pg_connection_parameters_1.IsUnusableSsl)(ssl) ? SSL_TEXT : undefined;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=probe-parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-parameters.js","sourceRoot":"","sources":["../src/probe-parameters.ts"],"names":[],"mappings":";;;AAiDA,gDAQC;AAMD,gCAGC;AAhED,yEAGoC;AAevB,QAAA,qBAAqB,GAChC,IAAI,GAAG,CAA4B;IACjC,CAAC,MAAM,EAAE,KAAK,CAAC;IACf,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,MAAM,EAAE,KAAK,CAAC;IACf,CAAC,MAAM,EAAE,KAAK,CAAC;IACf,CAAC,gBAAgB,EAAE,KAAK,CAAC;IACzB,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,SAAS,EAAE,KAAK,CAAC;IAClB,CAAC,KAAK,EAAE,KAAK,CAAC;IACd,CAAC,gBAAgB,EAAE,KAAK,CAAC;IACzB,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAC1B,CAAC,kBAAkB,EAAE,KAAK,CAAC;IAC3B,CAAC,2BAA2B,EAAE,KAAK,CAAC;IACpC,CAAC,eAAe,EAAE,OAAO,CAAC;IAC1B,CAAC,mBAAmB,EAAE,OAAO,CAAC;IAC9B,CAAC,cAAc,EAAE,OAAO,CAAC;IACzB,CAAC,qCAAqC,EAAE,OAAO,CAAC;IAChD,CAAC,aAAa,EAAE,OAAO,CAAC;IACxB,CAAC,QAAQ,EAAE,OAAO,CAAC;IACnB,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC5B,CAAC,YAAY,EAAE,OAAO,CAAC;IACvB,CAAC,iBAAiB,EAAE,OAAO,CAAC;CAC7B,CAAC,CAAC;AAML,SAAgB,kBAAkB,CAAC,MAAc,EAAE,SAAiB;IAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE;QACzC,aAAa,EAAE,SAAS;QACxB,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,SAAS;QACvB,mCAAmC,EAAE,SAAS;QAC9C,WAAW,EAAE,SAAS;KACqB,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,QAAQ,GACZ,+GAA+G,CAAC;AAGlH,SAAgB,UAAU,CAAC,MAAc;IACvC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAC;IAC5C,OAAO,IAAA,wCAAa,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReadUrl = ReadUrl;
|
|
4
|
+
const pg_connection_string_1 = require("pg-connection-string");
|
|
5
|
+
const FIRST_PRINTABLE = 0x20;
|
|
6
|
+
const CONTROL_REFUSAL = "the URL contains a control character, which the URL parser would remove or trim";
|
|
7
|
+
const CLIENT_CERTIFICATE = "the URL presents a client certificate of the probing host (sslcert, sslkey), which the probe never sends";
|
|
8
|
+
const ROOT_CERTIFICATE = "the URL names a CA file of the probing host (sslrootcert), and the probe reads no file: a read of one cannot be bounded in time";
|
|
9
|
+
const NO_USER = "the URL names no user, and the probe signs in as no user of the probing process";
|
|
10
|
+
const NO_HOST = "the URL names no host, and the probe sends credentials to no host the URL does not name";
|
|
11
|
+
function QueryOf(url) {
|
|
12
|
+
const query = url.indexOf("?");
|
|
13
|
+
const fragment = url.indexOf("#");
|
|
14
|
+
if (query < 0 || (fragment >= 0 && fragment < query)) {
|
|
15
|
+
return new URLSearchParams();
|
|
16
|
+
}
|
|
17
|
+
return new URLSearchParams(url.slice(query + 1, fragment > query ? fragment : undefined));
|
|
18
|
+
}
|
|
19
|
+
function HasControlCharacter(url) {
|
|
20
|
+
for (let index = 0; index < url.length; index += 1) {
|
|
21
|
+
if (url.charCodeAt(index) < FIRST_PRINTABLE) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
function FileRefusal(query) {
|
|
28
|
+
if (query.has("sslcert") || query.has("sslkey")) {
|
|
29
|
+
return CLIENT_CERTIFICATE;
|
|
30
|
+
}
|
|
31
|
+
return query.has("sslrootcert") ? ROOT_CERTIFICATE : undefined;
|
|
32
|
+
}
|
|
33
|
+
function ParsedRefusal(url) {
|
|
34
|
+
if (!url.user) {
|
|
35
|
+
return NO_USER;
|
|
36
|
+
}
|
|
37
|
+
return url.host ? undefined : NO_HOST;
|
|
38
|
+
}
|
|
39
|
+
function ReadUrl(url) {
|
|
40
|
+
if (HasControlCharacter(url)) {
|
|
41
|
+
return { kind: "refused", message: CONTROL_REFUSAL };
|
|
42
|
+
}
|
|
43
|
+
const query = QueryOf(url);
|
|
44
|
+
const queryRefusal = FileRefusal(query);
|
|
45
|
+
if (queryRefusal) {
|
|
46
|
+
return { kind: "refused", message: queryRefusal };
|
|
47
|
+
}
|
|
48
|
+
const parsed = (0, pg_connection_string_1.parse)(url);
|
|
49
|
+
const parsedRefusal = ParsedRefusal(parsed);
|
|
50
|
+
return parsedRefusal
|
|
51
|
+
? { kind: "refused", message: parsedRefusal }
|
|
52
|
+
: { kind: "read", url: parsed };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=probe-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-url.js","sourceRoot":"","sources":["../src/probe-url.ts"],"names":[],"mappings":";;AAyEA,0BAcC;AAvFD,+DAAqE;AAGrE,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,eAAe,GACnB,iFAAiF,CAAC;AAEpF,MAAM,kBAAkB,GACtB,0GAA0G,CAAC;AAE7G,MAAM,gBAAgB,GACpB,iIAAiI,CAAC;AAEpI,MAAM,OAAO,GACX,iFAAiF,CAAC;AAEpF,MAAM,OAAO,GACX,yFAAyF,CAAC;AAW5F,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,eAAe,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,eAAe,CACxB,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAC9D,CAAC;AACJ,CAAC;AAGD,SAAS,mBAAmB,CAAC,GAAW;IACtC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,eAAe,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,SAAS,WAAW,CAAC,KAAsB;IACzC,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAGD,SAAS,aAAa,CAAC,GAAsB;IAC3C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACxC,CAAC;AAMD,SAAgB,OAAO,CAAC,GAAW;IACjC,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IACvD,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,4BAAK,EAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,aAAa;QAClB,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE;QAC7C,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC"}
|
package/dist/probe.d.ts
ADDED
package/dist/probe.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.probe = void 0;
|
|
4
|
+
const node_net_1 = require("node:net");
|
|
5
|
+
const pg_1 = require("pg");
|
|
6
|
+
const external_access_1 = require("./implementations/database/external-access");
|
|
7
|
+
const probe_parameters_1 = require("./probe-parameters");
|
|
8
|
+
const probe_url_1 = require("./probe-url");
|
|
9
|
+
const CLOSE_GRACE_MS = 250;
|
|
10
|
+
const ACCOUNT_SQL = "SELECT current_user AS role";
|
|
11
|
+
const READ_ONLY_SQL = "BEGIN TRANSACTION READ ONLY";
|
|
12
|
+
const ABORTED = "The probe was aborted.";
|
|
13
|
+
const REFUSALS = new Map([
|
|
14
|
+
["28P01", "credentials"],
|
|
15
|
+
["28000", "host"],
|
|
16
|
+
["3D000", "database"],
|
|
17
|
+
["42501", "database-denied"],
|
|
18
|
+
]);
|
|
19
|
+
const PASSWORD_REQUIRED = "the server asks for a password the URL does not give";
|
|
20
|
+
class PasswordRequired extends Error {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(PASSWORD_REQUIRED);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function Ignore() {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
function WithholdPassword() {
|
|
29
|
+
throw new PasswordRequired();
|
|
30
|
+
}
|
|
31
|
+
function Open(url, password, timeoutMs) {
|
|
32
|
+
const sockets = [];
|
|
33
|
+
const client = new pg_1.Client({
|
|
34
|
+
connectionString: url,
|
|
35
|
+
connectionTimeoutMillis: timeoutMs,
|
|
36
|
+
stream: () => {
|
|
37
|
+
const socket = new node_net_1.Socket();
|
|
38
|
+
sockets.push(socket);
|
|
39
|
+
return socket;
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
(0, probe_parameters_1.OverrideParameters)(client, timeoutMs);
|
|
43
|
+
Object.defineProperty(client, "password", {
|
|
44
|
+
configurable: true,
|
|
45
|
+
enumerable: false,
|
|
46
|
+
writable: true,
|
|
47
|
+
value: password || WithholdPassword,
|
|
48
|
+
});
|
|
49
|
+
client.on("error", Ignore);
|
|
50
|
+
return { client, sockets };
|
|
51
|
+
}
|
|
52
|
+
function Shut(session) {
|
|
53
|
+
for (const socket of session.sockets) {
|
|
54
|
+
socket.destroy();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function Close(session, signal) {
|
|
58
|
+
if (signal.aborted) {
|
|
59
|
+
Shut(session);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const settle = () => {
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
signal.removeEventListener("abort", shut);
|
|
65
|
+
};
|
|
66
|
+
const shut = () => {
|
|
67
|
+
settle();
|
|
68
|
+
Shut(session);
|
|
69
|
+
};
|
|
70
|
+
const timer = setTimeout(shut, CLOSE_GRACE_MS);
|
|
71
|
+
timer.unref();
|
|
72
|
+
signal.addEventListener("abort", shut, { once: true });
|
|
73
|
+
session.client.end().then(settle, Ignore);
|
|
74
|
+
}
|
|
75
|
+
function Privileges(access) {
|
|
76
|
+
return {
|
|
77
|
+
canRead: access.length === 0 ||
|
|
78
|
+
access.some(({ unmappable }) => unmappable === undefined),
|
|
79
|
+
canWrite: access.some(({ writes }) => writes.insert || writes.update || writes.delete),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function MessageOf(err) {
|
|
83
|
+
if (!(err instanceof Error)) {
|
|
84
|
+
return String(err);
|
|
85
|
+
}
|
|
86
|
+
if (err.message || !(err instanceof AggregateError)) {
|
|
87
|
+
return err.message;
|
|
88
|
+
}
|
|
89
|
+
const causes = err.errors;
|
|
90
|
+
return causes.map(MessageOf).join("; ");
|
|
91
|
+
}
|
|
92
|
+
function Unanswered(err) {
|
|
93
|
+
return { outcome: "unreachable", message: MessageOf(err) };
|
|
94
|
+
}
|
|
95
|
+
function Refusal(err) {
|
|
96
|
+
if (err instanceof pg_1.DatabaseError) {
|
|
97
|
+
const refusal = (err.code && REFUSALS.get(err.code)) || "other";
|
|
98
|
+
return { outcome: "refused", refusal, message: err.message };
|
|
99
|
+
}
|
|
100
|
+
if (err instanceof PasswordRequired) {
|
|
101
|
+
return {
|
|
102
|
+
outcome: "refused",
|
|
103
|
+
refusal: "sign-in-required",
|
|
104
|
+
message: err.message,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return Unanswered(err);
|
|
108
|
+
}
|
|
109
|
+
async function Read(client) {
|
|
110
|
+
const started = performance.now();
|
|
111
|
+
const answer = {
|
|
112
|
+
outcome: "signed-in",
|
|
113
|
+
latencyMs: 0,
|
|
114
|
+
canRead: false,
|
|
115
|
+
canWrite: false,
|
|
116
|
+
};
|
|
117
|
+
try {
|
|
118
|
+
const account = await client.query(ACCOUNT_SQL);
|
|
119
|
+
answer.latencyMs = Math.ceil(performance.now() - started);
|
|
120
|
+
answer.user = account.rows[0].role;
|
|
121
|
+
await client.query(READ_ONLY_SQL);
|
|
122
|
+
const relations = await client.query(external_access_1.PRIVILEGES_SQL, [
|
|
123
|
+
null,
|
|
124
|
+
]);
|
|
125
|
+
return { ...answer, ...Privileges(relations.rows.map(external_access_1.AccessOf)) };
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
if (!(err instanceof pg_1.DatabaseError)) {
|
|
129
|
+
return Unanswered(err);
|
|
130
|
+
}
|
|
131
|
+
const latencyMs = answer.latencyMs || Math.ceil(performance.now() - started);
|
|
132
|
+
return { ...answer, latencyMs, unreadable: "cannot-list" };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function SignIn(session) {
|
|
136
|
+
try {
|
|
137
|
+
await session.client.connect();
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
return Refusal(err);
|
|
141
|
+
}
|
|
142
|
+
return Read(session.client);
|
|
143
|
+
}
|
|
144
|
+
function AbortedAnswer() {
|
|
145
|
+
return { outcome: "unreachable", message: ABORTED };
|
|
146
|
+
}
|
|
147
|
+
function WhenAborted(signal, onAbort) {
|
|
148
|
+
let withdraw = Ignore;
|
|
149
|
+
const answer = new Promise((resolve) => {
|
|
150
|
+
const abort = () => {
|
|
151
|
+
onAbort();
|
|
152
|
+
resolve(AbortedAnswer());
|
|
153
|
+
};
|
|
154
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
155
|
+
withdraw = () => signal.removeEventListener("abort", abort);
|
|
156
|
+
});
|
|
157
|
+
return { answer, withdraw };
|
|
158
|
+
}
|
|
159
|
+
const probe = async ({ url, timeoutMs, signal }) => {
|
|
160
|
+
if (signal.aborted) {
|
|
161
|
+
return AbortedAnswer();
|
|
162
|
+
}
|
|
163
|
+
let session;
|
|
164
|
+
const aborted = WhenAborted(signal, () => session && Shut(session));
|
|
165
|
+
try {
|
|
166
|
+
const reading = (0, probe_url_1.ReadUrl)(url);
|
|
167
|
+
if (reading.kind === "refused") {
|
|
168
|
+
return { outcome: "refused", refusal: "other", message: reading.message };
|
|
169
|
+
}
|
|
170
|
+
session = Open(url, reading.url.password, timeoutMs);
|
|
171
|
+
const sslRefusal = (0, probe_parameters_1.SslRefusal)(session.client);
|
|
172
|
+
if (sslRefusal) {
|
|
173
|
+
return { outcome: "refused", refusal: "other", message: sslRefusal };
|
|
174
|
+
}
|
|
175
|
+
return await Promise.race([SignIn(session), aborted.answer]);
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
return Unanswered(err);
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
aborted.withdraw();
|
|
182
|
+
if (session) {
|
|
183
|
+
Close(session, signal);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
exports.probe = probe;
|
|
188
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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"}
|
package/dist/test/atomic.test.js
CHANGED
|
@@ -19,21 +19,23 @@ const update = {
|
|
|
19
19
|
patch: { value: "after", details: { kept: true } },
|
|
20
20
|
};
|
|
21
21
|
async function Seed(document = {}) {
|
|
22
|
-
await table.insert({ _id: ID, value: "before", ...document });
|
|
22
|
+
await table.insert({ _id: ID, value: "before", ...document }).run();
|
|
23
23
|
}
|
|
24
24
|
describe("atomic mutation results and scope", () => {
|
|
25
25
|
beforeEach(async () => {
|
|
26
|
-
await table.delete();
|
|
26
|
+
await table.delete().run();
|
|
27
27
|
});
|
|
28
28
|
it("persists inserted overflow revisions and replaces nested fields as a whole", async () => {
|
|
29
29
|
await Seed({ revision: "old", details: { removed: true } });
|
|
30
|
-
(0, chai_1.expect)((await table.get(ID))?.revision).to.equal("old");
|
|
31
|
-
(0, chai_1.expect)(await table.atomicMutation(ID, update)).to.equal("applied");
|
|
32
|
-
(0, chai_1.expect)(await table.get(ID)).to.include({
|
|
30
|
+
(0, chai_1.expect)((await table.get(ID).run())?.revision).to.equal("old");
|
|
31
|
+
(0, chai_1.expect)(await table.atomicMutation(ID, update).run()).to.equal("applied");
|
|
32
|
+
(0, chai_1.expect)(await table.get(ID).run()).to.include({
|
|
33
33
|
revision: "fresh",
|
|
34
34
|
value: "after",
|
|
35
35
|
});
|
|
36
|
-
const rows = await table
|
|
36
|
+
const rows = await table
|
|
37
|
+
.filter((row) => row.key("revision").eq("fresh"))
|
|
38
|
+
.run();
|
|
37
39
|
(0, chai_1.expect)(rows).to.have.length(1);
|
|
38
40
|
(0, chai_1.expect)(rows[0].revision).to.equal("fresh");
|
|
39
41
|
(0, chai_1.expect)(rows[0].details).to.deep.equal({ kept: true });
|
|
@@ -43,12 +45,12 @@ describe("atomic mutation results and scope", () => {
|
|
|
43
45
|
...update,
|
|
44
46
|
expectedRevision: { kind: "missing" },
|
|
45
47
|
};
|
|
46
|
-
(0, chai_1.expect)(await table.atomicMutation(ID, request)).to.equal("not-applied");
|
|
48
|
+
(0, chai_1.expect)(await table.atomicMutation(ID, request).run()).to.equal("not-applied");
|
|
47
49
|
await Seed({ revision: null });
|
|
48
|
-
(0, chai_1.expect)(await table.atomicMutation(ID, request)).to.equal("not-applied");
|
|
49
|
-
await table.get(ID).update({ revision: undefined });
|
|
50
|
-
(0, chai_1.expect)(await table.atomicMutation(ID, request)).to.equal("applied");
|
|
51
|
-
(0, chai_1.expect)((await table.get(ID))?.revision).to.equal("fresh");
|
|
50
|
+
(0, chai_1.expect)(await table.atomicMutation(ID, request).run()).to.equal("not-applied");
|
|
51
|
+
await table.get(ID).update({ revision: undefined }).run();
|
|
52
|
+
(0, chai_1.expect)(await table.atomicMutation(ID, request).run()).to.equal("applied");
|
|
53
|
+
(0, chai_1.expect)((await table.get(ID).run())?.revision).to.equal("fresh");
|
|
52
54
|
});
|
|
53
55
|
it("rejects missing-revision bootstrap on declared columns", async () => {
|
|
54
56
|
try {
|
|
@@ -58,7 +60,8 @@ describe("atomic mutation results and scope", () => {
|
|
|
58
60
|
.atomicMutation(ID, {
|
|
59
61
|
...update,
|
|
60
62
|
expectedRevision: { kind: "missing" },
|
|
61
|
-
})
|
|
63
|
+
})
|
|
64
|
+
.run();
|
|
62
65
|
chai_1.expect.fail("expected unsupported bootstrap");
|
|
63
66
|
}
|
|
64
67
|
catch (error) {
|
|
@@ -67,9 +70,9 @@ describe("atomic mutation results and scope", () => {
|
|
|
67
70
|
});
|
|
68
71
|
it("supports the default instance and refuses cross-instance mutation", async () => {
|
|
69
72
|
const defaults = schema.instance().table("records");
|
|
70
|
-
await defaults.delete();
|
|
71
|
-
await defaults.insert({ _id: ID, revision: "old" });
|
|
72
|
-
(0, chai_1.expect)(await defaults.atomicMutation(ID, update)).to.equal("applied");
|
|
73
|
+
await defaults.delete().run();
|
|
74
|
+
await defaults.insert({ _id: ID, revision: "old" }).run();
|
|
75
|
+
(0, chai_1.expect)(await defaults.atomicMutation(ID, update).run()).to.equal("applied");
|
|
73
76
|
(0, chai_1.expect)(() => schema
|
|
74
77
|
.instance(schema_1.CROSS_INSTANCE)
|
|
75
78
|
.table("records")
|
|
@@ -78,55 +81,69 @@ describe("atomic mutation results and scope", () => {
|
|
|
78
81
|
});
|
|
79
82
|
describe("atomic scalar equality deletes", () => {
|
|
80
83
|
beforeEach(async () => {
|
|
81
|
-
await table.delete();
|
|
84
|
+
await table.delete().run();
|
|
82
85
|
});
|
|
83
86
|
it("compares declared dates by instant and leaves a changed date untouched", async () => {
|
|
84
87
|
const declared = schema.instance().table("declared");
|
|
85
|
-
await declared.delete();
|
|
88
|
+
await declared.delete().run();
|
|
86
89
|
const updatedAt = new Date("2026-01-05T10:00:00+02:00");
|
|
87
|
-
await declared.insert({ _id: ID, updatedAt });
|
|
88
|
-
(0, chai_1.expect)(await declared
|
|
90
|
+
await declared.insert({ _id: ID, updatedAt }).run();
|
|
91
|
+
(0, chai_1.expect)(await declared
|
|
92
|
+
.atomicMutation(ID, {
|
|
89
93
|
type: "deleteIfEqual",
|
|
90
94
|
field: "updatedAt",
|
|
91
95
|
expectedValue: new Date("2026-01-05T08:00:01Z"),
|
|
92
|
-
})
|
|
93
|
-
|
|
96
|
+
})
|
|
97
|
+
.run()).to.equal("not-applied");
|
|
98
|
+
(0, chai_1.expect)(await declared
|
|
99
|
+
.atomicMutation(ID, {
|
|
94
100
|
type: "deleteIfEqual",
|
|
95
101
|
field: "updatedAt",
|
|
96
102
|
expectedValue: new Date("2026-01-05T08:00:00Z"),
|
|
97
|
-
})
|
|
103
|
+
})
|
|
104
|
+
.run()).to.equal("applied");
|
|
98
105
|
});
|
|
99
106
|
it("preserves scalar types in overflow equality and ignores missing fields", async () => {
|
|
100
107
|
await Seed({ attempts: 7, active: true });
|
|
101
|
-
(0, chai_1.expect)(await table
|
|
108
|
+
(0, chai_1.expect)(await table
|
|
109
|
+
.atomicMutation(ID, {
|
|
102
110
|
type: "deleteIfEqual",
|
|
103
111
|
field: "updatedAt",
|
|
104
112
|
expectedValue: new Date(),
|
|
105
|
-
})
|
|
106
|
-
|
|
113
|
+
})
|
|
114
|
+
.run()).to.equal("not-applied");
|
|
115
|
+
(0, chai_1.expect)(await table
|
|
116
|
+
.atomicMutation(ID, {
|
|
107
117
|
type: "deleteIfEqual",
|
|
108
118
|
field: "attempts",
|
|
109
119
|
expectedValue: "7",
|
|
110
|
-
})
|
|
111
|
-
|
|
120
|
+
})
|
|
121
|
+
.run()).to.equal("not-applied");
|
|
122
|
+
(0, chai_1.expect)(await table
|
|
123
|
+
.atomicMutation(ID, {
|
|
112
124
|
type: "deleteIfEqual",
|
|
113
125
|
field: "active",
|
|
114
126
|
expectedValue: false,
|
|
115
|
-
})
|
|
116
|
-
|
|
127
|
+
})
|
|
128
|
+
.run()).to.equal("not-applied");
|
|
129
|
+
(0, chai_1.expect)(await table
|
|
130
|
+
.atomicMutation(ID, {
|
|
117
131
|
type: "deleteIfEqual",
|
|
118
132
|
field: "attempts",
|
|
119
133
|
expectedValue: 7,
|
|
120
|
-
})
|
|
134
|
+
})
|
|
135
|
+
.run()).to.equal("applied");
|
|
121
136
|
});
|
|
122
137
|
it("matches dates stored in overflow by the native insert compiler", async () => {
|
|
123
138
|
const updatedAt = new Date("2026-02-12T03:04:05Z");
|
|
124
139
|
await Seed({ updatedAt });
|
|
125
|
-
(0, chai_1.expect)(await table
|
|
140
|
+
(0, chai_1.expect)(await table
|
|
141
|
+
.atomicMutation(ID, {
|
|
126
142
|
type: "deleteIfEqual",
|
|
127
143
|
field: "updatedAt",
|
|
128
144
|
expectedValue: updatedAt,
|
|
129
|
-
})
|
|
145
|
+
})
|
|
146
|
+
.run()).to.equal("applied");
|
|
130
147
|
});
|
|
131
148
|
});
|
|
132
149
|
//# sourceMappingURL=atomic.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atomic.test.js","sourceRoot":"","sources":["../../src/test/atomic.test.ts"],"names":[],"mappings":";;AAAA,+BAA8B;AAE9B,kEAA+E;AAiB/E,MAAM,MAAM,GAAG,IAAI,eAAM,CAAS,gBAAgB,EAAE;IAClD,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACrD,QAAQ,EAAE;QACR,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE;QAClE,OAAO,EAAE,EAAE;KACZ;CACF,CAAC,CAAC;AACH,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACzD,MAAM,EAAE,GAAG,KAAK,CAAC;AACjB,MAAM,MAAM,GAA2B;IACrC,IAAI,EAAE,QAAQ;IACd,aAAa,EAAE,UAAU;IACzB,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,OAAO;IACrB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;CACnD,CAAC;AAEF,KAAK,UAAU,IAAI,CAAC,WAA8B,EAAE;IAClD,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"atomic.test.js","sourceRoot":"","sources":["../../src/test/atomic.test.ts"],"names":[],"mappings":";;AAAA,+BAA8B;AAE9B,kEAA+E;AAiB/E,MAAM,MAAM,GAAG,IAAI,eAAM,CAAS,gBAAgB,EAAE;IAClD,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACrD,QAAQ,EAAE;QACR,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE;QAClE,OAAO,EAAE,EAAE;KACZ;CACF,CAAC,CAAC;AACH,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACzD,MAAM,EAAE,GAAG,KAAK,CAAC;AACjB,MAAM,MAAM,GAA2B;IACrC,IAAI,EAAE,QAAQ;IACd,aAAa,EAAE,UAAU;IACzB,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,OAAO;IACrB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;CACnD,CAAC;AAEF,KAAK,UAAU,IAAI,CAAC,WAA8B,EAAE;IAClD,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;AACtE,CAAC;AAED,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAA,aAAM,EAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAA,aAAM,EAAC,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACzE,IAAA,aAAM,EAAC,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;YAC3C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK;aACrB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;aAChD,GAAG,EAAE,CAAC;QACT,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,OAAO,GAAG;YACd,GAAG,MAAM;YACT,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAW;SAC/C,CAAC;QACF,IAAA,aAAM,EAAC,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAC5D,aAAa,CACd,CAAC;QACF,MAAM,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,IAAA,aAAM,EAAC,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAC5D,aAAa,CACd,CAAC;QACF,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1D,IAAA,aAAM,EAAC,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1E,IAAA,aAAM,EAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,IAAI,CAAC;YACH,MAAM,MAAM;iBACT,QAAQ,EAAE;iBACV,KAAK,CAAC,UAAU,CAAC;iBACjB,cAAc,CAAC,EAAE,EAAE;gBAClB,GAAG,MAAM;gBACT,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;aACtC,CAAC;iBACD,GAAG,EAAE,CAAC;YACT,aAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAA,aAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAC9B,2CAA2C,CAC5C,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1D,IAAA,aAAM,EAAC,MAAM,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5E,IAAA,aAAM,EAAC,GAAG,EAAE,CACV,MAAM;aACH,QAAQ,CAAC,uBAAc,CAAC;aACxB,KAAK,CAAC,SAAS,CAAC;aAChB,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,CAC9B,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACxD,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QACpD,IAAA,aAAM,EACJ,MAAM,QAAQ;aACX,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;SAChD,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1B,IAAA,aAAM,EACJ,MAAM,QAAQ;aACX,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;SAChD,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAA,aAAM,EACJ,MAAM,KAAK;aACR,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,IAAI,IAAI,EAAE;SAC1B,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1B,IAAA,aAAM,EACJ,MAAM,KAAK;aACR,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,UAAU;YACjB,aAAa,EAAE,GAAG;SACnB,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1B,IAAA,aAAM,EACJ,MAAM,KAAK;aACR,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,aAAa,EAAE,KAAK;SACrB,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1B,IAAA,aAAM,EACJ,MAAM,KAAK;aACR,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,UAAU;YACjB,aAAa,EAAE,CAAC;SACjB,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1B,IAAA,aAAM,EACJ,MAAM,KAAK;aACR,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,WAAW;YAClB,aAAa,EAAE,SAAS;SACzB,CAAC;aACD,GAAG,EAAE,CACT,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -76,34 +76,38 @@ async function Compete(query, winner) {
|
|
|
76
76
|
}
|
|
77
77
|
describe("legacy conditional writes under contention", () => {
|
|
78
78
|
beforeEach(async () => {
|
|
79
|
-
await table.delete();
|
|
80
|
-
await table
|
|
79
|
+
await table.delete().run();
|
|
80
|
+
await table
|
|
81
|
+
.insert({
|
|
81
82
|
_id: ID,
|
|
82
83
|
revision: "old",
|
|
83
84
|
value: "initial",
|
|
84
|
-
})
|
|
85
|
+
})
|
|
86
|
+
.run();
|
|
85
87
|
});
|
|
86
88
|
it("reproduces two different patches matching one stale revision", async () => {
|
|
87
89
|
const result = await Compete(table
|
|
88
90
|
.filter((row) => row.key("revision").eq("old"))
|
|
89
91
|
.update({ revision: "next", value: "writer-b" }));
|
|
90
92
|
(0, chai_1.expect)(result).to.equal(1);
|
|
91
|
-
(0, chai_1.expect)((await table.get(ID))?.value).to.equal("writer-b");
|
|
93
|
+
(0, chai_1.expect)((await table.get(ID).run())?.value).to.equal("writer-b");
|
|
92
94
|
});
|
|
93
95
|
it("reproduces a stale conditional delete removing an updated row", async () => {
|
|
94
96
|
const result = await Compete(table.filter((row) => row.key("revision").eq("old")).delete());
|
|
95
97
|
(0, chai_1.expect)(result).to.equal(1);
|
|
96
|
-
(0, chai_1.expect)(await table.get(ID)).to.equal(undefined);
|
|
98
|
+
(0, chai_1.expect)(await table.get(ID).run()).to.equal(undefined);
|
|
97
99
|
});
|
|
98
100
|
});
|
|
99
101
|
describe("atomic mutations under contention", () => {
|
|
100
102
|
beforeEach(async () => {
|
|
101
|
-
await table.delete();
|
|
102
|
-
await table
|
|
103
|
+
await table.delete().run();
|
|
104
|
+
await table
|
|
105
|
+
.insert({
|
|
103
106
|
_id: ID,
|
|
104
107
|
revision: "old",
|
|
105
108
|
value: "initial",
|
|
106
|
-
})
|
|
109
|
+
})
|
|
110
|
+
.run();
|
|
107
111
|
});
|
|
108
112
|
function Winner() {
|
|
109
113
|
return table.atomicMutation(ID, {
|
|
@@ -123,7 +127,7 @@ describe("atomic mutations under contention", () => {
|
|
|
123
127
|
patch: { value: "writer-b" },
|
|
124
128
|
});
|
|
125
129
|
(0, chai_1.expect)(await Compete(second, Winner())).to.equal("not-applied");
|
|
126
|
-
const record = await table.get(ID);
|
|
130
|
+
const record = await table.get(ID).run();
|
|
127
131
|
(0, chai_1.expect)(record?.revision).to.equal("next-a");
|
|
128
132
|
(0, chai_1.expect)(record?.value).to.equal("writer-a");
|
|
129
133
|
});
|
|
@@ -134,7 +138,7 @@ describe("atomic mutations under contention", () => {
|
|
|
134
138
|
expectedRevision: "old",
|
|
135
139
|
});
|
|
136
140
|
(0, chai_1.expect)(await Compete(second, Winner())).to.equal("not-applied");
|
|
137
|
-
(0, chai_1.expect)((await table.get(ID))?.value).to.equal("writer-a");
|
|
141
|
+
(0, chai_1.expect)((await table.get(ID).run())?.value).to.equal("writer-a");
|
|
138
142
|
});
|
|
139
143
|
it("rechecks scalar equality after a concurrent update", async () => {
|
|
140
144
|
const second = table.atomicMutation(ID, {
|
|
@@ -143,12 +147,12 @@ describe("atomic mutations under contention", () => {
|
|
|
143
147
|
expectedValue: "initial",
|
|
144
148
|
});
|
|
145
149
|
(0, chai_1.expect)(await Compete(second, Winner())).to.equal("not-applied");
|
|
146
|
-
(0, chai_1.expect)((await table.get(ID))?.value).to.equal("writer-a");
|
|
150
|
+
(0, chai_1.expect)((await table.get(ID).run())?.value).to.equal("writer-a");
|
|
147
151
|
});
|
|
148
152
|
it("allows only one bootstrap of a missing overflow revision", async () => {
|
|
149
153
|
const overflow = schema.instance("tenant").table("overflow");
|
|
150
|
-
await overflow.delete();
|
|
151
|
-
await overflow.insert({ _id: ID, value: "initial" });
|
|
154
|
+
await overflow.delete().run();
|
|
155
|
+
await overflow.insert({ _id: ID, value: "initial" }).run();
|
|
152
156
|
const request = {
|
|
153
157
|
type: "update",
|
|
154
158
|
revisionField: "revision",
|
|
@@ -163,8 +167,8 @@ describe("atomic mutations under contention", () => {
|
|
|
163
167
|
patch: { value: "writer-b" },
|
|
164
168
|
});
|
|
165
169
|
(0, chai_1.expect)(await Compete(second, first)).to.equal("not-applied");
|
|
166
|
-
(0, chai_1.expect)((await overflow.get(ID))?.revision).to.equal("next-a");
|
|
167
|
-
(0, chai_1.expect)((await overflow.get(ID))?.value).to.equal("writer-a");
|
|
170
|
+
(0, chai_1.expect)((await overflow.get(ID).run())?.revision).to.equal("next-a");
|
|
171
|
+
(0, chai_1.expect)((await overflow.get(ID).run())?.value).to.equal("writer-a");
|
|
168
172
|
});
|
|
169
173
|
it("reports unknown when the committed response is lost without retrying", async () => {
|
|
170
174
|
const statement = Compile(Winner());
|
|
@@ -176,7 +180,7 @@ describe("atomic mutations under contention", () => {
|
|
|
176
180
|
});
|
|
177
181
|
(0, chai_1.expect)(outcome).to.equal("unknown");
|
|
178
182
|
(0, chai_1.expect)(calls).to.equal(1);
|
|
179
|
-
(0, chai_1.expect)((await table.get(ID))?.revision).to.equal("next-a");
|
|
183
|
+
(0, chai_1.expect)((await table.get(ID).run())?.revision).to.equal("next-a");
|
|
180
184
|
});
|
|
181
185
|
});
|
|
182
186
|
//# sourceMappingURL=contention.test.js.map
|