Compare commits

...

17 Commits

Author SHA1 Message Date
b8cd53cb59 chore(release): 3.3.4 2022-04-09 22:02:26 +02:00
e61f6153c3 Merge pull request #823 from AmruthPillai/i18n_main
New Crowdin updates
2022-04-09 22:01:54 +02:00
386e8ab902 Merge pull request #827 from AmruthPillai/compose-envs
Remove YAML anchors and prefer Docker Compose Environment Arrays
2022-04-09 22:01:41 +02:00
5e8f02e3ca add local build context comment in docker-compose 2022-04-09 21:47:41 +02:00
f219562e72 style(eslint): client/next: add specific rule for no-html-link-for-pages 2022-04-09 21:25:19 +02:00
29d94dfc14 ci(docker): remove yaml anchors in favor of environment array in docker-compose
fix #825, fix #824, fix #820
2022-04-09 21:21:45 +02:00
622f5fc28c ci(github-actions): update key tags for GitHub action to build docker image 2022-04-09 09:33:44 +02:00
647f01e25c Merge branch 'main' of github.com:AmruthPillai/Reactive-Resume 2022-04-09 09:32:20 +02:00
5a79c0e5c2 chore(release): 3.3.3 2022-04-09 09:32:04 +02:00
2a4c298572 Merge pull request #819 from martadinata666/combine-tags
combine-tags
2022-04-09 09:30:46 +02:00
1e59f73f79 feat(profile): add XING profile icon
fix #821
2022-04-09 09:29:51 +02:00
feb911aea0 feat(s3): implement non-ephemeral storage through S3/DO Spaces 2022-04-09 09:28:08 +02:00
d0863d68c6 chore(release): 3.3.3 2022-04-09 09:26:34 +02:00
447d9b3ca1 New translations builder.json (Greek) 2022-04-08 19:35:17 +02:00
86e66eb6a0 combine-tags 2022-04-08 19:08:01 +07:00
b2c9515a63 Create SECURITY.md 2022-04-08 10:37:24 +02:00
db04c5caee update CHANGELOG.md 2022-04-08 10:34:27 +02:00
18 changed files with 1419 additions and 162 deletions

View File

@ -1,10 +1,10 @@
# Shared
# Server + Client
TZ=UTC
PUBLIC_URL=http://localhost
PUBLIC_SERVER_URL=http://localhost/api
PUBLIC_URL=http://localhost:3000
PUBLIC_SERVER_URL=http://localhost:3000/api
PUBLIC_GOOGLE_CLIENT_ID=
# Database
# Server + Database
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
@ -16,13 +16,18 @@ POSTGRES_PORT=5432
POSTGRES_SSL_CERT=
JWT_SECRET=
JWT_EXPIRY_TIME=604800
PUBLIC_GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_API_KEY=
SENDGRID_API_KEY=
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
SENDGRID_FROM_NAME=
SENDGRID_FROM_EMAIL=
STORAGE_BUCKET=
STORAGE_REGION=
STORAGE_ENDPOINT=
STORAGE_URL_PREFIX=
STORAGE_ACCESS_KEY=
STORAGE_SECRET_KEY=
# Flags
# Flags (Client)
PUBLIC_FLAG_DISABLE_SIGNUPS=false

View File

@ -5,8 +5,8 @@ on:
types: [published]
jobs:
docker_client:
name: Docker (Client)
client:
name: Client
runs-on: ubuntu-latest
steps:
@ -29,6 +29,13 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Client Image
uses: docker/build-push-action@v2.10.0
with:
@ -39,9 +46,11 @@ jobs:
tags: |
amruthpillai/reactive-resume:client-latest
amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
ghcr.io/amruthpillai/reactive-resume:client-latest
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
docker_server:
name: Docker (Server)
server:
name: Server
runs-on: ubuntu-latest
steps:
@ -64,6 +73,13 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Server Image
uses: docker/build-push-action@v2.10.0
with:
@ -74,75 +90,5 @@ jobs:
tags: |
amruthpillai/reactive-resume:server-latest
amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}
github_client:
name: GitHub (Client)
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.0
- id: version
name: Get Version
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Client Image
uses: docker/build-push-action@v2.10.0
with:
context: .
push: true
file: client/Dockerfile
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/amruthpillai/reactive-resume:client-latest
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
github_server:
name: GitHub (Server)
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.0
- id: version
name: Get Version
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Server Image
uses: docker/build-push-action@v2.10.0
with:
context: .
push: true
file: server/Dockerfile
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/amruthpillai/reactive-resume:server-latest
ghcr.io/amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}

View File

@ -2,15 +2,19 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [3.3.4](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.3...v3.3.4) (2022-04-09)
### [3.3.3](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.2...v3.3.3) (2022-04-09)
### Features
* **profile:** add XING profile icon ([1e59f73](https://github.com/AmruthPillai/Reactive-Resume/commit/1e59f73f79a91d0264c0d2108906ee89d4eb27f8)), closes [#821](https://github.com/AmruthPillai/Reactive-Resume/issues/821)
* **s3:** implement non-ephemeral storage through S3/DO Spaces ([feb911a](https://github.com/AmruthPillai/Reactive-Resume/commit/feb911aea06bacf58ea933d2803a2a89fe36e57b))
### [3.3.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.1...v3.3.2) (2022-04-08)
### Bug Fixes
* **types/react:** downgrade to <18 ([fc77b54](https://github.com/AmruthPillai/Reactive-Resume/commit/fc77b548d8d61530b2d158ff83f088bed12d5080))
### [3.3.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.0...v3.3.1) (2022-04-08)
### Bug Fixes
* **types/react:** downgrade to <18 ([fc77b54](https://github.com/AmruthPillai/Reactive-Resume/commit/fc77b548d8d61530b2d158ff83f088bed12d5080))

13
SECURITY.md Normal file
View File

@ -0,0 +1,13 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 3.x.x | :white_check_mark: |
| 2.x.x | :x: |
| 1.x.x | :x: |
## Reporting a Vulnerability
Create an issue on GitHub or send me an email through the contact form on my website at https://amruthpillai.com/

View File

@ -3,6 +3,7 @@
"ignorePatterns": [".next", "__ENV.js"],
"rules": {
"@next/next/no-img-element": "off",
"@next/next/no-sync-scripts": "off"
"@next/next/no-sync-scripts": "off",
"@next/next/no-html-link-for-pages": [2, "client/pages"]
}
}

View File

@ -12,7 +12,7 @@ const nextConfig = {
},
images: {
domains: ['www.gravatar.com'],
domains: ['cdn.rxresu.me', 'www.gravatar.com'],
},
async rewrites() {

View File

@ -0,0 +1,358 @@
{
"common": {
"actions": {
"add": "Προσθήκη νέου {{token}}",
"delete": "Διαγραφή {{token}}",
"edit": "Επεξεργασία {{token}}"
},
"columns": {
"heading": "Στήλες",
"tooltip": "Αλλαγή αριθμού στηλών"
},
"form": {
"date": {
"label": "Ημερομηνία"
},
"description": {
"label": "Περιγραφή"
},
"email": {
"label": "Διεύθυνση Email"
},
"end-date": {
"help-text": "Αφήστε αυτό το πεδίο κενό, εάν εξακολουθεί να υπάρχει",
"label": "Ημερομηνία λήξης"
},
"keywords": {
"label": "Λέξεις κλειδιά"
},
"level": {
"label": "Επίπεδο"
},
"levelNum": {
"label": "Επίπεδο (αριθμός)"
},
"name": {
"label": "Όνομα"
},
"phone": {
"label": "Αριθμός τηλεφώνου"
},
"position": {
"label": "Θέση"
},
"start-date": {
"label": "Ημερομηνία έναρξης"
},
"subtitle": {
"label": "Υπότιτλος"
},
"summary": {
"label": "Σύνοψη"
},
"title": {
"label": "Τίτλος"
},
"url": {
"label": "Ιστοσελίδα"
}
},
"glossary": {
"page": "Σελίδα"
},
"list": {
"actions": {
"delete": "Διαγραφή",
"duplicate": "Διπλότυπο",
"edit": "Επεξεργασία"
},
"empty-text": "Αυτή η λίστα είναι κενή."
},
"tooltip": {
"delete-item": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτό το στοιχείο; Αυτή είναι μια μη αναστρέψιμη ενέργεια.",
"delete-section": "Διαγραφή ενότητας",
"rename-section": "Μετονομασία ενότητας",
"toggle-visibility": "Εναλλαγή ορατότητας"
}
},
"controller": {
"tooltip": {
"center-artboard": "Κεντράρισμα πίνακα",
"copy-link": "Αντιγραφή συνδέσμου στο βιογραφικό",
"export-pdf": "Εξαγωγή σε PDF",
"toggle-orientation": "Εναλλαγή προσανατολισμού σελίδας",
"toggle-page-break-line": "Εναλλαγή γραμμής αλλαγής σελίδας",
"toggle-sidebars": "Εναλλαγή πλευρικών γραμμών",
"zoom-in": "Μεγέθυνση",
"zoom-out": "Σμίκρυνση"
}
},
"header": {
"menu": {
"delete": "Διαγραφή",
"duplicate": "Διπλότυπο",
"rename": "Μετονομασία",
"share-link": "Κοινοποίηση συνδέσμου",
"tooltips": {
"delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το βιογραφικό; Αυτή είναι μια μη αναστρέψιμη ενέργεια.",
"share-link": "Πρέπει να αλλάξετε την ορατότητα του βιογραφικού σας σε δημόσιο για να το κάνετε ορατό σε άλλους."
}
}
},
"leftSidebar": {
"sections": {
"awards": {
"form": {
"awarder": {
"label": "Βραβευόμενος"
}
}
},
"basics": {
"actions": {
"photo-filters": "Φίλτρα φωτογραφιών"
},
"heading": "Βασικά",
"headline": {
"label": "Επικεφαλίδα"
},
"name": {
"label": "Ονοματεπώνυμο"
},
"photo-filters": {
"effects": {
"border": {
"label": "Περίγραμμα"
},
"grayscale": {
"label": "Κλίμακα του γκρι"
},
"heading": "Εφέ"
},
"shape": {
"heading": "Σχήμα"
},
"size": {
"heading": "Μέγεθος (σε px)"
}
},
"photo-upload": {
"tooltip": {
"remove": "Αφαίρεση φωτογραφίας",
"upload": "Ανέβασμα φωτογραφίας"
}
}
},
"certifications": {
"form": {
"issuer": {
"label": "Εκδότης"
}
}
},
"education": {
"form": {
"area-study": {
"label": "Τομέας σπουδών"
},
"courses": {
"label": "Σεμινάρια"
},
"degree": {
"label": "Πτυχίο"
},
"grade": {
"label": "Βαθμός"
},
"institution": {
"label": "Ίδρυμα"
}
}
},
"location": {
"address": {
"label": "Διεύθυνση"
},
"city": {
"label": "Πόλη"
},
"country": {
"label": "Χώρα"
},
"heading": "Τοποθεσία",
"postal-code": {
"label": "Ταχυδρομικός κώδικας"
},
"region": {
"label": "Περιοχή"
}
},
"profiles": {
"form": {
"network": {
"label": "Δίκτυο"
},
"username": {
"label": "Όνομα χρήστη"
}
},
"heading": "Προφίλ",
"heading_one": "Προφίλ"
},
"publications": {
"form": {
"publisher": {
"label": "Εκδότης"
}
}
},
"references": {
"form": {
"relationship": {
"label": "Σχέση"
}
}
},
"section": {
"heading": "Ενότητα"
},
"volunteer": {
"form": {
"organization": {
"label": "Οργανισμός"
}
}
}
}
},
"rightSidebar": {
"sections": {
"css": {
"heading": "Προσαρμοσμένο CSS"
},
"export": {
"heading": "Εξαγωγή",
"json": {
"primary": "JSON",
"secondary": "Κατεβάστε μια έκδοση JSON του βιογραφικού σας που μπορεί να εισαχθεί ξανά στο Reactive Resume."
},
"pdf": {
"loading": {
"primary": "Δημιουργία PDF",
"secondary": "Περιμένετε μέχρι να δημιουργηθεί το PDF σας, αυτό μπορεί να διαρκέσει έως και 15 δευτερόλεπτα."
},
"normal": {
"primary": "PDF",
"secondary": "Κατεβάστε ένα PDF του βιογραφικού σας που μπορείτε να εκτυπώσετε και να στείλετε στην εργασία των ονείρων σας. Αυτό το αρχείο δεν μπορεί να εισαχθεί ξανά για περαιτέρω επεξεργασία."
}
}
},
"layout": {
"heading": "Διάταξη",
"tooltip": {
"reset-layout": "Επαναφορά διάταξης"
}
},
"links": {
"bugs-features": {
"body": "Υπάρχει κάτι που σας εμποδίζει να φτιάξετε ένα βιογραφικό σημείωμα; Ή μήπως έχετε μια καταπληκτική ιδέα να προσθέσετε; Θέστε το ως σφάλμα στο GitHub για να ξεκινήσετε.",
"button": "Σφάλματα GitHub",
"heading": "Σφάλματα; Αιτήματα δυνατοτήτων;"
},
"donate": {
"body": "Αν σας άρεσε να χρησιμοποιείτε το Reactive Resume, σκεφτείτε το ενδεχόμενο να δωρίσετε όσο το δυνατόν περισσότερα για τον σκοπό της διατήρησης και λειτουργίας της εφαρμογής, χωρίς διαφημίσεις και δωρεάν για πάντα.",
"button": "Κεράστε με ένα καφεδάκι",
"heading": "Κάντε δωρεά στο Reactive βιογραφικό"
},
"github": "Πηγαίος κώδικας",
"heading": "Σύνδεσμοι"
},
"settings": {
"global": {
"date": {
"primary": "Ημερομηνία",
"secondary": "Μορφή ημερομηνίας για χρήση στην εφαρμογή"
},
"heading": "Καθολικό",
"language": {
"primary": "Γλώσσα",
"secondary": "Εμφάνιση γλώσσας για χρήση στην εφαρμογή"
},
"theme": {
"primary": "Θέμα"
}
},
"heading": "Ρυθμίσεις",
"page": {
"break-line": {
"primary": "Γραμμή διακοπής",
"secondary": "Εμφάνιση μιας γραμμής σε όλες τις σελίδες για να επισημάνετε το ύψος μιας σελίδας Α4"
},
"heading": "Σελίδα",
"orientation": {
"disabled": "Δεν έχει αποτέλεσμα όταν υπάρχει μόνο μία σελίδα",
"primary": "Προσανατολισμός",
"secondary": "Αν θα εμφανίζονται οι σελίδες οριζόντια ή κάθετα"
}
},
"resume": {
"heading": "Βιογραφικό σημείωμα",
"reset": {
"primary": "Επαναφορά όλων",
"secondary": "Κάνατε πάρα πολλά λάθη; Κάντε κλικ εδώ για να επαναφέρετε όλες τις αλλαγές και να ξεκινήσετε από την αρχή. Προσέξτε, αυτή η ενέργεια δεν μπορεί να αντιστραφεί."
},
"sample": {
"primary": "Φόρτωση δειγμάτων δεδομένων",
"secondary": "Δεν είστε σίγουροι από πού να ξεκινήσετε; Κάντε κλικ εδώ για να φορτώσετε μερικά δείγματα δεδομένων για να δείτε πώς φαίνεται ένα πλήρες βιογραφικό."
}
}
},
"sharing": {
"heading": "Κοινοποίηση",
"short-url": {
"label": "Προτίμηση σύντομης διεύθυνσης"
},
"visibility": {
"subtitle": "Επιτρέψτε σε οποιονδήποτε έχει σύνδεσμο να δει το βιογραφικό σας",
"title": "Δημόσιο"
}
},
"templates": {
"heading": "Πρότυπα"
},
"theme": {
"form": {
"background": {
"label": "Φόντο"
},
"primary": {
"label": "Πρωτεύον"
},
"text": {
"label": "Κείμενο"
}
},
"heading": "Θέμα"
},
"typography": {
"form": {
"font-family": {
"label": "Γραμματοσειρά"
},
"font-size": {
"label": "Μέγεθος γραμματοσειράς"
}
},
"heading": "Τυπογραφία",
"widgets": {
"body": {
"label": "Σώμα"
},
"headings": {
"label": "Επικεφαλίδες"
}
}
}
}
}
}

View File

@ -13,6 +13,7 @@ import {
FaStackOverflow,
FaTelegram,
FaTwitter,
FaXing,
FaYoutube,
} from 'react-icons/fa';
@ -29,6 +30,7 @@ const profileIconMap: Record<string, JSX.Element> = {
gitlab: <FaGitlab />,
telegram: <FaTelegram />,
skype: <FaSkype />,
xing: <FaXing />,
youtube: <FaYoutube />,
};

View File

@ -1,43 +1,13 @@
version: '3'
x-env-shared: &env-shared
environment:
- TZ=UTC
- PUBLIC_URL=http://localhost
- PUBLIC_SERVER_URL=http://localhost/api
- PUBLIC_GOOGLE_CLIENT_ID=
x-env-database: &env-database
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
x-env-server: &env-server
environment:
- SECRET_KEY=
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_SSL_CERT=
- JWT_SECRET=
- JWT_EXPIRY_TIME=604800
- PUBLIC_GOOGLE_CLIENT_ID=
- GOOGLE_CLIENT_SECRET=
- GOOGLE_API_KEY=
- SENDGRID_API_KEY=
- SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
- SENDGRID_FROM_NAME=
- SENDGRID_FROM_EMAIL=
x-env-flags: &env-flags
environment:
- PUBLIC_FLAG_DISABLE_SIGNUPS=false
services:
postgres:
image: postgres:14.2-alpine
container_name: postgres
<<: *env-database
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
ports:
- 5432:5432
volumes:
@ -64,10 +34,36 @@ services:
server:
image: amruthpillai/reactive-resume:server-latest
# build:
# context: .
# dockerfile: ./server/Dockerfile
container_name: server
<<: *env-shared
<<: *env-server
<<: *env-database
environment:
- TZ=UTC
- PUBLIC_URL=http://localhost:3000
- PUBLIC_SERVER_URL=http://localhost:3000/api
- PUBLIC_GOOGLE_CLIENT_ID=
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- SECRET_KEY=
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_SSL_CERT=
- JWT_SECRET=
- JWT_EXPIRY_TIME=604800
- GOOGLE_CLIENT_SECRET=
- GOOGLE_API_KEY=
- SENDGRID_API_KEY=
- SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
- SENDGRID_FROM_NAME=
- SENDGRID_FROM_EMAIL=
- STORAGE_BUCKET=
- STORAGE_REGION=
- STORAGE_ENDPOINT=
- STORAGE_URL_PREFIX=
- STORAGE_ACCESS_KEY=
- STORAGE_SECRET_KEY=
depends_on:
- traefik
- postgres
@ -82,9 +78,16 @@ services:
client:
image: amruthpillai/reactive-resume:client-latest
# build:
# context: .
# dockerfile: ./client/Dockerfile
container_name: client
<<: *env-shared
<<: *env-flags
environment:
- TZ=UTC
- PUBLIC_URL=http://localhost:3000
- PUBLIC_SERVER_URL=http://localhost:3000/api
- PUBLIC_GOOGLE_CLIENT_ID=
- PUBLIC_FLAG_DISABLE_SIGNUPS=false
depends_on:
- traefik
- server

View File

@ -161,3 +161,31 @@ You can get your own key here: https://docs.sendgrid.com/ui/account-and-settings
**Required**: `no`
**Description:** Sender's Email Address
## Storage
You can either use S3 or any S3-compliant service such as DigitalOcean Spaces to store profile pictures uploaded by users of the platform.
### `STORAGE_BUCKET`
**Required**: `yes`
### `STORAGE_REGION`
**Required**: `yes`
### `STORAGE_ENDPOINT`
**Required**: `yes`
### `STORAGE_URL_PREFIX`
**Required**: `yes`
### `STORAGE_ACCESS_KEY`
**Required**: `yes`
### `STORAGE_SECRET_KEY`
**Required**: `yes`

View File

@ -1,6 +1,6 @@
{
"name": "reactive-resume",
"version": "3.3.2",
"version": "3.3.4",
"private": true,
"workspaces": [
"schema",

864
pnpm-lock.yaml generated
View File

@ -205,6 +205,7 @@ importers:
server:
specifiers:
'@aws-sdk/client-s3': ^3.67.0
'@nestjs/axios': ^0.0.7
'@nestjs/cli': ^8.2.5
'@nestjs/common': ^8.4.4
@ -260,6 +261,7 @@ importers:
uuid: ^8.3.2
webpack: ^5.72.0
dependencies:
'@aws-sdk/client-s3': 3.67.0
'@nestjs/axios': 0.0.7_7670df531e7a1503cdbe395599f41db7
'@nestjs/common': 8.4.4_ea528571bae7e3437ac6e354bb00c0f4
'@nestjs/config': 2.0.0_7670df531e7a1503cdbe395599f41db7
@ -515,6 +517,859 @@ packages:
- chokidar
dev: true
/@aws-crypto/crc32/2.0.0:
resolution: {integrity: sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA==}
dependencies:
'@aws-crypto/util': 2.0.1
'@aws-sdk/types': 3.55.0
tslib: 1.14.1
dev: false
/@aws-crypto/crc32c/2.0.0:
resolution: {integrity: sha512-vF0eMdMHx3O3MoOXUfBZry8Y4ZDtcuskjjKgJz8YfIDjLStxTZrYXk+kZqtl6A0uCmmiN/Eb/JbC/CndTV1MHg==}
dependencies:
'@aws-crypto/util': 2.0.1
'@aws-sdk/types': 3.55.0
tslib: 1.14.1
dev: false
/@aws-crypto/ie11-detection/2.0.0:
resolution: {integrity: sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==}
dependencies:
tslib: 1.14.1
dev: false
/@aws-crypto/sha1-browser/2.0.0:
resolution: {integrity: sha512-3fIVRjPFY8EG5HWXR+ZJZMdWNRpwbxGzJ9IH9q93FpbgCH8u8GHRi46mZXp3cYD7gealmyqpm3ThZwLKJjWJhA==}
dependencies:
'@aws-crypto/ie11-detection': 2.0.0
'@aws-crypto/supports-web-crypto': 2.0.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-locate-window': 3.55.0
'@aws-sdk/util-utf8-browser': 3.55.0
tslib: 1.14.1
dev: false
/@aws-crypto/sha256-browser/2.0.0:
resolution: {integrity: sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==}
dependencies:
'@aws-crypto/ie11-detection': 2.0.0
'@aws-crypto/sha256-js': 2.0.0
'@aws-crypto/supports-web-crypto': 2.0.0
'@aws-crypto/util': 2.0.1
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-locate-window': 3.55.0
'@aws-sdk/util-utf8-browser': 3.55.0
tslib: 1.14.1
dev: false
/@aws-crypto/sha256-js/2.0.0:
resolution: {integrity: sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==}
dependencies:
'@aws-crypto/util': 2.0.1
'@aws-sdk/types': 3.55.0
tslib: 1.14.1
dev: false
/@aws-crypto/supports-web-crypto/2.0.0:
resolution: {integrity: sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==}
dependencies:
tslib: 1.14.1
dev: false
/@aws-crypto/util/2.0.1:
resolution: {integrity: sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==}
dependencies:
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-utf8-browser': 3.55.0
tslib: 1.14.1
dev: false
/@aws-sdk/abort-controller/3.55.0:
resolution: {integrity: sha512-rCcTxJDEFnmvo/PgbhCRv24/Uv03lEGfRslKZq7SjaMcOubflS/ZXYaMEgsjYHgAT0zlpSsyCIkJXmhFaM7H7w==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/chunked-blob-reader-native/3.58.0:
resolution: {integrity: sha512-+D3xnPD5985iphgAqgUerBDs371a2WzzoEVi7eHJUMMsP/gEnSTdSH0HNxsqhYv6CW4EdKtvDAQdAwA1VtCf2A==}
dependencies:
'@aws-sdk/util-base64-browser': 3.58.0
tslib: 2.3.1
dev: false
/@aws-sdk/chunked-blob-reader/3.55.0:
resolution: {integrity: sha512-o/xjMCq81opAjSBjt7YdHJwIJcGVG5XIV9+C2KXcY5QwVimkOKPybWTv0mXPvSwSilSx+EhpLNhkcJuXdzhw4w==}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/client-s3/3.67.0:
resolution: {integrity: sha512-+wSWhkxXG8mY5rlsTXdDaYULpzq8AZ3B2TZKVGEXb6zs1txedyWSYeZr6ENpBoxtJepmlwXDC7oRm39eVoRixw==}
engines: {node: '>=12.0.0'}
dependencies:
'@aws-crypto/sha1-browser': 2.0.0
'@aws-crypto/sha256-browser': 2.0.0
'@aws-crypto/sha256-js': 2.0.0
'@aws-sdk/client-sts': 3.67.0
'@aws-sdk/config-resolver': 3.58.0
'@aws-sdk/credential-provider-node': 3.67.0
'@aws-sdk/eventstream-serde-browser': 3.58.0
'@aws-sdk/eventstream-serde-config-resolver': 3.55.0
'@aws-sdk/eventstream-serde-node': 3.58.0
'@aws-sdk/fetch-http-handler': 3.58.0
'@aws-sdk/hash-blob-browser': 3.58.0
'@aws-sdk/hash-node': 3.55.0
'@aws-sdk/hash-stream-node': 3.58.0
'@aws-sdk/invalid-dependency': 3.55.0
'@aws-sdk/md5-js': 3.58.0
'@aws-sdk/middleware-bucket-endpoint': 3.58.0
'@aws-sdk/middleware-content-length': 3.58.0
'@aws-sdk/middleware-expect-continue': 3.58.0
'@aws-sdk/middleware-flexible-checksums': 3.58.0
'@aws-sdk/middleware-host-header': 3.58.0
'@aws-sdk/middleware-location-constraint': 3.55.0
'@aws-sdk/middleware-logger': 3.55.0
'@aws-sdk/middleware-retry': 3.58.0
'@aws-sdk/middleware-sdk-s3': 3.66.0
'@aws-sdk/middleware-serde': 3.55.0
'@aws-sdk/middleware-signing': 3.58.0
'@aws-sdk/middleware-ssec': 3.55.0
'@aws-sdk/middleware-stack': 3.55.0
'@aws-sdk/middleware-user-agent': 3.58.0
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/node-http-handler': 3.58.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/signature-v4-multi-region': 3.66.0
'@aws-sdk/smithy-client': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/url-parser': 3.55.0
'@aws-sdk/util-base64-browser': 3.58.0
'@aws-sdk/util-base64-node': 3.55.0
'@aws-sdk/util-body-length-browser': 3.55.0
'@aws-sdk/util-body-length-node': 3.55.0
'@aws-sdk/util-defaults-mode-browser': 3.55.0
'@aws-sdk/util-defaults-mode-node': 3.58.0
'@aws-sdk/util-stream-browser': 3.55.0
'@aws-sdk/util-stream-node': 3.55.0
'@aws-sdk/util-user-agent-browser': 3.58.0
'@aws-sdk/util-user-agent-node': 3.58.0
'@aws-sdk/util-utf8-browser': 3.55.0
'@aws-sdk/util-utf8-node': 3.55.0
'@aws-sdk/util-waiter': 3.55.0
'@aws-sdk/xml-builder': 3.55.0
entities: 2.2.0
fast-xml-parser: 3.19.0
tslib: 2.3.1
transitivePeerDependencies:
- '@aws-sdk/signature-v4-crt'
dev: false
/@aws-sdk/client-sso/3.67.0:
resolution: {integrity: sha512-njBLSqX2+4eTjeptODxdYgBC8cYwwNE3VwrIFgf+nosIo8Ll07evZgHhfZsyURou0cUUpxFInDf1KaAotH9lBQ==}
engines: {node: '>=12.0.0'}
dependencies:
'@aws-crypto/sha256-browser': 2.0.0
'@aws-crypto/sha256-js': 2.0.0
'@aws-sdk/config-resolver': 3.58.0
'@aws-sdk/fetch-http-handler': 3.58.0
'@aws-sdk/hash-node': 3.55.0
'@aws-sdk/invalid-dependency': 3.55.0
'@aws-sdk/middleware-content-length': 3.58.0
'@aws-sdk/middleware-host-header': 3.58.0
'@aws-sdk/middleware-logger': 3.55.0
'@aws-sdk/middleware-retry': 3.58.0
'@aws-sdk/middleware-serde': 3.55.0
'@aws-sdk/middleware-stack': 3.55.0
'@aws-sdk/middleware-user-agent': 3.58.0
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/node-http-handler': 3.58.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/smithy-client': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/url-parser': 3.55.0
'@aws-sdk/util-base64-browser': 3.58.0
'@aws-sdk/util-base64-node': 3.55.0
'@aws-sdk/util-body-length-browser': 3.55.0
'@aws-sdk/util-body-length-node': 3.55.0
'@aws-sdk/util-defaults-mode-browser': 3.55.0
'@aws-sdk/util-defaults-mode-node': 3.58.0
'@aws-sdk/util-user-agent-browser': 3.58.0
'@aws-sdk/util-user-agent-node': 3.58.0
'@aws-sdk/util-utf8-browser': 3.55.0
'@aws-sdk/util-utf8-node': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/client-sts/3.67.0:
resolution: {integrity: sha512-gTWQU/4tPQLMJpLXgSbUss5s5dsyxpXJW2gWosvLLtX5QlchGBzWEawoA3QIxFRkNJrXqLyaVDBdFFqB+l0mVQ==}
engines: {node: '>=12.0.0'}
dependencies:
'@aws-crypto/sha256-browser': 2.0.0
'@aws-crypto/sha256-js': 2.0.0
'@aws-sdk/config-resolver': 3.58.0
'@aws-sdk/credential-provider-node': 3.67.0
'@aws-sdk/fetch-http-handler': 3.58.0
'@aws-sdk/hash-node': 3.55.0
'@aws-sdk/invalid-dependency': 3.55.0
'@aws-sdk/middleware-content-length': 3.58.0
'@aws-sdk/middleware-host-header': 3.58.0
'@aws-sdk/middleware-logger': 3.55.0
'@aws-sdk/middleware-retry': 3.58.0
'@aws-sdk/middleware-sdk-sts': 3.58.0
'@aws-sdk/middleware-serde': 3.55.0
'@aws-sdk/middleware-signing': 3.58.0
'@aws-sdk/middleware-stack': 3.55.0
'@aws-sdk/middleware-user-agent': 3.58.0
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/node-http-handler': 3.58.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/smithy-client': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/url-parser': 3.55.0
'@aws-sdk/util-base64-browser': 3.58.0
'@aws-sdk/util-base64-node': 3.55.0
'@aws-sdk/util-body-length-browser': 3.55.0
'@aws-sdk/util-body-length-node': 3.55.0
'@aws-sdk/util-defaults-mode-browser': 3.55.0
'@aws-sdk/util-defaults-mode-node': 3.58.0
'@aws-sdk/util-user-agent-browser': 3.58.0
'@aws-sdk/util-user-agent-node': 3.58.0
'@aws-sdk/util-utf8-browser': 3.55.0
'@aws-sdk/util-utf8-node': 3.55.0
entities: 2.2.0
fast-xml-parser: 3.19.0
tslib: 2.3.1
dev: false
/@aws-sdk/config-resolver/3.58.0:
resolution: {integrity: sha512-NXEwYw0JrXcvenu42QpNMQXK+6pgZ+6bDGfCgOfCC0FmyI+w/CuF36lApwm7InHvHazOaDlwArXm2pfntErKoA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/signature-v4': 3.58.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-config-provider': 3.55.0
'@aws-sdk/util-middleware': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-env/3.55.0:
resolution: {integrity: sha512-4AIIXEdvinLlWNFtrUbUgoB7dkuV04RTcTruVWI4Ub4WSsuSCa72ZU1vqyvcEAOgGGLBmcSaGTWByjiD2sGcGA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-imds/3.58.0:
resolution: {integrity: sha512-CdtnTQ9zqLx1FbXdbgjijLbMcIWOyQM03TFaLSCjI3FNbUwyt3T7StBU9tj/LtbypHhSdXyQBpzUtXTOMWCEhg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/url-parser': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-ini/3.67.0:
resolution: {integrity: sha512-47uNhLsd2eKWOa+alsyoT48TbtIfYtIJmC85APunHczqfpUC1YHOyHZ3pCzByGrgx4khjnJ323gfq9kreEHCvA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/credential-provider-env': 3.55.0
'@aws-sdk/credential-provider-imds': 3.58.0
'@aws-sdk/credential-provider-sso': 3.67.0
'@aws-sdk/credential-provider-web-identity': 3.55.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/shared-ini-file-loader': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-node/3.67.0:
resolution: {integrity: sha512-nxBUJ4rANue9MWQyhrmkZwuKVVpwbUXEqyMwJD1uxEZnYXksmAoVxKW/m4vxy1nh/65wAFCCipeLmqYzwJ8m0A==}
engines: {node: '>=12.0.0'}
dependencies:
'@aws-sdk/credential-provider-env': 3.55.0
'@aws-sdk/credential-provider-imds': 3.58.0
'@aws-sdk/credential-provider-ini': 3.67.0
'@aws-sdk/credential-provider-process': 3.58.0
'@aws-sdk/credential-provider-sso': 3.67.0
'@aws-sdk/credential-provider-web-identity': 3.55.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/shared-ini-file-loader': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-process/3.58.0:
resolution: {integrity: sha512-npgFqPUjMhUamf1FvJjBYUdpbWx8XWkKCwJsX73I7IYQAvAi2atCOkdtKq+4rds0VWAYu6vzlaI1tXgFxjOPNQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/shared-ini-file-loader': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-sso/3.67.0:
resolution: {integrity: sha512-AwS7tvA++2li0+yZkiCL1zk56EC3N6fDXWDqPEG/lKuviwyv1B+up6r/6ks7ADWbXuOKzrmslS7rn3DT2ZUkig==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/client-sso': 3.67.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/shared-ini-file-loader': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/credential-provider-web-identity/3.55.0:
resolution: {integrity: sha512-aKnXfZNGohTuF9rCGYLg4JEIOvWIZ/sb66XMq7bOUrx13KRPDwL/eUQL8quS5jGRLpjXVNvrS17AFf65GbdUBg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/eventstream-marshaller/3.58.0:
resolution: {integrity: sha512-vTdVFLIHGZTx/Anp9GpkTXVuvwSCNOecTutU5Py4i6fATgefWiSutc5Xc/FLujBSc0EhAXDGZIcTMpZC7jUpeg==}
dependencies:
'@aws-crypto/crc32': 2.0.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-hex-encoding': 3.58.0
tslib: 2.3.1
dev: false
/@aws-sdk/eventstream-serde-browser/3.58.0:
resolution: {integrity: sha512-oR5yoOoJrTSUKwbxZSt37bZgMXUUSsOub96E6SOb8wh8TMq2f0wvqeO8A+aaxY487gKpzuVUClp7jSQ9LgiVcw==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/eventstream-marshaller': 3.58.0
'@aws-sdk/eventstream-serde-universal': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/eventstream-serde-config-resolver/3.55.0:
resolution: {integrity: sha512-NTJHLq1sbXyXAaJucKvcdN3Svr/fM2TjHEC3l8P/torFjIsX1+Ykpi8tZt8KsX8RjoUTTfKylh41AjJq0K9X4Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/eventstream-serde-node/3.58.0:
resolution: {integrity: sha512-U1DnRVfvKOXty+Bei6oqhRWFzGWzxl0OFHtev9GzC7BE/E6s4Gn695o+NO+9IwQgjOlc/JsGyAcWevq3MDxymg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/eventstream-marshaller': 3.58.0
'@aws-sdk/eventstream-serde-universal': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/eventstream-serde-universal/3.58.0:
resolution: {integrity: sha512-w7czmMNvCCspJi8Ij0lTByCiuYBhyNzYTM1wv33vtF7dL+FJgi4W4c5WFAOtvpsPulobY013TWCjPJG+V0IPGQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/eventstream-marshaller': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/fetch-http-handler/3.58.0:
resolution: {integrity: sha512-timF3FjPV5Bd+Kgph83LIKVlPCFObVYzious1a6doeLAT6YFwZpRrWbfP/HzS+DCoYiwUsH69oVJ91BoV66oyA==}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/querystring-builder': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-base64-browser': 3.58.0
tslib: 2.3.1
dev: false
/@aws-sdk/hash-blob-browser/3.58.0:
resolution: {integrity: sha512-fdp12BqypRxwvevbJSl/sUhXJRi4Ghv6JKEXAHI1klkR6xY1GRORO5SHWltVY/xl373ERMol5o/n+ra/7jcx/g==}
dependencies:
'@aws-sdk/chunked-blob-reader': 3.55.0
'@aws-sdk/chunked-blob-reader-native': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/hash-node/3.55.0:
resolution: {integrity: sha512-2UdYwY/++AlzWEAFaK9wOed2QSxbzV527vmqKjReLHpPKPrSIlooUxlTH3LU6Y6WVDAzDRtLK43KUVXTLgGK1A==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-buffer-from': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/hash-stream-node/3.58.0:
resolution: {integrity: sha512-y7HEeC3OiuXCRqsHnKDn5yef8UAbnegD9r+OM9bdD+3e6FLAL8Rq7hQTOpwIAiPXuD7HKx8h98s9JLvkwTOBkg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/invalid-dependency/3.55.0:
resolution: {integrity: sha512-delH0lV+78fdD/8MXIt9kTLS6IwHvdhqq9dw/ow5VjTUw+xBwUlfPfZplaai+3hKTKWh6a2WZCeDasNItBv9aA==}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/is-array-buffer/3.55.0:
resolution: {integrity: sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/md5-js/3.58.0:
resolution: {integrity: sha512-V5f4Re+CLn3aDF1nrmDqdUtcqBHCyxxD2s2Ot+hZ2JFit+OtJggo1cI03ldTrQpG79rwHG+bHqL2VvNQP7Aj9A==}
dependencies:
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-utf8-browser': 3.55.0
'@aws-sdk/util-utf8-node': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-bucket-endpoint/3.58.0:
resolution: {integrity: sha512-zocLfFzj+NQjXLGZKPJBAYWWldAKBJkGzGVpTfrYx9bxxHTA70Gu+3sx+Xe+iOu8dtQT0OAnIX0wGudOPnTGNg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-arn-parser': 3.55.0
'@aws-sdk/util-config-provider': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-content-length/3.58.0:
resolution: {integrity: sha512-h/BypPkhjv2CpCUbXA8Fa2s7V2GPiz9l11XhYK+sKSuQvQ7Lbq6VhaKaLqfeD3gLVZHgJZSLGl2btdHV1qHNNA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-expect-continue/3.58.0:
resolution: {integrity: sha512-nx6X6qLPwvbJrGoPxXSu4tsOek2eRnnjk78hhRUDfxFewpHJQLSPlyNKkXAo+C3syVALe6RJRmUYu5bShY6FfA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/middleware-header-default': 3.58.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-flexible-checksums/3.58.0:
resolution: {integrity: sha512-R8S3U1boaIb7+kYhLJBks7rv/eaGj7I5T/2CgmcGY1BJBUU0h0arjPC7eeA/5wV29EHapoxVYQvJda//706rCw==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-crypto/crc32': 2.0.0
'@aws-crypto/crc32c': 2.0.0
'@aws-sdk/is-array-buffer': 3.55.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-header-default/3.58.0:
resolution: {integrity: sha512-7F+CdLLauMmNbwFGYrE2pKsgTKY8G2PgazHmaE9s3FySEFcGPWmiEAG8sVImfZooj8gxGFQMLr97nanWjhSq2Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-host-header/3.58.0:
resolution: {integrity: sha512-q/UKGcanm9e6DBRNN6UKhVqLvpRRdZWbmmPCeDNr4HqhCmgT6i1OvWdhAMOnT++hvCX8DpTsIXzNSlY6zWAxBg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-location-constraint/3.55.0:
resolution: {integrity: sha512-OvCKwBFbl8Gbfk0HGX00pkdORJN8BPuH/O5l3+mOBWuwILPuckRP5WGnL+1HT/gu4hHS6h1lpxUrPxUOoeKIAg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-logger/3.55.0:
resolution: {integrity: sha512-PtRbVrxEzDmeV9prBIP4/9or7R5Dj66mjbFSvNRGZ0n+UBfBFfVRfNrhQPNzQpfV9A3KVl9YyWCVXDSW+/rk9Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-retry/3.58.0:
resolution: {integrity: sha512-sfSq+t0Yy47DQwrWGpA8iOx9sd26l4l1JDVTwHNi7+OKD4ClRPVCEdw3bTbbyYz/PV4f9AEfAZ6jwtSff4wkGw==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/service-error-classification': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-middleware': 3.55.0
tslib: 2.3.1
uuid: 8.3.2
dev: false
/@aws-sdk/middleware-sdk-s3/3.66.0:
resolution: {integrity: sha512-4ACAdKAZkIjEK99UwoaKTrTGhS7qGqyLmjiGHlzR0ggMUUVmlep7EtcluImFtT6pi+ANVLDzuZGa+95MwGY/Qg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-arn-parser': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-sdk-sts/3.58.0:
resolution: {integrity: sha512-HUz7MhcsSDDTGygOwL61l4voc0pZco06J3z06JjTX19D5XxcQ7hSCtkHHHz0oMb9M1himVSiEon2tjhjsnB99g==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/middleware-signing': 3.58.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/signature-v4': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-serde/3.55.0:
resolution: {integrity: sha512-NkEbTDrSZcC2NhuvfjXHKJEl0xgI2B5tMAwi/rMOq/TEnARwVUL9qAy+5lgeiPCqebiNllWatARrFgAaYf0VeA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-signing/3.58.0:
resolution: {integrity: sha512-4FXubHB66GbhyZUlo6YPQoWpYfED15GNbEmHbJLSONzrVzZR3IkViSPLasDngVm1a050JqKuqNkFYGJBP4No/Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/signature-v4': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-ssec/3.55.0:
resolution: {integrity: sha512-HTdA23hksOphQe0TmYORsa/kMNnKRGbdh0VJcsDGHQScJXzJ+C//THwfcoklff0XZfC+vGh93PECBWqixMELZw==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-stack/3.55.0:
resolution: {integrity: sha512-ouD+wFz8W2R0ZQ8HrbhgN8tg1jyINEg9lPEEXY79w1Q5sf94LJ90XKAMVk02rw3dJalUWjLHf0OQe1/qxZfHyA==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/middleware-user-agent/3.58.0:
resolution: {integrity: sha512-1c69bIWM63JwXijXvb9IWwcwQ/gViKMZ1lhxv52NvdG5VSxWXXsFJ2jETEXZoAypwT97Hmf3xo9SYuaHcKoq+g==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/node-config-provider/3.58.0:
resolution: {integrity: sha512-AMcPqPhKxo/3/yOMS9PsKlI0GWp2/8eD6gSlhzdBpznPCKplyqXOSnSX7wS814Cyh373hFSjCaOrCOA9/EYtDg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/shared-ini-file-loader': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/node-http-handler/3.58.0:
resolution: {integrity: sha512-D9xVZG2nfo4GbPsby3JuBiAhpqXTFk1+CfuQU0AZv0gQvE3fFTCnB3za83jo7JV/pyRPU+s+/LHIpxCWUHzStg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/abort-controller': 3.55.0
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/querystring-builder': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/property-provider/3.55.0:
resolution: {integrity: sha512-o7cKFJSHq5WOhwPsspYrzNto35oKKZvESZuWDtLxaZKSI6l7zpA366BI4kDG6Tc9i2+teV553MbxyZ9eya5A8g==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/protocol-http/3.58.0:
resolution: {integrity: sha512-0yFFRPbR+CCa9eOQBBQ2qtrIDLYqSMN0y7G4iqVM8wQdIw7n3QK1PsTI3RNPGJ3Oi2krFTw5uUKqQQZPZEBuVQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/querystring-builder/3.55.0:
resolution: {integrity: sha512-/ZAXNipt9nRR8k+eowwukE/YjXnQ49p5w/MkaQxsBk3IuIf7MAcgVg8glHr0igH84GfUQ7ZVP8v+G2S3tKUG+Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-uri-escape': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/querystring-parser/3.55.0:
resolution: {integrity: sha512-e+2FLgo+eDx7oh7ap5HngN9XSVMxredAVztLHxCcSN0lFHHHzMa8b2SpXbaowUxQHh7ziymSqvOrPYFQ71Filg==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/service-error-classification/3.55.0:
resolution: {integrity: sha512-HdjnDyarsa1Avq1MJurkLyEe9c3eRa76dPmK4TmRGgwJ+tInEzGHL0rBW7V8xBK+PDF+fJQ71hvm8jPYmzvBwQ==}
engines: {node: '>= 12.0.0'}
dev: false
/@aws-sdk/shared-ini-file-loader/3.58.0:
resolution: {integrity: sha512-ARDKQerIzgNs/MFNdCEuK2lgRJ1lneAaJw0p9O1LkJUvcSibvkSATwny7vwJMueOf+ae1Pf+8+54OMNIt0nTkQ==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/signature-v4-multi-region/3.66.0:
resolution: {integrity: sha512-Akvc8G9Del2+umg0R/5Gc/PWgQwbxxTXdnm6YTHtDzvyPPiYWBs6au6WqJQqcqk07gcQV67MLVqFFhnFuLlcVg==}
engines: {node: '>= 12.0.0'}
peerDependencies:
'@aws-sdk/signature-v4-crt': ^3.66.0
peerDependenciesMeta:
'@aws-sdk/signature-v4-crt':
optional: true
dependencies:
'@aws-sdk/protocol-http': 3.58.0
'@aws-sdk/signature-v4': 3.58.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-arn-parser': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/signature-v4/3.58.0:
resolution: {integrity: sha512-flEo8p3XkzWoBDqnIUQre4jLuT5aLnmfQNI8c2uSjyJ3OBxpJ0iS1cDu3E++d1/pN6Q8o0KOmr2ypHeiyBOujw==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/is-array-buffer': 3.55.0
'@aws-sdk/types': 3.55.0
'@aws-sdk/util-hex-encoding': 3.58.0
'@aws-sdk/util-middleware': 3.55.0
'@aws-sdk/util-uri-escape': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/smithy-client/3.55.0:
resolution: {integrity: sha512-YgBpqg6R3Qg8CH9biOP1N1lYTvh8VLGD6AoDGgy/R1dQSqRQuxgKANLl3DOVcZnIZLsw4TdB0m7U+ZPtirPR1Q==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/middleware-stack': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/types/3.55.0:
resolution: {integrity: sha512-wrDZjuy1CVAYxDCbm3bWQIKMGfNs7XXmG0eG4858Ixgqmq2avsIn5TORy8ynBxcXn9aekV/+tGEQ7BBSYzIVNQ==}
engines: {node: '>= 12.0.0'}
dev: false
/@aws-sdk/url-parser/3.55.0:
resolution: {integrity: sha512-qrTwN5xIgTLreqLnZ+x3cAudjNKfxi6srW1H/px2mk4lb2U9B4fpGjZ6VU+XV8U2kR+YlT8J6Jo5iwuVGfC91A==}
dependencies:
'@aws-sdk/querystring-parser': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-arn-parser/3.55.0:
resolution: {integrity: sha512-76KJxp4MRWufHYWys7DFl64znr5yeJ3AIQNAPCKKw1sP0hzO7p6Kx0PaJnw9x+CPSzOrT4NbuApL6/srYhKDGg==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-base64-browser/3.58.0:
resolution: {integrity: sha512-0ebsXIZNpu/fup9OgsFPnRKfCFbuuI9PPRzvP6twzLxUB0c/aix6Co7LGHFKcRKHZdaykoJMXArf8eHj2Nzv1Q==}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-base64-node/3.55.0:
resolution: {integrity: sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/util-buffer-from': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-body-length-browser/3.55.0:
resolution: {integrity: sha512-Ei2OCzXQw5N6ZkTMZbamUzc1z+z1R1Ja5tMEagz5BxuX4vWdBObT+uGlSzL8yvTbjoPjnxWA2aXyEqaUP3JS8Q==}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-body-length-node/3.55.0:
resolution: {integrity: sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-buffer-from/3.55.0:
resolution: {integrity: sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/is-array-buffer': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-config-provider/3.55.0:
resolution: {integrity: sha512-30dzofQQfx6tp1jVZkZ0DGRsT0wwC15nEysKRiAcjncM64A0Cm6sra77d0os3vbKiKoPCI/lMsFr4o3533+qvQ==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-defaults-mode-browser/3.55.0:
resolution: {integrity: sha512-OS3gAwR84bHz7ObhjsSJM+grfeaBq3leGrj7xiX4BH3C8J+c10GMo3fqx1pV8Fq5F+9lMmhHpfOocD63SN5Q8A==}
engines: {node: '>= 10.0.0'}
dependencies:
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/types': 3.55.0
bowser: 2.11.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-defaults-mode-node/3.58.0:
resolution: {integrity: sha512-KNUCp0MXI+z3Z3pQCKDkx3Stdy1TXDjcUB+ZJFxRTJGIuBYwX4fV6G8s/zeFJi5Qv1ztR3CJ9fWJGsrx9mQ5EA==}
engines: {node: '>= 10.0.0'}
dependencies:
'@aws-sdk/config-resolver': 3.58.0
'@aws-sdk/credential-provider-imds': 3.58.0
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/property-provider': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-hex-encoding/3.58.0:
resolution: {integrity: sha512-Rl+jXUzk/FJkOLYfUVYPhKa2aUmTpeobRP31l8IatQltSzDgLyRHO35f6UEs7Ztn5s1jbu/POatLAZ2WjbgVyg==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-locate-window/3.55.0:
resolution: {integrity: sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-middleware/3.55.0:
resolution: {integrity: sha512-82fW2XV+rUalv8lkd4VlhpPp6xnXO5n9sckMp1N+TrQ+p8eqxqT0+o8n1/6s9Qsnkw64Y3m6+EfCdc8/uFOY2g==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-stream-browser/3.55.0:
resolution: {integrity: sha512-3f/zQsAqexJpKssCL0adTjG8WO+NPQ63E3TingyKpnCnHQPEnqPdya5I5OLGzZ0WR0iUWRtpuW0MtuDabyLDWw==}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-stream-node/3.55.0:
resolution: {integrity: sha512-brCK3iENvXEL7BK5eDAdkZ2VuBSvXj7DH9EQezxl4Ntrj1lvb+McOk9WoU/o7yzE7A/bzEJEoNQAPi+VPNbb/w==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-uri-escape/3.55.0:
resolution: {integrity: sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-user-agent-browser/3.58.0:
resolution: {integrity: sha512-aJpqCvT09giJRg5xFTBDBRAVF0k0yq3OEf6UTuiOVf5azlL2MGp6PJ/xkJp9Z06PuQQkwBJ/2nIQZemo02a5Sw==}
dependencies:
'@aws-sdk/types': 3.55.0
bowser: 2.11.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-user-agent-node/3.58.0:
resolution: {integrity: sha512-VlbY/nzWdN2pfLUHqKvnlGBQ6tEeV4jyK9ggAD2Szjj0bkYvaaKwpBKswQmuJpi5/J2v7Bo4ayBLnqDL7PgzLA==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/node-config-provider': 3.58.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-utf8-browser/3.55.0:
resolution: {integrity: sha512-ljzqJcyjfJpEVSIAxwtIS8xMRUly84BdjlBXyp6cu4G8TUufgjNS31LWdhyGhgmW5vYBNr+LTz0Kwf6J+ou7Ug==}
dependencies:
tslib: 2.3.1
dev: false
/@aws-sdk/util-utf8-node/3.55.0:
resolution: {integrity: sha512-FsFm7GFaC7j0tlPEm/ri8bU2QCwFW5WKjxUg8lm1oWaxplCpKGUsmcfPJ4sw58GIoyoGu4QXBK60oCWosZYYdQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/util-buffer-from': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/util-waiter/3.55.0:
resolution: {integrity: sha512-Do34MKPFSC/+zVN6vY+FZ+0WN61hzga4nPoAC590AOjs8rW6/H6sDN6Gz1KAZbPnuQUZfvsIJjMxN7lblXHJkQ==}
engines: {node: '>= 12.0.0'}
dependencies:
'@aws-sdk/abort-controller': 3.55.0
'@aws-sdk/types': 3.55.0
tslib: 2.3.1
dev: false
/@aws-sdk/xml-builder/3.55.0:
resolution: {integrity: sha512-BH+i5S2FLprmfSeIuGy3UbNtEoJPVjh8arl5+LV3i2KY/+TmrS4yT8JtztDlDxHF0cMtNLZNO0KEPtsACS6SOg==}
engines: {node: '>= 12.0.0'}
dependencies:
tslib: 2.3.1
dev: false
/@babel/code-frame/7.16.7:
resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==}
engines: {node: '>=6.9.0'}
@ -5151,6 +6006,10 @@ packages:
resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=}
dev: false
/bowser/2.11.0:
resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==}
dev: false
/boxen/5.1.2:
resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==}
engines: {node: '>=10'}
@ -7459,6 +8318,11 @@ packages:
punycode: 1.4.1
dev: false
/fast-xml-parser/3.19.0:
resolution: {integrity: sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==}
hasBin: true
dev: false
/fastq/1.13.0:
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
dependencies:

View File

@ -10,6 +10,7 @@
"lint": "eslint --fix --ext .ts ./src"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.67.0",
"@nestjs/axios": "^0.0.7",
"@nestjs/common": "^8.4.4",
"@nestjs/config": "^2.0.0",

View File

@ -7,6 +7,7 @@ import authConfig from './auth.config';
import databaseConfig from './database.config';
import googleConfig from './google.config';
import sendgridConfig from './sendgrid.config';
import storageConfig from './storage.config';
const validationSchema = Joi.object({
// App
@ -40,12 +41,20 @@ const validationSchema = Joi.object({
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID: Joi.string().allow(''),
SENDGRID_FROM_NAME: Joi.string().allow(''),
SENDGRID_FROM_EMAIL: Joi.string().allow(''),
// Storage
STORAGE_BUCKET: Joi.string().allow(''),
STORAGE_REGION: Joi.string().allow(''),
STORAGE_ENDPOINT: Joi.string().allow(''),
STORAGE_URL_PREFIX: Joi.string().allow(''),
STORAGE_ACCESS_KEY: Joi.string().allow(''),
STORAGE_SECRET_KEY: Joi.string().allow(''),
});
@Module({
imports: [
NestConfigModule.forRoot({
load: [appConfig, authConfig, databaseConfig, googleConfig, sendgridConfig],
load: [appConfig, authConfig, databaseConfig, googleConfig, sendgridConfig, storageConfig],
validationSchema: validationSchema,
}),
],

View File

@ -0,0 +1,10 @@
import { registerAs } from '@nestjs/config';
export default registerAs('storage', () => ({
bucket: process.env.STORAGE_BUCKET,
region: process.env.STORAGE_REGION,
endpoint: process.env.STORAGE_ENDPOINT,
urlPrefix: process.env.STORAGE_URL_PREFIX,
accessKey: process.env.STORAGE_ACCESS_KEY,
secretKey: process.env.STORAGE_SECRET_KEY,
}));

View File

@ -99,7 +99,7 @@ export class ResumeController {
@Put(':id/photo')
@UseInterceptors(FileInterceptor('file'))
async uploadPhoto(@Param('id') id: string, @User('id') userId: number, @UploadedFile() file: Express.Multer.File) {
return this.resumeService.uploadPhoto(+id, userId, file.filename);
return this.resumeService.uploadPhoto(+id, userId, file);
}
@UseGuards(JwtAuthGuard)

View File

@ -2,12 +2,9 @@ import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MulterModule } from '@nestjs/platform-express';
import { TypeOrmModule } from '@nestjs/typeorm';
import { mkdir } from 'fs/promises';
import { diskStorage } from 'multer';
import { extname, join } from 'path';
import { memoryStorage } from 'multer';
import { AuthModule } from '@/auth/auth.module';
import { User } from '@/users/entities/user.entity';
import { UsersModule } from '@/users/users.module';
import { Resume } from './entities/resume.entity';
@ -18,24 +15,7 @@ import { ResumeService } from './resume.service';
imports: [
ConfigModule,
TypeOrmModule.forFeature([Resume]),
MulterModule.register({
storage: diskStorage({
destination: async (req, _, cb) => {
const userId = (req.user as User).id;
const resumeId = +req.params.id;
const destination = join(__dirname, '..', `assets/uploads/${userId}/${resumeId}`);
await mkdir(destination, { recursive: true });
cb(null, destination);
},
filename: (_, file, cb) => {
const filename = new Date().getTime() + extname(file.originalname);
cb(null, filename);
},
}),
}),
MulterModule.register({ storage: memoryStorage() }),
AuthModule,
UsersModule,
],

View File

@ -1,11 +1,11 @@
import { DeleteObjectCommand, PutObjectCommand, S3, S3Client } from '@aws-sdk/client-s3';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import { Resume as ResumeSchema } from '@reactive-resume/schema';
import { unlink } from 'fs/promises';
import { pick, sample, set } from 'lodash';
import { nanoid } from 'nanoid';
import { join } from 'path';
import { extname } from 'path';
import { Repository } from 'typeorm';
import { PostgresErrorCode } from '@/database/errorCodes.enum';
@ -22,11 +22,22 @@ export const SHORT_ID_LENGTH = 8;
@Injectable()
export class ResumeService {
private s3Client: S3Client;
constructor(
@InjectRepository(Resume) private resumeRepository: Repository<Resume>,
private configService: ConfigService,
private usersService: UsersService
) {}
) {
this.s3Client = new S3({
endpoint: configService.get<string>('storage.endpoint'),
region: configService.get<string>('storage.region'),
credentials: {
accessKeyId: configService.get<string>('storage.accessKey'),
secretAccessKey: configService.get<string>('storage.secretKey'),
},
});
}
async create(createResumeDto: CreateResumeDto, userId: number) {
try {
@ -216,22 +227,44 @@ export class ResumeService {
return this.resumeRepository.update(id, nextResume);
}
async uploadPhoto(id: number, userId: number, filename: string) {
async uploadPhoto(id: number, userId: number, file: Express.Multer.File) {
const resume = await this.findOne(id, userId);
const url = `/api/assets/uploads/${userId}/${id}/${filename}`;
const updatedResume = set(resume, 'basics.photo.url', url);
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
const filename = new Date().getTime() + extname(file.originalname);
const key = `uploads/${userId}/${id}/${filename}`;
await this.s3Client.send(
new PutObjectCommand({
Bucket: this.configService.get<string>('storage.bucket'),
Key: key,
Body: file.buffer,
ACL: 'public-read',
})
);
const publicUrl = urlPrefix + key;
const updatedResume = set(resume, 'basics.photo.url', publicUrl);
return this.resumeRepository.save<Resume>(updatedResume);
}
async deletePhoto(id: number, userId: number) {
const resume = await this.findOne(id, userId);
const filepath = new URL(resume.basics.photo.url).pathname;
const photoPath = join(__dirname, '..', `assets/${filepath}`);
const updatedResume = set(resume, 'basics.photo.url', '');
await unlink(photoPath);
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
const publicUrl = resume.basics.photo.url;
const key = publicUrl.replace(urlPrefix, '');
await this.s3Client.send(
new DeleteObjectCommand({
Bucket: this.configService.get<string>('storage.bucket'),
Key: key,
})
);
const updatedResume = set(resume, 'basics.photo.url', '');
return this.resumeRepository.save<Resume>(updatedResume);
}