From d829a26d1c34f070cf9b93f687c9a86bd76053b0 Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Fri, 14 Mar 2025 13:16:59 -0700 Subject: [PATCH 1/6] add postgres support --- samples/demo/package-lock.json | 537 +++++++++++++++++++++++++----- samples/demo/package.json | 5 +- samples/demo/src/db/postgres.ts | 76 +++++ samples/demo/src/db/repository.ts | 77 +++-- 4 files changed, 572 insertions(+), 123 deletions(-) create mode 100644 samples/demo/src/db/postgres.ts diff --git a/samples/demo/package-lock.json b/samples/demo/package-lock.json index f6ad8273..b900da0f 100644 --- a/samples/demo/package-lock.json +++ b/samples/demo/package-lock.json @@ -13,13 +13,16 @@ "@dapr/dapr": "^3.3.1", "@types/mongodb": "^4.0.7", "@types/morgan": "^1.9.9", + "@types/pg": "^8.11.11", + "@types/redis": "^4.0.11", "@types/uuid": "^9.0.8", "bootstrap": "^5.3.3", "dotenv": "^16.4.5", "express": "^4.21.1", "mongodb": "^6.5.0", "morgan": "^1.10.0", - "redis": "^4.6.13", + "pg": "^8.14.0", + "redis": "^4.7.0", "uuid": "^9.0.1" }, "devDependencies": { @@ -1608,6 +1611,66 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@opentelemetry/instrumentation-redis": { "version": "0.38.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.38.0.tgz", @@ -2280,9 +2343,9 @@ } }, "node_modules/@redis/client": { - "version": "1.5.14", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", - "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", + "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -2301,25 +2364,25 @@ } }, "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz", + "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz", + "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz", + "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3025,13 +3088,13 @@ } }, "node_modules/@types/pg": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", - "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "version": "8.11.11", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.11.tgz", + "integrity": "sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==", "dependencies": { "@types/node": "*", "pg-protocol": "*", - "pg-types": "^2.2.0" + "pg-types": "^4.0.1" } }, "node_modules/@types/pg-pool": { @@ -3054,6 +3117,15 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, + "node_modules/@types/redis": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.11.tgz", + "integrity": "sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==", + "deprecated": "This is a stub types definition. redis provides its own type definitions, so you do not need this installed.", + "dependencies": { + "redis": "*" + } + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -4645,6 +4717,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4749,6 +4826,43 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, + "node_modules/pg": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.0.tgz", + "integrity": "sha512-nXbVpyoaXVmdqlKEzToFf37qzyeeh7mbiXsnoWvstSqohj88yaa/I/Rq/HEVn2QPSZEuLIJa/jSpRDyzjEx4FQ==", + "dependencies": { + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.8.0", + "pg-protocol": "^1.8.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + }, "node_modules/pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", @@ -4757,12 +4871,45 @@ "node": ">=4.0.0" } }, + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg-pool": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", + "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", + "peerDependencies": { + "pg": ">=8.0" + } + }, "node_modules/pg-protocol": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", - "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", + "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==" }, "node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pg/node_modules/pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", @@ -4777,19 +4924,7 @@ "node": ">=4" } }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postgres-array": { + "node_modules/pg/node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", @@ -4797,7 +4932,7 @@ "node": ">=4" } }, - "node_modules/postgres-bytea": { + "node_modules/pg/node_modules/postgres-bytea": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", @@ -4805,7 +4940,7 @@ "node": ">=0.10.0" } }, - "node_modules/postgres-date": { + "node_modules/pg/node_modules/postgres-date": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", @@ -4813,7 +4948,7 @@ "node": ">=0.10.0" } }, - "node_modules/postgres-interval": { + "node_modules/pg/node_modules/postgres-interval": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", @@ -4824,6 +4959,66 @@ "node": ">=0.10.0" } }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postgres-array": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz", + "integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==" + }, "node_modules/protobufjs": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", @@ -4927,19 +5122,19 @@ } }, "node_modules/redis": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", - "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", + "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", "workspaces": [ "./packages/*" ], "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.14", + "@redis/client": "1.6.0", "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" + "@redis/json": "1.0.7", + "@redis/search": "1.2.0", + "@redis/time-series": "1.1.0" } }, "node_modules/regenerator-runtime": { @@ -5271,6 +5466,14 @@ "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -6946,6 +7149,53 @@ "@opentelemetry/sql-common": "^0.40.0", "@types/pg": "8.6.1", "@types/pg-pool": "2.0.4" + }, + "dependencies": { + "@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "requires": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + } } }, "@opentelemetry/instrumentation-redis": { @@ -7390,9 +7640,9 @@ "requires": {} }, "@redis/client": { - "version": "1.5.14", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", - "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", + "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", "requires": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -7406,21 +7656,21 @@ "requires": {} }, "@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz", + "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", "requires": {} }, "@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz", + "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", "requires": {} }, "@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz", + "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", "requires": {} }, "@smithy/abort-controller": { @@ -8023,13 +8273,13 @@ } }, "@types/pg": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", - "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "version": "8.11.11", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.11.tgz", + "integrity": "sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==", "requires": { "@types/node": "*", "pg-protocol": "*", - "pg-types": "^2.2.0" + "pg-types": "^4.0.1" } }, "@types/pg-pool": { @@ -8052,6 +8302,14 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, + "@types/redis": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.11.tgz", + "integrity": "sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==", + "requires": { + "redis": "*" + } + }, "@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -9211,6 +9469,11 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -9284,26 +9547,108 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, + "pg": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.0.tgz", + "integrity": "sha512-nXbVpyoaXVmdqlKEzToFf37qzyeeh7mbiXsnoWvstSqohj88yaa/I/Rq/HEVn2QPSZEuLIJa/jSpRDyzjEx4FQ==", + "requires": { + "pg-cloudflare": "^1.1.1", + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.8.0", + "pg-protocol": "^1.8.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "dependencies": { + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + } + } + }, + "pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "pg-connection-string": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + }, "pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, + "pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==" + }, + "pg-pool": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", + "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", + "requires": {} + }, "pg-protocol": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", - "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", + "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==" }, "pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", "requires": { "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "requires": { + "split2": "^4.1.0" } }, "picomatch": { @@ -9313,27 +9658,32 @@ "dev": true }, "postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz", + "integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==" }, "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "requires": { + "obuf": "~1.1.2" + } }, "postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==" }, "postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "requires": { - "xtend": "^4.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==" + }, + "postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==" }, "protobufjs": { "version": "7.2.5", @@ -9415,16 +9765,16 @@ } }, "redis": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", - "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", + "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", "requires": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.14", + "@redis/client": "1.6.0", "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" + "@redis/json": "1.0.7", + "@redis/search": "1.2.0", + "@redis/time-series": "1.1.0" } }, "regenerator-runtime": { @@ -9669,6 +10019,11 @@ "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/samples/demo/package.json b/samples/demo/package.json index 8efc4bce..c3b2d1ed 100644 --- a/samples/demo/package.json +++ b/samples/demo/package.json @@ -27,13 +27,16 @@ "@dapr/dapr": "^3.3.1", "@types/mongodb": "^4.0.7", "@types/morgan": "^1.9.9", + "@types/pg": "^8.11.11", + "@types/redis": "^4.0.11", "@types/uuid": "^9.0.8", "bootstrap": "^5.3.3", "dotenv": "^16.4.5", "express": "^4.21.1", "mongodb": "^6.5.0", "morgan": "^1.10.0", - "redis": "^4.6.13", + "pg": "^8.14.0", + "redis": "^4.7.0", "uuid": "^9.0.1" } } diff --git a/samples/demo/src/db/postgres.ts b/samples/demo/src/db/postgres.ts new file mode 100644 index 00000000..78deb8af --- /dev/null +++ b/samples/demo/src/db/postgres.ts @@ -0,0 +1,76 @@ +import { Pool } from 'pg'; +import { Repository, Item, RepositoryFactory } from './repository'; +import { v4 as uuidv4 } from 'uuid'; + +export class PostgresFactory implements RepositoryFactory { + private connectionString: string; + + constructor(connectionString: string) { + this.connectionString = connectionString; + } + + async create(): Promise { + const pool = new Pool({ + connectionString: this.connectionString, + }); + + // Ensure the table exists + await pool.query(` + CREATE TABLE IF NOT EXISTS items ( + id UUID PRIMARY KEY, + title TEXT NOT NULL, + done BOOLEAN NOT NULL + ); + `); + + return new PostgresRepository(pool); + } +} + +export class PostgresRepository implements Repository { + private pool: Pool; + + constructor(pool: Pool) { + this.pool = pool; + } + + async dispose(): Promise { + await this.pool.end(); + } + + isRealDatabase(): boolean { + return true; + } + + async get(id: string): Promise { + const result = await this.pool.query('SELECT * FROM items WHERE id = $1', [id]); + if (result.rows.length === 0) { + return null; + } + return result.rows[0]; + } + + async list(): Promise { + const result = await this.pool.query('SELECT * FROM items'); + return result.rows; + } + + async update(item: Item): Promise { + const result = await this.pool.query('UPDATE items SET title = $1, done = $2 WHERE id = $3 RETURNING *', [item.title, item.done, item.id]); + if (result.rows.length === 0) { + return null; + } + return result.rows[0]; + } + + async create(item: Item): Promise { + const id = uuidv4(); + item.id = id; + const result = await this.pool.query('INSERT INTO items (id, title, done) VALUES ($1, $2, $3) RETURNING *', [item.id, item.title, item.done]); + return result.rows[0]; + } + + async delete(id: string): Promise { + await this.pool.query('DELETE FROM items WHERE id = $1', [id]); + } +} \ No newline at end of file diff --git a/samples/demo/src/db/repository.ts b/samples/demo/src/db/repository.ts index a8edd591..9449368e 100644 --- a/samples/demo/src/db/repository.ts +++ b/samples/demo/src/db/repository.ts @@ -1,7 +1,8 @@ -import { MongoFactory } from './mongo'; +import { MongoFactory } from './mongo'; import { RedisFactory } from './redis'; import { InMemoryFactory } from './inmemory'; import { DaprFactory } from './dapr'; +import { PostgresFactory } from './postgres'; import { CommunicationProtocolEnum } from '@dapr/dapr'; export interface Item { @@ -18,51 +19,65 @@ export interface Repository { dispose(): Promise isRealDatabase(): boolean get(id: string): Promise - list() : Promise - update(item: Item) : Promise + list(): Promise + update(item: Item): Promise create(item: Item): Promise delete(id: string): Promise } export function createFactory(): RepositoryFactory { if (process.env.CONNECTION_STATESTORE_COMPONENTNAME) { - console.log(`Using Dapr state store: found component name '${process.env.CONNECTION_STATESTORE_COMPONENTNAME}'in environment variable CONNECTION_STATESTORE_COMPONENTNAME`); - return new DaprFactory(process.env.CONNECTION_STATESTORE_COMPONENTNAME, { communicationProtocol: CommunicationProtocolEnum.GRPC }); + console.log(`Using Dapr state store: found component name '${process.env.CONNECTION_STATESTORE_COMPONENTNAME}' in environment variable CONNECTION_STATESTORE_COMPONENTNAME`); + return new DaprFactory(process.env.CONNECTION_STATESTORE_COMPONENTNAME, { communicationProtocol: CommunicationProtocolEnum.GRPC }); } if (process.env.CONNECTION_MONGODB_CONNECTIONSTRING) { - console.log("Using MongoDB: found connection string in environment variable CONNECTION_MONGODB_CONNECTIONSTRING"); - return new MongoFactory(process.env.CONNECTION_MONGODB_CONNECTIONSTRING); + console.log("Using MongoDB: found connection string in environment variable CONNECTION_MONGODB_CONNECTIONSTRING"); + return new MongoFactory(process.env.CONNECTION_MONGODB_CONNECTIONSTRING); } if (process.env.CONNECTION_REDIS_URL) { - console.log("Using Redis: found url in environment variable CONNECTION_REDIS_URL"); - return new RedisFactory(process.env.CONNECTION_REDIS_URL); + console.log("Using Redis: found url in environment variable CONNECTION_REDIS_URL"); + return new RedisFactory(process.env.CONNECTION_REDIS_URL); } if (process.env.CONNECTION_REDIS_HOST) { - console.log("Using Redis: found hostname in environment variable CONNECTION_REDIS_HOST"); - const connection = { - host: process.env.CONNECTION_REDIS_HOST!, - port: process.env.CONNECTION_REDIS_PORT!, - username: process.env.CONNECTION_REDIS_USERNAME || '', - password: process.env.CONNECTION_REDIS_PASSWORD || '', - } - - let scheme = "redis" - if (connection.port === "6380") { - scheme = "rediss" - } - - let usernamePass = ""; - if (connection.username !== "" || connection.password !== "") { - usernamePass = `${connection.username}:${connection.password}@` - } - - const url = `${scheme}://${usernamePass}${connection.host}:${connection.port}` - return new RedisFactory(url); + console.log("Using Redis: found hostname in environment variable CONNECTION_REDIS_HOST"); + const connection = { + host: process.env.CONNECTION_REDIS_HOST!, + port: process.env.CONNECTION_REDIS_PORT!, + username: process.env.CONNECTION_REDIS_USERNAME || '', + password: process.env.CONNECTION_REDIS_PASSWORD || '', + } + + let scheme = "redis" + if (connection.port === "6380") { + scheme = "rediss" + } + + let usernamePass = ""; + if (connection.username !== "" || connection.password !== "") { + usernamePass = `${connection.username}:${connection.password}@` + } + + const url = `${scheme}://${usernamePass}${connection.host}:${connection.port}` + return new RedisFactory(url); } - + + if (process.env.CONNECTION_POSTGRES_HOST) { + console.log("Using PostgreSQL: found hostname in environment variable CONNECTION_POSTGRES_HOST"); + const connection = { + host: process.env.CONNECTION_POSTGRES_HOST!, + port: process.env.CONNECTION_POSTGRES_PORT!, + username: process.env.CONNECTION_POSTGRES_USERNAME || '', + password: process.env.CONNECTION_POSTGRES_PASSWORD || '', + database: process.env.CONNECTION_POSTGRES_DATABASE || '', + } + const url = `postgresql://${connection.username}:${connection.password}@${connection.host}:${connection.port}/${connection.database}` + console.log(`Postgres URL: ${url}`); + return new PostgresFactory(url); + } + console.log("Using in-memory store: no connection string found"); return new InMemoryFactory(); - } \ No newline at end of file +} \ No newline at end of file From c5c425971524df18ff75f21e2b6083364e9fcd74 Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Tue, 1 Apr 2025 08:55:28 -0700 Subject: [PATCH 2/6] remove debug prints --- samples/demo/src/db/repository.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/demo/src/db/repository.ts b/samples/demo/src/db/repository.ts index 9449368e..e4e204bf 100644 --- a/samples/demo/src/db/repository.ts +++ b/samples/demo/src/db/repository.ts @@ -74,7 +74,6 @@ export function createFactory(): RepositoryFactory { database: process.env.CONNECTION_POSTGRES_DATABASE || '', } const url = `postgresql://${connection.username}:${connection.password}@${connection.host}:${connection.port}/${connection.database}` - console.log(`Postgres URL: ${url}`); return new PostgresFactory(url); } From 19e4274a2516b335f2759701267ffd5888a11e09 Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Tue, 1 Apr 2025 10:00:29 -0700 Subject: [PATCH 3/6] update tests --- playwright/tests/demo/demo.app.spec.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/playwright/tests/demo/demo.app.spec.ts b/playwright/tests/demo/demo.app.spec.ts index b9819b44..a3b3e86a 100644 --- a/playwright/tests/demo/demo.app.spec.ts +++ b/playwright/tests/demo/demo.app.spec.ts @@ -44,18 +44,23 @@ test("To-Do App Basic UI Checks", async ({ page }) => { // Make sure important environment variables are visible await expect( page - .getByRole("cell", { name: "CONNECTION_REDIS_CONNECTIONSTRING" }) - .getByText("CONNECTION_REDIS_CONNECTIONSTRING") + .getByRole("cell", { name: "CONNECTION_POSTGRES_HOST" }) + .getByText("CONNECTION_POSTGRES_HOST") ).toBeVisible(); await expect( page - .getByRole("cell", { name: "CONNECTION_REDIS_HOST" }) - .getByText("CONNECTION_REDIS_HOST") + .getByRole("cell", { name: "CONNECTION_POSTGRES_PORT" }) + .getByText("CONNECTION_POSTGRES_PORT") ).toBeVisible(); await expect( page - .getByRole("cell", { name: "CONNECTION_REDIS_PORT" }) - .getByText("CONNECTION_REDIS_PORT") + .getByRole("cell", { name: "CONNECTION_POSTGRES_USERNAME" }) + .getByText("CONNECTION_POSTGRES_USERNAME") + ).toBeVisible(); + await expect( + page + .getByRole("cell", { name: "CONNECTION_POSTGRES_DATABASE" }) + .getByText("CONNECTION_POSTGRES_DATABASE") ).toBeVisible(); }); From 1623b6c6c969849c1dc4a3dd5b5f0488fc3e0392 Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Tue, 1 Apr 2025 11:24:02 -0700 Subject: [PATCH 4/6] add postgres info for deployment --- samples/demo/Chart/templates/app.yaml | 14 +++++++++++--- samples/demo/Chart/values.yaml | 9 ++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/samples/demo/Chart/templates/app.yaml b/samples/demo/Chart/templates/app.yaml index c9c62e11..5d9dc7c8 100644 --- a/samples/demo/Chart/templates/app.yaml +++ b/samples/demo/Chart/templates/app.yaml @@ -16,10 +16,18 @@ spec: - name: webapp image: {{ .Values.image.repository }}:{{ .Values.image.tag }} env: - - name: CONNECTION_REDIS_URL + - name: CONNECTION_POSTGRES_HOST + value: {{ .Values.datastore.postgres.host }} + - name: CONNECTION_POSTGRES_PORT + value: {{ .Values.datastore.postgres.port }} + - name: CONNECTION_POSTGRES_USER + value: {{ .Values.datastore.postgres.username }} + - name: CONNECTION_POSTGRES_DB + value: {{ .Values.datastore.postgres.database }} + - name: CONNECTION_POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: redis-secret - key: url + name: postgres-secret + key: password ports: - containerPort: 3000 \ No newline at end of file diff --git a/samples/demo/Chart/values.yaml b/samples/demo/Chart/values.yaml index ac86339d..0f161c36 100644 --- a/samples/demo/Chart/values.yaml +++ b/samples/demo/Chart/values.yaml @@ -1,4 +1,11 @@ image: repository: ghcr.io/radius-project/samples/demo tag: latest -environment: default \ No newline at end of file +environment: default +datastore: + postgres: + host: postgres + port: 5432 + username: postgres + database: demo + \ No newline at end of file From 04bce798759c7b51e6bcd4075884232291b29bbe Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Tue, 1 Apr 2025 11:59:07 -0700 Subject: [PATCH 5/6] Revert "add postgres info for deployment" This reverts commit 1623b6c6c969849c1dc4a3dd5b5f0488fc3e0392. --- samples/demo/Chart/templates/app.yaml | 14 +++----------- samples/demo/Chart/values.yaml | 9 +-------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/samples/demo/Chart/templates/app.yaml b/samples/demo/Chart/templates/app.yaml index 5d9dc7c8..c9c62e11 100644 --- a/samples/demo/Chart/templates/app.yaml +++ b/samples/demo/Chart/templates/app.yaml @@ -16,18 +16,10 @@ spec: - name: webapp image: {{ .Values.image.repository }}:{{ .Values.image.tag }} env: - - name: CONNECTION_POSTGRES_HOST - value: {{ .Values.datastore.postgres.host }} - - name: CONNECTION_POSTGRES_PORT - value: {{ .Values.datastore.postgres.port }} - - name: CONNECTION_POSTGRES_USER - value: {{ .Values.datastore.postgres.username }} - - name: CONNECTION_POSTGRES_DB - value: {{ .Values.datastore.postgres.database }} - - name: CONNECTION_POSTGRES_PASSWORD + - name: CONNECTION_REDIS_URL valueFrom: secretKeyRef: - name: postgres-secret - key: password + name: redis-secret + key: url ports: - containerPort: 3000 \ No newline at end of file diff --git a/samples/demo/Chart/values.yaml b/samples/demo/Chart/values.yaml index 0f161c36..ac86339d 100644 --- a/samples/demo/Chart/values.yaml +++ b/samples/demo/Chart/values.yaml @@ -1,11 +1,4 @@ image: repository: ghcr.io/radius-project/samples/demo tag: latest -environment: default -datastore: - postgres: - host: postgres - port: 5432 - username: postgres - database: demo - \ No newline at end of file +environment: default \ No newline at end of file From e604ae966d5239ef78eb425d0f46f7374cdb8989 Mon Sep 17 00:00:00 2001 From: nithyatsu Date: Tue, 1 Apr 2025 11:59:30 -0700 Subject: [PATCH 6/6] Revert "update tests" This reverts commit 19e4274a2516b335f2759701267ffd5888a11e09. --- playwright/tests/demo/demo.app.spec.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/playwright/tests/demo/demo.app.spec.ts b/playwright/tests/demo/demo.app.spec.ts index a3b3e86a..b9819b44 100644 --- a/playwright/tests/demo/demo.app.spec.ts +++ b/playwright/tests/demo/demo.app.spec.ts @@ -44,23 +44,18 @@ test("To-Do App Basic UI Checks", async ({ page }) => { // Make sure important environment variables are visible await expect( page - .getByRole("cell", { name: "CONNECTION_POSTGRES_HOST" }) - .getByText("CONNECTION_POSTGRES_HOST") + .getByRole("cell", { name: "CONNECTION_REDIS_CONNECTIONSTRING" }) + .getByText("CONNECTION_REDIS_CONNECTIONSTRING") ).toBeVisible(); await expect( page - .getByRole("cell", { name: "CONNECTION_POSTGRES_PORT" }) - .getByText("CONNECTION_POSTGRES_PORT") + .getByRole("cell", { name: "CONNECTION_REDIS_HOST" }) + .getByText("CONNECTION_REDIS_HOST") ).toBeVisible(); await expect( page - .getByRole("cell", { name: "CONNECTION_POSTGRES_USERNAME" }) - .getByText("CONNECTION_POSTGRES_USERNAME") - ).toBeVisible(); - await expect( - page - .getByRole("cell", { name: "CONNECTION_POSTGRES_DATABASE" }) - .getByText("CONNECTION_POSTGRES_DATABASE") + .getByRole("cell", { name: "CONNECTION_REDIS_PORT" }) + .getByText("CONNECTION_REDIS_PORT") ).toBeVisible(); });