diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..864765d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,48 @@ +name: โ— SCG Project Bug report +description: Report bug to SCG Project +title: "[BUG] " +labels: ['bug', 'pending'] +body: + - type: textarea + attributes: + label: Description ๐Ÿ“– + id: bug-description + description: | + ๋ฐœ์ƒํ•œ ๋ฒ„๊ทธ์— ๋Œ€ํ•ด ์ƒ์„ธํ•˜๊ฒŒ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š” + validations: + required: true + - type: textarea + attributes: + label: Reproduction ๐Ÿ—๏ธ + id: bug-reproduction + description: | + ๋ฒ„๊ทธ reproduction ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š” + ์‚ฌ์ง„, ๋™์˜์ƒ ํ˜น์€ ํ•ด๋‹น ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ ๋งํฌ ๋“ฑ์„ ๋‚จ๊ธฐ๋ฉด ๊ฐœ๋ฐœ์‹œ๊ฐ„์„ ๋”์šฑ ๋” ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!๐Ÿ™‡ + value: | + 1. + 2. + 3. + validations: + required: true + - type: textarea + attributes: + label: Logs ๐Ÿชต + id: bug-log + description: | + ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ์˜ Log๋ฅผ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๋”์šฑ ๋” ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค!๐Ÿ™‡ + render: shell + - type: textarea + attributes: + label: Environment ๐Ÿ–ฅ๏ธ + id: bug-environment + description: | + ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š” (๋ธŒ๋ผ์šฐ์ €, OS, ํ•˜๋“œ์›จ์–ด ๋“ฑ) + - type: checkboxes + id: bug-checkboxes + attributes: + label: CheckList โœ”๏ธ + description: | + Issue ์˜ฌ๋ฆฌ๊ธฐ ์ „์— ํ•œ ๋ฒˆ ํ™•์ธํ•ด์ฃผ์„ธ์š”! ๐Ÿ‘ + options: + - label: ๊ด€๋ จ Issue ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ง€ ํ™•์ธํ•ด๋ณด์…จ๋‚˜์š”? + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ec4bb38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..7402b41 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,36 @@ +name: ๐Ÿš€ SCG Project New Feature Request +description: Propose new feature to SCG Project +title: "๐Ÿš€ " +labels: ['enhancement', 'pending'] +body: + - type: textarea + attributes: + label: Describe Existing Problem โ“ + id: feature-problem + description: | + ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ๋ฅผ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”! + validations: + required: true + - type: textarea + attributes: + label: Describe Solution ๐Ÿ’ธ + id: feature-solution + description: | + ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ์ง€ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”! + validations: + required: true + - type: textarea + attributes: + label: Describe Alternatives ๐Ÿ’ผ + id: feature-solution + description: | + ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ๋ฏผํ•œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค์— ๋Œ€ํ•ด์„œ๋„ ์ž์œ ๋กญ๊ฒŒ ์„œ์ˆ ํ•ด์ฃผ์„ธ์š”! + - type: checkboxes + id: feature-checkboxes + attributes: + label: CheckList โœ”๏ธ + description: | + Issue ์˜ฌ๋ฆฌ๊ธฐ ์ „์— ํ•œ ๋ฒˆ ํ™•์ธํ•ด์ฃผ์„ธ์š”! ๐Ÿ‘ + options: + - label: ๊ด€๋ จ Issue ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ง€ ํ™•์ธํ•ด๋ณด์…จ๋‚˜์š”? + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..d940276 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ +์ž‘์„ฑ์ž: @github_nickname + +## ์ฒดํฌ ๋ฆฌ์ŠคํŠธ + +- [ ] ์ ์ ˆํ•œ ์ œ๋ชฉ์œผ๋กœ ์ˆ˜์ •ํ–ˆ๋‚˜์š”? +- [ ] ์ƒ๋‹จ์— ์ด์Šˆ ๋ฒˆํ˜ธ๋ฅผ ๊ธฐ์ž…ํ–ˆ๋‚˜์š”? +- [ ] Target Branch๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •ํ–ˆ๋‚˜์š”? +- [ ] Label์„ ์•Œ๋งž๊ฒŒ ์„ค์ •ํ–ˆ๋‚˜์š”? + +## ์ž‘์—… ๋‚ด์—ญ + +- ์ž‘์—…ํ•œ ๋‚ด์šฉ์„ ๊ฐ„๋žตํ•˜๊ฒŒ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”. + +## ๋น„๊ณ  + +- ์ฐธ๊ณ  ์‚ฌํ•ญ์„ ์ ์–ด์ฃผ์„ธ์š”. ์ฝ”๋“œ ๋ฆฌ๋ทฐํ•˜๋Š” ์‚ฌ๋žŒ์ด ์ฐธ๊ณ ํ•ด์•ผ ํ•˜๋Š” ๋‚ด์šฉ์„ ์ž์œ ๋กœ์šด ํ˜•์‹์œผ๋กœ ์ ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +close/resolve/fix #{์ด์Šˆ ๋ฒˆํ˜ธ ๊ธฐ์ž…} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..4d2fd6c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,91 @@ +name: Docker Image CI + +on: + push: + branches: ["main"] +env: + dockerimage_tag: ${{ github.sha }} + dockerimage_name: harbor.k8s.scg.skku.ac.kr/library/ice-gs-thesis-be +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + steps: + - name: --------------- Code Repo --------------- + run: echo "Code Repo" + - name: Code Repo ๋ถˆ๋Ÿฌ์˜ค๊ธฐ + uses: actions/checkout@v4 + - name: Docker ์ค€๋น„(1/4) - ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ƒ์„ฑ + id: meta + uses: docker/metadata-action@v5.5.1 + with: + images: | + ${{ env.dockerimage_name }} + tags: | + ${{ env.dockerimage_tag }} + latest + flavor: | + latest=true + - name: Docker ์ค€๋น„(2/4) - QEMU ์„ค์ • + uses: docker/setup-qemu-action@v3 + - name: Docker ์ค€๋น„(3/4) - buildx ์„ค์ • + uses: docker/setup-buildx-action@v3 + - name: Docker ์ค€๋น„(4/4) - ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋กœ๊ทธ์ธ + uses: docker/login-action@v2 + with: + registry: ${{ secrets.HARBOR_REGISTRY }} + username: ${{ secrets.HARBOR_USERNAME }} + password: ${{ secrets.HARBOR_PASSWORD }} + - name: env ํŒŒ์ผ ์ƒ์„ฑ + run: | + echo APP_ENV=${{secrets.APP_ENV}} >> .env + echo APP_PORT=${{secrets.APP_PORT}} >> .env + echo DATABASE_URL="${{secrets.DATABASE_URL_PROD}}" >> .env + echo JWT_SECRET="${{secrets.JWT_SECRET}}" >> .env + echo MINIO_END_POINT="${{secrets.MINIO_END_POINT}}" >> .env + echo MINIO_PORT=${{secrets.MINIO_PORT}} >> .env + echo MINIO_ACCESS_KEY="${{secrets.MINIO_ACCESS_KEY}}" >> .env + echo MINIO_SECRET_KEY="${{secrets.MINIO_SECRET_KEY}}" >> .env + echo MINIO_BUCKET_NAME="${{secrets.MINIO_BUCKET_NAME_PROD}}" >> .env + cat .env + - name: Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ+ํ‘ธ์‹œ + id: build-and-push + uses: docker/build-push-action@v5.1.0 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: false + - name: --------------- Config Repo --------------- + run: echo "[Config Repo]" + - name: Config Repo ๋ถˆ๋Ÿฌ์˜ค๊ธฐ + uses: actions/checkout@v4 + with: + repository: SystemConsultantGroup/ice-grad-thesis-config + ref: main + token: ${{ secrets.ACTION_TOKEN }} + path: ice-grad-thesis-config + - name: Kustomize ์ค€๋น„ + uses: imranismail/setup-kustomize@v2.0.0 + - name: Config Repo ์ด๋ฏธ์ง€ ๊ฐ’ ์—…๋ฐ์ดํŠธ (Kustomize) + run: | + cd ice-grad-thesis-config/overlays/prod/be/ + kustomize edit set image ${{ env.dockerimage_name }}:${{ env.dockerimage_tag }} + cat kustomization.yaml + - name: Config Repo ๋ณ€๊ฒฝ์‚ฌํ•ญ ํ‘ธ์‹œ + run: | + cd ice-grad-thesis-config + git config --global user.email "wefwef12e@naver.com" + git config --global user.name "hynseok" + git commit -am "Update image tag" + git push -u origin main + - name: --------------- Clean Up --------------- + run: echo "Clean Up" diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index c05d39b..2d49483 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -6,9 +6,6 @@ on: env: dockerimage_tag: ${{ github.sha }} dockerimage_name: harbor.k8s.scg.skku.ac.kr/library/ice-gs-thesis-be - DATABASE_URL_QA: ${{secrets.DATABASE_URL_QA}} - JWT_SECRET: ${{secrets.JWT_SECRET}} - MINIO_SECRET_KEY: ${{secrets.MINIO_SECRET_KEY}} jobs: build: runs-on: ubuntu-latest @@ -46,12 +43,12 @@ jobs: run: | echo APP_ENV=${{secrets.APP_ENV}} >> .env echo APP_PORT=${{secrets.APP_PORT}} >> .env - echo DATABASE_URL=$DATABASE_URL_QA >> .env - echo JWT_SECRET=$JWT_SECRET >> .env + echo DATABASE_URL=${{secrets.DATABASE_URL_QA}} >> .env + echo JWT_SECRET=${{secrets.JWT_SECRET}} >> .env echo MINIO_END_POINT=${{secrets.MINIO_END_POINT}} >> .env echo MINIO_PORT=${{secrets.MINIO_PORT}} >> .env echo MINIO_ACCESS_KEY=${{secrets.MINIO_ACCESS_KEY}} >> .env - echo MINIO_SECRET_KEY=$MINIO_SECRET_KEY >> .env + echo MINIO_SECRET_KEY=${{secrets.MINIO_SECRET_KEY}} >> .env echo MINIO_BUCKET_NAME=${{secrets.MINIO_BUCKET_NAME_QA}} >> .env cat .env - name: Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ+ํ‘ธ์‹œ diff --git a/.gitignore b/.gitignore index 5f881f5..9c76080 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,7 @@ lerna-debug.log* !.vscode/extensions.json # Prisma -migrations/ \ No newline at end of file +migrations/ + +# Environment +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 150b8fe..1571083 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,13 @@ COPY tsconfig.json ./ COPY tsconfig.build.json ./ COPY .env ./ +RUN apk update +RUN apk upgrade +RUN apk add --no-cache udev ttf-freefont chromium + +ENV LANG=ko_KR.UTF-8 +ENV LANGUAGE=ko_KR.UTF- + # package.json, package-lock.json COPY package*.json ./ RUN npm install diff --git a/README.md b/README.md index a392e0b..3414dff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ -### local (port=4000) +### Overall Structure +![image](https://github.com/SystemConsultantGroup/real-ice-gs-thesis-backend/assets/60565169/ec77a2c2-8400-457b-8dd6-df2b92461082) + + +### local์—์„œ ์‹คํ–‰ (port=4000) +local ํ™˜๊ฒฝ์— ๋งž๋Š” .env ํŒŒ์ผ ์ƒ์„ฑ ```bash -npm i +npm install +npx prisma db seed npm run start ``` + +### ๊ฐœ๋ฐœ์ค‘.. +- PDF ์ƒ์„ฑ ๋ชจ๋“ˆ MSA ์ „ํ™˜ diff --git a/package-lock.json b/package-lock.json index 6075e19..9630e1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,6 @@ "class-validator": "^0.14.0", "cron": "^3.1.3", "fs": "^0.0.1-security", - "html-pdf": "^3.0.1", "jszip": "^3.10.1", "minio": "^7.1.3", "nest-winston": "^1.9.4", @@ -37,6 +36,7 @@ "path": "^0.12.7", "pdf-merger-js": "^5.0.0", "prisma": "^5.8.1", + "puppeteer": "^22.6.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "uuid": "^9.0.1", @@ -183,7 +183,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.23.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/highlight": "^7.23.4", @@ -195,7 +194,6 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -206,7 +204,6 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -219,7 +216,6 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", - "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -227,12 +223,10 @@ }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "dev": true, "license": "MIT" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -240,7 +234,6 @@ }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -248,7 +241,6 @@ }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -259,7 +251,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -267,7 +258,6 @@ }, "node_modules/@babel/highlight": { "version": "7.23.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -280,7 +270,6 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -291,7 +280,6 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -304,7 +292,6 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -312,12 +299,10 @@ }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -325,7 +310,6 @@ }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -333,7 +317,6 @@ }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -1108,6 +1091,32 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@puppeteer/browsers": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.1.tgz", + "integrity": "sha512-QSXujx4d4ogDamQA8ckkkRieFzDgZEuZuGiey9G7CuDcbnX4iINKWxTPC5Br2AEzY9ICAvcndqgAUFMMKnS/Tw==", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "dev": true, @@ -1306,6 +1315,15 @@ "version": "13.11.7", "license": "MIT" }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.15.0", "dev": true, @@ -1864,20 +1882,15 @@ "dev": true, "license": "MIT" }, - "node_modules/asn1": { - "version": "0.2.6", - "license": "MIT", - "optional": true, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "license": "MIT", - "optional": true, + "tslib": "^2.0.1" + }, "engines": { - "node": ">=0.8" + "node": ">=4" } }, "node_modules/async": { @@ -1886,7 +1899,7 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/available-typed-arrays": { @@ -1899,26 +1912,49 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "license": "Apache-2.0", + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.3.tgz", + "integrity": "sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==", "optional": true, - "engines": { - "node": "*" + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" } }, - "node_modules/aws4": { - "version": "1.12.0", - "license": "MIT", + "node_modules/bare-os": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", + "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", "optional": true }, - "node_modules/balanced-match": { - "version": "1.0.2", - "license": "MIT" + "node_modules/bare-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.1.tgz", + "integrity": "sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } }, "node_modules/base64-js": { "version": "1.5.1", - "dev": true, "funding": [ { "type": "github", @@ -1935,6 +1971,14 @@ ], "license": "MIT" }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt": { "version": "5.1.1", "hasInstallScript": true, @@ -1947,14 +1991,6 @@ "node": ">= 10.0.0" } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/big-integer": { "version": "1.6.52", "dev": true, @@ -2113,7 +2149,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "dev": true, "funding": [ { "type": "github", @@ -2193,7 +2228,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2218,11 +2252,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/caseless": { - "version": "0.12.0", - "license": "Apache-2.0", - "optional": true - }, "node_modules/cfb": { "version": "1.2.2", "dev": true, @@ -2295,6 +2324,19 @@ "node": ">=6.0" } }, + "node_modules/chromium-bidi": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.16.tgz", + "integrity": "sha512-IT5lnR44h/qZQ4GaCHvBxYIl4cQL2i9UvFyYeRyVdcpY04hx5H720HQfe/7Oz7ndxaYVLQFGpCO71J4X2Ye/Gw==", + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, "node_modules/class-transformer": { "version": "0.5.1", "license": "MIT" @@ -2352,6 +2394,35 @@ "node": ">= 10" } }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clone": { "version": "1.0.4", "dev": true, @@ -2426,7 +2497,7 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -2602,15 +2673,12 @@ "node": ">= 8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "license": "MIT", - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "engines": { - "node": ">=0.10" + "node": ">= 14" } }, "node_modules/debug": { @@ -2821,9 +2889,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -2855,6 +2936,11 @@ "node": ">=8" } }, + "node_modules/devtools-protocol": { + "version": "0.0.1262051", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1262051.tgz", + "integrity": "sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==" + }, "node_modules/dezalgo": { "version": "1.0.4", "dev": true, @@ -2916,15 +3002,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "license": "MIT", - "optional": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "license": "Apache-2.0", @@ -2958,7 +3035,6 @@ }, "node_modules/end-of-stream": { "version": "1.4.4", - "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -2976,9 +3052,16 @@ "node": ">=10.13.0" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", - "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -2989,14 +3072,8 @@ "dev": true, "license": "MIT" }, - "node_modules/es6-promise": { - "version": "4.2.8", - "license": "MIT", - "optional": true - }, "node_modules/escalade": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3017,6 +3094,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { "version": "8.56.0", "dev": true, @@ -3185,7 +3291,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -3219,7 +3324,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -3227,7 +3331,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -3365,11 +3468,6 @@ "node": ">= 0.8" } }, - "node_modules/extend": { - "version": "3.0.2", - "license": "MIT", - "optional": true - }, "node_modules/external-editor": { "version": "3.1.0", "dev": true, @@ -3384,43 +3482,41 @@ } }, "node_modules/extract-zip": { - "version": "1.7.0", - "license": "BSD-2-Clause", - "optional": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "optional": true, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dependencies": { - "ms": "2.0.0" + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "license": "MIT", - "optional": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "optional": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/fast-diff": { @@ -3428,6 +3524,11 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.2", "dev": true, @@ -3445,7 +3546,7 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -3487,8 +3588,8 @@ }, "node_modules/fd-slicer": { "version": "1.1.0", - "license": "MIT", - "optional": true, + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dependencies": { "pend": "~1.2.0" } @@ -3674,14 +3775,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "9.0.2", "dev": true, @@ -3837,6 +3930,14 @@ "version": "3.0.7", "license": "ISC" }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.2", "license": "MIT", @@ -3861,12 +3962,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "license": "MIT", - "optional": true, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dependencies": { - "assert-plus": "^1.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" } }, "node_modules/glob": { @@ -3973,7 +4093,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "devOptional": true, "license": "ISC" }, "node_modules/graphemer": { @@ -3981,63 +4100,23 @@ "dev": true, "license": "MIT" }, - "node_modules/har-schema": { - "version": "2.0.0", - "license": "ISC", - "optional": true, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/har-validator": { - "version": "5.1.5", + "node_modules/has-own-prop": { + "version": "2.0.0", + "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "license": "MIT", - "optional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/har-validator/node_modules/json-schema-traverse": { - "version": "0.4.1", - "license": "MIT", - "optional": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-own-prop": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", + "node_modules/has-property-descriptors": { + "version": "1.0.1", "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2" @@ -4083,26 +4162,6 @@ "version": "2.0.1", "license": "ISC" }, - "node_modules/hasha": { - "version": "2.2.0", - "license": "MIT", - "optional": true, - "dependencies": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hasha/node_modules/is-stream": { - "version": "1.1.0", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/hasown": { "version": "2.0.0", "license": "MIT", @@ -4121,19 +4180,6 @@ "node": ">=8" } }, - "node_modules/html-pdf": { - "version": "3.0.1", - "license": "MIT", - "bin": { - "html-pdf": "bin/index.js" - }, - "engines": { - "node": ">=4.0.0" - }, - "optionalDependencies": { - "phantomjs-prebuilt": "^2.1.16" - } - }, "node_modules/http-errors": { "version": "2.0.0", "license": "MIT", @@ -4148,18 +4194,27 @@ "node": ">= 0.8" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "license": "MIT", - "optional": true, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "debug": "^4.3.4" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">= 14" } }, "node_modules/https-proxy-agent": { @@ -4207,7 +4262,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, "funding": [ { "type": "github", @@ -4238,7 +4292,6 @@ }, "node_modules/import-fresh": { "version": "3.3.0", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -4304,6 +4357,18 @@ "node": ">= 0.10" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "license": "MIT", @@ -4327,7 +4392,6 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { @@ -4479,11 +4543,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "license": "MIT", - "optional": true - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "dev": true, @@ -4526,14 +4585,9 @@ }, "node_modules/isexe": { "version": "2.0.0", - "devOptional": true, + "dev": true, "license": "ISC" }, - "node_modules/isstream": { - "version": "0.1.2", - "license": "MIT", - "optional": true - }, "node_modules/iterare": { "version": "1.2.1", "license": "ISC", @@ -4560,7 +4614,6 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -4574,9 +4627,9 @@ } }, "node_modules/jsbn": { - "version": "0.1.1", - "license": "MIT", - "optional": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" }, "node_modules/json-buffer": { "version": "3.0.1", @@ -4585,14 +4638,8 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, "license": "MIT" }, - "node_modules/json-schema": { - "version": "0.4.0", - "license": "(AFL-2.1 OR BSD-3-Clause)", - "optional": true - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "dev": true, @@ -4607,11 +4654,6 @@ "version": "1.0.0", "license": "MIT" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "license": "ISC", - "optional": true - }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -4630,7 +4672,6 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -4659,20 +4700,6 @@ "npm": ">=6" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "license": "MIT", - "optional": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jszip": { "version": "3.10.1", "license": "(MIT OR GPL-3.0-or-later)", @@ -4700,11 +4727,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/kew": { - "version": "0.7.0", - "license": "Apache-2.0", - "optional": true - }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -4713,14 +4735,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/klaw": { - "version": "1.3.1", - "license": "MIT", - "optional": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, "node_modules/kuler": { "version": "2.0.0", "license": "MIT" @@ -4750,7 +4764,6 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, "license": "MIT" }, "node_modules/loader-runner": { @@ -4849,6 +4862,14 @@ "node": ">=0.1.90" } }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/luxon": { "version": "3.4.4", "license": "MIT", @@ -5052,6 +5073,11 @@ "version": "4.0.0", "license": "ISC" }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "node_modules/mkdirp": { "version": "0.5.6", "license": "MIT", @@ -5135,6 +5161,14 @@ "@nestjs/core": ">=9.0.0" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "dev": true, @@ -5217,14 +5251,6 @@ "set-blocking": "^2.0.0" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "license": "MIT", @@ -5390,13 +5416,65 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/pako": { "version": "1.0.11", "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -5407,7 +5485,6 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -5581,62 +5658,8 @@ }, "node_modules/pend": { "version": "1.2.0", - "license": "MIT", - "optional": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "license": "MIT", - "optional": true - }, - "node_modules/phantomjs-prebuilt": { - "version": "2.1.16", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - }, - "bin": { - "phantomjs": "bin/phantomjs" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/fs-extra": { - "version": "1.0.0", - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/jsonfile": { - "version": "2.4.0", - "license": "MIT", - "optional": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/which": { - "version": "1.3.1", - "license": "ISC", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -5654,25 +5677,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "license": "MIT", - "optional": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pluralize": { "version": "8.0.0", "dev": true, @@ -5756,8 +5760,9 @@ "license": "MIT" }, "node_modules/progress": { - "version": "1.1.8", - "optional": true, + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "engines": { "node": ">=0.4.0" } @@ -5773,14 +5778,54 @@ "node": ">= 0.10" } }, - "node_modules/psl": { - "version": "1.9.0", - "license": "MIT", - "optional": true + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pump": { "version": "3.0.0", - "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -5789,12 +5834,70 @@ }, "node_modules/punycode": { "version": "2.3.1", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/puppeteer": { + "version": "22.6.3", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.6.3.tgz", + "integrity": "sha512-KZOnthMbvr4+7cPKFeeOCJPe8DzOKGC0GbMXmZKOP/YusXQ6sqxA0vt6frstZq3rUJ277qXHlZNFf01VVwdHKw==", + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.2.1", + "cosmiconfig": "9.0.0", + "devtools-protocol": "0.0.1262051", + "puppeteer-core": "22.6.3" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "22.6.3", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.6.3.tgz", + "integrity": "sha512-YrTAak5zCTWVTnVaCK1b7FD1qFCCT9bSvQhLzamnIsJ57/tfuXiT8ZvPJR2SBfahyFTYFCcaZAd/Npow3lmDGA==", + "dependencies": { + "@puppeteer/browsers": "2.2.1", + "chromium-bidi": "0.5.16", + "debug": "4.3.4", + "devtools-protocol": "0.0.1262051", + "ws": "8.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/qs": { "version": "6.11.0", "license": "BSD-3-Clause", @@ -5843,6 +5946,11 @@ ], "license": "MIT" }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/randombytes": { "version": "2.1.0", "dev": true, @@ -5921,71 +6029,12 @@ "node": ">=0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-progress": { - "version": "2.0.1", - "license": "MIT", - "optional": true, - "dependencies": { - "throttleit": "^1.0.0" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "license": "MIT", - "optional": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "license": "BSD-3-Clause", - "optional": true, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "license": "MIT", - "optional": true, - "bin": { - "uuid": "bin/uuid" + "node": ">=0.10.0" } }, "node_modules/require-from-string": { @@ -6014,7 +6063,6 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -6240,8 +6288,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.5.4", - "license": "ISC", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6445,6 +6494,52 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.7.4", "dev": true, @@ -6477,6 +6572,11 @@ "node": ">=6" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, "node_modules/ssf": { "version": "0.11.2", "dev": true, @@ -6488,30 +6588,6 @@ "node": ">=0.8" } }, - "node_modules/sshpk": { - "version": "1.18.0", - "license": "MIT", - "optional": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-trace": { "version": "0.0.10", "license": "MIT", @@ -6532,6 +6608,18 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/strict-uri-encode": { "version": "2.0.0", "license": "MIT", @@ -6735,6 +6823,29 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "license": "ISC", @@ -6847,17 +6958,8 @@ "dev": true, "license": "MIT" }, - "node_modules/throttleit": { - "version": "1.0.1", - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/through": { "version": "2.3.8", - "dev": true, "license": "MIT" }, "node_modules/through2": { @@ -6919,18 +7021,6 @@ "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tr46": { "version": "0.0.3", "license": "MIT" @@ -7060,22 +7150,6 @@ "version": "2.6.2", "license": "0BSD" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "license": "Unlicense", - "optional": true - }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -7115,7 +7189,7 @@ }, "node_modules/typescript": { "version": "5.3.2", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -7135,13 +7209,21 @@ "node": ">=8" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "node_modules/undici-types": { "version": "5.26.5", "license": "MIT" }, "node_modules/universalify": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -7193,12 +7275,17 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "devOptional": true, + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" + }, "node_modules/util": { "version": "0.12.5", "license": "MIT", @@ -7251,24 +7338,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "license": "MIT", - "optional": true - }, "node_modules/watchpack": { "version": "2.4.0", "dev": true, @@ -7623,6 +7692,26 @@ "version": "1.0.2", "license": "ISC" }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xlsx": { "version": "0.18.5", "dev": true, @@ -7672,9 +7761,33 @@ "node": ">=0.4" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/yargs-parser": { "version": "21.1.1", - "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -7682,8 +7795,8 @@ }, "node_modules/yauzl": { "version": "2.10.0", - "license": "MIT", - "optional": true, + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -7707,6 +7820,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 7f91097..6d92475 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "class-validator": "^0.14.0", "cron": "^3.1.3", "fs": "^0.0.1-security", - "html-pdf": "^3.0.1", "jszip": "^3.10.1", "minio": "^7.1.3", "nest-winston": "^1.9.4", @@ -50,6 +49,7 @@ "path": "^0.12.7", "pdf-merger-js": "^5.0.0", "prisma": "^5.8.1", + "puppeteer": "^22.6.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "uuid": "^9.0.1", diff --git "a/resources/format/\354\213\254\354\202\254\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234_\354\226\221\354\213\235.html" "b/resources/format/\354\213\254\354\202\254\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234_\354\226\221\354\213\235.html" index acd1c01..b346d87 100644 --- "a/resources/format/\354\213\254\354\202\254\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234_\354\226\221\354\213\235.html" +++ "b/resources/format/\354\213\254\354\202\254\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234_\354\226\221\354\213\235.html" @@ -1,7 +1,12 @@ + + + + + - - -
-
- ์„์‚ฌํ•™์œ„ ์ฒญ๊ตฌ๋…ผ๋ฌธ ์˜ˆ๋น„์‹ฌ์‚ฌ ๋ณด๊ณ ์„œ
- Report on Pre Defense for Master's Thesis -
-
- - - - - - - - - - - - -
- ๋…ผ๋ฌธ์ œ์ถœ์ž
- Dissertion
- Submitter -
- ํ•™๊ณผ
- Dept. -
- $ํ•™๊ณผ -
- ํ•™๋ฒˆ
- Student ID -
- $ํ•™๋ฒˆ - - ์„ฑ๋ช…
- Name -
- $์ด๋ฆ„ -
- - - - - - - - -
- ์‹ฌ์‚ฌ๊ฒฐ๊ณผ
- Result of Evaluation -
- ํ•ฉ๊ฒฉ(PASS) - - $ํ•ฉ๊ฒฉ - - ๋ถˆํ•ฉ๊ฒฉ(FAIL) - - $๋ถˆํ•ฉ๊ฒฉ -
- - - - - - - -
- ์‹ฌ์‚ฌ์˜๊ฒฌ( Comments ) -
- $์‹ฌ์‚ฌ์˜๊ฒฌ -
-
- ์œ„์™€ ๊ฐ™์ด ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.
- (I hereby report the result.) + + + + + + + + + +
+
+ ์„์‚ฌํ•™์œ„ ์ฒญ๊ตฌ๋…ผ๋ฌธ ์˜ˆ๋น„์‹ฌ์‚ฌ ๋ณด๊ณ ์„œ
+ Report on Pre Defense for Master's Thesis
-
-
- $year๋…„     $month์›”     $day์ผ +
+ + + + + + + + + + + + +
+ ๋…ผ๋ฌธ์ œ์ถœ์ž
+ Dissertion
+ Submitter +
+ ํ•™๊ณผ
+ Dept. +
+ $ํ•™๊ณผ +
+ ํ•™๋ฒˆ
+ Student ID +
+ $ํ•™๋ฒˆ + + ์„ฑ๋ช…
+ Name +
+ $์ด๋ฆ„ +
+ + + + + + + + +
+ ์‹ฌ์‚ฌ๊ฒฐ๊ณผ
+ Result of Evaluation +
+ ํ•ฉ๊ฒฉ(PASS) + + $ํ•ฉ๊ฒฉ + + ๋ถˆํ•ฉ๊ฒฉ(FAIL) + + $๋ถˆํ•ฉ๊ฒฉ +
+ + + + + + + +
+ ์‹ฌ์‚ฌ์˜๊ฒฌ( Comments ) +
+ $์‹ฌ์‚ฌ์˜๊ฒฌ +
+
+ ์œ„์™€ ๊ฐ™์ด ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.
+ (I hereby report the result.)
-
-         Year       Month      day +
+
+ $year๋…„     $month์›”     $day์ผ +
+
+         Year       Month      day +
+ + + + + + +
+ ์‹ฌ์‚ฌ์œ„์›
+ (Committee Member) +
+ $์‹ฌ์‚ฌ์œ„์›:์„ฑ๋ช… + + + (์„œ๋ช…/์ธ) +
- - - - - - -
- ์‹ฌ์‚ฌ์œ„์›
- (Committee Member) -
- $์‹ฌ์‚ฌ์œ„์›:์„ฑ๋ช… - - - (์„œ๋ช…/์ธ) -
-
- \ No newline at end of file + + diff --git a/src/common/utils/convert-html-to-pdf.ts b/src/common/utils/convert-html-to-pdf.ts new file mode 100644 index 0000000..2b64c5a --- /dev/null +++ b/src/common/utils/convert-html-to-pdf.ts @@ -0,0 +1,42 @@ +import puppeteer from "puppeteer"; + +export const convertHTMLToPDF = async (html, callback, options = null, puppeteerArgs = null, remoteContent = false) => { + if (typeof html !== "string") { + throw new Error( + "Invalid Argument: HTML expected as type of string and received a value of a different type. Check your request body and request headers." + ); + } + let browser; + if (puppeteerArgs) { + browser = await puppeteer.launch(puppeteerArgs); + } else { + browser = await puppeteer.launch({ + executablePath: "/usr/bin/chromium-browser", + args: [ + "--no-sandbox", + "--disable-dev-shm-usage", + "--allow-file-access-from-files", + "--enable-local-file-accesses", + ], + }); + } + + const page = await browser.newPage(); + if (!options) { + options = { width: "16.5in", height: "23.4in", preferCSSPageSize: false, printBackground: true }; + } + + if (remoteContent === true) { + await page.goto(`data:text/html;base64,${Buffer.from(html).toString("base64")}`, { + waitUntil: "networkidle0", + }); + } else { + //page.setContent will be faster than page.goto if html is a static + await page.setContent(html); + } + + await page.pdf(options).then(callback, function (error) { + console.log(error); + }); + await browser.close(); +}; diff --git a/src/common/utils/readable-to-buf.ts b/src/common/utils/readable-to-buf.ts new file mode 100644 index 0000000..de39955 --- /dev/null +++ b/src/common/utils/readable-to-buf.ts @@ -0,0 +1,20 @@ +import internal from "stream"; + +// readable stream to buffer +export const readableToBuffer = async (readable: internal.Readable) => { + let buffer: Buffer; + const chunks = []; + + const streamToBuf = new Promise((resolve) => { + readable.on("data", (chunk) => { + chunks.push(chunk); + }); + readable.on("end", () => { + buffer = Buffer.concat(chunks); + resolve(null); + }); + }); + await streamToBuf; + + return buffer; +}; diff --git a/src/modules/professors/dtos/create-professor.dto.ts b/src/modules/professors/dtos/create-professor.dto.ts index ca758f6..40782a1 100644 --- a/src/modules/professors/dtos/create-professor.dto.ts +++ b/src/modules/professors/dtos/create-professor.dto.ts @@ -37,7 +37,7 @@ export class CreateProfessorDto { required: false, }) @IsOptional() - @IsNotEmpty({ message: "์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." }) + @IsNotEmpty() @IsEmail() @Type(() => String) email: string; @@ -48,7 +48,7 @@ export class CreateProfessorDto { required: false, }) @IsOptional() - @IsNotEmpty({ message: "์—ฐ๋ฝ์ฒ˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." }) + @IsNotEmpty() @IsString() @IsKoreanPhoneNumber() @Type(() => String) @@ -58,7 +58,8 @@ export class CreateProfessorDto { description: "ํ•™๊ณผ ์•„์ด๋””", example: 1, }) - @IsNotEmpty({ message: "ํ•™๊ณผ ์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." }) + @IsOptional() + @IsNotEmpty() @Type(() => Number) deptId: number; } diff --git a/src/modules/professors/dtos/professor.dto.ts b/src/modules/professors/dtos/professor.dto.ts index f02d367..25544eb 100644 --- a/src/modules/professors/dtos/professor.dto.ts +++ b/src/modules/professors/dtos/professor.dto.ts @@ -22,7 +22,7 @@ export class ProfessorDto { @ApiProperty({ description: "์•„์ด๋””" }) @Type(() => Number) id: number; - @ApiProperty({ description: "๋‚ด์„ ๋ฒˆํ˜ธ" }) + @ApiProperty({ description: "๋กœ๊ทธ์ธ ์•„์ด๋””" }) @Type(() => String) loginId: string; @ApiProperty({ description: "์ด๋ฆ„" }) @@ -43,11 +43,11 @@ export class ProfessorDto { converDtoToExcelRecord() { return { - ๋‚ด์„ ๋ฒˆํ˜ธ: this.loginId, + ๋กœ๊ทธ์ธ์•„์ด๋””: this.loginId, ์ด๋ฆ„: this.name, ์ด๋ฉ”์ผ: this.email, ์—ฐ๋ฝ์ฒ˜: this.phone, - ํ•™๊ณผ: this.department.name, + ํ•™๊ณผ: this.department ? this.department.name : null, }; } } diff --git a/src/modules/professors/dtos/professors-list-query.dto.ts b/src/modules/professors/dtos/professors-list-query.dto.ts index b0aee9a..6941fc9 100644 --- a/src/modules/professors/dtos/professors-list-query.dto.ts +++ b/src/modules/professors/dtos/professors-list-query.dto.ts @@ -5,7 +5,7 @@ import { PageQuery } from "src/common/dtos/pagination.dto"; export class ProfessorListPaginationQuery extends PageQuery { // ๋‹ค์ค‘ ์ƒ์†์ด ์•ˆ๋จ.... - @ApiProperty({ description: "์•„์ด๋””", required: false }) + @ApiProperty({ description: "๋กœ๊ทธ์ธ ์•„์ด๋””", required: false }) @IsOptional() @IsNotEmpty() @Type(() => String) @@ -39,7 +39,7 @@ export class ProfessorListPaginationQuery extends PageQuery { } export class ProfessorListQuery { - @ApiProperty({ description: "์•„์ด๋””", required: false }) + @ApiProperty({ description: "๋กœ๊ทธ์ธ ์•„์ด๋””", required: false }) @IsOptional() @IsNotEmpty() @Type(() => String) diff --git a/src/modules/professors/dtos/upload-professor.dto.ts b/src/modules/professors/dtos/upload-professor.dto.ts index 6982db4..94f2f59 100644 --- a/src/modules/professors/dtos/upload-professor.dto.ts +++ b/src/modules/professors/dtos/upload-professor.dto.ts @@ -5,7 +5,7 @@ import { IsKoreanPhoneNumber } from "src/common/decorators/is-kr-phone-number.de export class UploadProfessorDto { constructor(excelRecord) { - this.loginId = excelRecord["๋‚ด์„ ๋ฒˆํ˜ธ"].toString(); + this.loginId = excelRecord["๋กœ๊ทธ์ธ์•„์ด๋””"].toString(); this.name = excelRecord["์ด๋ฆ„"]; this.password = excelRecord["๋น„๋ฐ€๋ฒˆํ˜ธ"] ? excelRecord["๋น„๋ฐ€๋ฒˆํ˜ธ"].toString() : undefined; this.email = excelRecord["์ด๋ฉ”์ผ"] ? excelRecord["์ด๋ฉ”์ผ"].toString() : undefined; @@ -13,7 +13,7 @@ export class UploadProfessorDto { this.departmentName = excelRecord["ํ•™๊ณผ"]; } - @ApiProperty({ description: "๋‚ด์„ ๋ฒˆํ˜ธ" }) + @ApiProperty({ description: "๋กœ๊ทธ์ธ ์•„์ด๋””" }) @Type(() => String) loginId: string; diff --git a/src/modules/professors/professors.service.ts b/src/modules/professors/professors.service.ts index c1a3b57..646d02f 100644 --- a/src/modules/professors/professors.service.ts +++ b/src/modules/professors/professors.service.ts @@ -92,12 +92,13 @@ export class ProfessorsService { } } - const checkDepartment = await this.prismaService.department.findUnique({ - where: { id: deptId }, - }); - - if (!checkDepartment) { - throw new BadRequestException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ•™๊ณผ์ž…๋‹ˆ๋‹ค."); + if (deptId) { + const checkDepartment = await this.prismaService.department.findUnique({ + where: { id: deptId }, + }); + if (!checkDepartment) { + throw new BadRequestException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ•™๊ณผ์ž…๋‹ˆ๋‹ค."); + } } try { @@ -220,12 +221,15 @@ export class ProfessorsService { professors.map(async (professor, index) => { const { loginId, name, password, email, phone, departmentName } = professor; - const dept = await tx.department.findFirst({ - where: { name: departmentName }, - select: { id: true }, - }); + let dept; + if (departmentName) { + dept = await tx.department.findFirst({ + where: { name: departmentName }, + select: { id: true }, + }); - if (!dept) throw new BadRequestException(`${index + 2}๋ฒˆ์งธ ์ค„์˜ ์†Œ์†ํ•™๊ณผ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.`); + if (!dept) throw new BadRequestException(`${index + 2}๋ฒˆ์งธ ์ค„์˜ ์†Œ์†ํ•™๊ณผ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.`); + } // ํ•ด๋‹น ID๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธ ์ง„ํ–‰ // ์—†๋Š” ๊ฒฝ์šฐ ์ƒ์„ฑ ์ง„ํ–‰ @@ -269,14 +273,13 @@ export class ProfessorsService { data: { name, phone, - deptId: dept.id, + deptId: dept ? dept.id : undefined, password: password ? await this.authService.createHash(password) : undefined, }, include: { department: true }, }); } else { // ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ์œ ์ € - if (!departmentName) throw new BadRequestException(`${index + 2}๋ฒˆ์งธ ์ค„์˜ ์†Œ์†ํ•™๊ณผ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.`); if (!name) throw new BadRequestException(`${index + 2}๋ฒˆ์งธ ์ค„์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.`); if (!password) throw new BadRequestException(`${index + 2}๋ฒˆ์งธ ์ค„์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.`); if (existingEmail) @@ -295,7 +298,7 @@ export class ProfessorsService { name, email, phone, - deptId: dept.id, + deptId: dept ? dept.id : undefined, password: await this.authService.createHash(password), type: UserType.PROFESSOR, }, diff --git a/src/modules/reviews/reviews.service.ts b/src/modules/reviews/reviews.service.ts index 67cb188..991fbf9 100644 --- a/src/modules/reviews/reviews.service.ts +++ b/src/modules/reviews/reviews.service.ts @@ -20,12 +20,13 @@ import { GetRevisionListResDto } from "./dtos/get-revision-list.res.dto"; import { SearchCurrentReqDto } from "./dtos/search-current.req.dto"; import { MinioClientService } from "src/config/file/minio-client.service"; import { v1 } from "uuid"; -import { readFile, createWriteStream, unlink } from "fs"; -import { create as createPdf } from "html-pdf"; +import { readFile } from "fs"; import * as path from "path"; import * as Zip from "jszip"; import { GetCurrentListResDto } from "./dtos/get-current-list.res.dto"; import { GetResultResDto } from "./dtos/get-result.res.dto"; +import { readableToBuffer } from "src/common/utils/readable-to-buf"; +import { convertHTMLToPDF } from "src/common/utils/convert-html-to-pdf"; @Injectable() export class ReviewsService { @@ -64,21 +65,9 @@ export class ReviewsService { } async buildResultPdf(tx, reviewId, replacer, isMain) { - const options = { - width: "16.5in", - height: "23.4in", - orientation: "portrait", - border: { - top: "2.8in", - bottom: "2.8in", - }, - base: "file:///" + path.resolve("./") + "/", - localUrlAccess: true, - }; const fileName = (isMain ? "" : "์˜ˆ๋น„") + "์‹ฌ์‚ฌ๊ฒฐ๊ณผ๋ณด๊ณ ์„œ_์–‘์‹.html"; const filePath = path.join("resources", "format", fileName); try { - let signPath = ""; return new Promise((resolve, reject) => { readFile(filePath, "utf8", async (err, formatHtml) => { if (err) throw new InternalServerErrorException("reading format html file failed: " + filePath); @@ -177,21 +166,12 @@ export class ReviewsService { } } else if (key == "$์„œ๋ช…") { const readable = await this.minioClientService.getFile(replacer[key]); - signPath = path.join("resources", "img", "tmp", replacer[key]); - const writeStream = new Promise((resolve) => { - const ws = createWriteStream(signPath); - readable.pipe(ws); - readable.on("end", () => { - resolve(null); - }); - }); - await writeStream; - formatHtml = formatHtml.replace(key, signPath); + const buf = await readableToBuffer(readable); + formatHtml = formatHtml.replace(key, `data:image/png;base64, ${buf.toString("base64")}`); } else { formatHtml = formatHtml.replace(key, replacer[key]); } } - formatHtml = formatHtml.replaceAll("$row", ""); } else { for (const key of replacerKeys) { if (key == "$์‹ฌ์‚ฌ์œ„์›์žฅ") { @@ -272,21 +252,19 @@ export class ReviewsService { } formatHtml = formatHtml.replaceAll("$row", ""); } + const key = v1(); const createdAt = new Date(); - await createPdf(formatHtml, options).toBuffer(async (err, buffer) => { + await convertHTMLToPDF(formatHtml, async (pdf) => { if (err) throw new InternalServerErrorException("Creating PDF Buffer failed!"); await this.minioClientService.uploadFile( key, - buffer, - Buffer.byteLength(buffer), + pdf, + Buffer.byteLength(pdf), createdAt, reviewId.toString() + "_" + fileName.replace(".html", ".pdf"), "application/pdf" ); - unlink(signPath, async (err) => { - if (err) throw new InternalServerErrorException("Deleting temporary img file failed: " + signPath); - }); }); return resolve( @@ -308,21 +286,9 @@ export class ReviewsService { } async buildReportPdf(tx, reviewId, replacer, isMain) { - const options = { - width: "16.5in", - height: "23.4in", - orientation: "portrait", - border: { - top: "2.8in", - bottom: "2.8in", - }, - base: "file:///" + path.resolve("./") + "/", - localUrlAccess: true, - }; const fileName = (isMain ? "" : "์˜ˆ๋น„") + "์‹ฌ์‚ฌ๋ณด๊ณ ์„œ_์–‘์‹.html"; const filePath = path.join("resources", "format", fileName); try { - let signPath = ""; return new Promise((resolve, reject) => { readFile(filePath, "utf8", async (err, formatHtml) => { if (err) throw new InternalServerErrorException("reading format html file failed: " + filePath); @@ -330,36 +296,27 @@ export class ReviewsService { for (const key of replacerKeys) { if (key == "$์„œ๋ช…") { const readable = await this.minioClientService.getFile(replacer[key]); - signPath = path.join("resources", "img", "tmp", replacer[key]); - const writeStream = new Promise((resolve) => { - const ws = createWriteStream(signPath); - readable.pipe(ws); - ws.on("close", () => { - resolve(null); - }); - }); - await writeStream; - formatHtml = formatHtml.replace(key, signPath); + const buf = await readableToBuffer(readable); + formatHtml = formatHtml.replace(key, `data:image/png;base64, ${buf.toString("base64")}`); } else { formatHtml = formatHtml.replaceAll(key, replacer[key]); } } + const key = v1(); const createdAt = new Date(); - await createPdf(formatHtml, options).toBuffer(async (err, buffer) => { + await convertHTMLToPDF(formatHtml, async (pdf) => { if (err) throw new InternalServerErrorException("Creating PDF Buffer failed!"); await this.minioClientService.uploadFile( key, - buffer, - Buffer.byteLength(buffer), + pdf, + Buffer.byteLength(pdf), createdAt, reviewId.toString() + "_" + fileName.replace(".html", ".pdf"), "application/pdf" ); - unlink(signPath, async (err) => { - if (err) throw new InternalServerErrorException("Deleting temporary img file failed: " + signPath); - }); }); + return resolve( await tx.file.create({ data: { @@ -458,16 +415,16 @@ export class ReviewsService { ...(searchQuery.department && { department: { id: searchQuery.department } }), }, }, - ...(searchQuery.stage && { stage: searchQuery.stage }), + stage: { in: [Stage.MAIN, Stage.PRELIMINARY] }, ...(searchQuery.title && { title: { contains: searchQuery.title } }), }, reviewerId: id, isFinal: false, - NOT: { - thesisInfo: { - stage: Stage.REVISION, - }, - }, + // NOT: { + // thesisInfo: { + // stage: Stage.REVISION, + // }, + // }, ...(statusQuery && statusQuery), }, include: { @@ -860,9 +817,9 @@ export class ReviewsService { }, ...(searchQuery.stage && { stage: searchQuery.stage }), ...(searchQuery.title && { title: { contains: searchQuery.title } }), + ...(searchQuery.status && { status: searchQuery.status }), }, isFinal: true, - ...(searchQuery.status && { status: searchQuery.status }), }, include: { reviewer: { diff --git a/src/modules/students/dtos/create-student.dto.ts b/src/modules/students/dtos/create-student.dto.ts index d85e8fb..d64f58c 100644 --- a/src/modules/students/dtos/create-student.dto.ts +++ b/src/modules/students/dtos/create-student.dto.ts @@ -90,8 +90,8 @@ export class CreateStudentDto { committeeIds: number[]; // ๋…ผ๋ฌธ ์ •๋ณด - @ApiProperty({ description: "๋…ผ๋ฌธ ์ œ๋ชฉ", example: "๋…ผ๋ฌธ ์ œ๋ชฉ ์˜ˆ์‹œ" }) - @IsNotEmpty() + @ApiProperty({ description: "๋…ผ๋ฌธ ์ œ๋ชฉ", example: "๋…ผ๋ฌธ ์ œ๋ชฉ ์˜ˆ์‹œ", required: false }) + @IsOptional() @IsString() thesisTitle: string; } diff --git a/src/modules/students/dtos/update-system.dto.ts b/src/modules/students/dtos/update-system.dto.ts index f558a82..25fc1a5 100644 --- a/src/modules/students/dtos/update-system.dto.ts +++ b/src/modules/students/dtos/update-system.dto.ts @@ -1,6 +1,15 @@ import { ApiProperty } from "@nestjs/swagger"; import { Type } from "class-transformer"; -import { ArrayMaxSize, ArrayMinSize, IsArray, IsInt, IsNotEmpty, IsPositive, IsString } from "class-validator"; +import { + ArrayMaxSize, + ArrayMinSize, + IsArray, + IsInt, + IsNotEmpty, + IsOptional, + IsPositive, + IsString, +} from "class-validator"; export class UpdateSystemDto { // ์‹ฌ์‚ฌ ์œ„์› ์ •๋ณด @@ -30,8 +39,8 @@ export class UpdateSystemDto { committeeIds: number[]; // ๋…ผ๋ฌธ ์ •๋ณด - @ApiProperty({ description: "๋…ผ๋ฌธ ์ œ๋ชฉ", example: "๋…ผ๋ฌธ ์ œ๋ชฉ ์˜ˆ์‹œ" }) - @IsNotEmpty() + @ApiProperty({ description: "๋…ผ๋ฌธ ์ œ๋ชฉ", example: "๋…ผ๋ฌธ ์ œ๋ชฉ ์˜ˆ์‹œ", required: false }) + @IsOptional() @IsString() thesisTitle: string; } diff --git a/src/modules/students/students.controller.ts b/src/modules/students/students.controller.ts index 5b4274c..75ad21a 100644 --- a/src/modules/students/students.controller.ts +++ b/src/modules/students/students.controller.ts @@ -394,4 +394,18 @@ export class StudentsController { const reviewersDto = new ReviewersDto(headReviewer, advisors, committees); return new CommonResponseDto(reviewersDto); } + + @Delete("") + @ApiOperation({ + summary: "ํ•™์ƒ ๋ชฉ๋ก ์‚ญ์ œ", + description: "ํ•™์ƒ ๋ชฉ๋ก ์‚ญ์ œ", + }) + @UseUserTypeGuard([UserType.ADMIN]) + @ApiUnauthorizedResponse({ description: "[๊ด€๋ฆฌ์ž] ๋กœ๊ทธ์ธ ํ›„ ์ ‘๊ทผ ๊ฐ€๋Šฅ" }) + @ApiInternalServerErrorResponse({ description: "์„œ๋ฒ„ ๋‚ด๋ถ€ ์˜ค๋ฅ˜" }) + async deleteStudentsList() { + await this.studentsService.deleteStudentsList(); + + return new CommonResponseDto(); + } } diff --git a/src/modules/students/students.service.ts b/src/modules/students/students.service.ts index 7d27bd7..062a596 100644 --- a/src/modules/students/students.service.ts +++ b/src/modules/students/students.service.ts @@ -291,7 +291,7 @@ export class StudentsService { } } - // ๊ต์ˆ˜๋“ค ๋‚ด์„ ๋ฒˆํ˜ธ > Id๋กœ ๋ณ€๊ฒฝ + // ๊ต์ˆ˜๋“ค ๋กœ๊ทธ์ธ์•„์ด๋”” > Id๋กœ ๋ณ€๊ฒฝ let advisor1Id: number, advisor2Id: number, committee1Id: number, @@ -299,42 +299,42 @@ export class StudentsService { headReviewerId: number; if (advisor1) { const foundProfessor = await this.prismaService.user.findUnique({ - where: { loginId: advisor1, type: UserType.PROFESSOR, deletedAt: null }, // ๋‚ด์„ ๋ฒˆํ˜ธ ์‚ฌ์šฉ + where: { loginId: advisor1, type: UserType.PROFESSOR, deletedAt: null }, // ๋กœ๊ทธ์ธ ์•„์ด๋”” ์‚ฌ์šฉ }); if (!foundProfessor) - throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋‚ด์„ ๋ฒˆํ˜ธ ${advisor1}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); + throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋กœ๊ทธ์ธ ์•„์ด๋”” ${advisor1}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); advisor1Id = foundProfessor.id; } if (advisor2) { const foundProfessor = await this.prismaService.user.findUnique({ - where: { loginId: advisor2, type: UserType.PROFESSOR, deletedAt: null }, // ๋‚ด์„ ๋ฒˆํ˜ธ ์‚ฌ์šฉ + where: { loginId: advisor2, type: UserType.PROFESSOR, deletedAt: null }, // ๋กœ๊ทธ์ธ ์•„์ด๋”” ์‚ฌ์šฉ }); if (!foundProfessor) - throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋‚ด์„ ๋ฒˆํ˜ธ ${advisor2}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); + throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋กœ๊ทธ์ธ ์•„์ด๋”” ${advisor2}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); advisor2Id = foundProfessor.id; } if (committee1) { const foundProfessor = await this.prismaService.user.findUnique({ - where: { loginId: committee1, type: UserType.PROFESSOR, deletedAt: null }, // ๋‚ด์„ ๋ฒˆํ˜ธ ์‚ฌ์šฉ + where: { loginId: committee1, type: UserType.PROFESSOR, deletedAt: null }, // ๋กœ๊ทธ์ธ ์•„์ด๋”” ์‚ฌ์šฉ }); if (!foundProfessor) - throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋‚ด์„ ๋ฒˆํ˜ธ ${committee1}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); + throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋กœ๊ทธ์ธ ์•„์ด๋”” ${committee1}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); committee1Id = foundProfessor.id; } if (committee2) { const foundProfessor = await this.prismaService.user.findUnique({ - where: { loginId: committee2, type: UserType.PROFESSOR, deletedAt: null }, // ๋‚ด์„ ๋ฒˆํ˜ธ ์‚ฌ์šฉ + where: { loginId: committee2, type: UserType.PROFESSOR, deletedAt: null }, // ๋กœ๊ทธ์ธ ์•„์ด๋”” ์‚ฌ์šฉ }); if (!foundProfessor) - throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋‚ด์„ ๋ฒˆํ˜ธ ${committee2}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); + throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋กœ๊ทธ์ธ ์•„์ด๋”” ${committee2}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); committee2Id = foundProfessor.id; } if (headReviewer) { const foundProfessor = await this.prismaService.user.findUnique({ - where: { loginId: headReviewer, type: UserType.PROFESSOR, deletedAt: null }, // ๋‚ด์„ ๋ฒˆํ˜ธ ์‚ฌ์šฉ + where: { loginId: headReviewer, type: UserType.PROFESSOR, deletedAt: null }, // ๋กœ๊ทธ์ธ ์•„์ด๋”” ์‚ฌ์šฉ }); if (!foundProfessor) - throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋‚ด์„ ๋ฒˆํ˜ธ ${headReviewer}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); + throw new BadRequestException(`${index + 2}ํ–‰ : ๊ต์ˆ˜ ๋กœ๊ทธ์ธ ์•„์ด๋”” ${headReviewer}๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.`); headReviewerId = foundProfessor.id; } @@ -2036,4 +2036,20 @@ export class StudentsService { .map((reviewerInfo) => reviewerInfo.reviewer); return { headReviewer, advisors, committees }; } + + async deleteStudentsList() { + try { + return await this.prismaService.user.updateMany({ + where: { + type: UserType.STUDENT, + deletedAt: null, + }, + data: { + deletedAt: DateUtil.getCurrentTime().fullDateTime, + }, + }); + } catch (e) { + throw new InternalServerErrorException("ํ•™์ƒ ๋ชฉ๋ก ์‚ญ์ œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."); + } + } }