@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.
Files changed (206) hide show
  1. package/README.md +5 -5
  2. package/dist/config.d.ts +1 -1
  3. package/dist/config.js +51 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/implementations/database/external-access.d.ts +22 -0
  6. package/dist/implementations/database/external-access.js +59 -0
  7. package/dist/implementations/database/external-access.js.map +1 -0
  8. package/dist/implementations/database/external-catalog.d.ts +0 -1
  9. package/dist/implementations/database/external-catalog.js +2 -3
  10. package/dist/implementations/database/external-catalog.js.map +1 -1
  11. package/dist/implementations/database/external-discovery.d.ts +1 -15
  12. package/dist/implementations/database/external-discovery.js +4 -44
  13. package/dist/implementations/database/external-discovery.js.map +1 -1
  14. package/dist/implementations/database/external-profile.d.ts +1 -1
  15. package/dist/implementations/database/external-profile.js.map +1 -1
  16. package/dist/implementations/database/external-reference.js.map +1 -1
  17. package/dist/implementations/database/external-sample.d.ts +1 -1
  18. package/dist/implementations/database/member.js.map +1 -1
  19. package/dist/implementations/database/result.js +2 -3
  20. package/dist/implementations/database/result.js.map +1 -1
  21. package/dist/implementations/database/schema.d.ts +1 -0
  22. package/dist/implementations/database/schema.js +4 -0
  23. package/dist/implementations/database/schema.js.map +1 -1
  24. package/dist/pg-connection-parameters.d.ts +17 -0
  25. package/dist/pg-connection-parameters.js +8 -0
  26. package/dist/pg-connection-parameters.js.map +1 -0
  27. package/dist/probe-parameters.d.ts +5 -0
  28. package/dist/probe-parameters.js +44 -0
  29. package/dist/probe-parameters.js.map +1 -0
  30. package/dist/probe-url.d.ts +9 -0
  31. package/dist/probe-url.js +54 -0
  32. package/dist/probe-url.js.map +1 -0
  33. package/dist/probe.d.ts +2 -0
  34. package/dist/probe.js +188 -0
  35. package/dist/probe.js.map +1 -0
  36. package/dist/test/atomic.test.js +49 -32
  37. package/dist/test/atomic.test.js.map +1 -1
  38. package/dist/test/contention.test.js +20 -16
  39. package/dist/test/contention.test.js.map +1 -1
  40. package/dist/test/convergence.test.d.ts +1 -0
  41. package/dist/test/convergence.test.js +9 -0
  42. package/dist/test/convergence.test.js.map +1 -0
  43. package/dist/test/duplicate-key.test.js +38 -18
  44. package/dist/test/duplicate-key.test.js.map +1 -1
  45. package/dist/test/indexes.test.js +14 -13
  46. package/dist/test/indexes.test.js.map +1 -1
  47. package/dist/test/nested-paths.test.js +27 -18
  48. package/dist/test/nested-paths.test.js.map +1 -1
  49. package/dist/test/typed-operations.test.js +55 -38
  50. package/dist/test/typed-operations.test.js.map +1 -1
  51. package/dist/test/unit/config-fixture.d.ts +2 -0
  52. package/dist/test/unit/config-fixture.js +11 -0
  53. package/dist/test/unit/config-fixture.js.map +1 -0
  54. package/dist/test/unit/config.spec.js +2 -32
  55. package/dist/test/unit/config.spec.js.map +1 -1
  56. package/dist/test/unit/config.untyped.spec.d.ts +1 -0
  57. package/dist/test/unit/config.untyped.spec.js +34 -0
  58. package/dist/test/unit/config.untyped.spec.js.map +1 -0
  59. package/dist/test/unit/expression-array-walk.spec.js +0 -8
  60. package/dist/test/unit/expression-array-walk.spec.js.map +1 -1
  61. package/dist/test/unit/expression-array-walk.untyped.spec.d.ts +1 -0
  62. package/dist/test/unit/expression-array-walk.untyped.spec.js +17 -0
  63. package/dist/test/unit/expression-array-walk.untyped.spec.js.map +1 -0
  64. package/dist/test/unit/expression-array.spec.js +0 -18
  65. package/dist/test/unit/expression-array.spec.js.map +1 -1
  66. package/dist/test/unit/expression-array.untyped.spec.d.ts +1 -0
  67. package/dist/test/unit/expression-array.untyped.spec.js +32 -0
  68. package/dist/test/unit/expression-array.untyped.spec.js.map +1 -0
  69. package/dist/test/unit/expression-date.spec.js +0 -21
  70. package/dist/test/unit/expression-date.spec.js.map +1 -1
  71. package/dist/test/unit/expression-date.untyped.spec.d.ts +1 -0
  72. package/dist/test/unit/expression-date.untyped.spec.js +33 -0
  73. package/dist/test/unit/expression-date.untyped.spec.js.map +1 -0
  74. package/dist/test/unit/expression-numeric.spec.js +0 -20
  75. package/dist/test/unit/expression-numeric.spec.js.map +1 -1
  76. package/dist/test/unit/expression-numeric.untyped.spec.d.ts +1 -0
  77. package/dist/test/unit/expression-numeric.untyped.spec.js +31 -0
  78. package/dist/test/unit/expression-numeric.untyped.spec.js.map +1 -0
  79. package/dist/test/unit/expression-object.spec.js +0 -12
  80. package/dist/test/unit/expression-object.spec.js.map +1 -1
  81. package/dist/test/unit/expression-object.untyped.spec.d.ts +1 -0
  82. package/dist/test/unit/expression-object.untyped.spec.js +23 -0
  83. package/dist/test/unit/expression-object.untyped.spec.js.map +1 -0
  84. package/dist/test/unit/expression-string.spec.js +0 -5
  85. package/dist/test/unit/expression-string.spec.js.map +1 -1
  86. package/dist/test/unit/expression-string.untyped.spec.d.ts +1 -0
  87. package/dist/test/unit/expression-string.untyped.spec.js +14 -0
  88. package/dist/test/unit/expression-string.untyped.spec.js.map +1 -0
  89. package/dist/test/unit/expression.spec.js +0 -16
  90. package/dist/test/unit/expression.spec.js.map +1 -1
  91. package/dist/test/unit/expression.untyped.spec.d.ts +1 -0
  92. package/dist/test/unit/expression.untyped.spec.js +29 -0
  93. package/dist/test/unit/expression.untyped.spec.js.map +1 -0
  94. package/dist/test/unit/feeds-fixture.d.ts +30 -0
  95. package/dist/test/unit/feeds-fixture.js +65 -0
  96. package/dist/test/unit/feeds-fixture.js.map +1 -0
  97. package/dist/test/unit/feeds.spec.js +80 -143
  98. package/dist/test/unit/feeds.spec.js.map +1 -1
  99. package/dist/test/unit/feeds.untyped.spec.d.ts +1 -0
  100. package/dist/test/unit/feeds.untyped.spec.js +22 -0
  101. package/dist/test/unit/feeds.untyped.spec.js.map +1 -0
  102. package/dist/test/unit/fields.spec.js +0 -5
  103. package/dist/test/unit/fields.spec.js.map +1 -1
  104. package/dist/test/unit/fields.untyped.spec.d.ts +1 -0
  105. package/dist/test/unit/fields.untyped.spec.js +12 -0
  106. package/dist/test/unit/fields.untyped.spec.js.map +1 -0
  107. package/dist/test/unit/pipeline-fold-fixture.d.ts +10 -0
  108. package/dist/test/unit/pipeline-fold-fixture.js +46 -0
  109. package/dist/test/unit/pipeline-fold-fixture.js.map +1 -0
  110. package/dist/test/unit/pipeline-group.spec.js +0 -3
  111. package/dist/test/unit/pipeline-group.spec.js.map +1 -1
  112. package/dist/test/unit/pipeline-group.untyped.spec.d.ts +1 -0
  113. package/dist/test/unit/pipeline-group.untyped.spec.js +11 -0
  114. package/dist/test/unit/pipeline-group.untyped.spec.js.map +1 -0
  115. package/dist/test/unit/pipeline-lambda-ids.untyped.spec.d.ts +1 -0
  116. package/dist/test/unit/{pipeline-lambda-ids.spec.js → pipeline-lambda-ids.untyped.spec.js} +7 -7
  117. package/dist/test/unit/pipeline-lambda-ids.untyped.spec.js.map +1 -0
  118. package/dist/test/unit/pipeline-projection.spec.js +0 -7
  119. package/dist/test/unit/pipeline-projection.spec.js.map +1 -1
  120. package/dist/test/unit/pipeline-projection.untyped.spec.d.ts +1 -0
  121. package/dist/test/unit/pipeline-projection.untyped.spec.js +16 -0
  122. package/dist/test/unit/pipeline-projection.untyped.spec.js.map +1 -0
  123. package/dist/test/unit/pipeline-selection.spec.js +0 -31
  124. package/dist/test/unit/pipeline-selection.spec.js.map +1 -1
  125. package/dist/test/unit/pipeline-selection.untyped.spec.d.ts +1 -0
  126. package/dist/test/unit/pipeline-selection.untyped.spec.js +44 -0
  127. package/dist/test/unit/pipeline-selection.untyped.spec.js.map +1 -0
  128. package/dist/test/unit/pipeline.spec.js +6 -54
  129. package/dist/test/unit/pipeline.spec.js.map +1 -1
  130. package/dist/test/unit/pipeline.untyped.spec.d.ts +1 -0
  131. package/dist/test/unit/pipeline.untyped.spec.js +21 -0
  132. package/dist/test/unit/pipeline.untyped.spec.js.map +1 -0
  133. package/dist/test/unit/probe-parameters.spec.d.ts +1 -0
  134. package/dist/test/unit/probe-parameters.spec.js +17 -0
  135. package/dist/test/unit/probe-parameters.spec.js.map +1 -0
  136. package/dist/test/unit/selection-fixture.d.ts +15 -0
  137. package/dist/test/unit/selection-fixture.js +41 -0
  138. package/dist/test/unit/selection-fixture.js.map +1 -0
  139. package/dist/test/unit/selection.spec.js +45 -83
  140. package/dist/test/unit/selection.spec.js.map +1 -1
  141. package/dist/test/unit/selection.untyped.spec.d.ts +1 -0
  142. package/dist/test/unit/selection.untyped.spec.js +19 -0
  143. package/dist/test/unit/selection.untyped.spec.js.map +1 -0
  144. package/dist/test/unit/ssl-url.spec.d.ts +1 -0
  145. package/dist/test/unit/ssl-url.spec.js +147 -0
  146. package/dist/test/unit/ssl-url.spec.js.map +1 -0
  147. package/dist/test/unit/utils.spec.js +0 -13
  148. package/dist/test/unit/utils.spec.js.map +1 -1
  149. package/dist/test/unit/utils.untyped.spec.d.ts +1 -0
  150. package/dist/test/unit/utils.untyped.spec.js +21 -0
  151. package/dist/test/unit/utils.untyped.spec.js.map +1 -0
  152. package/dist/test/unit/value.spec.js +0 -4
  153. package/dist/test/unit/value.spec.js.map +1 -1
  154. package/dist/test/unit/value.untyped.spec.d.ts +1 -0
  155. package/dist/test/unit/value.untyped.spec.js +12 -0
  156. package/dist/test/unit/value.untyped.spec.js.map +1 -0
  157. package/dist/test/unit/writes-insert.spec.js +0 -9
  158. package/dist/test/unit/writes-insert.spec.js.map +1 -1
  159. package/dist/test/unit/writes-insert.untyped.spec.d.ts +1 -0
  160. package/dist/test/unit/writes-insert.untyped.spec.js +18 -0
  161. package/dist/test/unit/writes-insert.untyped.spec.js.map +1 -0
  162. package/dist/test/unit/writes-replace.spec.js +0 -3
  163. package/dist/test/unit/writes-replace.spec.js.map +1 -1
  164. package/dist/test/unit/writes-replace.untyped.spec.d.ts +1 -0
  165. package/dist/test/unit/writes-replace.untyped.spec.js +12 -0
  166. package/dist/test/unit/writes-replace.untyped.spec.js.map +1 -0
  167. package/dist/test/unit/writes-update.spec.js +0 -6
  168. package/dist/test/unit/writes-update.spec.js.map +1 -1
  169. package/dist/test/unit/writes-update.untyped.spec.d.ts +1 -0
  170. package/dist/test/unit/writes-update.untyped.spec.js +13 -0
  171. package/dist/test/unit/writes-update.untyped.spec.js.map +1 -0
  172. package/dist/test-external/catalog.test.js +1 -4
  173. package/dist/test-external/catalog.test.js.map +1 -1
  174. package/dist/test-external/native.test.js +19 -10
  175. package/dist/test-external/native.test.js.map +1 -1
  176. package/dist/test-external/probe-access.test.js +90 -0
  177. package/dist/test-external/probe-access.test.js.map +1 -0
  178. package/dist/test-external/probe-closing.test.d.ts +1 -0
  179. package/dist/test-external/probe-closing.test.js +111 -0
  180. package/dist/test-external/probe-closing.test.js.map +1 -0
  181. package/dist/test-external/probe-fixture.d.ts +36 -0
  182. package/dist/test-external/probe-fixture.js +166 -0
  183. package/dist/test-external/probe-fixture.js.map +1 -0
  184. package/dist/test-external/probe-refusals.test.d.ts +1 -0
  185. package/dist/test-external/probe-refusals.test.js +110 -0
  186. package/dist/test-external/probe-refusals.test.js.map +1 -0
  187. package/dist/test-external/probe-url.test.d.ts +1 -0
  188. package/dist/test-external/probe-url.test.js +242 -0
  189. package/dist/test-external/probe-url.test.js.map +1 -0
  190. package/dist/test-external/reads.test.js +51 -26
  191. package/dist/test-external/reads.test.js.map +1 -1
  192. package/dist/test-external/refusals.test.js +12 -7
  193. package/dist/test-external/refusals.test.js.map +1 -1
  194. package/dist/test-external/registration.test.js +8 -0
  195. package/dist/test-external/registration.test.js.map +1 -1
  196. package/dist/test-external/relays.d.ts +27 -0
  197. package/dist/test-external/relays.js +176 -0
  198. package/dist/test-external/relays.js.map +1 -0
  199. package/dist/test-external/sales.d.ts +4 -1
  200. package/dist/test-external/sales.js +38 -1
  201. package/dist/test-external/sales.js.map +1 -1
  202. package/dist/test-external/writes.test.js +84 -48
  203. package/dist/test-external/writes.test.js.map +1 -1
  204. package/package.json +11 -9
  205. package/dist/test/unit/pipeline-lambda-ids.spec.js.map +0 -1
  206. /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":"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"}
@@ -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().get("42").pluck("signed_on", "last_seen");
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.instance().table("events").orderBy("at").nth(0);
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))