jinaga-server 3.1.0 → 3.1.2

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 (46) hide show
  1. package/README.md +2 -0
  2. package/dist/http/line-reader.d.ts +2 -0
  3. package/dist/http/line-reader.js +68 -0
  4. package/dist/http/line-reader.js.map +1 -0
  5. package/dist/http/router.d.ts +4 -1
  6. package/dist/http/router.js +122 -15
  7. package/dist/http/router.js.map +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +3 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/jinaga-server.d.ts +1 -0
  12. package/dist/jinaga-server.js +1 -1
  13. package/dist/jinaga-server.js.map +1 -1
  14. package/dist/memory/memory-keystore.js +5 -8
  15. package/dist/memory/memory-keystore.js.map +1 -1
  16. package/dist/postgres/postgres-keystore.js +5 -32
  17. package/dist/postgres/postgres-keystore.js.map +1 -1
  18. package/http/sans-auth/Feeds options.http +1 -0
  19. package/http/sans-auth/Save graph.http +6 -0
  20. package/http/sans-auth/Save json.http +13 -0
  21. package/http/with-auth/Create post with auth.http +24 -0
  22. package/http/with-auth/Define authorization rules.http +25 -0
  23. package/http/with-auth/Define distribution rules.http +30 -0
  24. package/http/with-auth/Feed sites.http +3 -0
  25. package/http/with-auth/Feeds options.http +1 -0
  26. package/http/with-auth/Feeds sites.http +32 -0
  27. package/http/with-auth/Get posts with auth.http +32 -0
  28. package/http/with-auth/Load titles.http +21 -0
  29. package/integration-test/jinaga-test/Dockerfile +1 -1
  30. package/integration-test/jinaga-test/package-lock.json +6 -5
  31. package/integration-test/jinaga-test/package.json +1 -1
  32. package/package.json +3 -5
  33. package/replicator/index.ts +0 -2
  34. package/replicator/package-lock.json +29 -75
  35. package/replicator/package.json +2 -4
  36. package/src/http/line-reader.ts +69 -0
  37. package/src/http/router.ts +152 -20
  38. package/src/index.ts +1 -0
  39. package/src/jinaga-server.ts +2 -1
  40. package/src/memory/memory-keystore.ts +7 -10
  41. package/src/postgres/postgres-keystore.ts +6 -38
  42. package/dist/http/serializer.d.ts +0 -11
  43. package/dist/http/serializer.js +0 -68
  44. package/dist/http/serializer.js.map +0 -1
  45. package/src/http/serializer.ts +0 -81
  46. package/test/http/serializerSpec.ts +0 -140
@@ -0,0 +1,13 @@
1
+ POST {{replicatorUrl}}/save
2
+ Content-Type: application/json
3
+
4
+ {
5
+ "facts": [{
6
+ "type": "Test.Root",
7
+ "hash": "sdkjbks",
8
+ "predecessors": {},
9
+ "fields": {
10
+ "identifier": "rootfact"
11
+ }
12
+ }]
13
+ }
@@ -0,0 +1,24 @@
1
+ POST {{replicatorUrl}}/write
2
+ Content-Type: text/plain
3
+ Authorization: oauth2 authorization_code
4
+
5
+ let site: Blog.Site = {
6
+ creator: me,
7
+ domain: "michaelperry.net"
8
+ }
9
+
10
+ let post: Blog.Post = {
11
+ createdAt: "2022-08-16T15:23:13.231Z",
12
+ site
13
+ }
14
+
15
+ let title: Blog.Post.Title = {
16
+ post,
17
+ value: "Introducing Jinaga Replicator",
18
+ prior: []
19
+ }
20
+ let title2: Blog.Post.Title = {
21
+ post,
22
+ value: "Introduction to the Jinaga Replicator",
23
+ prior: [ title ]
24
+ }
@@ -0,0 +1,25 @@
1
+ POST {{authorizationEndpoint}}
2
+ Content-Type: text/plain
3
+ Authorization: Bearer {{secret}}
4
+
5
+ authorization {
6
+ any Jinaga.User
7
+
8
+ (site: Blog.Site) {
9
+ creator: Jinaga.User [
10
+ creator = site->creator: Jinaga.User
11
+ ]
12
+ } => creator
13
+
14
+ (post: Blog.Post) {
15
+ creator: Jinaga.User [
16
+ creator = post->site: Blog.Site->creator: Jinaga.User
17
+ ]
18
+ } => creator
19
+
20
+ (title: Blog.Post.Title) {
21
+ creator: Jinaga.User [
22
+ creator = title->post: Blog.Post->site: Blog.Site->creator: Jinaga.User
23
+ ]
24
+ } => creator
25
+ }
@@ -0,0 +1,30 @@
1
+ POST {{distributionEndpoint}}
2
+ Content-Type: text/plain
3
+ Authorization: Bearer {{secret}}
4
+
5
+ distribution {
6
+ share (site: Blog.Site) {
7
+ post: Blog.Post [
8
+ post->site: Blog.Site = site
9
+ !E {
10
+ deleted: Blog.Post.Deleted [
11
+ deleted->post: Blog.Post = post
12
+ ]
13
+ }
14
+ ]
15
+ } => {
16
+ id = #post
17
+ createdAt = post.createdAt
18
+ titles = {
19
+ title: Blog.Post.Title [
20
+ title->post: Blog.Post = post
21
+ !E {
22
+ next: Blog.Post.Title [
23
+ next->prior: Blog.Post.Title = title
24
+ ]
25
+ }
26
+ ]
27
+ } => title.value
28
+ }
29
+ with everyone
30
+ }
@@ -0,0 +1,3 @@
1
+ GET {{replicatorUrl}}/feeds/dx2gDQc8HI5kA1zm4p32D8b4mL_UySPtTMCbIUO43E-FiCG7bqRWqOLQRIDDL6J4qLUMdJI8q0aHl0Yel9zVlQ
2
+ Authorization: oauth2 authorization_code
3
+ Accept: application/json
@@ -0,0 +1 @@
1
+ OPTIONS {{replicatorUrl}}/feeds
@@ -0,0 +1,32 @@
1
+ POST {{replicatorUrl}}/feeds
2
+ Content-Type: text/plain
3
+ Authorization: oauth2 authorization_code
4
+
5
+ let site: Blog.Site = {
6
+ creator: me,
7
+ domain: "michaelperry.net"
8
+ }
9
+
10
+ (site: Blog.Site) {
11
+ post: Blog.Post [
12
+ post->site: Blog.Site = site
13
+ !E {
14
+ deleted: Blog.Post.Deleted [
15
+ deleted->post: Blog.Post = post
16
+ ]
17
+ }
18
+ ]
19
+ } => {
20
+ id = #post
21
+ createdAt = post.createdAt
22
+ titles = {
23
+ title: Blog.Post.Title [
24
+ title->post: Blog.Post = post
25
+ !E {
26
+ next: Blog.Post.Title [
27
+ next->prior: Blog.Post.Title = title
28
+ ]
29
+ }
30
+ ]
31
+ } => title.value
32
+ }
@@ -0,0 +1,32 @@
1
+ POST {{replicatorUrl}}/read
2
+ Content-Type: text/plain
3
+ Authorization: oauth2 authorization_code
4
+
5
+ let site: Blog.Site = {
6
+ creator: me,
7
+ domain: "michaelperry.net"
8
+ }
9
+
10
+ (site: Blog.Site) {
11
+ post: Blog.Post [
12
+ post->site: Blog.Site = site
13
+ !E {
14
+ deleted: Blog.Post.Deleted [
15
+ deleted->post: Blog.Post = post
16
+ ]
17
+ }
18
+ ]
19
+ } => {
20
+ id = #post
21
+ createdAt = post.createdAt
22
+ titles = {
23
+ title: Blog.Post.Title [
24
+ title->post: Blog.Post = post
25
+ !E {
26
+ next: Blog.Post.Title [
27
+ next->prior: Blog.Post.Title = title
28
+ ]
29
+ }
30
+ ]
31
+ } => title.value
32
+ }
@@ -0,0 +1,21 @@
1
+ POST {{replicatorUrl}}/load
2
+ Authorization: oauth2 authorization_code
3
+ Content-Type: application/json
4
+ Accept: application/x-jinaga-graph-v1
5
+
6
+ {
7
+ "references": [
8
+ {
9
+ "type": "Blog.Post",
10
+ "hash": "XiDu5OWoNUwZhTBs+mwHrxjBDlFjBmDIgEt9ZXmCeMq8uv3Tv89Am6GQSt2ppl4wGG1UWMFxd9tstg5NMSSjKg=="
11
+ },
12
+ {
13
+ "type": "Blog.Post.Title",
14
+ "hash": "n+hKtiGWHVu16UlxKY73Va+jsriQ/UxVFn3DCdXQEccWeXN5/SIxhWXmuMlfzelpHjuwPgCyeyid/jJrkJRRtQ=="
15
+ },
16
+ {
17
+ "type": "Blog.Post.Title",
18
+ "hash": "iuRHB3Zkj0P3+b7XPvbEzA/ANdJ3C8Bm1dJ/nW8I9Tb+9VdHQP5g2bpp8hwS4KqzecgG6KSG6VCNOY7RoaEsIQ=="
19
+ }
20
+ ]
21
+ }
@@ -1,4 +1,4 @@
1
- FROM node:20.11.0-bullseye-slim
1
+ FROM node:20.12-bullseye-slim
2
2
 
3
3
  WORKDIR /root
4
4
 
@@ -13,7 +13,7 @@
13
13
  "express": "^4.19.2",
14
14
  "jest": "^29.7.0",
15
15
  "jest-compact-reporter": "^1.2.9",
16
- "jinaga": "^6.0.1",
16
+ "jinaga": "^6.1.2",
17
17
  "node-forge": "^1.3.0",
18
18
  "pg": "^8.11.3"
19
19
  }
@@ -2959,13 +2959,14 @@
2959
2959
  }
2960
2960
  },
2961
2961
  "node_modules/jinaga": {
2962
- "version": "6.0.1",
2963
- "resolved": "https://registry.npmjs.org/jinaga/-/jinaga-6.0.1.tgz",
2964
- "integrity": "sha512-0ViCNhYkG1FgOg7vy626xSY8N6Jk72mdXx00wolVWUN9Lx7vaYvnreTPwcrXmlbW4XIjvIVUIQjhXrjkZ2u+WA==",
2962
+ "version": "6.1.2",
2963
+ "resolved": "https://registry.npmjs.org/jinaga/-/jinaga-6.1.2.tgz",
2964
+ "integrity": "sha512-772WIhCyt56EVVsABgmLgVr7GdciqoOJTGL6L7RDws6bCdeUTAcT4st3r0ThFeGJ58dHFzPqAE3ScuHp99TXhg==",
2965
2965
  "dependencies": {
2966
2966
  "@stablelib/base64": "^1.0.1",
2967
2967
  "@stablelib/sha512": "^1.0.1",
2968
- "@stablelib/utf8": "^1.0.2"
2968
+ "@stablelib/utf8": "^1.0.2",
2969
+ "node-forge": "^1.3.1"
2969
2970
  },
2970
2971
  "engines": {
2971
2972
  "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
@@ -17,7 +17,7 @@
17
17
  "express": "^4.19.2",
18
18
  "jest": "^29.7.0",
19
19
  "jest-compact-reporter": "^1.2.9",
20
- "jinaga": "^6.0.1",
20
+ "jinaga": "^6.1.2",
21
21
  "node-forge": "^1.3.0",
22
22
  "pg": "^8.11.3"
23
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinaga-server",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "Data management for web and mobile applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,7 +35,6 @@
35
35
  "devDependencies": {
36
36
  "@types/express": "^4.17.13",
37
37
  "@types/jest": "^27.5.1",
38
- "@types/node-forge": "^0.10.10",
39
38
  "@types/passport": "^1.0.7",
40
39
  "@types/pg": "^8.6.1",
41
40
  "jest": "^28.1.0",
@@ -48,8 +47,7 @@
48
47
  },
49
48
  "dependencies": {
50
49
  "express": "^4.19.2",
51
- "jinaga": "^6.0.1",
52
- "node-forge": "^1.3.1",
53
- "pg": "^8.11.3"
50
+ "jinaga": "^6.1.2",
51
+ "pg": "^8.11.5"
54
52
  }
55
53
  }
@@ -1,4 +1,3 @@
1
- import cors = require("cors");
2
1
  import express = require("express");
3
2
  import * as http from "http";
4
3
  import { JinagaServer } from "../src";
@@ -15,7 +14,6 @@ const server = http.createServer(app);
15
14
  app.set('port', process.env.PORT || 8080);
16
15
  app.use(express.json());
17
16
  app.use(express.text());
18
- app.use(cors());
19
17
 
20
18
  const pgConnection = process.env.JINAGA_POSTGRESQL ||
21
19
  'postgresql://appuser:apppw@localhost:5432/appdb';
@@ -9,12 +9,10 @@
9
9
  "version": "1.0.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "cors": "^2.8.5",
13
- "express": "^4.18.3",
14
- "pg": "8.11.3"
12
+ "express": "^4.19.2",
13
+ "pg": "^8.11.4"
15
14
  },
16
15
  "devDependencies": {
17
- "@types/cors": "^2.8.12",
18
16
  "@types/express": "^4.17.13",
19
17
  "typescript": "^4.7.4"
20
18
  }
@@ -38,23 +36,14 @@
38
36
  "@types/node": "*"
39
37
  }
40
38
  },
41
- "node_modules/@types/cors": {
42
- "version": "2.8.13",
43
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
44
- "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
45
- "dev": true,
46
- "dependencies": {
47
- "@types/node": "*"
48
- }
49
- },
50
39
  "node_modules/@types/express": {
51
- "version": "4.17.16",
52
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.16.tgz",
53
- "integrity": "sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==",
40
+ "version": "4.17.21",
41
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
42
+ "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
54
43
  "dev": true,
55
44
  "dependencies": {
56
45
  "@types/body-parser": "*",
57
- "@types/express-serve-static-core": "^4.17.31",
46
+ "@types/express-serve-static-core": "^4.17.33",
58
47
  "@types/qs": "*",
59
48
  "@types/serve-static": "*"
60
49
  }
@@ -144,14 +133,6 @@
144
133
  "npm": "1.2.8000 || >= 1.4.16"
145
134
  }
146
135
  },
147
- "node_modules/buffer-writer": {
148
- "version": "2.0.0",
149
- "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
150
- "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
151
- "engines": {
152
- "node": ">=4"
153
- }
154
- },
155
136
  "node_modules/bytes": {
156
137
  "version": "3.1.2",
157
138
  "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -198,9 +179,9 @@
198
179
  }
199
180
  },
200
181
  "node_modules/cookie": {
201
- "version": "0.5.0",
202
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
203
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
182
+ "version": "0.6.0",
183
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
184
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
204
185
  "engines": {
205
186
  "node": ">= 0.6"
206
187
  }
@@ -210,18 +191,6 @@
210
191
  "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
211
192
  "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
212
193
  },
213
- "node_modules/cors": {
214
- "version": "2.8.5",
215
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
216
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
217
- "dependencies": {
218
- "object-assign": "^4",
219
- "vary": "^1"
220
- },
221
- "engines": {
222
- "node": ">= 0.10"
223
- }
224
- },
225
194
  "node_modules/debug": {
226
195
  "version": "2.6.9",
227
196
  "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -309,16 +278,16 @@
309
278
  }
310
279
  },
311
280
  "node_modules/express": {
312
- "version": "4.18.3",
313
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz",
314
- "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==",
281
+ "version": "4.19.2",
282
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
283
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
315
284
  "dependencies": {
316
285
  "accepts": "~1.3.8",
317
286
  "array-flatten": "1.1.1",
318
287
  "body-parser": "1.20.2",
319
288
  "content-disposition": "0.5.4",
320
289
  "content-type": "~1.0.4",
321
- "cookie": "0.5.0",
290
+ "cookie": "0.6.0",
322
291
  "cookie-signature": "1.0.6",
323
292
  "debug": "2.6.9",
324
293
  "depd": "2.0.0",
@@ -566,14 +535,6 @@
566
535
  "node": ">= 0.6"
567
536
  }
568
537
  },
569
- "node_modules/object-assign": {
570
- "version": "4.1.1",
571
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
572
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
573
- "engines": {
574
- "node": ">=0.10.0"
575
- }
576
- },
577
538
  "node_modules/object-inspect": {
578
539
  "version": "1.13.1",
579
540
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
@@ -593,11 +554,6 @@
593
554
  "node": ">= 0.8"
594
555
  }
595
556
  },
596
- "node_modules/packet-reader": {
597
- "version": "1.0.0",
598
- "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
599
- "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
600
- },
601
557
  "node_modules/parseurl": {
602
558
  "version": "1.3.3",
603
559
  "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -612,15 +568,13 @@
612
568
  "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
613
569
  },
614
570
  "node_modules/pg": {
615
- "version": "8.11.3",
616
- "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz",
617
- "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==",
618
- "dependencies": {
619
- "buffer-writer": "2.0.0",
620
- "packet-reader": "1.0.0",
621
- "pg-connection-string": "^2.6.2",
622
- "pg-pool": "^3.6.1",
623
- "pg-protocol": "^1.6.0",
571
+ "version": "8.11.4",
572
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.4.tgz",
573
+ "integrity": "sha512-pWb7JKPxGk1UFbtq7jQ0m3IfPpb7LLACCEyN8/u9DYEom+Q/BSKy+4TRl4+Hh003AOYhppB/z+QK87/hx/bk0w==",
574
+ "dependencies": {
575
+ "pg-connection-string": "^2.6.3",
576
+ "pg-pool": "^3.6.2",
577
+ "pg-protocol": "^1.6.1",
624
578
  "pg-types": "^2.1.0",
625
579
  "pgpass": "1.x"
626
580
  },
@@ -646,9 +600,9 @@
646
600
  "optional": true
647
601
  },
648
602
  "node_modules/pg-connection-string": {
649
- "version": "2.6.2",
650
- "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
651
- "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
603
+ "version": "2.6.4",
604
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
605
+ "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
652
606
  },
653
607
  "node_modules/pg-int8": {
654
608
  "version": "1.0.1",
@@ -659,17 +613,17 @@
659
613
  }
660
614
  },
661
615
  "node_modules/pg-pool": {
662
- "version": "3.6.1",
663
- "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
664
- "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==",
616
+ "version": "3.6.2",
617
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz",
618
+ "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==",
665
619
  "peerDependencies": {
666
620
  "pg": ">=8.0"
667
621
  }
668
622
  },
669
623
  "node_modules/pg-protocol": {
670
- "version": "1.6.0",
671
- "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz",
672
- "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q=="
624
+ "version": "1.6.1",
625
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz",
626
+ "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg=="
673
627
  },
674
628
  "node_modules/pg-types": {
675
629
  "version": "2.2.0",
@@ -15,12 +15,10 @@
15
15
  "author": "Michael L Perry",
16
16
  "license": "MIT",
17
17
  "dependencies": {
18
- "cors": "^2.8.5",
19
- "express": "^4.18.3",
20
- "pg": "8.11.3"
18
+ "express": "^4.19.2",
19
+ "pg": "8.11.4"
21
20
  },
22
21
  "devDependencies": {
23
- "@types/cors": "^2.8.12",
24
22
  "@types/express": "^4.17.13",
25
23
  "typescript": "^4.7.4"
26
24
  }
@@ -0,0 +1,69 @@
1
+ const PauseAt = 10;
2
+ const ResumeAt = 5;
3
+
4
+ export function createLineReader(stream: NodeJS.ReadableStream): () => Promise<string | null> {
5
+ // Store the bytes read so far that have not yet been processed.
6
+ let buffer = Buffer.alloc(0);
7
+ // Store a queue of promises that resolve to the next line read.
8
+ let promiseQueue: Promise<string | null>[] = [];
9
+ // Initialize the queue.
10
+ let resolve: (value: string | null) => void;
11
+ let reject: (reason: any) => void;
12
+ promiseQueue.push(new Promise<string | null>((res, rej) => { resolve = res; reject = rej; }));
13
+
14
+ stream.on('data', (data: Buffer) => {
15
+ let newline = -1;
16
+ // Look for the first newline in the data.
17
+ while ((newline = data.indexOf(10)) >= 0) {
18
+ // Extract the line from the data.
19
+ let line = Buffer.concat([buffer, data.slice(0, newline)]).toString();
20
+ data = data.slice(newline + 1);
21
+ buffer = Buffer.alloc(0);
22
+ if (line.charCodeAt(0) === 0xFEFF) {
23
+ // Remove BOM
24
+ line = line.slice(1);
25
+ }
26
+ // Resolve the promise with the line.
27
+ resolve(line);
28
+ // Create a new promise for the next line.
29
+ promiseQueue.push(new Promise<string | null>((res, rej) => { resolve = res; reject = rej; }));
30
+
31
+ // Apply backpressure if the promise queue gets too deep
32
+ if (promiseQueue.length > PauseAt) {
33
+ stream.pause();
34
+ }
35
+ }
36
+ // Append the remaining data to the buffer.
37
+ buffer = Buffer.concat([buffer, data]);
38
+ });
39
+
40
+ stream.on('end', () => {
41
+ // Extract the last line from the buffer.
42
+ let line = buffer.toString();
43
+ if (line.charCodeAt(0) === 0xFEFF) {
44
+ // Remove BOM
45
+ line = line.slice(1);
46
+ }
47
+ // If the stream ends with a newline, then don't add an empty line.
48
+ if (line.length > 0) {
49
+ resolve(line);
50
+ promiseQueue.push(new Promise<string | null>((res, rej) => { resolve = res; reject = rej; }));
51
+ }
52
+ resolve(null);
53
+ });
54
+
55
+ stream.on('error', (e: Error) => {
56
+ reject(e);
57
+ });
58
+
59
+ return () => {
60
+ if (promiseQueue.length === 0) {
61
+ throw new Error("Line reader has been closed.");
62
+ }
63
+ const promise = promiseQueue.shift()!;
64
+ if (stream.isPaused() && promiseQueue.length <= ResumeAt) {
65
+ stream.resume();
66
+ }
67
+ return promise;
68
+ };
69
+ }