From 7b71c74147e8e84c451f4a69b52e865e26e0a499 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 14:37:38 +0900 Subject: [PATCH 01/13] =?UTF-8?q?=E2=9C=A8=20feat(module=20openapi-scrappe?= =?UTF-8?q?r=20=EC=B6=94=EA=B0=80):=20module=EB=A1=9C=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 3 ++- .../src/openapi-scraper/openapi-scraper.controller.ts | 4 ++++ .../src/openapi-scraper/openapi-scraper.module.ts | 9 +++++++++ packages/backend/src/openapi-scraper/openapi-scraper.ts | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.controller.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.module.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 86628031..8cf93bee 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; @Module({ - imports: [], + imports: [OpenapiScraperModule], controllers: [AppController], providers: [AppService], }) diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts new file mode 100644 index 00000000..56e60188 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('openapi-scraper') +export class OpenapiScraperController {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts new file mode 100644 index 00000000..ea4f791f --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { OpenapiScraperController } from './openapi-scraper.controller'; +import { OpenapiScraper } from './openapi-scraper'; + +@Module({ + controllers: [OpenapiScraperController], + providers: [OpenapiScraper] +}) +export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.ts b/packages/backend/src/openapi-scraper/openapi-scraper.ts new file mode 100644 index 00000000..621c0988 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class OpenapiScraper {} From afb4f6ca5c40b7478dddd1f046d2777f9f2209e7 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 15:57:34 +0900 Subject: [PATCH 02/13] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20nestjs=20typeorm?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 5 +- yarn.lock | 227 ++++++++++++++++++++++++++++++++-- 2 files changed, 223 insertions(+), 9 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index bdd11622..662fc33e 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -23,8 +23,11 @@ "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "@nestjs/typeorm": "^10.0.2", + "mysql2": "^3.11.4", "reflect-metadata": "^0.2.0", - "rxjs": "^7.8.1" + "rxjs": "^7.8.1", + "typeorm": "^0.3.20" }, "devDependencies": { "@nestjs/cli": "^10.0.0", diff --git a/yarn.lock b/yarn.lock index aee7506c..a71fb545 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1107,6 +1107,13 @@ dependencies: tslib "2.7.0" +"@nestjs/typeorm@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@nestjs/typeorm/-/typeorm-10.0.2.tgz#25e3ec3c9a127b085c06fd7ea25f8690dba145c2" + integrity sha512-H738bJyydK4SQkRCTeh1aFBxoO1E9xdL/HaLGThwrqN95os5mEyAtK7BLADOS+vldP4jDZ2VQPLj4epWwRqCeQ== + dependencies: + uuid "9.0.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1261,6 +1268,11 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@sqltools/formatter@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" + integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== + "@tanstack/query-core@5.59.17": version "5.59.17" resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.59.17.tgz#bda3bb678be48e2f6ee692abd1cfc2db3d455e4b" @@ -1915,6 +1927,11 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +app-root-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86" + integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== + append-field@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" @@ -2062,6 +2079,11 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +aws-ssl-profiles@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz#157dd77e9f19b1d123678e93f120e6f193022641" + integrity sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g== + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2226,6 +2248,14 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + busboy@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -2355,6 +2385,18 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" +cli-highlight@^2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" + integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== + dependencies: + chalk "^4.0.0" + highlight.js "^10.7.1" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^6.0.0" + yargs "^16.0.0" + cli-spinners@^2.5.0: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" @@ -2384,6 +2426,15 @@ cli-width@^4.1.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -2709,6 +2760,11 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" +dayjs@^1.11.9: + version "1.11.13" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== + debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2780,6 +2836,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -2854,6 +2915,11 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv@^16.0.3: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -3717,6 +3783,13 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +generate-function@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -3951,6 +4024,11 @@ hexoid@^2.0.0: resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-2.0.0.tgz#fb36c740ebbf364403fa1ec0c7efd268460ec5b9" integrity sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw== +highlight.js@^10.7.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -3991,7 +4069,14 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.13: +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -4035,7 +4120,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4266,6 +4351,11 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -5020,6 +5110,11 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +long@^5.2.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + longest@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-2.0.1.tgz#781e183296aa94f6d4d916dc335d0d17aefa23f8" @@ -5044,6 +5139,16 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru.min@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.1.tgz#146e01e3a183fa7ba51049175de04667d5701f0e" + integrity sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q== + magic-string@0.30.8: version "0.30.8" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" @@ -5195,6 +5300,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.4: dependencies: minimist "^1.2.6" +mkdirp@^2.1.3: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5233,7 +5343,22 @@ mute-stream@1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -mz@^2.7.0: +mysql2@^3.11.4: + version "3.11.4" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.11.4.tgz#08658b6285adbace7d43b2eaa18efddb85f99501" + integrity sha512-Z2o3tY4Z8EvSRDwknaC40MdZ3+m0sKbpnXrShQLdxPrAvcNli7jLrD2Zd2IzsRMw4eK9Yle500FDmlkIqp+krg== + dependencies: + aws-ssl-profiles "^1.1.1" + denque "^2.1.0" + generate-function "^2.3.1" + iconv-lite "^0.6.3" + long "^5.2.1" + lru.min "^1.0.0" + named-placeholders "^1.1.3" + seq-queue "^0.0.5" + sqlstring "^2.3.2" + +mz@^2.4.0, mz@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== @@ -5242,6 +5367,13 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" +named-placeholders@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" + integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w== + dependencies: + lru-cache "^7.14.1" + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -5505,6 +5637,23 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -5805,7 +5954,7 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reflect-metadata@^0.2.0: +reflect-metadata@^0.2.0, reflect-metadata@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== @@ -5977,7 +6126,7 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5996,7 +6145,7 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -6046,6 +6195,11 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" +seq-queue@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" + integrity sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q== + serialize-javascript@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" @@ -6090,6 +6244,14 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -6173,6 +6335,11 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sqlstring@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" + integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -6637,7 +6804,7 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.6.2: +tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.2: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -6721,6 +6888,27 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== +typeorm@^0.3.20: + version "0.3.20" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.20.tgz#4b61d737c6fed4e9f63006f88d58a5e54816b7ab" + integrity sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q== + dependencies: + "@sqltools/formatter" "^1.2.5" + app-root-path "^3.1.0" + buffer "^6.0.3" + chalk "^4.1.2" + cli-highlight "^2.1.11" + dayjs "^1.11.9" + debug "^4.3.4" + dotenv "^16.0.3" + glob "^10.3.10" + mkdirp "^2.1.3" + reflect-metadata "^0.2.1" + sha.js "^2.4.11" + tslib "^2.5.0" + uuid "^9.0.0" + yargs "^17.6.2" + typescript-eslint@^8.11.0: version "8.12.2" resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.12.2.tgz#e273d69af30b478b1c410f4159d675ce7925f9a7" @@ -6809,6 +6997,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@9.0.1, uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -7028,7 +7221,25 @@ yargs-parser@21.1.1, yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.0.0, yargs@^17.3.1: +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.0.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.0.0, yargs@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 9ed421dcaa278a13329a5515a53e909851080b50 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 16:40:55 +0900 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20dotenv=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 1 + yarn.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 662fc33e..d31e4a62 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -24,6 +24,7 @@ "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.2", + "dotenv": "^16.4.5", "mysql2": "^3.11.4", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", diff --git a/yarn.lock b/yarn.lock index a71fb545..342924eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2915,7 +2915,7 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dotenv@^16.0.3: +dotenv@^16.0.3, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== From 8bbab9caba435539758d3ea4c57fe1539c31736b Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 16:44:49 +0900 Subject: [PATCH 04/13] =?UTF-8?q?=E2=9C=A8=20feat:=20typeorm=20mysql=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 86628031..441df278 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,9 +1,24 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import * as dotenv from 'dotenv'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +dotenv.config(); + @Module({ - imports: [], + imports: [ + TypeOrmModule.forRoot({ + type: 'mysql', + host: process.env.DB_HOST, + port: Number(process.env.DB_PORT), + username: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME, + entities: [__dirname + '/**/*.entity.{js,ts}'], + logging: true, + }), + ], controllers: [AppController], providers: [AppService], }) From 55b208d22d586beaba8ee8daec8ef65f5ac7048c Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 16:54:20 +0900 Subject: [PATCH 05/13] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20typeorm?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=ED=8C=8C=EC=9D=BC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 17 ++--------------- packages/backend/src/configs/typeorm.config.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 packages/backend/src/configs/typeorm.config.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 441df278..327ab3fa 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,24 +1,11 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import * as dotenv from 'dotenv'; import { AppController } from './app.controller'; import { AppService } from './app.service'; - -dotenv.config(); +import { typeormConfig } from '@/configs/typeorm.config'; @Module({ - imports: [ - TypeOrmModule.forRoot({ - type: 'mysql', - host: process.env.DB_HOST, - port: Number(process.env.DB_PORT), - username: process.env.DB_USER, - password: process.env.DB_PASS, - database: process.env.DB_NAME, - entities: [__dirname + '/**/*.entity.{js,ts}'], - logging: true, - }), - ], + imports: [TypeOrmModule.forRoot(typeormConfig)], controllers: [AppController], providers: [AppService], }) diff --git a/packages/backend/src/configs/typeorm.config.ts b/packages/backend/src/configs/typeorm.config.ts new file mode 100644 index 00000000..9d504e5b --- /dev/null +++ b/packages/backend/src/configs/typeorm.config.ts @@ -0,0 +1,15 @@ +import { TypeOrmModuleOptions } from '@nestjs/typeorm'; +import * as dotenv from 'dotenv'; + +dotenv.config(); + +export const typeormConfig: TypeOrmModuleOptions = { + type: 'mysql', + host: process.env.DB_HOST, + port: Number(process.env.DB_PORT), + username: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME, + entities: [__dirname + '/../**/*.entity.{js,ts}'], + logging: true, +}; From 0daf7a9311c3bf2da89f5ecbc178ecbd14bcd800 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:04:46 +0900 Subject: [PATCH 06/13] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20backend=20packege?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/openapi-scraper/env.service.ts | 23 +++++++++++++++++++ .../openapi-scraper.controller.ts | 4 ---- .../openapi-scraper/openapi-scraper.module.ts | 16 +++++++++---- .../openapi-scraper.service.ts | 12 ++++++++++ .../src/openapi-scraper/openapi-scraper.ts | 4 ---- 5 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 packages/backend/src/openapi-scraper/env.service.ts delete mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.controller.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.service.ts delete mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.ts diff --git a/packages/backend/src/openapi-scraper/env.service.ts b/packages/backend/src/openapi-scraper/env.service.ts new file mode 100644 index 00000000..d6f22a46 --- /dev/null +++ b/packages/backend/src/openapi-scraper/env.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; + +@Injectable() +export class EnvService { + public constructor(private configService: ConfigService) {} + + private getKeyValue(key: string): { key: string; value: string } { + return { key: key, value: this.configService.get(key) }; + } + + public getOpenApiUrl() { + return this.getKeyValue("PROD"); + } + + public getAppKey() { + return this.getKeyValue("PROD_APPKEY"); + } + + public getAppSecret() { + return this.getKeyValue("PROD_APPSECRET"); + } +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts deleted file mode 100644 index 56e60188..00000000 --- a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Controller } from '@nestjs/common'; - -@Controller('openapi-scraper') -export class OpenapiScraperController {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts index ea4f791f..d8c45d28 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -1,9 +1,15 @@ -import { Module } from '@nestjs/common'; -import { OpenapiScraperController } from './openapi-scraper.controller'; -import { OpenapiScraper } from './openapi-scraper'; +import { Module } from "@nestjs/common"; +import { ConfigModule } from "@nestjs/config"; +import { OpenapiScraperService } from "./openapi-scraper.service"; +import { EnvService } from "./env.service"; @Module({ - controllers: [OpenapiScraperController], - providers: [OpenapiScraper] + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + }), + ], + controllers: [], + providers: [OpenapiScraperService, EnvService], }) export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts new file mode 100644 index 00000000..69c366f0 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { EnvService } from "./env.service"; + +@Injectable() +export class OpenapiScraperService { + private token: string; + public constructor(private env: EnvService) {} + + private async fetchOpenApiSpec(url: string): Promise {} + + private getToken() {} +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.ts b/packages/backend/src/openapi-scraper/openapi-scraper.ts deleted file mode 100644 index 621c0988..00000000 --- a/packages/backend/src/openapi-scraper/openapi-scraper.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class OpenapiScraper {} From 8550f8cb240555b45841a9dcdc4160981520281d Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:06:00 +0900 Subject: [PATCH 07/13] =?UTF-8?q?=E2=9C=A8=20feat:=20backend/stock-price?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 3 +++ packages/backend/src/app.controller.spec.ts | 22 ------------------- packages/backend/src/app.controller.ts | 16 -------------- packages/backend/src/app.module.ts | 9 ++++---- packages/backend/src/app.service.ts | 8 ------- .../src/stock-price/stock-price.module.ts | 4 ++++ 6 files changed, 11 insertions(+), 51 deletions(-) delete mode 100644 packages/backend/src/app.controller.spec.ts delete mode 100644 packages/backend/src/app.controller.ts delete mode 100644 packages/backend/src/app.service.ts create mode 100644 packages/backend/src/stock-price/stock-price.module.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index bdd11622..338862d4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -21,8 +21,10 @@ }, "dependencies": { "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "dotenv": "^16.4.5", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, @@ -36,6 +38,7 @@ "@types/supertest": "^6.0.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", + "cz-emoji-conventional": "^1.1.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", diff --git a/packages/backend/src/app.controller.spec.ts b/packages/backend/src/app.controller.spec.ts deleted file mode 100644 index d22f3890..00000000 --- a/packages/backend/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/packages/backend/src/app.controller.ts b/packages/backend/src/app.controller.ts deleted file mode 100644 index d87f0844..00000000 --- a/packages/backend/src/app.controller.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Controller, Get } from "@nestjs/common"; -import { AppService } from "./app.service"; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } - - getHi(a: any): string { - return "hi"; - } -} diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 8cf93bee..38fa4dea 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,11 +1,10 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; +import { StockPriceModule } from './stock-price/stock-price.module'; import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; @Module({ - imports: [OpenapiScraperModule], - controllers: [AppController], - providers: [AppService], + imports: [OpenapiScraperModule, StockPriceModule], + controllers: [], + providers: [], }) export class AppModule {} diff --git a/packages/backend/src/app.service.ts b/packages/backend/src/app.service.ts deleted file mode 100644 index 927d7cca..00000000 --- a/packages/backend/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/packages/backend/src/stock-price/stock-price.module.ts b/packages/backend/src/stock-price/stock-price.module.ts new file mode 100644 index 00000000..c6df3a29 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class StockPriceModule {} From 4a3a04ddbc8525b439e3503158f95e6892c54847 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:06:33 +0900 Subject: [PATCH 08/13] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20yarn.lock=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yarn.lock | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 27daad31..42756536 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1066,6 +1066,15 @@ iterare "1.2.1" tslib "2.7.0" +"@nestjs/config@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-3.3.0.tgz#ddc520ba26a8453ee5e690e18fb7b35e9bac7974" + integrity sha512-pdGTp8m9d0ZCrjTpjkUbZx6gyf2IKf+7zlkrPNMsJzYZ4bFRRTpXrnj+556/5uiI6AfL5mMrJc2u7dB6bvM+VA== + dependencies: + dotenv "16.4.5" + dotenv-expand "10.0.0" + lodash "4.17.21" + "@nestjs/core@^10.0.0": version "10.4.6" resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-10.4.6.tgz#797b381f12bd62d2e425897058fa219da4c3689d" @@ -2377,7 +2386,7 @@ comment-json@4.2.5: has-own-prop "^2.0.0" repeat-string "^1.6.1" -commitizen@^4.0.3, commitizen@^4.3.1: +commitizen@^4.0.3, commitizen@^4.3.0, commitizen@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.3.1.tgz#f0e0e4b7ae3fafc92e444bbb78f2ded5a1d4311a" integrity sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw== @@ -2594,6 +2603,15 @@ cz-customizable@^7.2.1: temp "^0.9.0" word-wrap "^1.2.3" +cz-emoji-conventional@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cz-emoji-conventional/-/cz-emoji-conventional-1.1.0.tgz#c42c34828619a5c2c7337afd4798c7da4366c753" + integrity sha512-W0EHK/Ek9ZHwJ+UaClF/xBHp6lkLuJgkiREiCVnwGuIz8Jhp/khoQzLcRI9AAF6vfT2slfz7E+RgGelmsVfzoQ== + dependencies: + chalk "4.1.2" + commitizen "^4.3.0" + word-wrap "^1.2.3" + dargs@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-8.1.0.tgz#a34859ea509cbce45485e5aa356fef70bfcc7272" @@ -2721,6 +2739,16 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv-expand@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + +dotenv@16.4.5, dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" From a789549694a826d51ecaa10f1460c087b75424f4 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 22:15:33 +0900 Subject: [PATCH 09/13] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/src/stock/domain/stock.entity.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 packages/backend/src/stock/domain/stock.entity.ts diff --git a/packages/backend/src/stock/domain/stock.entity.ts b/packages/backend/src/stock/domain/stock.entity.ts new file mode 100644 index 00000000..ee3748d1 --- /dev/null +++ b/packages/backend/src/stock/domain/stock.entity.ts @@ -0,0 +1,17 @@ +import { Column, Entity, PrimaryColumn } from 'typeorm'; + +@Entity() +export class Stock { + @PrimaryColumn({ name: 'stock_id' }) + id: string; + @Column({ name: 'stock_name' }) + name: string; + @Column() + views: number; + + constructor(id: string, name: string, views?: number) { + this.id = id; + this.name = name; + this.views = views ?? 0; + } +} From 57f897a35eaac235bfabecf2c0b53393896bae8f Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 22:44:32 +0900 Subject: [PATCH 10/13] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EC=A6=9D=EA=B0=80=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/src/stock/stock.service.spec.ts | 37 +++++++++++++++++++ packages/backend/src/stock/stock.service.ts | 18 +++++++++ 2 files changed, 55 insertions(+) create mode 100644 packages/backend/src/stock/stock.service.spec.ts create mode 100644 packages/backend/src/stock/stock.service.ts diff --git a/packages/backend/src/stock/stock.service.spec.ts b/packages/backend/src/stock/stock.service.spec.ts new file mode 100644 index 00000000..f7a13836 --- /dev/null +++ b/packages/backend/src/stock/stock.service.spec.ts @@ -0,0 +1,37 @@ +import { DataSource } from 'typeorm'; +import { StockService } from './stock.service'; + +describe('StockService 테스트', () => { + test('주식의 조회수를 증가시킨다.', async () => { + const dataSource: Partial = { + transaction: jest.fn().mockImplementation(async (work) => { + const managerMock = { + exists: jest.fn().mockResolvedValue(true), + increment: jest.fn().mockResolvedValue({ id: 'A005930', views: 1 }), + }; + return work(managerMock); + }), + }; + const stockService = new StockService(dataSource as DataSource); + + await stockService.increaseView('A005930'); + + expect(dataSource.transaction).toHaveBeenCalled(); + }); + + test('존재하지 않는 주식의 조회수를 증가시키려 하면 예외가 발생한다.', async () => { + const dataSource: Partial = { + transaction: jest.fn().mockImplementation(async (work) => { + const managerMock = { + exists: jest.fn().mockResolvedValue(false), + }; + return work(managerMock); + }), + }; + const stockService = new StockService(dataSource as DataSource); + + await expect(async () => + stockService.increaseView('1'), + ).rejects.toThrowError('stock not found'); + }); +}); diff --git a/packages/backend/src/stock/stock.service.ts b/packages/backend/src/stock/stock.service.ts new file mode 100644 index 00000000..194ed8d8 --- /dev/null +++ b/packages/backend/src/stock/stock.service.ts @@ -0,0 +1,18 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { DataSource } from 'typeorm'; +import { Stock } from './domain/stock.entity'; + +@Injectable() +export class StockService { + constructor(private readonly datasource: DataSource) {} + + async increaseView(stockId: string) { + await this.datasource.transaction(async (manager) => { + const isExists = await manager.exists(Stock, { where: { id: stockId } }); + if (!isExists) { + throw new NotFoundException('stock not found'); + } + return await manager.increment(Stock, { id: stockId }, 'views', 1); + }); + } +} From 267ef55d1262ae4205ef7011ea321f7f0c487c38 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Wed, 6 Nov 2024 22:47:13 +0900 Subject: [PATCH 11/13] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EC=A6=9D=EA=B0=80=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=EC=8B=9C=20200=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 3 ++- packages/backend/src/stock/stock.controller.ts | 17 +++++++++++++++++ packages/backend/src/stock/stock.module.ts | 12 ++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/stock/stock.controller.ts create mode 100644 packages/backend/src/stock/stock.module.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 327ab3fa..98f166e9 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -3,9 +3,10 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { typeormConfig } from '@/configs/typeorm.config'; +import { StockModule } from '@/stock/stock.module'; @Module({ - imports: [TypeOrmModule.forRoot(typeormConfig)], + imports: [StockModule, TypeOrmModule.forRoot(typeormConfig)], controllers: [AppController], providers: [AppService], }) diff --git a/packages/backend/src/stock/stock.controller.ts b/packages/backend/src/stock/stock.controller.ts new file mode 100644 index 00000000..9904bc9d --- /dev/null +++ b/packages/backend/src/stock/stock.controller.ts @@ -0,0 +1,17 @@ +import { Body, Controller, HttpCode, Post } from '@nestjs/common'; +import { StockService } from './stock.service'; + +export type stockViewRequest = { + id: string; +}; + +@Controller('stock') +export class StockController { + constructor(private readonly stockService: StockService) {} + + @HttpCode(200) + @Post('/view') + async increaseStock(@Body() request: stockViewRequest): Promise { + await this.stockService.increaseView(request.id); + } +} diff --git a/packages/backend/src/stock/stock.module.ts b/packages/backend/src/stock/stock.module.ts new file mode 100644 index 00000000..9bbfd915 --- /dev/null +++ b/packages/backend/src/stock/stock.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Stock } from './domain/stock.entity'; +import { StockController } from './stock.controller'; +import { StockService } from './stock.service'; + +@Module({ + imports: [TypeOrmModule.forFeature([Stock])], + controllers: [StockController], + providers: [StockService], +}) +export class StockModule {} From 2f40f4b4b719087ab1e30684c4066b1d83d87420 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Thu, 7 Nov 2024 14:43:20 +0900 Subject: [PATCH 12/13] =?UTF-8?q?=E2=9C=A8=20feat(korea-stock-info.*.ts):?= =?UTF-8?q?=20=ED=95=9C=EA=B5=AD=20=EC=A3=BC=EC=8B=9D=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=A5=BC=20=ED=8C=8C=EC=8B=B1=ED=95=98=EA=B3=A0,=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=EA=B2=83=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.controller.ts | 16 -- packages/backend/src/app.module.ts | 6 +- .../src/openapi-scraper/env.service.ts | 23 --- .../korea-stock-info/dto/download.dto.ts | 3 + .../korea-stock-info/entities/stock.entity.ts | 22 +++ .../korea-stock-info.controller.spec.ts | 18 +++ .../korea-stock-info.controller.ts | 4 + .../korea-stock-info.service.spec.ts | 18 +++ .../korea-stock-info.service.ts | 140 ++++++++++++++++++ .../openapi-scraper/openapi-scraper.module.ts | 14 +- .../openapi-scraper.service.ts | 35 ++++- .../src/openapi-scraper/openapi.config.ts | 12 ++ 12 files changed, 255 insertions(+), 56 deletions(-) delete mode 100644 packages/backend/src/app.controller.ts delete mode 100644 packages/backend/src/openapi-scraper/env.service.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts create mode 100644 packages/backend/src/openapi-scraper/openapi.config.ts diff --git a/packages/backend/src/app.controller.ts b/packages/backend/src/app.controller.ts deleted file mode 100644 index 8de39f5b..00000000 --- a/packages/backend/src/app.controller.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } - - getHi(a: any): string { - return 'hi'; - } -} diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 17340480..2270d70a 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -5,7 +5,11 @@ import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; import { typeormConfig } from '@/configs/typeorm.config'; @Module({ - imports: [TypeOrmModule.forRoot(typeormConfig)OpenapiScraperModule, StockPriceModule], + imports: [ + TypeOrmModule.forRoot(typeormConfig), + OpenapiScraperModule, + StockPriceModule, + ], controllers: [], providers: [], }) diff --git a/packages/backend/src/openapi-scraper/env.service.ts b/packages/backend/src/openapi-scraper/env.service.ts deleted file mode 100644 index d6f22a46..00000000 --- a/packages/backend/src/openapi-scraper/env.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; - -@Injectable() -export class EnvService { - public constructor(private configService: ConfigService) {} - - private getKeyValue(key: string): { key: string; value: string } { - return { key: key, value: this.configService.get(key) }; - } - - public getOpenApiUrl() { - return this.getKeyValue("PROD"); - } - - public getAppKey() { - return this.getKeyValue("PROD_APPKEY"); - } - - public getAppSecret() { - return this.getKeyValue("PROD_APPSECRET"); - } -} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts b/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts new file mode 100644 index 00000000..c4c886b8 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts @@ -0,0 +1,3 @@ +export class DownloadDto { + baseDir!: string; +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts new file mode 100644 index 00000000..4c52f1c6 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts @@ -0,0 +1,22 @@ +import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity() +export class KospiMaster { + @PrimaryGeneratedColumn({ type: 'int', unsigned: true }) + id?: number; + + @Column() + shortCode?: string; + + @Column() + standardCode?: string; + + @Column() + koreanName?: string; + + @Column() + groupCode?: string; + + @Column() + marketCapSize?: string; +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts new file mode 100644 index 00000000..6818fba0 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KoreaStockInfoController } from './korea-stock-info.controller'; + +describe('KoreaStockInfoController', () => { + let controller: KoreaStockInfoController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [KoreaStockInfoController], + }).compile(); + + controller = module.get(KoreaStockInfoController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts new file mode 100644 index 00000000..0171b0d6 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('korea-stock-info') +export class KoreaStockInfoController {} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts new file mode 100644 index 00000000..c8197ee4 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KoreaStockInfoService } from './korea-stock-info.service'; + +describe('KoreaStockInfoService', () => { + let service: KoreaStockInfoService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [KoreaStockInfoService], + }).compile(); + + service = module.get(KoreaStockInfoService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts new file mode 100644 index 00000000..87de51d9 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts @@ -0,0 +1,140 @@ +import { Injectable } from '@nestjs/common'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as https from 'https'; +import * as readline from 'readline'; +import * as iconv from 'iconv-lite'; +import * as unzipper from 'unzipper'; +import { DownloadDto } from './dto/download.dto'; +import { KospiMaster } from './entities/stock.entity'; + +@Injectable() +export class KoreaStockInfoService { + constructor() { + this.downloadKosdaqMaster({ baseDir: './' }); + this.downloadKospiMaster({ baseDir: './' }); + + this.getKospiMasterData('./'); + this.getKosdaqMasterData('./'); + } + + private async downloadFile(url: string, filePath: string): Promise { + return new Promise((resolve, reject) => { + const file = fs.createWriteStream(filePath); + https + .get(url, (response) => { + response.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + }) + .on('error', (error) => { + fs.unlinkSync(filePath); + reject(error); + }); + }); + } + + private async extractZip(filePath: string, extractTo: string): Promise { + await fs + .createReadStream(filePath) + .pipe(unzipper.Extract({ path: extractTo })) + .promise(); + } + + public async downloadKosdaqMaster(downloadDto: DownloadDto): Promise { + const { baseDir } = downloadDto; + const fileName = 'kosdaq_code.zip'; + const filePath = path.join(baseDir, fileName); + const extractedFile = path.join(baseDir, 'kosdaq_code.mst'); + + await this.downloadFile( + 'https://new.real.download.dws.co.kr/common/master/kosdaq_code.mst.zip', + filePath, + ); + await this.extractZip(filePath, baseDir); + + fs.unlink(filePath, (err) => { + if (err) throw err; + }); + + return extractedFile; + } + + public async downloadKospiMaster(downloadDto: DownloadDto): Promise { + const { baseDir } = downloadDto; + const fileName = 'kospi_code.zip'; + const filePath = path.join(baseDir, fileName); + const extractedFile = path.join(baseDir, 'kospi_code.mst'); + + await this.downloadFile( + 'https://new.real.download.dws.co.kr/common/master/kospi_code.mst.zip', + filePath, + ); + await this.extractZip(filePath, baseDir); + fs.unlink(filePath, (err) => { + if (err) throw err; + }); + + return extractedFile; + } + + public async getKospiMasterData(baseDir: string): Promise { + const fileName = path.join(baseDir, 'kospi_code.mst'); + const kospiMasters: KospiMaster[] = []; + + const rl = readline.createInterface({ + input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + crlfDelay: Infinity, + }); + + for await (const row of rl) { + const shortCode = row.slice(0, 9).trim(); + const standardCode = row.slice(9, 21).trim(); + const koreanName = row.slice(21, row.length - 228).trim(); + const groupCode = row.slice(-228, -226).trim(); + const marketCapSize = row.slice(-226, -225).trim(); + + kospiMasters.push({ + shortCode, + standardCode, + koreanName, + groupCode, + marketCapSize, + }); + } + + console.log('Done'); + return kospiMasters; + } + + public async getKosdaqMasterData(baseDir: string): Promise { + const fileName = path.join(baseDir, 'kosdaq_code.mst'); + const kosdaqMasters: KospiMaster[] = []; + + const rl = readline.createInterface({ + input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + crlfDelay: Infinity, + }); + + for await (const row of rl) { + const shortCode = row.slice(0, 9).trim(); + const standardCode = row.slice(9, 21).trim(); + const koreanName = row.slice(21, row.length - 222).trim(); + const groupCode = row.slice(-222, -220).trim(); + const marketCapSize = row.slice(-220, -219).trim(); + + kosdaqMasters.push({ + shortCode, + standardCode, + koreanName, + groupCode, + marketCapSize, + }); + } + + console.log('Done'); + return kosdaqMasters; + } +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts index d8c45d28..7f272bd9 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -1,15 +1,9 @@ -import { Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { OpenapiScraperService } from "./openapi-scraper.service"; -import { EnvService } from "./env.service"; +import { Module } from '@nestjs/common'; +import { OpenapiScraperService } from './openapi-scraper.service'; @Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - }), - ], + imports: [], controllers: [], - providers: [OpenapiScraperService, EnvService], + providers: [OpenapiScraperService], }) export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts index 69c366f0..a4b14527 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts @@ -1,12 +1,35 @@ -import { Injectable } from "@nestjs/common"; -import { EnvService } from "./env.service"; +import { Injectable } from '@nestjs/common'; +import axios from 'axios'; +import { openApiConfig } from './openapi.config'; @Injectable() export class OpenapiScraperService { - private token: string; - public constructor(private env: EnvService) {} + private readonly config: typeof openApiConfig; + public constructor() { + this.config = openApiConfig; + this.getToken(); + } - private async fetchOpenApiSpec(url: string): Promise {} + private async fetchOpenApi( + url: string, + query: {} | undefined, + body: {}, + ): Promise { + try { + const response = await axios.post(url + "/oauth2/tokenP", body); + return response.data; // 응답에서 data 부분만 추출 + } catch (error) { + throw new Error(`Request failed: ${error}`); + } + } - private getToken() {} + private async getToken() { + const body = { + grant_type: 'client_credentials', + appkey: this.config.APPKEY, + appsecret: this.config.APPSECRET, + }; + const tmp = await this.fetchOpenApi(this.config.PROD!, undefined, body); + console.log(tmp.access_token); + } } diff --git a/packages/backend/src/openapi-scraper/openapi.config.ts b/packages/backend/src/openapi-scraper/openapi.config.ts new file mode 100644 index 00000000..3f3410ed --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi.config.ts @@ -0,0 +1,12 @@ +import * as dotenv from 'dotenv'; + +dotenv.config({ + path: './.env', +}); + +export const openApiConfig = { + PROD: process.env.PROD, + CANO_REAL: process.env.CANO_REAL, + APPKEY: process.env.PROD_APPKEY, + APPSECRET: process.env.PROD_APPSECRET, +}; From 33a64f10b5bbfb5308fdb947e2c9bb1723960d7e Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 14:18:02 +0900 Subject: [PATCH 13/13] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20deploy=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20front,=20backend=20dockerfile=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 66 +++++++++++++++++++ packages/backend/Dockerfile | 7 ++ .../stock-price.controller.spec.ts | 18 +++++ .../src/stock-price/stock-price.controller.ts | 5 ++ packages/frontend/Dockerfile | 11 ++++ 5 files changed, 107 insertions(+) create mode 100644 .github/workflows/deploy.yml create mode 100644 packages/backend/Dockerfile create mode 100644 packages/backend/src/stock-price/stock-price.controller.spec.ts create mode 100644 packages/backend/src/stock-price/stock-price.controller.ts create mode 100644 packages/frontend/Dockerfile diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..7ac3d1bc --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,66 @@ +name: Deploy Monorepo + +on: + push: + branches: + - dev + pull_request: + branches: + - dev + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + services: + docker: + image: docker:20.10.7 + options: --privileged + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build frontend + run: | + yarn workspace frontend build + + - name: Build backend + run: | + yarn workspace backend build + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push frontend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest + + - name: Build and push backend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + + - name: Deploy to server + uses: appleboy/ssh-action@v1.1.0 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SERVER_SSH_KEY }} + script: | + docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest + docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest + docker-compose up -d diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile new file mode 100644 index 00000000..64d3605c --- /dev/null +++ b/packages/backend/Dockerfile @@ -0,0 +1,7 @@ +FROM node:18-alpine +WORKDIR /packages +COPY . . +RUN yarn install --frozen-lockfile +RUN yarn workspace backend build +EXPOSE 3000 +CMD ["yarn", "workspace", "backend", "start:prod"] diff --git a/packages/backend/src/stock-price/stock-price.controller.spec.ts b/packages/backend/src/stock-price/stock-price.controller.spec.ts new file mode 100644 index 00000000..a6fe3fb6 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StockPriceController } from './stock-price.controller'; + +describe('StockPriceController', () => { + let controller: StockPriceController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StockPriceController], + }).compile(); + + controller = module.get(StockPriceController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/packages/backend/src/stock-price/stock-price.controller.ts b/packages/backend/src/stock-price/stock-price.controller.ts new file mode 100644 index 00000000..1436c6a1 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.controller.ts @@ -0,0 +1,5 @@ +import { Controller, HttpCode, Post } from '@nestjs/common'; + +@Controller('stock-price') +export class StockPriceController { +} diff --git a/packages/frontend/Dockerfile b/packages/frontend/Dockerfile new file mode 100644 index 00000000..e7f9eb0c --- /dev/null +++ b/packages/frontend/Dockerfile @@ -0,0 +1,11 @@ +FROM node:18-alpine AS builder +WORKDIR /packages +COPY . . +RUN yarn install --frozen-lockfile +RUN yarn workspace frontend build + +# Nginx 서버로 빌드된 파일 서빙 +FROM nginx:alpine +COPY --from=builder /packages/frontend/build /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"]