From 2ba00cf851e6d4dc69020d2cdc1cfcbe78aec007 Mon Sep 17 00:00:00 2001 From: 14f3v Date: Mon, 15 Jul 2024 16:56:58 +0700 Subject: [PATCH] first submit --- .vscode/launch.json | 14 ++ package-lock.json | 353 +++++++++++++++++++++++++++++++- package.json | 7 +- src/endpoints/postcodeList.ts | 168 +++++++++++++++ src/endpoints/taskCreate.ts | 58 ------ src/endpoints/taskDelete.ts | 56 ----- src/endpoints/taskFetch.ts | 81 -------- src/endpoints/taskList.ts | 69 ------- src/index.ts | 19 +- src/services/dbs/index.ts | 41 ++++ src/types.ts | 23 ++- src/utils/dbs/connector.ts | 26 +++ src/utils/dbs/supabase/index.ts | 2 + 13 files changed, 629 insertions(+), 288 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/endpoints/postcodeList.ts delete mode 100644 src/endpoints/taskCreate.ts delete mode 100644 src/endpoints/taskDelete.ts delete mode 100644 src/endpoints/taskFetch.ts delete mode 100644 src/endpoints/taskList.ts create mode 100644 src/services/dbs/index.ts create mode 100644 src/utils/dbs/connector.ts create mode 100644 src/utils/dbs/supabase/index.ts diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..9311275 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "command": "npm run dev", + "name": "Run npm dev", + "request": "launch", + "type": "node-terminal" + }, + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 198d9c5..0ad33af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,13 @@ "name": "cloudflare-workers-openapi", "version": "0.0.1", "dependencies": { + "@cloudflare/itty-router-openapi": "^1.1.1", + "@supabase/supabase-js": "^2.44.4", + "@types/pg": "^8.11.6", "chanfana": "^2.0.2", "hono": "^4.4.7", + "itty-router": "^5.0.17", + "pg": "^8.12.0", "zod": "^3.23.8" }, "devDependencies": { @@ -30,6 +35,34 @@ "zod": "^3.20.2" } }, + "node_modules/@cloudflare/itty-router-openapi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cloudflare/itty-router-openapi/-/itty-router-openapi-1.1.1.tgz", + "integrity": "sha512-iJKV7vIaJctMykyiNC89W+ZR3cQ5q8tQL1rVejtkXSj+/AuJYX0l7NrrM3D3u+SijbvsNsNMjFsoCGIzG7tpmQ==", + "dependencies": { + "@asteasolutions/zod-to-openapi": "^6.4.0", + "itty-router": "4.0.26", + "js-yaml": "^4.1.0", + "openapi3-ts": "^4.1.2", + "zod": "^3.21.4" + } + }, + "node_modules/@cloudflare/itty-router-openapi/node_modules/@asteasolutions/zod-to-openapi": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@asteasolutions/zod-to-openapi/-/zod-to-openapi-6.4.0.tgz", + "integrity": "sha512-8cxfF7AHHx2PqnN4Cd8/O8CBu/nVYJP9DpnfVLW3BFb66VJDnqI/CczZnkqMc3SNh6J9GiX7JbJ5T4BSP4HZ2Q==", + "dependencies": { + "openapi3-ts": "^4.1.2" + }, + "peerDependencies": { + "zod": "^3.20.2" + } + }, + "node_modules/@cloudflare/itty-router-openapi/node_modules/itty-router": { + "version": "4.0.26", + "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-4.0.26.tgz", + "integrity": "sha512-GBcmhxQRvIQ7fuzXPlvfeQcN6O7VGhctzdG9WHIcEcaRYH4FvDpMxuSWRIAxQrIM+nxtfxK0/bR78ATvb4LC5Q==" + }, "node_modules/@cloudflare/kv-asset-handler": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz", @@ -548,11 +581,77 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@supabase/auth-js": { + "version": "2.64.4", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.4.tgz", + "integrity": "sha512-9ITagy4WP4FLl+mke1rchapOH0RQpf++DI+WSG2sO1OFOZ0rW3cwAM0nCrMOxu+Zw4vJ4zObc08uvQrXx590Tg==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.1.tgz", + "integrity": "sha512-8sZ2ibwHlf+WkHDUZJUXqqmPvWQ3UHN0W30behOJngVh/qHHekhJLCFbh0AjkE9/FqqXtf9eoVvmYgfCLk5tNA==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.8.tgz", + "integrity": "sha512-YunjXpoQjQ0a0/7vGAvGZA2dlMABXFdVI/8TuVKtlePxyT71sl6ERl6ay1fmIeZcqxiuFQuZw/LXUuStUG9bbg==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.10.2.tgz", + "integrity": "sha512-qyCQaNg90HmJstsvr2aJNxK2zgoKh9ZZA8oqb7UT2LCh3mj9zpa3Iwu167AuyNxsxrUE8eEJ2yH6wLCij4EApA==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.14.2" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.6.0.tgz", + "integrity": "sha512-REAxr7myf+3utMkI2oOmZ6sdplMZZ71/2NEIEMBZHL9Fkmm3/JnaOZVSRqvG4LStYj2v5WhCruCzuMn6oD/Drw==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.44.4", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.44.4.tgz", + "integrity": "sha512-vqtUp8umqcgj+RPUc7LiEcQmgsEWFDPJdJizRJF/5tf2zSlVB+3YbUwyQE/hLagYA8TLvGXe7oAqtYyFde6llw==", + "dependencies": { + "@supabase/auth-js": "2.64.4", + "@supabase/functions-js": "2.4.1", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.15.8", + "@supabase/realtime-js": "2.10.2", + "@supabase/storage-js": "2.6.0" + } + }, "node_modules/@types/node": { "version": "20.8.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz", - "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==", - "dev": true + "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==" }, "node_modules/@types/node-forge": { "version": "1.3.11", @@ -563,12 +662,87 @@ "@types/node": "*" } }, + "node_modules/@types/pg": { + "version": "8.11.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.6.tgz", + "integrity": "sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" + } + }, + "node_modules/@types/pg/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/@types/pg/node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/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/@types/pg/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/@types/pg/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/@types/phoenix": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.5.tgz", + "integrity": "sha512-xegpDuR+z0UqG9fwHqNoy3rI7JDlvaPh2TY47Fl80oq6g+hXT+c/LEuE43X48clZ6lOfANl5WrPur9fYO1RJ/w==" + }, "node_modules/@types/service-worker-mock": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/service-worker-mock/-/service-worker-mock-2.0.4.tgz", "integrity": "sha512-MEBT2eiqYfhxjqYm/oAf2AvKLbPTPwJJAYrMdheKnGyz1yG9XBRfxCzi93h27qpSvI7jOYfXqFLVMLBXFDqo4A==", "dev": true }, + "node_modules/@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -959,6 +1133,11 @@ "node": ">=0.12.0" } }, + "node_modules/itty-router": { + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-5.0.17.tgz", + "integrity": "sha512-ZHnPI0OOyTTLuNp2FdciejYaK4Wl3ZV3O0yEm8njOGggh/k/ek3BL7X2I5YsCOfc5vLhIJgj3Z4pUtLs6k9Ucg==" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1074,6 +1253,11 @@ "node": ">=0.10.0" } }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, "node_modules/openapi3-ts": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-4.3.3.tgz", @@ -1100,6 +1284,95 @@ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, + "node_modules/pg": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz", + "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", + "dependencies": { + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", + "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.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "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.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "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==" + }, + "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/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", @@ -1112,6 +1385,46 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "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/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/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/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/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/printable-characters": { "version": "1.0.42", "resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz", @@ -1215,6 +1528,14 @@ "deprecated": "Please use @jridgewell/sourcemap-codec instead", "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/stacktracey": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz", @@ -1259,6 +1580,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -1298,6 +1624,20 @@ "ufo": "^1.5.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/workerd": { "version": "1.20240701.0", "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240701.0.tgz", @@ -1364,7 +1704,6 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -1381,6 +1720,14 @@ } } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/xxhash-wasm": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz", diff --git a/package.json b/package.json index 800c268..7b8e395 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,18 @@ "private": true, "scripts": { "deploy": "wrangler deploy", - "dev": "wrangler dev", + "dev": "wrangler dev --port 3000", "start": "wrangler dev", "cf-typegen": "wrangler types" }, "dependencies": { + "@cloudflare/itty-router-openapi": "^1.1.1", + "@supabase/supabase-js": "^2.44.4", + "@types/pg": "^8.11.6", "chanfana": "^2.0.2", "hono": "^4.4.7", + "itty-router": "^5.0.17", + "pg": "^8.12.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/src/endpoints/postcodeList.ts b/src/endpoints/postcodeList.ts new file mode 100644 index 0000000..a8e53eb --- /dev/null +++ b/src/endpoints/postcodeList.ts @@ -0,0 +1,168 @@ +import { Bool, Num, OpenAPIRoute, Str } from "chanfana"; +import { z } from "zod"; +import { PostCode, } from "../types"; +import supabaseConnect from 'utils/dbs/supabase'; +export class PostCodeLists extends OpenAPIRoute { + schema = { + tags: ["Postcodes"], + summary: "List Postcode", + request: { + query: z.object({ + page: Num({ + description: "Page number", + default: 0, + required: false, + }), + id: Num({ + description: 'Record No.', + required: false + }), + country_code: Str({ + description: 'Country Code', + required: false, + }), + country_code_name: Str({ + description: 'Country Code Name', + required: false, + }), + country_name: Str({ + description: 'Country Name', + required: false, + }), + mobile_code: Str({ + description: 'Mobile Prefix Code', + required: false, + }), + nationality_code: Str({ + description: 'Nationality Code', + required: false, + }), + country_master_id: Num({ + description: 'Country Id', + required: false, + }), + type: Str({ + description: 'State Type', + required: false, + }), + state_code: Str({ + description: 'State Code', + required: false, + }), + code_name: Str({ + description: 'State Code Name', + required: false, + }), + state_name: Str({ + description: 'State name', + required: false, + }), + state_entity_id: Str({ + description: 'Parent State Id', + required: false, + }), + }), + }, + responses: { + "200": { + description: "Returns a list of tasks", + content: { + "application/json": { + schema: z.object({ + series: z.object({ + success: Bool(), + result: z.object({ + postcodes: PostCode.array(), + }), + }), + }), + }, + }, + }, + }, + }; + + async handle(context) { + const data = await this.getValidatedData(); + const supabase = supabaseConnect(context?.env); + + // Retrieve the validated parameters + const { + page, + id, + country_code, + country_code_name, + country_name, + mobile_code, + nationality_code, + country_master_id, + type, + state_code, + code_name, + state_name, + state_entity_id, + } = data.query; + + let statement = supabase + .from("postcodes") + .select('*') + + if (id) { + statement.eq('id', id); + } + + if (country_code) { + statement.eq('country_code', country_code); + } + + if (country_code_name) { + statement.eq('country_code_name', country_code_name); + } + + if (country_name) { + statement.eq('country_name', country_name); + } + + if (mobile_code) { + statement.eq('mobile_code', mobile_code); + } + + if (nationality_code) { + statement.eq('nationality_code', nationality_code); + } + + if (country_master_id) { + statement.eq('country_master_id', country_master_id); + } + + if (type) { + statement.eq('type', type); + } + + if (state_code) { + statement.eq('state_code', state_code); + } + + if (code_name) { + statement.eq('code_name', code_name); + } + + if (state_name) { + statement.eq('state_name', state_name); + } + + if (state_entity_id) { + statement.eq('state_entity_id', state_entity_id); + } + + const { data: dataRec, error } = await statement; + + console.log({ dataRec, error }); + // Implement your own object list here + + return { + success: true, + postcodes: dataRec, + }; + } +} diff --git a/src/endpoints/taskCreate.ts b/src/endpoints/taskCreate.ts deleted file mode 100644 index 798aa82..0000000 --- a/src/endpoints/taskCreate.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Bool, OpenAPIRoute } from "chanfana"; -import { z } from "zod"; -import { Task } from "../types"; - -export class TaskCreate extends OpenAPIRoute { - schema = { - tags: ["Tasks"], - summary: "Create a new Task", - request: { - body: { - content: { - "application/json": { - schema: Task, - }, - }, - }, - }, - responses: { - "200": { - description: "Returns the created task", - content: { - "application/json": { - schema: z.object({ - series: z.object({ - success: Bool(), - result: z.object({ - task: Task, - }), - }), - }), - }, - }, - }, - }, - }; - - async handle(c) { - // Get validated data - const data = await this.getValidatedData(); - - // Retrieve the validated request body - const taskToCreate = data.body; - - // Implement your own object insertion here - - // return the new task - return { - success: true, - task: { - name: taskToCreate.name, - slug: taskToCreate.slug, - description: taskToCreate.description, - completed: taskToCreate.completed, - due_date: taskToCreate.due_date, - }, - }; - } -} diff --git a/src/endpoints/taskDelete.ts b/src/endpoints/taskDelete.ts deleted file mode 100644 index ed6f691..0000000 --- a/src/endpoints/taskDelete.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Bool, OpenAPIRoute, Str } from "chanfana"; -import { z } from "zod"; -import { Task } from "../types"; - -export class TaskDelete extends OpenAPIRoute { - schema = { - tags: ["Tasks"], - summary: "Delete a Task", - request: { - params: z.object({ - taskSlug: Str({ description: "Task slug" }), - }), - }, - responses: { - "200": { - description: "Returns if the task was deleted successfully", - content: { - "application/json": { - schema: z.object({ - series: z.object({ - success: Bool(), - result: z.object({ - task: Task, - }), - }), - }), - }, - }, - }, - }, - }; - - async handle(c) { - // Get validated data - const data = await this.getValidatedData(); - - // Retrieve the validated slug - const { taskSlug } = data.params; - - // Implement your own object deletion here - - // Return the deleted task for confirmation - return { - result: { - task: { - name: "Build something awesome with Cloudflare Workers", - slug: taskSlug, - description: "Lorem Ipsum", - completed: true, - due_date: "2022-12-24", - }, - }, - success: true, - }; - } -} diff --git a/src/endpoints/taskFetch.ts b/src/endpoints/taskFetch.ts deleted file mode 100644 index 07cf324..0000000 --- a/src/endpoints/taskFetch.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Bool, OpenAPIRoute, Str } from "chanfana"; -import { z } from "zod"; -import { Task } from "../types"; - -export class TaskFetch extends OpenAPIRoute { - schema = { - tags: ["Tasks"], - summary: "Get a single Task by slug", - request: { - params: z.object({ - taskSlug: Str({ description: "Task slug" }), - }), - }, - responses: { - "200": { - description: "Returns a single task if found", - content: { - "application/json": { - schema: z.object({ - series: z.object({ - success: Bool(), - result: z.object({ - task: Task, - }), - }), - }), - }, - }, - }, - "404": { - description: "Task not found", - content: { - "application/json": { - schema: z.object({ - series: z.object({ - success: Bool(), - error: Str(), - }), - }), - }, - }, - }, - }, - }; - - async handle(c) { - // Get validated data - const data = await this.getValidatedData(); - - // Retrieve the validated slug - const { taskSlug } = data.params; - - // Implement your own object fetch here - - const exists = true; - - // @ts-ignore: check if the object exists - if (exists === false) { - return Response.json( - { - success: false, - error: "Object not found", - }, - { - status: 404, - }, - ); - } - - return { - success: true, - task: { - name: "my task", - slug: taskSlug, - description: "this needs to be done", - completed: false, - due_date: new Date().toISOString().slice(0, 10), - }, - }; - } -} diff --git a/src/endpoints/taskList.ts b/src/endpoints/taskList.ts deleted file mode 100644 index 8f50506..0000000 --- a/src/endpoints/taskList.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Bool, Num, OpenAPIRoute } from "chanfana"; -import { z } from "zod"; -import { Task } from "../types"; - -export class TaskList extends OpenAPIRoute { - schema = { - tags: ["Tasks"], - summary: "List Tasks", - request: { - query: z.object({ - page: Num({ - description: "Page number", - default: 0, - }), - isCompleted: Bool({ - description: "Filter by completed flag", - required: false, - }), - }), - }, - responses: { - "200": { - description: "Returns a list of tasks", - content: { - "application/json": { - schema: z.object({ - series: z.object({ - success: Bool(), - result: z.object({ - tasks: Task.array(), - }), - }), - }), - }, - }, - }, - }, - }; - - async handle(c) { - // Get validated data - const data = await this.getValidatedData(); - - // Retrieve the validated parameters - const { page, isCompleted } = data.query; - - // Implement your own object list here - - return { - success: true, - tasks: [ - { - name: "Clean my room", - slug: "clean-room", - description: null, - completed: false, - due_date: "2025-01-05", - }, - { - name: "Build something awesome with Cloudflare Workers", - slug: "cloudflare-workers", - description: "Lorem Ipsum", - completed: true, - due_date: "2022-12-24", - }, - ], - }; - } -} diff --git a/src/index.ts b/src/index.ts index 46aee73..f63c9f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,6 @@ -import { fromHono } from "chanfana"; +import { fromHono, } from "chanfana"; import { Hono } from "hono"; -import { TaskCreate } from "./endpoints/taskCreate"; -import { TaskDelete } from "./endpoints/taskDelete"; -import { TaskFetch } from "./endpoints/taskFetch"; -import { TaskList } from "./endpoints/taskList"; +import { PostCodeLists } from "endpoints/postcodeList"; // Start a Hono app const app = new Hono(); @@ -13,11 +10,9 @@ const openapi = fromHono(app, { docs_url: "/", }); -// Register OpenAPI endpoints -openapi.get("/api/tasks", TaskList); -openapi.post("/api/tasks", TaskCreate); -openapi.get("/api/tasks/:taskSlug", TaskFetch); -openapi.delete("/api/tasks/:taskSlug", TaskDelete); - // Export the Hono app -export default app; +export default { + fetch: app.fetch, +} + +openapi.get("/api/postcodes", PostCodeLists); \ No newline at end of file diff --git a/src/services/dbs/index.ts b/src/services/dbs/index.ts new file mode 100644 index 0000000..b51693f --- /dev/null +++ b/src/services/dbs/index.ts @@ -0,0 +1,41 @@ +import pg from 'pg'; +import type { + ClientConfig, + Client as ClientType, +} from 'pg'; +const { Client } = pg; + +export default class DataBaseServices { + private static instance: DataBaseServices; + private config: ClientConfig = { + host: 'aws-0-ap-southeast-1.pooler.supabase.com', + database: 'postgres', + user: 'postgres.hofyowuhtxudcabxylbq', + password: 'vadky6-vaXqym-hydnir', + port: 5432, + + }; + + private _client: ClientType; + + private constructor() { + this.clientInitConnection(); + }; + + public static getInstance(): DataBaseServices { + if (!DataBaseServices.instance) { + DataBaseServices.instance = new DataBaseServices(); + } + return DataBaseServices.instance; + }; + + public async clientInitConnection(): Promise { + this._client = new Client(this.config); + await this._client.connect(); + } + + public async checkingConnection() { + const res = await this._client.query('SELECT NOW()'); + console.log(res); + } +}; \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index f91817f..67304bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,10 +1,17 @@ -import { DateTime, Str } from "chanfana"; +import { Str, Num } from "chanfana"; import { z } from "zod"; -export const Task = z.object({ - name: Str({ example: "lorem" }), - slug: Str(), - description: Str({ required: false }), - completed: z.boolean().default(false), - due_date: DateTime(), -}); +export const PostCode = z.object({ + id: Num(), + country_code: Str(), + country_code_name: Str(), + country_name: Str(), + mobile_code: Str(), + nationality_code: Str(), + country_master_id: Str(), + type: Str({ example: 'PROVINCE' }), + state_code: Str(), + code_name: Str(), + state_name: Str(), + state_entity_id: Str() +}); \ No newline at end of file diff --git a/src/utils/dbs/connector.ts b/src/utils/dbs/connector.ts new file mode 100644 index 0000000..e704589 --- /dev/null +++ b/src/utils/dbs/connector.ts @@ -0,0 +1,26 @@ +import pg from 'pg'; +import type { + Connection, + ClientConfig, + Client as ClientType, +} from 'pg'; +const { Client } = pg; +export default new Promise(async (resolve, reject) => { + try { + const config: ClientConfig = { + host: 'aws-0-ap-southeast-1.pooler.supabase.com', + database: 'postgres', + user: 'postgres.hofyowuhtxudcabxylbq', + password: 'vadky6-vaXqym-hydnir', + port: 5432, + + }; + const client = new Client(config); + await client.connect(); + resolve(client); + } + + catch (Exception) { + throw new Error(Exception); + } +}) as Promise; \ No newline at end of file diff --git a/src/utils/dbs/supabase/index.ts b/src/utils/dbs/supabase/index.ts new file mode 100644 index 0000000..8af342f --- /dev/null +++ b/src/utils/dbs/supabase/index.ts @@ -0,0 +1,2 @@ +import { createClient } from '@supabase/supabase-js'; +export default (env = {} as any) => createClient(env.SUPABASE_URL, env.SUPABASE_KEY); \ No newline at end of file