@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,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const probe_fixture_1 = require("./probe-fixture");
|
|
5
|
+
const relays_1 = require("./relays");
|
|
6
|
+
function WithoutPassword(url) {
|
|
7
|
+
return (0, probe_fixture_1.Altered)(url, (target) => {
|
|
8
|
+
target.password = "";
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const SSL_REQUEST = Buffer.from([0, 0, 0, 8, 0x04, 0xd2, 0x16, 0x2f]);
|
|
12
|
+
function OnDatabase(url, database) {
|
|
13
|
+
return (0, probe_fixture_1.Altered)(url, (target) => {
|
|
14
|
+
target.pathname = `/${database}`;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
describe("the connection probe's refusals", function () {
|
|
18
|
+
this.timeout(60_000);
|
|
19
|
+
(0, probe_fixture_1.WithProbeLogins)();
|
|
20
|
+
it("refuses a wrong password as credentials", async () => {
|
|
21
|
+
const answer = await (0, probe_fixture_1.Probe)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader, "not-the-password"));
|
|
22
|
+
(0, chai_1.expect)(answer).to.include({ outcome: "refused", refusal: "credentials" });
|
|
23
|
+
});
|
|
24
|
+
it("refuses a login the server does not let in as host", async () => {
|
|
25
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.NO_LOGIN))).to.include({
|
|
26
|
+
outcome: "refused",
|
|
27
|
+
refusal: "host",
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
it("refuses a database the server does not have as database", async () => {
|
|
31
|
+
const url = OnDatabase((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), "antelopejs_missing");
|
|
32
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(url)).to.include({
|
|
33
|
+
outcome: "refused",
|
|
34
|
+
refusal: "database",
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
it("refuses a database the login may not connect to as database-denied", async () => {
|
|
38
|
+
const url = OnDatabase((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), probe_fixture_1.LOCKED_DATABASE);
|
|
39
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(url)).to.include({
|
|
40
|
+
outcome: "refused",
|
|
41
|
+
refusal: "database-denied",
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it("refuses a URL without the password the server asks for as sign-in-required", async () => {
|
|
45
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(WithoutPassword((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader)))).to.include({
|
|
46
|
+
outcome: "refused",
|
|
47
|
+
refusal: "sign-in-required",
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
it("never fills a password the URL lacks from PGPASSWORD", async () => {
|
|
51
|
+
const reader = (0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader);
|
|
52
|
+
await (0, probe_fixture_1.WithEnvironment)({ PGPASSWORD: new URL(reader).password }, async () => {
|
|
53
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(WithoutPassword(reader))).to.include({
|
|
54
|
+
outcome: "refused",
|
|
55
|
+
refusal: "sign-in-required",
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
it("sends nothing to a server asking for a cleartext password the URL lacks", async () => {
|
|
60
|
+
const server = await (0, relays_1.StartRecordingServer)(relays_1.CLEARTEXT_PASSWORD_REQUEST);
|
|
61
|
+
try {
|
|
62
|
+
await (0, probe_fixture_1.WithEnvironment)({ PGPASSWORD: "the probing process's own secret" }, async () => {
|
|
63
|
+
const url = WithoutPassword((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port));
|
|
64
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(url)).to.include({
|
|
65
|
+
outcome: "refused",
|
|
66
|
+
refusal: "sign-in-required",
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
(0, chai_1.expect)(server.received()).to.equal(0);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
await server.close();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
it("asks for TLS before anything else when the URL says ssl=no-verify", async () => {
|
|
76
|
+
const server = await (0, relays_1.StartRecordingServer)(relays_1.CLEARTEXT_PASSWORD_REQUEST);
|
|
77
|
+
try {
|
|
78
|
+
const url = (0, probe_fixture_1.Altered)((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), (target) => {
|
|
79
|
+
target.searchParams.set("ssl", "no-verify");
|
|
80
|
+
});
|
|
81
|
+
await (0, probe_fixture_1.Probe)(url);
|
|
82
|
+
(0, chai_1.expect)(server.first()).to.deep.equal(SSL_REQUEST);
|
|
83
|
+
(0, chai_1.expect)(server.received()).to.equal(0);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await server.close();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
it("refuses any other server error during the sign-in as other, with its message", async () => {
|
|
90
|
+
const url = (0, probe_fixture_1.Altered)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), (target) => {
|
|
91
|
+
target.searchParams.set("options", "-c probe_bogus=1");
|
|
92
|
+
});
|
|
93
|
+
const answer = await (0, probe_fixture_1.Probe)(url);
|
|
94
|
+
(0, chai_1.expect)(answer).to.include({ outcome: "refused", refusal: "other" });
|
|
95
|
+
(0, chai_1.expect)(answer).to.have.property("message").that.contains("probe_bogus");
|
|
96
|
+
});
|
|
97
|
+
it("answers a port nothing listens on as unreachable, within the timeout", async () => {
|
|
98
|
+
const started = performance.now();
|
|
99
|
+
const answer = await (0, probe_fixture_1.Probe)((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), await (0, relays_1.ClosedPort)()));
|
|
100
|
+
(0, chai_1.expect)(performance.now() - started).to.be.lessThan(probe_fixture_1.TIMEOUT_MS);
|
|
101
|
+
(0, chai_1.expect)(answer.outcome).to.equal("unreachable");
|
|
102
|
+
});
|
|
103
|
+
it("says why when every address of a host name refuses", async () => {
|
|
104
|
+
const port = await (0, relays_1.ClosedPort)();
|
|
105
|
+
const answer = await (0, probe_fixture_1.Probe)((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), port, "localhost"));
|
|
106
|
+
(0, chai_1.expect)(answer.outcome).to.equal("unreachable");
|
|
107
|
+
(0, chai_1.expect)(answer).to.have.property("message").that.contains("ECONNREFUSED");
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=probe-refusals.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-refusals.test.js","sourceRoot":"","sources":["../../src/test-external/probe-refusals.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const probe_1 = require("../probe");
|
|
5
|
+
const probe_fixture_1 = require("./probe-fixture");
|
|
6
|
+
const relays_1 = require("./relays");
|
|
7
|
+
const BOUND_MS = 300;
|
|
8
|
+
const LIFTED_MS = 60_000;
|
|
9
|
+
const NO_CONNECTION = { connections: 0, received: 0 };
|
|
10
|
+
function WithParameter(url, name, value) {
|
|
11
|
+
return (0, probe_fixture_1.Altered)(url, (target) => {
|
|
12
|
+
target.searchParams.set(name, value);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function Bounded(url) {
|
|
16
|
+
return (0, probe_1.probe)({
|
|
17
|
+
url,
|
|
18
|
+
timeoutMs: BOUND_MS,
|
|
19
|
+
signal: new AbortController().signal,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function StartupParameters(packet) {
|
|
23
|
+
const fields = (packet ?? Buffer.alloc(0))
|
|
24
|
+
.subarray(8, -1)
|
|
25
|
+
.toString("utf8")
|
|
26
|
+
.split("\0")
|
|
27
|
+
.slice(0, -1);
|
|
28
|
+
const parameters = new Map();
|
|
29
|
+
for (let index = 0; index + 1 < fields.length; index += 2) {
|
|
30
|
+
parameters.set(fields[index], fields[index + 1]);
|
|
31
|
+
}
|
|
32
|
+
return parameters;
|
|
33
|
+
}
|
|
34
|
+
async function WithServer(server, check) {
|
|
35
|
+
try {
|
|
36
|
+
await check(server);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await server.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function Seen(server) {
|
|
43
|
+
return { connections: server.connections(), received: server.received() };
|
|
44
|
+
}
|
|
45
|
+
const STARTUP_ROWS = [
|
|
46
|
+
{ name: "statement_timeout", value: "0", sent: String(BOUND_MS) },
|
|
47
|
+
{ name: "lock_timeout", value: "0", sent: String(BOUND_MS) },
|
|
48
|
+
{
|
|
49
|
+
name: "idle_in_transaction_session_timeout",
|
|
50
|
+
value: "0",
|
|
51
|
+
sent: String(BOUND_MS),
|
|
52
|
+
},
|
|
53
|
+
{ name: "replication", value: "database", sent: undefined },
|
|
54
|
+
{ name: "application_name", value: "probe-app", sent: "probe-app" },
|
|
55
|
+
{ name: "options", value: "-c search_path=x", sent: "-c search_path=x" },
|
|
56
|
+
];
|
|
57
|
+
const TLS_ACCEPTED = Buffer.from("S");
|
|
58
|
+
const HOSTILE_LENGTH = 1_000_000;
|
|
59
|
+
function HostileUrls(port) {
|
|
60
|
+
const base = `postgres://${probe_fixture_1.LOGIN.reader}:secret@127.0.0.1:${port}/shop`;
|
|
61
|
+
const repeat = (text) => text.repeat(Math.ceil(HOSTILE_LENGTH / text.length));
|
|
62
|
+
return new Map([
|
|
63
|
+
["host", `postgres://${probe_fixture_1.LOGIN.reader}:secret@${repeat("a")}:${port}/shop`],
|
|
64
|
+
["user", `postgres://${repeat("%2")}:secret@127.0.0.1:${port}/shop`],
|
|
65
|
+
[
|
|
66
|
+
"database",
|
|
67
|
+
`postgres://${probe_fixture_1.LOGIN.reader}:secret@127.0.0.1:${port}/${repeat("%41")}`,
|
|
68
|
+
],
|
|
69
|
+
["options", `${base}?options=${repeat("-c%20a%3Db%20")}`],
|
|
70
|
+
["application_name", `${base}?application_name=${repeat("a")}`],
|
|
71
|
+
["bad escapes", `${base}?x=${repeat("%zz %")}`],
|
|
72
|
+
["parameter count", `${base}?${repeat("k=v&")}`],
|
|
73
|
+
["sslmode", `${base}?sslmode=${repeat("verify-")}`],
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
function CredentialCases() {
|
|
77
|
+
it("refuses a URL with no user before connecting, whatever PGUSER says", async () => {
|
|
78
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
79
|
+
const url = (0, probe_fixture_1.Altered)((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), (target) => {
|
|
80
|
+
target.username = "";
|
|
81
|
+
});
|
|
82
|
+
await (0, probe_fixture_1.WithEnvironment)({ PGUSER: probe_fixture_1.LOGIN.reader }, async () => {
|
|
83
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(url)).to.include({
|
|
84
|
+
outcome: "refused",
|
|
85
|
+
refusal: "other",
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
(0, chai_1.expect)(Seen(server)).to.deep.equal(NO_CONNECTION);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it("refuses a URL with no host before connecting, whatever PGHOST says", async () => {
|
|
92
|
+
await (0, probe_fixture_1.WithEnvironment)({ PGHOST: "127.0.0.1" }, async () => {
|
|
93
|
+
const answer = await (0, probe_fixture_1.Probe)(`postgres://${probe_fixture_1.LOGIN.reader}:secret@/shop`);
|
|
94
|
+
(0, chai_1.expect)(answer).to.include({ outcome: "refused", refusal: "other" });
|
|
95
|
+
(0, chai_1.expect)(answer).to.have.property("message").that.contains("no host");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
it("refuses a client certificate of the probing host before connecting", async () => {
|
|
99
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
100
|
+
for (const name of ["sslcert", "sslkey"]) {
|
|
101
|
+
const url = WithParameter((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), name, __filename);
|
|
102
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.Probe)(url), name).to.include({
|
|
103
|
+
outcome: "refused",
|
|
104
|
+
refusal: "other",
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
(0, chai_1.expect)(Seen(server)).to.deep.equal(NO_CONNECTION);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function WorkCases() {
|
|
112
|
+
const ROOT_CERTIFICATES = [
|
|
113
|
+
"/dev/zero",
|
|
114
|
+
__dirname,
|
|
115
|
+
"/proc/self/pagemap",
|
|
116
|
+
__filename,
|
|
117
|
+
];
|
|
118
|
+
for (const path of ROOT_CERTIFICATES) {
|
|
119
|
+
it(`refuses sslrootcert=${path} without reading it`, async () => {
|
|
120
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
121
|
+
const url = WithParameter((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), "sslrootcert", path);
|
|
122
|
+
const started = performance.now();
|
|
123
|
+
(0, chai_1.expect)(await Bounded(url)).to.include({
|
|
124
|
+
outcome: "refused",
|
|
125
|
+
refusal: "other",
|
|
126
|
+
});
|
|
127
|
+
(0, chai_1.expect)(performance.now() - started).to.be.lessThan(BOUND_MS);
|
|
128
|
+
(0, chai_1.expect)(Seen(server)).to.deep.equal(NO_CONNECTION);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
for (const query of [
|
|
133
|
+
"ssl=false",
|
|
134
|
+
"ssl=require",
|
|
135
|
+
"ssl=abc",
|
|
136
|
+
"ssl=false&sslmode=",
|
|
137
|
+
]) {
|
|
138
|
+
it(`refuses ${query}, which pg fails on once TLS starts, before connecting`, async () => {
|
|
139
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(TLS_ACCEPTED), async (server) => {
|
|
140
|
+
const url = `${(0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port)}?${query}`;
|
|
141
|
+
(0, chai_1.expect)(await Bounded(url)).to.include({
|
|
142
|
+
outcome: "refused",
|
|
143
|
+
refusal: "other",
|
|
144
|
+
});
|
|
145
|
+
(0, chai_1.expect)(Seen(server)).to.deep.equal(NO_CONNECTION);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
for (const query of ["ssl=", "ssl=0"]) {
|
|
150
|
+
it(`keeps ${query}, which pg reads as no TLS`, async () => {
|
|
151
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
152
|
+
await Bounded(`${(0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port)}?${query}`);
|
|
153
|
+
(0, chai_1.expect)(StartupParameters(server.first()).get("user")).to.equal(probe_fixture_1.LOGIN.reader);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
it("keeps ssl=no-verify and asks for TLS", async () => {
|
|
158
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
159
|
+
await Bounded(WithParameter((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), "ssl", "no-verify"));
|
|
160
|
+
(0, chai_1.expect)(server.connections()).to.equal(1);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
it("refuses many sslrootcert keys within its bound", async () => {
|
|
164
|
+
const url = `${(0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), await (0, relays_1.ClosedPort)())}?${`sslrootcert=${__filename}&`.repeat(10_000)}`;
|
|
165
|
+
const started = performance.now();
|
|
166
|
+
(0, chai_1.expect)(await Bounded(url)).to.include({
|
|
167
|
+
outcome: "refused",
|
|
168
|
+
refusal: "other",
|
|
169
|
+
});
|
|
170
|
+
(0, chai_1.expect)(performance.now() - started).to.be.lessThan(BOUND_MS);
|
|
171
|
+
});
|
|
172
|
+
for (const [key, character] of [
|
|
173
|
+
["sslkey", "\t"],
|
|
174
|
+
["sslcert", "\n"],
|
|
175
|
+
["sslrootcert", "\r"],
|
|
176
|
+
]) {
|
|
177
|
+
it(`refuses ${key} with ${JSON.stringify(character)} inside its name before reading it`, async () => {
|
|
178
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
179
|
+
const name = `${key.slice(0, 3)}${character}${key.slice(3)}`;
|
|
180
|
+
const path = key === "sslrootcert" ? "/dev/zero" : __filename;
|
|
181
|
+
const url = `${(0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port)}?${name}=${path}`;
|
|
182
|
+
const started = performance.now();
|
|
183
|
+
(0, chai_1.expect)(await Bounded(url)).to.include({
|
|
184
|
+
outcome: "refused",
|
|
185
|
+
refusal: "other",
|
|
186
|
+
});
|
|
187
|
+
(0, chai_1.expect)(performance.now() - started).to.be.lessThan(BOUND_MS);
|
|
188
|
+
(0, chai_1.expect)(Seen(server)).to.deep.equal(NO_CONNECTION);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
it("answers within its bound however long and awkward each URL value is", async () => {
|
|
193
|
+
for (const [name, url] of HostileUrls(await (0, relays_1.ClosedPort)())) {
|
|
194
|
+
const started = performance.now();
|
|
195
|
+
const answer = await Bounded(url);
|
|
196
|
+
(0, chai_1.expect)(performance.now() - started, name).to.be.lessThan(BOUND_MS * 4);
|
|
197
|
+
(0, chai_1.expect)(answer.outcome, name).to.not.equal("signed-in");
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function ParameterCases() {
|
|
202
|
+
for (const { name, value, sent } of STARTUP_ROWS) {
|
|
203
|
+
it(`sends ${name} as ${sent ?? "nothing"} when the URL says ${value}`, async () => {
|
|
204
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(), async (server) => {
|
|
205
|
+
const url = WithParameter((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), name, value);
|
|
206
|
+
await Bounded(url);
|
|
207
|
+
const parameters = StartupParameters(server.first());
|
|
208
|
+
(0, chai_1.expect)(parameters.get("user")).to.equal(probe_fixture_1.LOGIN.reader);
|
|
209
|
+
(0, chai_1.expect)(parameters.get(name)).to.equal(sent);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
it("answers within its bound when the URL lifts query_timeout", async () => {
|
|
214
|
+
await WithServer(await (0, relays_1.StartRecordingServer)(relays_1.SIGNED_IN), async (server) => {
|
|
215
|
+
const url = WithParameter((0, probe_fixture_1.OnPort)((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.reader), server.port), "query_timeout", String(LIFTED_MS));
|
|
216
|
+
const started = performance.now();
|
|
217
|
+
const answer = await Bounded(url);
|
|
218
|
+
(0, chai_1.expect)(performance.now() - started).to.be.lessThan(BOUND_MS * 4);
|
|
219
|
+
(0, chai_1.expect)(answer.outcome).to.equal("unreachable");
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
it("changes no row when the URL's options put a writing function on the path", async () => {
|
|
223
|
+
const url = WithParameter((0, probe_fixture_1.LoginUrl)(probe_fixture_1.LOGIN.writer), "options", `-c search_path=${probe_fixture_1.SCRIBBLE_SCHEMA},pg_catalog`);
|
|
224
|
+
const answer = (0, probe_fixture_1.SignedIn)(await (0, probe_fixture_1.Probe)(url));
|
|
225
|
+
(0, chai_1.expect)(answer).to.include({ unreadable: "cannot-list" });
|
|
226
|
+
(0, chai_1.expect)(await (0, probe_fixture_1.CountAsOwner)(`${probe_fixture_1.SCRIBBLE_SCHEMA}.marks`)).to.equal(0);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
describe("the connection probe's URL", function () {
|
|
230
|
+
this.timeout(60_000);
|
|
231
|
+
(0, probe_fixture_1.WithProbeLogins)();
|
|
232
|
+
describe("credentials", () => {
|
|
233
|
+
CredentialCases();
|
|
234
|
+
});
|
|
235
|
+
describe("work before the probe can refuse", () => {
|
|
236
|
+
WorkCases();
|
|
237
|
+
});
|
|
238
|
+
describe("parameters", () => {
|
|
239
|
+
ParameterCases();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
//# sourceMappingURL=probe-url.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-url.test.js","sourceRoot":"","sources":["../../src/test-external/probe-url.test.ts"],"names":[],"mappings":";;AAAA,+BAA8B;AAE9B,oCAAiC;AACjC,mDAWyB;AACzB,qCAKkB;AAGlB,MAAM,QAAQ,GAAG,GAAG,CAAC;AAGrB,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,MAAM,aAAa,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AAEtD,SAAS,aAAa,CAAC,GAAW,EAAE,IAAY,EAAE,KAAa;IAC7D,OAAO,IAAA,uBAAO,EAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;QAC7B,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAA,aAAK,EAAC;QACX,GAAG;QACH,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;KACrC,CAAC,CAAC;AACL,CAAC;AAGD,SAAS,iBAAiB,CAAC,MAA0B;IACnD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACvC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACf,QAAQ,CAAC,MAAM,CAAC;SAChB,KAAK,CAAC,IAAI,CAAC;SACX,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1D,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,MAAuB,EACvB,KAAiD;IAEjD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,MAAuB;IACnC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5E,CAAC;AAMD,MAAM,YAAY,GAAG;IACnB,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;IACjE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;IAC5D;QACE,IAAI,EAAE,qCAAqC;QAC3C,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;KACvB;IACD,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;IAC3D,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;IACnE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE;CACzE,CAAC;AAGF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAGtC,MAAM,cAAc,GAAG,SAAS,CAAC;AAGjC,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,IAAI,GAAG,cAAc,qBAAK,CAAC,MAAM,qBAAqB,IAAI,OAAO,CAAC;IACxE,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,OAAO,IAAI,GAAG,CAAC;QACb,CAAC,MAAM,EAAE,cAAc,qBAAK,CAAC,MAAM,WAAW,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC;QACzE,CAAC,MAAM,EAAE,cAAc,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,OAAO,CAAC;QACpE;YACE,UAAU;YACV,cAAc,qBAAK,CAAC,MAAM,qBAAqB,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;SACvE;QACD,CAAC,SAAS,EAAE,GAAG,IAAI,YAAY,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;QACzD,CAAC,kBAAkB,EAAE,GAAG,IAAI,qBAAqB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,CAAC,aAAa,EAAE,GAAG,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,CAAC,iBAAiB,EAAE,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,CAAC,SAAS,EAAE,GAAG,IAAI,YAAY,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;KACpD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe;IACtB,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC9D,MAAM,GAAG,GAAG,IAAA,uBAAO,EACjB,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,CAAC,MAAM,EAAE,EAAE;gBACT,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvB,CAAC,CACF,CAAC;YACF,MAAM,IAAA,+BAAe,EAAC,EAAE,MAAM,EAAE,qBAAK,CAAC,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE;gBACzD,IAAA,aAAM,EAAC,MAAM,IAAA,qBAAK,EAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;oBAClC,OAAO,EAAE,SAAS;oBAClB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,IAAA,aAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,IAAA,+BAAe,EAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAK,EAAC,cAAc,qBAAK,CAAC,MAAM,eAAe,CAAC,CAAC;YACtE,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACpE,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC9D,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,aAAa,CACvB,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,IAAI,EACJ,UAAU,CACX,CAAC;gBACF,IAAA,aAAM,EAAC,MAAM,IAAA,qBAAK,EAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;oBACxC,OAAO,EAAE,SAAS;oBAClB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC;YACD,IAAA,aAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,iBAAiB,GAAG;QACxB,WAAW;QACX,SAAS;QACT,oBAAoB;QACpB,UAAU;KACX,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QACrC,EAAE,CAAC,uBAAuB,IAAI,qBAAqB,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC9D,MAAM,GAAG,GAAG,aAAa,CACvB,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,aAAa,EACb,IAAI,CACL,CAAC;gBACF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBAClC,IAAA,aAAM,EAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;oBACpC,OAAO,EAAE,SAAS;oBAClB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;gBACH,IAAA,aAAM,EAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAA,aAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,KAAK,IAAI;QAClB,WAAW;QACX,aAAa;QACb,SAAS;QACT,oBAAoB;KACrB,EAAE,CAAC;QACF,EAAE,CAAC,WAAW,KAAK,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtF,MAAM,UAAU,CACd,MAAM,IAAA,6BAAoB,EAAC,YAAY,CAAC,EACxC,KAAK,EAAE,MAAM,EAAE,EAAE;gBACf,MAAM,GAAG,GAAG,GAAG,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtE,IAAA,aAAM,EAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;oBACpC,OAAO,EAAE,SAAS;oBAClB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;gBACH,IAAA,aAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACpD,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QACtC,EAAE,CAAC,SAAS,KAAK,4BAA4B,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC9D,MAAM,OAAO,CACX,GAAG,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAC1D,CAAC;gBACF,IAAA,aAAM,EAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAC5D,qBAAK,CAAC,MAAM,CACb,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC9D,MAAM,OAAO,CACX,aAAa,CACX,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,KAAK,EACL,WAAW,CACZ,CACF,CAAC;YACF,IAAA,aAAM,EAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,GAAG,GAAG,GAAG,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,IAAA,mBAAU,GAAE,CAAC,IAAI,eAAe,UAAU,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACnH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,IAAA,aAAM,EAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;YACpC,OAAO,EAAE,SAAS;YAClB,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QACH,IAAA,aAAM,EAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI;QAC7B,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChB,CAAC,SAAS,EAAE,IAAI,CAAC;QACjB,CAAC,aAAa,EAAE,IAAI,CAAC;KACtB,EAAE,CAAC;QACF,EAAE,CAAC,WAAW,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClG,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC9D,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,MAAM,IAAI,GAAG,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC9D,MAAM,GAAG,GAAG,GAAG,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC7E,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBAClC,IAAA,aAAM,EAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;oBACpC,OAAO,EAAE,SAAS;oBAClB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;gBACH,IAAA,aAAM,EAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAA,aAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,IAAA,mBAAU,GAAE,CAAC,EAAE,CAAC;YAC1D,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,IAAA,aAAM,EAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YACvE,IAAA,aAAM,EAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc;IACrB,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,YAAY,EAAE,CAAC;QACjD,EAAE,CAAC,SAAS,IAAI,OAAO,IAAI,IAAI,SAAS,sBAAsB,KAAK,EAAE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC9D,MAAM,GAAG,GAAG,aAAa,CACvB,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,IAAI,EACJ,KAAK,CACN,CAAC;gBACF,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;gBACnB,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBACrD,IAAA,aAAM,EAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,qBAAK,CAAC,MAAM,CAAC,CAAC;gBACtD,IAAA,aAAM,EAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,UAAU,CAAC,MAAM,IAAA,6BAAoB,EAAC,kBAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACvE,MAAM,GAAG,GAAG,aAAa,CACvB,IAAA,sBAAM,EAAC,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAC3C,eAAe,EACf,MAAM,CAAC,SAAS,CAAC,CAClB,CAAC;YACF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,IAAA,aAAM,EAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YACjE,IAAA,aAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,GAAG,GAAG,aAAa,CACvB,IAAA,wBAAQ,EAAC,qBAAK,CAAC,MAAM,CAAC,EACtB,SAAS,EACT,kBAAkB,+BAAe,aAAa,CAC/C,CAAC;QACF,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,MAAM,IAAA,qBAAK,EAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;QACzD,IAAA,aAAM,EAAC,MAAM,IAAA,4BAAY,EAAC,GAAG,+BAAe,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,4BAA4B,EAAE;IACrC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,IAAA,+BAAe,GAAE,CAAC;IAElB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,eAAe,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,SAAS,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,cAAc,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -18,7 +18,8 @@ function NextDay(iso) {
|
|
|
18
18
|
return new Date(Day(iso).getTime() + 86_400_000);
|
|
19
19
|
}
|
|
20
20
|
describe("listing an external relation as a TableView does", () => {
|
|
21
|
-
before(async ()
|
|
21
|
+
before(async function () {
|
|
22
|
+
this.timeout(sales_1.REGISTRATION_TIMEOUT_MS);
|
|
22
23
|
sales = await (0, sales_1.RegisterSales)();
|
|
23
24
|
});
|
|
24
25
|
it("lists with an enum filter, a (?i) search, a sort and a page, as a TableView does", async () => {
|
|
@@ -27,7 +28,8 @@ describe("listing an external relation as a TableView does", () => {
|
|
|
27
28
|
.filter((row) => row.key("status").eq("active"))
|
|
28
29
|
.filter((row) => row.key("name").match("(?i)acct 1"))
|
|
29
30
|
.slice(0, 5)
|
|
30
|
-
.pluck("_internal", "_id", "name", "status")
|
|
31
|
+
.pluck("_internal", "_id", "name", "status")
|
|
32
|
+
.run();
|
|
31
33
|
const expected = await (0, sales_1.Native)(`SELECT id::text AS "_id", name, status::text AS status FROM sales.accounts
|
|
32
34
|
WHERE status = 'active' AND name ~* 'acct 1' ORDER BY name DESC LIMIT 5`);
|
|
33
35
|
(0, chai_1.expect)(rows).to.deep.equal(expected);
|
|
@@ -36,14 +38,16 @@ describe("listing an external relation as a TableView does", () => {
|
|
|
36
38
|
const total = await Accounts()
|
|
37
39
|
.filter((row) => row.key("status").eq("active"))
|
|
38
40
|
.filter((row) => row.key("name").match("(?i)acct 1"))
|
|
39
|
-
.count()
|
|
41
|
+
.count()
|
|
42
|
+
.run();
|
|
40
43
|
(0, chai_1.expect)(total).to.equal(await (0, sales_1.NativeCount)("SELECT count(*) FROM sales.accounts WHERE status = 'active' AND name ~* 'acct 1'"));
|
|
41
44
|
});
|
|
42
45
|
it("filters an integer and a numeric column by the numbers the DMS parses", async () => {
|
|
43
46
|
const total = await Accounts()
|
|
44
47
|
.filter((row) => row.key("score").gt(97))
|
|
45
48
|
.filter((row) => row.key("revenue").ge(267000))
|
|
46
|
-
.count()
|
|
49
|
+
.count()
|
|
50
|
+
.run();
|
|
47
51
|
(0, chai_1.expect)(total).to.equal(await (0, sales_1.NativeCount)("SELECT count(*) FROM sales.accounts WHERE score > 97 AND revenue >= 267000"));
|
|
48
52
|
});
|
|
49
53
|
for (const [table, column] of [
|
|
@@ -60,7 +64,8 @@ describe("listing an external relation as a TableView does", () => {
|
|
|
60
64
|
.key(column)
|
|
61
65
|
.ge(Day(day))
|
|
62
66
|
.and(row.key(column).lt(NextDay(day))))
|
|
63
|
-
.count()
|
|
67
|
+
.count()
|
|
68
|
+
.run();
|
|
64
69
|
(0, chai_1.expect)(total).to.equal(await (0, sales_1.NativeCount)(`SELECT count(*) FROM sales.${table}
|
|
65
70
|
WHERE (${column})::timestamp >= $1::timestamp AND (${column})::timestamp < $1::timestamp + interval '1 day'`, [day]));
|
|
66
71
|
(0, chai_1.expect)(total).to.be.greaterThan(0);
|
|
@@ -69,7 +74,8 @@ describe("listing an external relation as a TableView does", () => {
|
|
|
69
74
|
it("searches a date column through its ISO rendering, as a TableView search does", async () => {
|
|
70
75
|
const total = await Accounts()
|
|
71
76
|
.filter((row) => row.key("created_at").match("(?i)2026-01-02T0"))
|
|
72
|
-
.count()
|
|
77
|
+
.count()
|
|
78
|
+
.run();
|
|
73
79
|
(0, chai_1.expect)(total).to.equal(10);
|
|
74
80
|
});
|
|
75
81
|
it("searches enum and uuid columns through their text", async () => {
|
|
@@ -78,18 +84,21 @@ describe("listing an external relation as a TableView does", () => {
|
|
|
78
84
|
.key("status")
|
|
79
85
|
.match("(?i)CHURN")
|
|
80
86
|
.or(row.key("external_ref").match("(?i)^0")))
|
|
81
|
-
.count()
|
|
87
|
+
.count()
|
|
88
|
+
.run();
|
|
82
89
|
(0, chai_1.expect)(total).to.equal(await (0, sales_1.NativeCount)("SELECT count(*) FROM sales.accounts WHERE status::text ~* 'churn' OR external_ref::text ~* '^0'"));
|
|
83
90
|
});
|
|
84
91
|
});
|
|
85
92
|
describe("reading an external row by key", () => {
|
|
86
|
-
before(async ()
|
|
93
|
+
before(async function () {
|
|
94
|
+
this.timeout(sales_1.REGISTRATION_TIMEOUT_MS);
|
|
87
95
|
sales = await (0, sales_1.RegisterSales)();
|
|
88
96
|
});
|
|
89
97
|
it("gets a row by its bigint key as a string _id, with exact bigints and true instants", async () => {
|
|
90
98
|
const row = await Accounts()
|
|
91
99
|
.get("42")
|
|
92
|
-
.pluck("_id", "id", "big_counter", "signed_on", "last_seen")
|
|
100
|
+
.pluck("_id", "id", "big_counter", "signed_on", "last_seen")
|
|
101
|
+
.run();
|
|
93
102
|
(0, chai_1.expect)(row).to.deep.equal({
|
|
94
103
|
_id: "42",
|
|
95
104
|
id: "42",
|
|
@@ -102,7 +111,10 @@ describe("reading an external row by key", () => {
|
|
|
102
111
|
const original = process.env.TZ;
|
|
103
112
|
process.env.TZ = "America/New_York";
|
|
104
113
|
try {
|
|
105
|
-
const row = await Accounts()
|
|
114
|
+
const row = await Accounts()
|
|
115
|
+
.get("42")
|
|
116
|
+
.pluck("signed_on", "last_seen")
|
|
117
|
+
.run();
|
|
106
118
|
(0, chai_1.expect)(row).to.deep.equal({
|
|
107
119
|
signed_on: new Date("2026-02-12T00:00:00.000Z"),
|
|
108
120
|
last_seen: new Date("2026-01-01T00:42:00.000Z"),
|
|
@@ -113,7 +125,7 @@ describe("reading an external row by key", () => {
|
|
|
113
125
|
}
|
|
114
126
|
});
|
|
115
127
|
it("reads a whole row in row mode with _id first and every declared field", async () => {
|
|
116
|
-
const row = await Accounts().get("7");
|
|
128
|
+
const row = await Accounts().get("7").run();
|
|
117
129
|
(0, chai_1.expect)(Object.keys(row)[0]).to.equal("_id");
|
|
118
130
|
(0, chai_1.expect)(row).to.include({
|
|
119
131
|
_id: "7",
|
|
@@ -126,12 +138,13 @@ describe("reading an external row by key", () => {
|
|
|
126
138
|
});
|
|
127
139
|
it("answers getAll by _id with the rows whose key matches, and nothing for a key that cannot", async () => {
|
|
128
140
|
const [known] = await (0, sales_1.Native)("SELECT contact_id::text AS id FROM sales.contacts ORDER BY first_name LIMIT 1");
|
|
129
|
-
const rows = await Contacts().getAll([known.id, "not-a-uuid"], "_id");
|
|
141
|
+
const rows = await Contacts().getAll([known.id, "not-a-uuid"], "_id").run();
|
|
130
142
|
(0, chai_1.expect)(rows.map((row) => row._id)).to.deep.equal([known.id]);
|
|
131
143
|
});
|
|
132
144
|
});
|
|
133
145
|
describe("reading across external relations", () => {
|
|
134
|
-
before(async ()
|
|
146
|
+
before(async function () {
|
|
147
|
+
this.timeout(sales_1.REGISTRATION_TIMEOUT_MS);
|
|
135
148
|
sales = await (0, sales_1.RegisterSales)();
|
|
136
149
|
});
|
|
137
150
|
it("resolves a foreign field: lookup from a bigint foreign key to the account's _id", async () => {
|
|
@@ -139,7 +152,8 @@ describe("reading across external relations", () => {
|
|
|
139
152
|
.orderBy("first_name", "asc")
|
|
140
153
|
.slice(0, 3)
|
|
141
154
|
.lookup(Accounts().pluck("_internal", "_id", "name"), "account_id", "_id")
|
|
142
|
-
.pluck("first_name", "account_id")
|
|
155
|
+
.pluck("first_name", "account_id")
|
|
156
|
+
.run();
|
|
143
157
|
const expected = await (0, sales_1.Native)(`SELECT c.first_name, jsonb_build_object('_id', a.id::text, 'name', a.name) AS account_id
|
|
144
158
|
FROM sales.contacts c JOIN sales.accounts a ON a.id = c.account_id
|
|
145
159
|
ORDER BY c.first_name LIMIT 3`);
|
|
@@ -159,22 +173,25 @@ describe("reading across external relations", () => {
|
|
|
159
173
|
}))
|
|
160
174
|
.group("bucket", (rows, group) => ({ x: group, y: rows.count() }))
|
|
161
175
|
.orderBy("x", "asc")
|
|
162
|
-
.slice(0, 3)
|
|
176
|
+
.slice(0, 3)
|
|
177
|
+
.run();
|
|
163
178
|
const expected = await (0, sales_1.Native)(`SELECT to_char(created_at AT TIME ZONE 'UTC' AT TIME ZONE '${PARIS}', 'YYYYMMDD') AS x, count(*) AS y
|
|
164
179
|
FROM sales.contacts GROUP BY 1 ORDER BY 1 LIMIT 3`);
|
|
165
180
|
(0, chai_1.expect)(series).to.deep.equal(expected.map((bucket) => ({ x: Number(bucket.x), y: Number(bucket.y) })));
|
|
166
181
|
});
|
|
167
182
|
it("reads an undeclared key, such as the _internal data-api plucks, as absent", async () => {
|
|
168
|
-
const row = await Accounts().get("1").pluck("_internal", "name");
|
|
183
|
+
const row = await Accounts().get("1").pluck("_internal", "name").run();
|
|
169
184
|
(0, chai_1.expect)(row).to.deep.equal({ name: "Acct 1" });
|
|
170
185
|
const total = await Accounts()
|
|
171
186
|
.filter((row) => row.key("nickname").eq("x"))
|
|
172
|
-
.count()
|
|
187
|
+
.count()
|
|
188
|
+
.run();
|
|
173
189
|
(0, chai_1.expect)(total).to.equal(0);
|
|
174
190
|
});
|
|
175
191
|
});
|
|
176
192
|
describe("the _id of relations without a single-column primary key", () => {
|
|
177
|
-
before(async ()
|
|
193
|
+
before(async function () {
|
|
194
|
+
this.timeout(sales_1.REGISTRATION_TIMEOUT_MS);
|
|
178
195
|
sales = await (0, sales_1.RegisterSales)();
|
|
179
196
|
});
|
|
180
197
|
it("answers a composite key's _id as its parts, and gets the row back by it", async () => {
|
|
@@ -182,16 +199,23 @@ describe("the _id of relations without a single-column primary key", () => {
|
|
|
182
199
|
.instance()
|
|
183
200
|
.table("order_lines")
|
|
184
201
|
.orderBy("_id")
|
|
185
|
-
.slice(0, 1)
|
|
202
|
+
.slice(0, 1)
|
|
203
|
+
.run();
|
|
186
204
|
(0, chai_1.expect)(first._id).to.equal('["0", "1"]');
|
|
187
205
|
const again = await sales
|
|
188
206
|
.instance()
|
|
189
207
|
.table("order_lines")
|
|
190
|
-
.get(String(first._id))
|
|
208
|
+
.get(String(first._id))
|
|
209
|
+
.run();
|
|
191
210
|
(0, chai_1.expect)(again).to.deep.equal(first);
|
|
192
211
|
});
|
|
193
212
|
it("answers _id from the unique index of a table without a primary key", async () => {
|
|
194
|
-
const row = await sales
|
|
213
|
+
const row = await sales
|
|
214
|
+
.instance()
|
|
215
|
+
.table("events")
|
|
216
|
+
.orderBy("at")
|
|
217
|
+
.nth(0)
|
|
218
|
+
.run();
|
|
195
219
|
if (row === null)
|
|
196
220
|
throw new Error("the relation answered no row");
|
|
197
221
|
(0, chai_1.expect)(row._id).to.equal(row.event_ref);
|
|
@@ -199,23 +223,24 @@ describe("the _id of relations without a single-column primary key", () => {
|
|
|
199
223
|
for (const relation of ["raw_log", "big_accounts", "daily_signups"]) {
|
|
200
224
|
it(`counts ${relation}, which has no key, and its rows answer no _id`, async () => {
|
|
201
225
|
const table = sales.instance().table(relation);
|
|
202
|
-
(0, chai_1.expect)(await table.count()).to.equal(await (0, sales_1.NativeCount)(`SELECT count(*) FROM sales.${relation}`));
|
|
203
|
-
const [row] = await table.slice(0, 1);
|
|
226
|
+
(0, chai_1.expect)(await table.count().run()).to.equal(await (0, sales_1.NativeCount)(`SELECT count(*) FROM sales.${relation}`));
|
|
227
|
+
const [row] = await table.slice(0, 1).run();
|
|
204
228
|
(0, chai_1.expect)(row).to.not.have.property("_id");
|
|
205
229
|
});
|
|
206
230
|
}
|
|
207
231
|
});
|
|
208
232
|
describe("instances over an external relation", () => {
|
|
209
|
-
before(async ()
|
|
233
|
+
before(async function () {
|
|
234
|
+
this.timeout(sales_1.REGISTRATION_TIMEOUT_MS);
|
|
210
235
|
sales = await (0, sales_1.RegisterSales)();
|
|
211
236
|
});
|
|
212
237
|
it("reads every row through CROSS_INSTANCE, since an external relation has no instances", async () => {
|
|
213
|
-
(0, chai_1.expect)(await sales.instance(schema_1.CROSS_INSTANCE).table("accounts").count()).to.equal(20000);
|
|
238
|
+
(0, chai_1.expect)(await sales.instance(schema_1.CROSS_INSTANCE).table("accounts").count().run()).to.equal(20000);
|
|
214
239
|
});
|
|
215
240
|
it("refuses a named instance rather than answer rows nobody scoped to it", async () => {
|
|
216
241
|
let refusal;
|
|
217
242
|
try {
|
|
218
|
-
await sales.instance("tenant-1").table("accounts").count();
|
|
243
|
+
await sales.instance("tenant-1").table("accounts").count().run();
|
|
219
244
|
}
|
|
220
245
|
catch (err) {
|
|
221
246
|
if (!(err instanceof Error))
|