├── .dockerignore ├── .gitignore ├── .nginx └── nginx.conf ├── Dockerfile ├── Dockerfile.client ├── LICENSE ├── README.md ├── docker-compose.yaml ├── package-lock.json ├── package.json └── src ├── client ├── index.html └── index.js └── server └── index.js /.dockerignore: -------------------------------------------------------------------------------- 1 | dist 2 | build 3 | node_modules -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/server/data/messages.json 2 | messages.json 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # Snowpack dependency directory (https://snowpack.dev/) 49 | web_modules/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional stylelint cache 61 | .stylelintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variable files 79 | .env 80 | .env.development.local 81 | .env.test.local 82 | .env.production.local 83 | .env.local 84 | 85 | # parcel-bundler cache (https://parceljs.org/) 86 | .cache 87 | .parcel-cache 88 | 89 | # Next.js build output 90 | .next 91 | out 92 | 93 | # Nuxt.js build / generate output 94 | .nuxt 95 | dist 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and not Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # vuepress v2.x temp and cache directory 107 | .temp 108 | .cache 109 | 110 | # Docusaurus cache and generated files 111 | .docusaurus 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | 135 | # MAC OS 136 | # General 137 | .DS_Store 138 | .AppleDouble 139 | .LSOverride 140 | 141 | # Icon must end with two \r 142 | Icon 143 | 144 | # Thumbnails 145 | ._* 146 | 147 | # Files that might appear in the root of a volume 148 | .DocumentRevisions-V100 149 | .fseventsd 150 | .Spotlight-V100 151 | .TemporaryItems 152 | .Trashes 153 | .VolumeIcon.icns 154 | .com.apple.timemachine.donotpresent 155 | 156 | # Directories potentially created on remote AFP share 157 | .AppleDB 158 | .AppleDesktop 159 | Network Trash Folder 160 | Temporary Items 161 | .apdisk 162 | 163 | # WINDOWS 164 | # Windows thumbnail cache files 165 | Thumbs.db 166 | Thumbs.db:encryptable 167 | ehthumbs.db 168 | ehthumbs_vista.db 169 | 170 | # Dump file 171 | *.stackdump 172 | 173 | # Folder config file 174 | [Dd]esktop.ini 175 | 176 | # Recycle Bin used on file shares 177 | $RECYCLE.BIN/ 178 | 179 | # Windows Installer files 180 | *.cab 181 | *.msi 182 | *.msix 183 | *.msm 184 | *.msp 185 | 186 | # Windows shortcuts 187 | *.lnk 188 | 189 | # LINUX 190 | *~ 191 | 192 | # temporary files which can be created if a process still has a handle open of a deleted file 193 | .fuse_hidden* 194 | 195 | # KDE directory preferences 196 | .directory 197 | 198 | # Linux trash folder which might appear on any partition or disk 199 | .Trash-* 200 | 201 | # .nfs files are created when an open file is removed but is still being accessed 202 | .nfs* 203 | -------------------------------------------------------------------------------- /.nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | 6 | root /var/www; 7 | 8 | location / { 9 | try_files $uri $uri/ $uri.html =404; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # the next line sets the base image for this image 2 | # the base image is also based on an Dockerfile 3 | # see: https://hub.docker.com/layers/library/node/18-alpine/images/sha256-a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097 4 | # node provides offical images for nodejs and alpine 5 | # is used as a lightweight linux distribution 6 | # to reduce image size 7 | FROM node:18-alpine 8 | 9 | # we update the package list so that we always install 10 | # the latest version of a package 11 | RUN apk update && apk upgrade --no-cache 12 | # we install tini to have a proper init process 13 | # see: https://github.com/krallin/tini 14 | # this is needed to properly handle signals 15 | # like SIGTERM and SIGINT to stop and kill the container 16 | RUN apk add --no-cache tini 17 | # Tini is now available at /sbin/tini 18 | ENTRYPOINT ["/sbin/tini", "--"] 19 | 20 | # sets the working directory inside the image 21 | # all commands after this insturction will be 22 | # executed inside this directory 23 | WORKDIR /app 24 | 25 | # copies the package.json and package-lock.json 26 | # from the client (e.g. your server or your development machine) 27 | # into the /app directory inside the image 28 | # this is done before running npm ci to 29 | # get the advantage of layer caching 30 | COPY ./package* . 31 | 32 | # installs all node.js dependencies 33 | # npm ci is similar to npm install but intended to be 34 | # used in continuous integration (CI) environments 35 | # it will do a clean install based on the package-lock.json 36 | RUN npm ci 37 | 38 | # copies the source code into the image 39 | COPY . . 40 | 41 | # this runs the build command specified in the package.json 42 | RUN npm run build:server 43 | 44 | # does nothing 45 | # this is documentation so that we know which port is used for that image 46 | EXPOSE 3000 47 | 48 | # executes the server.js file that is located in the build directory 49 | CMD ["node", "./build/index.js"] 50 | -------------------------------------------------------------------------------- /Dockerfile.client: -------------------------------------------------------------------------------- 1 | # the base image 2 | # name it builder 3 | # you can reference this stage 4 | # in other stages by this name 5 | FROM node:18-alpine as builder 6 | 7 | # working directory inside the image 8 | WORKDIR /app 9 | 10 | # copies files from the client to the image 11 | COPY ./package* . 12 | 13 | # run a command inside the image 14 | RUN npm ci 15 | 16 | # copies files from the client to the image 17 | COPY . . 18 | 19 | # run a command inside the container 20 | # this will create a new folder in called dist in our app directory 21 | # inside the dist directory, you will find the 22 | # final HTML and JavaScript file 23 | RUN npm run build:client 24 | 25 | # serve stage 26 | # unprivileged nginx base image named as serve 27 | # will start nginx as non root user 28 | FROM nginxinc/nginx-unprivileged:1.24 as serve 29 | 30 | # we can now copy things from the first stage to the second 31 | # we copy the build output to the directory where nginx serves files 32 | COPY --from=builder /app/dist /var/www 33 | 34 | # we overwrite the default config with our own 35 | # if you take a look at the GitHub repository, you 36 | # see the .nginx directory with the nginx.conf 37 | # here we only use the port 80 38 | # in production, you would also want to make sure 39 | # all requests, even in your internal network or Kubernetes cluster 40 | # is served via HTTPS when dealing with sensible data 41 | COPY --from=builder /app/.nginx/nginx.conf /etc/nginx/conf.d/default.conf 42 | 43 | # this instruction does not really expose the port 80 44 | # this is documentation so that we know which port is used for that image 45 | # we nee to expose this port via the --publish flag when running the container 46 | EXPOSE 80 47 | 48 | # The command used when the image is started as a container 49 | # Note: for Docker containers (or for debugging), 50 | # the "daemon off;" directive which is used in this example 51 | # tells nginx to stay in the foreground. 52 | # for containers, this is useful. 53 | # best practice: one container = one process. 54 | # one server (container) has only one service. 55 | CMD ["nginx", "-g", "daemon off;"] 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Lukas Aichbauer, MSc (https://devopscycle.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

6 | 7 | # The Ultimate Docker Compose Cheat Sheet 8 | 9 | > Learn Docker Compose 10 | 11 | The content of this repository can guide you to learn to use Docker Compose. Here is the accompanying blog article: [The Ultimate Docker Compose Cheat Sheet](https://devopscycle.com/blog/the-ultimate-docker-compose-cheat-sheet) with the [PDF](https://devopscycle.com/wp-content/uploads/sites/4/2024/03/the-ultimate-docker-compose-cheat-sheet.pdf) or an [image](https://devopscycle.com/wp-content/uploads/sites/4/2024/03/the-ultimate-docker-compose-cheat-sheet.png) to the Docker Compose Cheat Sheet. If you need a refresher on Docker itself you can read this article: [The Ultimate Docker Cheat Sheet](https://devopscycle.com/blog/the-ultimate-docker-cheat-sheet). This repository is intended for corporate trainings, university courses and all people (mainly developers and system administrators, but also QA, security experts) that are interested into learning DevOps and especially in automating their processes and tasks to improve the iteration speed, the quality of their work output, and the overall transparancy in their company. 12 | 13 | ## Why? 14 | 15 | It is hard getting started with the technical implementation of DevOps tools. Sharing Knowledge is an important part in DevOps and this is why this repository exists. This repository should give you some guidance on how you can start. This is by no means a silver bullet and also never finished. Another important part is continuous imporvement. You could use this repository as entrypoint for an internal hackathon at your company or your university. Feel free to share your results and learnings as a pull request to this repository. 16 | 17 | Before you start with automating the product lifecycle and implementation of DevOps tools, you should have the correct foundation. 18 | 19 | Start with the culture and the mindset. 20 | 21 | You get a slighty different definition for DevOps when you look at different websites, but the intersection is always culture or the cultural philosophy. So get the key principles straight, then you will be able to profit from the technical tools as well: 22 | 23 | * Colloboration & Communication 24 | * Continuous Improvement 25 | * Automation of the Product Lifecycle 26 | * Customer Centric Action & Short Feedback Loops 27 | 28 | Here are some good resources to get started with colloboration, communication and continuous imporvment: 29 | 30 | * [https://dora.dev/devops-capabilities/cultural/generative-organizational-culture/](https://dora.dev/devops-capabilities/cultural/generative-organizational-culture/) 31 | * [https://dora.dev/devops-capabilities/cultural/learning-culture/](https://dora.dev/devops-capabilities/cultural/learning-culture/) 32 | 33 | ## Prerequistits 34 | 35 | * [Docker](https://docs.docker.com/install/) 36 | * [Docker Compose](https://docs.docker.com/compose/install/) (if you install Docker Desktop, it comes out of the box) 37 | * [Node.js](https://nodejs.org/) 38 | 39 | ## Apps 40 | 41 | In this section you will get an overview of the applications in this repository. 42 | 43 | ### Client 44 | 45 | The client application consits of a HTML and a JS file. The app makes a HTTP Get request to the server application to get all messages and displays them in an unordered list. The App has also an button, which you can click to make a HTTP POST request to add a new message on the server. The server responds with the new message and the client appends the newly created message to the unordered list. The client is located at `./src/client`. 46 | 47 | You can visit [http://localhost](http://localhost) to see the client in action. 48 | 49 | ## Development 50 | 51 | In this section you will get an overview of how you can start the client in development. 52 | 53 | ### Start 54 | 55 | ```sh 56 | # start development 57 | # you need to cancel and restart this cmd 58 | # if you want to see changes that you make to the client 59 | # you can visit http://localhost now to see the client in action 60 | $ npm run start:client 61 | ``` 62 | 63 | ## Production 64 | 65 | In this section you will get an overview of how you can start the client in production. 66 | 67 | ### Start 68 | 69 | This command will start all required containers (client, server, database). 70 | 71 | You can visit [http://localhost](http://localhost) to see the client in action. 72 | 73 | ```sh 74 | # make sure you are in the project's root directory 75 | # where the docker-compose.yaml is located 76 | # you can visit http://localhost now to see the client in action 77 | $ docker compose up --detach 78 | # if you run this command without the --detach flag 79 | # you will start all containers in a foreground process 80 | # the containers will stop as soon as you kill the terminal 81 | # or when you press CTRL+C 82 | ``` 83 | 84 | ### Stop 85 | 86 | This command will stop all containers (client, server, database). 87 | 88 | ```sh 89 | # make sure you are in the project's root directory 90 | # where the docker-compose.yaml is located 91 | $ docker compose stop 92 | ``` 93 | 94 | ### Stop & Remove 95 | 96 | This command will stop and remove all containers (client, server, database). 97 | 98 | ```sh 99 | # make sure you are in the project's root directory 100 | # where the docker-compose.yaml is located 101 | $ docker compose down --detach 102 | ``` 103 | 104 | ### Server 105 | 106 | The server consists of a single JS file. It hosts a simple Fastify app with two routes `GET /` and `POST /`. 107 | The GET route will make a request to a Postgres database to get all messages. The POST route will add a new entry to the messages in the Postgres database. On start up of the server it will create a new table called messages in the Postgres database with the fields id (auto increment integer [serial]) and message (text). The server app is located in `./src/server` directory. 108 | 109 | You can visit [http://localhost:3000](http://localhost:3000) to see the server in action. 110 | 111 | The JSON respond from the server looks like: 112 | 113 | ```json 114 | { 115 | "messages": [ 116 | { 117 | "id": 0, 118 | "message": "Hello World" 119 | } 120 | ] 121 | } 122 | ``` 123 | 124 | ## Development 125 | 126 | In this section you will get an overview of how you can start the server in development. 127 | 128 | > NOTE: currently the connection string for the database is hard coded, which means you need to update this string manually if you want to run it without docker compose. 129 | 130 | ### Start 131 | 132 | ```sh 133 | # start development 134 | # you need to cancel and restart this cmd 135 | # if you want to see changes that you make to the server 136 | # you can visit http://localhost:3000 now to see the client in action 137 | $ npm run start:server 138 | ``` 139 | 140 | ## Production 141 | 142 | In this section you will get an overview of how you can start the server in production. 143 | 144 | ### Start 145 | 146 | This command will start all required containers (client, server, database). 147 | 148 | You can visit [http://localhost:3000](http://localhost:3000) to see the server in action. 149 | 150 | ```sh 151 | # make sure you are in the project's root directory 152 | # where the docker-compose.yaml is located 153 | # you can visit http://localhost:3000 now to see the client in action 154 | $ docker compose up --detach 155 | # if you run this command without the --detach flag 156 | # you will start all containers in a foreground process 157 | # the containers will stop as soon as you kill the terminal 158 | # or when you press CTRL+C 159 | ``` 160 | 161 | ### Stop 162 | 163 | This command will stop all containers (client, server, database). 164 | 165 | ```sh 166 | # make sure you are in the project's root directory 167 | # where the docker-compose.yaml is located 168 | $ docker compose stop --detach 169 | ``` 170 | 171 | ### Stop & Remove 172 | 173 | This command will stop and remove all containers (client, server, database). 174 | 175 | ```sh 176 | # make sure you are in the project's root directory 177 | # where the docker-compose.yaml is located 178 | $ docker compose down --detach 179 | ``` 180 | 181 | ## LICENSE 182 | 183 | MIT @ Lukas Aichbauer 184 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | # the version of Docker Compose we are using 2 | version: '3' 3 | 4 | # all the services that we are defining 5 | # services are running containers 6 | services: 7 | 8 | # we are defining a service called client 9 | # this is the client side of our application 10 | client: 11 | # we use the build command to create the image 12 | # from the Dockerfile that we pass to this command 13 | # in this case "Dockerfile.client" 14 | # this image will then be used to create the container 15 | # we also pass the context of the build 16 | # as the docker-compose.yml file is in the same directory 17 | # as the source code, we can use the . 18 | # to refer to the current directory 19 | build: 20 | context: . 21 | dockerfile: Dockerfile.client 22 | # the ports that we want to publish 23 | # the first port ist the port on the host system 24 | # the second port is the port inside the container 25 | # so we map the port 80 of the container to the 26 | # port 80 of the host 27 | ports: 28 | - "80:80" 29 | # whenever our container stops, we want it to restart 30 | # unless explicitly stopped manually by us 31 | restart: always 32 | 33 | # we are defining a service called server 34 | # this is the server side of our application 35 | server: 36 | # we use the build command to create the image 37 | # from the Dockerfile that we pass to this command 38 | # in this case "Dockerfile" 39 | # this image will then be used to create the container 40 | # we also pass the context of the build 41 | # as the docker-compose.yml file is in the same directory 42 | # as the source code, we can use the . 43 | # to refer to the current directory 44 | build: 45 | context: . 46 | dockerfile: Dockerfile 47 | # the ports that we want to publish 48 | # the first port ist the port on the host system 49 | # the second port is the port inside the container 50 | # so we map the port 3000 of the container to the 51 | # port 3000 of the host 52 | ports: 53 | - "3000:3000" 54 | # whenever our container stops, we want it to restart 55 | # unless explicitly stopped manually by us 56 | # e.g. if our server crashes for whatever reason 57 | # database not available, etc. 58 | # we docker restarts the container automatically 59 | restart: always 60 | # docker compose uses a default network if we do not speficfy one 61 | # but for this example we created our own network 62 | # that connects our database and our server 63 | # the definition of the network is at the bottom of this file 64 | networks: 65 | - server_database 66 | # we want our server to wait for the database to be ready 67 | # if we do not add a condition, the server will start 68 | # before the database is ready, because the docker compose 69 | # only checks if the container is running, not if the database 70 | # is ready 71 | depends_on: 72 | database: 73 | # our condition is that the database is healthy 74 | # we define the healthcheck in the database service 75 | condition: service_healthy 76 | 77 | # we are defining a service called database 78 | # this is the postgres database of our application 79 | # container that are connected to the same network 80 | # can communicate with each other 81 | # the server can connect to the database 82 | # by using the IP address of the database container 83 | # in this network or the DNS name of the container 84 | # in this network 85 | # docker compose will automatically create a DNS name 86 | # for each container in the network 87 | # the DNS name is the name of the service 88 | database: 89 | # this time we do not use the build command 90 | # we use the image command to use an existing image 91 | # by default docker compose will look at the local registry 92 | # to find the image 93 | # if it is not available locally, it will pull it from 94 | # the docker hub registry 95 | image: postgres:16.1 96 | ports: 97 | # the ports that we want to publish 98 | # the first port ist the port on the host system 99 | # the second port is the port inside the container 100 | # so we map the port 5432 of the container to the 101 | # port 5432 of the host 102 | # 5432 is the default port on which a postgres database 103 | # will listen for incomming requests 104 | - "5432:5432" 105 | # we can define and pass environment variables 106 | # to the container 107 | # we will use this variables to connect to the database 108 | # in our server 109 | environment: 110 | POSTGRES_PASSWORD: password 111 | POSTGRES_USER: user 112 | POSTGRES_DB: database 113 | # whenever our container stops, we want it to restart 114 | # unless explicitly stopped manually by us 115 | restart: always 116 | # in docker compose we can define health checks 117 | # health checks are commands that are executed 118 | # to check if the container is healthy or not 119 | healthcheck: 120 | # in this case we check if the database is ready 121 | # by using the pg_isready command 122 | test: ["CMD", "pg_isready", "-U", "user", "-d", "database"] 123 | # we check if the database is ready every 2 seconds 124 | interval: 2s 125 | # when a checks duration takes more than 2 seconds 126 | # we consider it a failure 127 | timeout: 2s 128 | # we retry 3 times before we set the status to unhealthy 129 | retries: 3 130 | # we give the container 2 seconds for bootstrapping 131 | # before we consider a failed health check 132 | start_period: 2s 133 | # we want to persist the data of the database 134 | # so we use a volume 135 | # the volume is defined at the bottom of this file 136 | # we use a named volume 137 | # the name is postgres_data_volume 138 | # and we mount the path /var/lib/postgresql/data 139 | # from the container to the volume 140 | # when we create a named volume, docker will create 141 | # a directory on the host system to store the data 142 | # this is managed by docker 143 | # it follows the same rules like the port mapping 144 | # the first path (or name) is the path on the host system 145 | # the second path is the path inside the container 146 | volumes: 147 | - postgres_data_volume:/var/lib/postgresql/data 148 | # docker compose uses a default network if we do not speficfy one 149 | # but for this example we created our own network 150 | # that connects our database and our server 151 | # the definition of the network is at the bottom of this file 152 | networks: 153 | - server_database 154 | 155 | # here we define the volumes that we use 156 | # if we want that a service uses a volume 157 | # we need to explicitly use it in the service 158 | volumes: 159 | # we create a named volume called 160 | # postgres_data_volume 161 | postgres_data_volume: 162 | # if we do not specify anything here 163 | # docker will use the default settings for this volume 164 | 165 | # here we define the networks that we use 166 | # if we want that a service uses a network 167 | # we need to explicitly use it in the service 168 | networks: 169 | # we create a network called 170 | # server_database 171 | server_database: 172 | # if we do not specify anything here 173 | # docker will use the default settings for this network 174 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "the-ultimate-docker-compose-cheat-sheet", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "the-ultimate-docker-compose-cheat-sheet", 9 | "version": "0.1.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@fastify/cors": "^8.4.1", 13 | "@fastify/postgres": "^5.2.2", 14 | "fastify": "^4.24.3", 15 | "pg": "^8.11.3" 16 | }, 17 | "devDependencies": { 18 | "serve": "^14.2.1" 19 | } 20 | }, 21 | "node_modules/@fastify/ajv-compiler": { 22 | "version": "3.5.0", 23 | "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.5.0.tgz", 24 | "integrity": "sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==", 25 | "dependencies": { 26 | "ajv": "^8.11.0", 27 | "ajv-formats": "^2.1.1", 28 | "fast-uri": "^2.0.0" 29 | } 30 | }, 31 | "node_modules/@fastify/cors": { 32 | "version": "8.4.2", 33 | "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.4.2.tgz", 34 | "integrity": "sha512-IVynbcPG9eWiJ0P/A1B+KynmiU/yTYbu3ooBUSIeHfca/N1XLb9nIJVCws+YTr2q63MA8Y6QLeXQczEv4npM9g==", 35 | "dependencies": { 36 | "fastify-plugin": "^4.0.0", 37 | "mnemonist": "0.39.5" 38 | } 39 | }, 40 | "node_modules/@fastify/deepmerge": { 41 | "version": "1.3.0", 42 | "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", 43 | "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==" 44 | }, 45 | "node_modules/@fastify/error": { 46 | "version": "3.4.1", 47 | "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", 48 | "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==" 49 | }, 50 | "node_modules/@fastify/fast-json-stringify-compiler": { 51 | "version": "4.3.0", 52 | "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", 53 | "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", 54 | "dependencies": { 55 | "fast-json-stringify": "^5.7.0" 56 | } 57 | }, 58 | "node_modules/@fastify/postgres": { 59 | "version": "5.2.2", 60 | "resolved": "https://registry.npmjs.org/@fastify/postgres/-/postgres-5.2.2.tgz", 61 | "integrity": "sha512-8TWRqDSiXJp0SZjbHrqwyhl0f55eV4fpYAd9m7G0hGUpyEZJFwcxIDQYjnlRAXcVTq5NloUjFH6DxgmxZ3apbQ==", 62 | "dependencies": { 63 | "fastify-plugin": "^4.0.0" 64 | }, 65 | "peerDependencies": { 66 | "pg": ">=6.0.0" 67 | } 68 | }, 69 | "node_modules/@zeit/schemas": { 70 | "version": "2.29.0", 71 | "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.29.0.tgz", 72 | "integrity": "sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==", 73 | "dev": true 74 | }, 75 | "node_modules/abort-controller": { 76 | "version": "3.0.0", 77 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 78 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 79 | "dependencies": { 80 | "event-target-shim": "^5.0.0" 81 | }, 82 | "engines": { 83 | "node": ">=6.5" 84 | } 85 | }, 86 | "node_modules/abstract-logging": { 87 | "version": "2.0.1", 88 | "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", 89 | "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" 90 | }, 91 | "node_modules/accepts": { 92 | "version": "1.3.8", 93 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 94 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 95 | "dev": true, 96 | "dependencies": { 97 | "mime-types": "~2.1.34", 98 | "negotiator": "0.6.3" 99 | }, 100 | "engines": { 101 | "node": ">= 0.6" 102 | } 103 | }, 104 | "node_modules/ajv": { 105 | "version": "8.12.0", 106 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", 107 | "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", 108 | "dependencies": { 109 | "fast-deep-equal": "^3.1.1", 110 | "json-schema-traverse": "^1.0.0", 111 | "require-from-string": "^2.0.2", 112 | "uri-js": "^4.2.2" 113 | }, 114 | "funding": { 115 | "type": "github", 116 | "url": "https://github.com/sponsors/epoberezkin" 117 | } 118 | }, 119 | "node_modules/ajv-formats": { 120 | "version": "2.1.1", 121 | "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", 122 | "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", 123 | "dependencies": { 124 | "ajv": "^8.0.0" 125 | }, 126 | "peerDependencies": { 127 | "ajv": "^8.0.0" 128 | }, 129 | "peerDependenciesMeta": { 130 | "ajv": { 131 | "optional": true 132 | } 133 | } 134 | }, 135 | "node_modules/ansi-align": { 136 | "version": "3.0.1", 137 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", 138 | "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", 139 | "dev": true, 140 | "dependencies": { 141 | "string-width": "^4.1.0" 142 | } 143 | }, 144 | "node_modules/ansi-align/node_modules/ansi-regex": { 145 | "version": "5.0.1", 146 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 147 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 148 | "dev": true, 149 | "engines": { 150 | "node": ">=8" 151 | } 152 | }, 153 | "node_modules/ansi-align/node_modules/emoji-regex": { 154 | "version": "8.0.0", 155 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 156 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 157 | "dev": true 158 | }, 159 | "node_modules/ansi-align/node_modules/string-width": { 160 | "version": "4.2.3", 161 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 162 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 163 | "dev": true, 164 | "dependencies": { 165 | "emoji-regex": "^8.0.0", 166 | "is-fullwidth-code-point": "^3.0.0", 167 | "strip-ansi": "^6.0.1" 168 | }, 169 | "engines": { 170 | "node": ">=8" 171 | } 172 | }, 173 | "node_modules/ansi-align/node_modules/strip-ansi": { 174 | "version": "6.0.1", 175 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 176 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 177 | "dev": true, 178 | "dependencies": { 179 | "ansi-regex": "^5.0.1" 180 | }, 181 | "engines": { 182 | "node": ">=8" 183 | } 184 | }, 185 | "node_modules/ansi-regex": { 186 | "version": "6.0.1", 187 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", 188 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", 189 | "dev": true, 190 | "engines": { 191 | "node": ">=12" 192 | }, 193 | "funding": { 194 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 195 | } 196 | }, 197 | "node_modules/ansi-styles": { 198 | "version": "6.2.1", 199 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 200 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 201 | "dev": true, 202 | "engines": { 203 | "node": ">=12" 204 | }, 205 | "funding": { 206 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 207 | } 208 | }, 209 | "node_modules/arch": { 210 | "version": "2.2.0", 211 | "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", 212 | "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", 213 | "dev": true, 214 | "funding": [ 215 | { 216 | "type": "github", 217 | "url": "https://github.com/sponsors/feross" 218 | }, 219 | { 220 | "type": "patreon", 221 | "url": "https://www.patreon.com/feross" 222 | }, 223 | { 224 | "type": "consulting", 225 | "url": "https://feross.org/support" 226 | } 227 | ] 228 | }, 229 | "node_modules/archy": { 230 | "version": "1.0.0", 231 | "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", 232 | "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" 233 | }, 234 | "node_modules/arg": { 235 | "version": "5.0.2", 236 | "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", 237 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", 238 | "dev": true 239 | }, 240 | "node_modules/atomic-sleep": { 241 | "version": "1.0.0", 242 | "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", 243 | "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", 244 | "engines": { 245 | "node": ">=8.0.0" 246 | } 247 | }, 248 | "node_modules/avvio": { 249 | "version": "8.2.1", 250 | "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz", 251 | "integrity": "sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==", 252 | "dependencies": { 253 | "archy": "^1.0.0", 254 | "debug": "^4.0.0", 255 | "fastq": "^1.6.1" 256 | } 257 | }, 258 | "node_modules/balanced-match": { 259 | "version": "1.0.2", 260 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 261 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 262 | "dev": true 263 | }, 264 | "node_modules/base64-js": { 265 | "version": "1.5.1", 266 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 267 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 268 | "funding": [ 269 | { 270 | "type": "github", 271 | "url": "https://github.com/sponsors/feross" 272 | }, 273 | { 274 | "type": "patreon", 275 | "url": "https://www.patreon.com/feross" 276 | }, 277 | { 278 | "type": "consulting", 279 | "url": "https://feross.org/support" 280 | } 281 | ] 282 | }, 283 | "node_modules/boxen": { 284 | "version": "7.0.0", 285 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", 286 | "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", 287 | "dev": true, 288 | "dependencies": { 289 | "ansi-align": "^3.0.1", 290 | "camelcase": "^7.0.0", 291 | "chalk": "^5.0.1", 292 | "cli-boxes": "^3.0.0", 293 | "string-width": "^5.1.2", 294 | "type-fest": "^2.13.0", 295 | "widest-line": "^4.0.1", 296 | "wrap-ansi": "^8.0.1" 297 | }, 298 | "engines": { 299 | "node": ">=14.16" 300 | }, 301 | "funding": { 302 | "url": "https://github.com/sponsors/sindresorhus" 303 | } 304 | }, 305 | "node_modules/brace-expansion": { 306 | "version": "1.1.11", 307 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 308 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 309 | "dev": true, 310 | "dependencies": { 311 | "balanced-match": "^1.0.0", 312 | "concat-map": "0.0.1" 313 | } 314 | }, 315 | "node_modules/buffer": { 316 | "version": "6.0.3", 317 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 318 | "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 319 | "funding": [ 320 | { 321 | "type": "github", 322 | "url": "https://github.com/sponsors/feross" 323 | }, 324 | { 325 | "type": "patreon", 326 | "url": "https://www.patreon.com/feross" 327 | }, 328 | { 329 | "type": "consulting", 330 | "url": "https://feross.org/support" 331 | } 332 | ], 333 | "dependencies": { 334 | "base64-js": "^1.3.1", 335 | "ieee754": "^1.2.1" 336 | } 337 | }, 338 | "node_modules/buffer-writer": { 339 | "version": "2.0.0", 340 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", 341 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", 342 | "engines": { 343 | "node": ">=4" 344 | } 345 | }, 346 | "node_modules/bytes": { 347 | "version": "3.0.0", 348 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 349 | "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", 350 | "dev": true, 351 | "engines": { 352 | "node": ">= 0.8" 353 | } 354 | }, 355 | "node_modules/camelcase": { 356 | "version": "7.0.1", 357 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", 358 | "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", 359 | "dev": true, 360 | "engines": { 361 | "node": ">=14.16" 362 | }, 363 | "funding": { 364 | "url": "https://github.com/sponsors/sindresorhus" 365 | } 366 | }, 367 | "node_modules/chalk": { 368 | "version": "5.0.1", 369 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 370 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", 371 | "dev": true, 372 | "engines": { 373 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 374 | }, 375 | "funding": { 376 | "url": "https://github.com/chalk/chalk?sponsor=1" 377 | } 378 | }, 379 | "node_modules/chalk-template": { 380 | "version": "0.4.0", 381 | "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", 382 | "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", 383 | "dev": true, 384 | "dependencies": { 385 | "chalk": "^4.1.2" 386 | }, 387 | "engines": { 388 | "node": ">=12" 389 | }, 390 | "funding": { 391 | "url": "https://github.com/chalk/chalk-template?sponsor=1" 392 | } 393 | }, 394 | "node_modules/chalk-template/node_modules/ansi-styles": { 395 | "version": "4.3.0", 396 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 397 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 398 | "dev": true, 399 | "dependencies": { 400 | "color-convert": "^2.0.1" 401 | }, 402 | "engines": { 403 | "node": ">=8" 404 | }, 405 | "funding": { 406 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 407 | } 408 | }, 409 | "node_modules/chalk-template/node_modules/chalk": { 410 | "version": "4.1.2", 411 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 412 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 413 | "dev": true, 414 | "dependencies": { 415 | "ansi-styles": "^4.1.0", 416 | "supports-color": "^7.1.0" 417 | }, 418 | "engines": { 419 | "node": ">=10" 420 | }, 421 | "funding": { 422 | "url": "https://github.com/chalk/chalk?sponsor=1" 423 | } 424 | }, 425 | "node_modules/cli-boxes": { 426 | "version": "3.0.0", 427 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", 428 | "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", 429 | "dev": true, 430 | "engines": { 431 | "node": ">=10" 432 | }, 433 | "funding": { 434 | "url": "https://github.com/sponsors/sindresorhus" 435 | } 436 | }, 437 | "node_modules/clipboardy": { 438 | "version": "3.0.0", 439 | "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", 440 | "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", 441 | "dev": true, 442 | "dependencies": { 443 | "arch": "^2.2.0", 444 | "execa": "^5.1.1", 445 | "is-wsl": "^2.2.0" 446 | }, 447 | "engines": { 448 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 449 | }, 450 | "funding": { 451 | "url": "https://github.com/sponsors/sindresorhus" 452 | } 453 | }, 454 | "node_modules/color-convert": { 455 | "version": "2.0.1", 456 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 457 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 458 | "dev": true, 459 | "dependencies": { 460 | "color-name": "~1.1.4" 461 | }, 462 | "engines": { 463 | "node": ">=7.0.0" 464 | } 465 | }, 466 | "node_modules/color-name": { 467 | "version": "1.1.4", 468 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 469 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 470 | "dev": true 471 | }, 472 | "node_modules/compressible": { 473 | "version": "2.0.18", 474 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 475 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 476 | "dev": true, 477 | "dependencies": { 478 | "mime-db": ">= 1.43.0 < 2" 479 | }, 480 | "engines": { 481 | "node": ">= 0.6" 482 | } 483 | }, 484 | "node_modules/compression": { 485 | "version": "1.7.4", 486 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", 487 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", 488 | "dev": true, 489 | "dependencies": { 490 | "accepts": "~1.3.5", 491 | "bytes": "3.0.0", 492 | "compressible": "~2.0.16", 493 | "debug": "2.6.9", 494 | "on-headers": "~1.0.2", 495 | "safe-buffer": "5.1.2", 496 | "vary": "~1.1.2" 497 | }, 498 | "engines": { 499 | "node": ">= 0.8.0" 500 | } 501 | }, 502 | "node_modules/compression/node_modules/debug": { 503 | "version": "2.6.9", 504 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 505 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 506 | "dev": true, 507 | "dependencies": { 508 | "ms": "2.0.0" 509 | } 510 | }, 511 | "node_modules/compression/node_modules/ms": { 512 | "version": "2.0.0", 513 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 514 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 515 | "dev": true 516 | }, 517 | "node_modules/concat-map": { 518 | "version": "0.0.1", 519 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 520 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 521 | "dev": true 522 | }, 523 | "node_modules/content-disposition": { 524 | "version": "0.5.2", 525 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 526 | "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", 527 | "dev": true, 528 | "engines": { 529 | "node": ">= 0.6" 530 | } 531 | }, 532 | "node_modules/cookie": { 533 | "version": "0.5.0", 534 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 535 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 536 | "engines": { 537 | "node": ">= 0.6" 538 | } 539 | }, 540 | "node_modules/cross-spawn": { 541 | "version": "7.0.3", 542 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 543 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 544 | "dev": true, 545 | "dependencies": { 546 | "path-key": "^3.1.0", 547 | "shebang-command": "^2.0.0", 548 | "which": "^2.0.1" 549 | }, 550 | "engines": { 551 | "node": ">= 8" 552 | } 553 | }, 554 | "node_modules/debug": { 555 | "version": "4.3.4", 556 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 557 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 558 | "dependencies": { 559 | "ms": "2.1.2" 560 | }, 561 | "engines": { 562 | "node": ">=6.0" 563 | }, 564 | "peerDependenciesMeta": { 565 | "supports-color": { 566 | "optional": true 567 | } 568 | } 569 | }, 570 | "node_modules/deep-extend": { 571 | "version": "0.6.0", 572 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 573 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 574 | "dev": true, 575 | "engines": { 576 | "node": ">=4.0.0" 577 | } 578 | }, 579 | "node_modules/eastasianwidth": { 580 | "version": "0.2.0", 581 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 582 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 583 | "dev": true 584 | }, 585 | "node_modules/emoji-regex": { 586 | "version": "9.2.2", 587 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 588 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 589 | "dev": true 590 | }, 591 | "node_modules/event-target-shim": { 592 | "version": "5.0.1", 593 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 594 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 595 | "engines": { 596 | "node": ">=6" 597 | } 598 | }, 599 | "node_modules/events": { 600 | "version": "3.3.0", 601 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 602 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 603 | "engines": { 604 | "node": ">=0.8.x" 605 | } 606 | }, 607 | "node_modules/execa": { 608 | "version": "5.1.1", 609 | "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", 610 | "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", 611 | "dev": true, 612 | "dependencies": { 613 | "cross-spawn": "^7.0.3", 614 | "get-stream": "^6.0.0", 615 | "human-signals": "^2.1.0", 616 | "is-stream": "^2.0.0", 617 | "merge-stream": "^2.0.0", 618 | "npm-run-path": "^4.0.1", 619 | "onetime": "^5.1.2", 620 | "signal-exit": "^3.0.3", 621 | "strip-final-newline": "^2.0.0" 622 | }, 623 | "engines": { 624 | "node": ">=10" 625 | }, 626 | "funding": { 627 | "url": "https://github.com/sindresorhus/execa?sponsor=1" 628 | } 629 | }, 630 | "node_modules/fast-content-type-parse": { 631 | "version": "1.1.0", 632 | "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", 633 | "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==" 634 | }, 635 | "node_modules/fast-decode-uri-component": { 636 | "version": "1.0.1", 637 | "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", 638 | "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" 639 | }, 640 | "node_modules/fast-deep-equal": { 641 | "version": "3.1.3", 642 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 643 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 644 | }, 645 | "node_modules/fast-json-stringify": { 646 | "version": "5.9.1", 647 | "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.9.1.tgz", 648 | "integrity": "sha512-NMrf+uU9UJnTzfxaumMDXK1NWqtPCfGoM9DYIE+ESlaTQqjlANFBy0VAbsm6FB88Mx0nceyi18zTo5kIEUlzxg==", 649 | "dependencies": { 650 | "@fastify/deepmerge": "^1.0.0", 651 | "ajv": "^8.10.0", 652 | "ajv-formats": "^2.1.1", 653 | "fast-deep-equal": "^3.1.3", 654 | "fast-uri": "^2.1.0", 655 | "json-schema-ref-resolver": "^1.0.1", 656 | "rfdc": "^1.2.0" 657 | } 658 | }, 659 | "node_modules/fast-querystring": { 660 | "version": "1.1.2", 661 | "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", 662 | "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", 663 | "dependencies": { 664 | "fast-decode-uri-component": "^1.0.1" 665 | } 666 | }, 667 | "node_modules/fast-redact": { 668 | "version": "3.3.0", 669 | "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", 670 | "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", 671 | "engines": { 672 | "node": ">=6" 673 | } 674 | }, 675 | "node_modules/fast-uri": { 676 | "version": "2.3.0", 677 | "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.3.0.tgz", 678 | "integrity": "sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==" 679 | }, 680 | "node_modules/fast-url-parser": { 681 | "version": "1.1.3", 682 | "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", 683 | "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", 684 | "dev": true, 685 | "dependencies": { 686 | "punycode": "^1.3.2" 687 | } 688 | }, 689 | "node_modules/fastify": { 690 | "version": "4.24.3", 691 | "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.24.3.tgz", 692 | "integrity": "sha512-6HHJ+R2x2LS3y1PqxnwEIjOTZxFl+8h4kSC/TuDPXtA+v2JnV9yEtOsNSKK1RMD7sIR2y1ZsA4BEFaid/cK5pg==", 693 | "dependencies": { 694 | "@fastify/ajv-compiler": "^3.5.0", 695 | "@fastify/error": "^3.4.0", 696 | "@fastify/fast-json-stringify-compiler": "^4.3.0", 697 | "abstract-logging": "^2.0.1", 698 | "avvio": "^8.2.1", 699 | "fast-content-type-parse": "^1.1.0", 700 | "fast-json-stringify": "^5.8.0", 701 | "find-my-way": "^7.7.0", 702 | "light-my-request": "^5.11.0", 703 | "pino": "^8.16.0", 704 | "process-warning": "^2.2.0", 705 | "proxy-addr": "^2.0.7", 706 | "rfdc": "^1.3.0", 707 | "secure-json-parse": "^2.7.0", 708 | "semver": "^7.5.4", 709 | "toad-cache": "^3.3.0" 710 | } 711 | }, 712 | "node_modules/fastify-plugin": { 713 | "version": "4.5.1", 714 | "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", 715 | "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" 716 | }, 717 | "node_modules/fastq": { 718 | "version": "1.15.0", 719 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 720 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 721 | "dependencies": { 722 | "reusify": "^1.0.4" 723 | } 724 | }, 725 | "node_modules/find-my-way": { 726 | "version": "7.7.0", 727 | "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.7.0.tgz", 728 | "integrity": "sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==", 729 | "dependencies": { 730 | "fast-deep-equal": "^3.1.3", 731 | "fast-querystring": "^1.0.0", 732 | "safe-regex2": "^2.0.0" 733 | }, 734 | "engines": { 735 | "node": ">=14" 736 | } 737 | }, 738 | "node_modules/forwarded": { 739 | "version": "0.2.0", 740 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 741 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 742 | "engines": { 743 | "node": ">= 0.6" 744 | } 745 | }, 746 | "node_modules/get-stream": { 747 | "version": "6.0.1", 748 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", 749 | "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", 750 | "dev": true, 751 | "engines": { 752 | "node": ">=10" 753 | }, 754 | "funding": { 755 | "url": "https://github.com/sponsors/sindresorhus" 756 | } 757 | }, 758 | "node_modules/has-flag": { 759 | "version": "4.0.0", 760 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 761 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 762 | "dev": true, 763 | "engines": { 764 | "node": ">=8" 765 | } 766 | }, 767 | "node_modules/human-signals": { 768 | "version": "2.1.0", 769 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", 770 | "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", 771 | "dev": true, 772 | "engines": { 773 | "node": ">=10.17.0" 774 | } 775 | }, 776 | "node_modules/ieee754": { 777 | "version": "1.2.1", 778 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 779 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 780 | "funding": [ 781 | { 782 | "type": "github", 783 | "url": "https://github.com/sponsors/feross" 784 | }, 785 | { 786 | "type": "patreon", 787 | "url": "https://www.patreon.com/feross" 788 | }, 789 | { 790 | "type": "consulting", 791 | "url": "https://feross.org/support" 792 | } 793 | ] 794 | }, 795 | "node_modules/ini": { 796 | "version": "1.3.8", 797 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", 798 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", 799 | "dev": true 800 | }, 801 | "node_modules/ipaddr.js": { 802 | "version": "1.9.1", 803 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 804 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 805 | "engines": { 806 | "node": ">= 0.10" 807 | } 808 | }, 809 | "node_modules/is-docker": { 810 | "version": "2.2.1", 811 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", 812 | "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", 813 | "dev": true, 814 | "bin": { 815 | "is-docker": "cli.js" 816 | }, 817 | "engines": { 818 | "node": ">=8" 819 | }, 820 | "funding": { 821 | "url": "https://github.com/sponsors/sindresorhus" 822 | } 823 | }, 824 | "node_modules/is-fullwidth-code-point": { 825 | "version": "3.0.0", 826 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 827 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 828 | "dev": true, 829 | "engines": { 830 | "node": ">=8" 831 | } 832 | }, 833 | "node_modules/is-port-reachable": { 834 | "version": "4.0.0", 835 | "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", 836 | "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", 837 | "dev": true, 838 | "engines": { 839 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 840 | }, 841 | "funding": { 842 | "url": "https://github.com/sponsors/sindresorhus" 843 | } 844 | }, 845 | "node_modules/is-stream": { 846 | "version": "2.0.1", 847 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", 848 | "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", 849 | "dev": true, 850 | "engines": { 851 | "node": ">=8" 852 | }, 853 | "funding": { 854 | "url": "https://github.com/sponsors/sindresorhus" 855 | } 856 | }, 857 | "node_modules/is-wsl": { 858 | "version": "2.2.0", 859 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", 860 | "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", 861 | "dev": true, 862 | "dependencies": { 863 | "is-docker": "^2.0.0" 864 | }, 865 | "engines": { 866 | "node": ">=8" 867 | } 868 | }, 869 | "node_modules/isexe": { 870 | "version": "2.0.0", 871 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 872 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 873 | "dev": true 874 | }, 875 | "node_modules/json-schema-ref-resolver": { 876 | "version": "1.0.1", 877 | "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", 878 | "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", 879 | "dependencies": { 880 | "fast-deep-equal": "^3.1.3" 881 | } 882 | }, 883 | "node_modules/json-schema-traverse": { 884 | "version": "1.0.0", 885 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 886 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" 887 | }, 888 | "node_modules/light-my-request": { 889 | "version": "5.11.0", 890 | "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.11.0.tgz", 891 | "integrity": "sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA==", 892 | "dependencies": { 893 | "cookie": "^0.5.0", 894 | "process-warning": "^2.0.0", 895 | "set-cookie-parser": "^2.4.1" 896 | } 897 | }, 898 | "node_modules/lru-cache": { 899 | "version": "6.0.0", 900 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 901 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 902 | "dependencies": { 903 | "yallist": "^4.0.0" 904 | }, 905 | "engines": { 906 | "node": ">=10" 907 | } 908 | }, 909 | "node_modules/merge-stream": { 910 | "version": "2.0.0", 911 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 912 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 913 | "dev": true 914 | }, 915 | "node_modules/mime-db": { 916 | "version": "1.52.0", 917 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 918 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 919 | "dev": true, 920 | "engines": { 921 | "node": ">= 0.6" 922 | } 923 | }, 924 | "node_modules/mime-types": { 925 | "version": "2.1.35", 926 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 927 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 928 | "dev": true, 929 | "dependencies": { 930 | "mime-db": "1.52.0" 931 | }, 932 | "engines": { 933 | "node": ">= 0.6" 934 | } 935 | }, 936 | "node_modules/mimic-fn": { 937 | "version": "2.1.0", 938 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 939 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 940 | "dev": true, 941 | "engines": { 942 | "node": ">=6" 943 | } 944 | }, 945 | "node_modules/minimatch": { 946 | "version": "3.1.2", 947 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 948 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 949 | "dev": true, 950 | "dependencies": { 951 | "brace-expansion": "^1.1.7" 952 | }, 953 | "engines": { 954 | "node": "*" 955 | } 956 | }, 957 | "node_modules/minimist": { 958 | "version": "1.2.8", 959 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 960 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 961 | "dev": true, 962 | "funding": { 963 | "url": "https://github.com/sponsors/ljharb" 964 | } 965 | }, 966 | "node_modules/mnemonist": { 967 | "version": "0.39.5", 968 | "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.5.tgz", 969 | "integrity": "sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==", 970 | "dependencies": { 971 | "obliterator": "^2.0.1" 972 | } 973 | }, 974 | "node_modules/ms": { 975 | "version": "2.1.2", 976 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 977 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 978 | }, 979 | "node_modules/negotiator": { 980 | "version": "0.6.3", 981 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 982 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 983 | "dev": true, 984 | "engines": { 985 | "node": ">= 0.6" 986 | } 987 | }, 988 | "node_modules/npm-run-path": { 989 | "version": "4.0.1", 990 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", 991 | "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", 992 | "dev": true, 993 | "dependencies": { 994 | "path-key": "^3.0.0" 995 | }, 996 | "engines": { 997 | "node": ">=8" 998 | } 999 | }, 1000 | "node_modules/obliterator": { 1001 | "version": "2.0.4", 1002 | "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", 1003 | "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" 1004 | }, 1005 | "node_modules/on-exit-leak-free": { 1006 | "version": "2.1.2", 1007 | "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", 1008 | "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", 1009 | "engines": { 1010 | "node": ">=14.0.0" 1011 | } 1012 | }, 1013 | "node_modules/on-headers": { 1014 | "version": "1.0.2", 1015 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 1016 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 1017 | "dev": true, 1018 | "engines": { 1019 | "node": ">= 0.8" 1020 | } 1021 | }, 1022 | "node_modules/onetime": { 1023 | "version": "5.1.2", 1024 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", 1025 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", 1026 | "dev": true, 1027 | "dependencies": { 1028 | "mimic-fn": "^2.1.0" 1029 | }, 1030 | "engines": { 1031 | "node": ">=6" 1032 | }, 1033 | "funding": { 1034 | "url": "https://github.com/sponsors/sindresorhus" 1035 | } 1036 | }, 1037 | "node_modules/packet-reader": { 1038 | "version": "1.0.0", 1039 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", 1040 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" 1041 | }, 1042 | "node_modules/path-is-inside": { 1043 | "version": "1.0.2", 1044 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1045 | "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", 1046 | "dev": true 1047 | }, 1048 | "node_modules/path-key": { 1049 | "version": "3.1.1", 1050 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1051 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1052 | "dev": true, 1053 | "engines": { 1054 | "node": ">=8" 1055 | } 1056 | }, 1057 | "node_modules/path-to-regexp": { 1058 | "version": "2.2.1", 1059 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", 1060 | "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", 1061 | "dev": true 1062 | }, 1063 | "node_modules/pg": { 1064 | "version": "8.11.3", 1065 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", 1066 | "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", 1067 | "dependencies": { 1068 | "buffer-writer": "2.0.0", 1069 | "packet-reader": "1.0.0", 1070 | "pg-connection-string": "^2.6.2", 1071 | "pg-pool": "^3.6.1", 1072 | "pg-protocol": "^1.6.0", 1073 | "pg-types": "^2.1.0", 1074 | "pgpass": "1.x" 1075 | }, 1076 | "engines": { 1077 | "node": ">= 8.0.0" 1078 | }, 1079 | "optionalDependencies": { 1080 | "pg-cloudflare": "^1.1.1" 1081 | }, 1082 | "peerDependencies": { 1083 | "pg-native": ">=3.0.1" 1084 | }, 1085 | "peerDependenciesMeta": { 1086 | "pg-native": { 1087 | "optional": true 1088 | } 1089 | } 1090 | }, 1091 | "node_modules/pg-cloudflare": { 1092 | "version": "1.1.1", 1093 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", 1094 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", 1095 | "optional": true 1096 | }, 1097 | "node_modules/pg-connection-string": { 1098 | "version": "2.6.2", 1099 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", 1100 | "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" 1101 | }, 1102 | "node_modules/pg-int8": { 1103 | "version": "1.0.1", 1104 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", 1105 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", 1106 | "engines": { 1107 | "node": ">=4.0.0" 1108 | } 1109 | }, 1110 | "node_modules/pg-pool": { 1111 | "version": "3.6.1", 1112 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", 1113 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", 1114 | "peerDependencies": { 1115 | "pg": ">=8.0" 1116 | } 1117 | }, 1118 | "node_modules/pg-protocol": { 1119 | "version": "1.6.0", 1120 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", 1121 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" 1122 | }, 1123 | "node_modules/pg-types": { 1124 | "version": "2.2.0", 1125 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 1126 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 1127 | "dependencies": { 1128 | "pg-int8": "1.0.1", 1129 | "postgres-array": "~2.0.0", 1130 | "postgres-bytea": "~1.0.0", 1131 | "postgres-date": "~1.0.4", 1132 | "postgres-interval": "^1.1.0" 1133 | }, 1134 | "engines": { 1135 | "node": ">=4" 1136 | } 1137 | }, 1138 | "node_modules/pgpass": { 1139 | "version": "1.0.5", 1140 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", 1141 | "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", 1142 | "dependencies": { 1143 | "split2": "^4.1.0" 1144 | } 1145 | }, 1146 | "node_modules/pino": { 1147 | "version": "8.16.2", 1148 | "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.2.tgz", 1149 | "integrity": "sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==", 1150 | "dependencies": { 1151 | "atomic-sleep": "^1.0.0", 1152 | "fast-redact": "^3.1.1", 1153 | "on-exit-leak-free": "^2.1.0", 1154 | "pino-abstract-transport": "v1.1.0", 1155 | "pino-std-serializers": "^6.0.0", 1156 | "process-warning": "^2.0.0", 1157 | "quick-format-unescaped": "^4.0.3", 1158 | "real-require": "^0.2.0", 1159 | "safe-stable-stringify": "^2.3.1", 1160 | "sonic-boom": "^3.7.0", 1161 | "thread-stream": "^2.0.0" 1162 | }, 1163 | "bin": { 1164 | "pino": "bin.js" 1165 | } 1166 | }, 1167 | "node_modules/pino-abstract-transport": { 1168 | "version": "1.1.0", 1169 | "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", 1170 | "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", 1171 | "dependencies": { 1172 | "readable-stream": "^4.0.0", 1173 | "split2": "^4.0.0" 1174 | } 1175 | }, 1176 | "node_modules/pino-abstract-transport/node_modules/readable-stream": { 1177 | "version": "4.4.2", 1178 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", 1179 | "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", 1180 | "dependencies": { 1181 | "abort-controller": "^3.0.0", 1182 | "buffer": "^6.0.3", 1183 | "events": "^3.3.0", 1184 | "process": "^0.11.10", 1185 | "string_decoder": "^1.3.0" 1186 | }, 1187 | "engines": { 1188 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1189 | } 1190 | }, 1191 | "node_modules/pino-abstract-transport/node_modules/safe-buffer": { 1192 | "version": "5.2.1", 1193 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1194 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1195 | "funding": [ 1196 | { 1197 | "type": "github", 1198 | "url": "https://github.com/sponsors/feross" 1199 | }, 1200 | { 1201 | "type": "patreon", 1202 | "url": "https://www.patreon.com/feross" 1203 | }, 1204 | { 1205 | "type": "consulting", 1206 | "url": "https://feross.org/support" 1207 | } 1208 | ] 1209 | }, 1210 | "node_modules/pino-abstract-transport/node_modules/string_decoder": { 1211 | "version": "1.3.0", 1212 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1213 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1214 | "dependencies": { 1215 | "safe-buffer": "~5.2.0" 1216 | } 1217 | }, 1218 | "node_modules/pino-std-serializers": { 1219 | "version": "6.2.2", 1220 | "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", 1221 | "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" 1222 | }, 1223 | "node_modules/postgres-array": { 1224 | "version": "2.0.0", 1225 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 1226 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", 1227 | "engines": { 1228 | "node": ">=4" 1229 | } 1230 | }, 1231 | "node_modules/postgres-bytea": { 1232 | "version": "1.0.0", 1233 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 1234 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", 1235 | "engines": { 1236 | "node": ">=0.10.0" 1237 | } 1238 | }, 1239 | "node_modules/postgres-date": { 1240 | "version": "1.0.7", 1241 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 1242 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", 1243 | "engines": { 1244 | "node": ">=0.10.0" 1245 | } 1246 | }, 1247 | "node_modules/postgres-interval": { 1248 | "version": "1.2.0", 1249 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 1250 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 1251 | "dependencies": { 1252 | "xtend": "^4.0.0" 1253 | }, 1254 | "engines": { 1255 | "node": ">=0.10.0" 1256 | } 1257 | }, 1258 | "node_modules/process": { 1259 | "version": "0.11.10", 1260 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 1261 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 1262 | "engines": { 1263 | "node": ">= 0.6.0" 1264 | } 1265 | }, 1266 | "node_modules/process-warning": { 1267 | "version": "2.3.2", 1268 | "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", 1269 | "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" 1270 | }, 1271 | "node_modules/proxy-addr": { 1272 | "version": "2.0.7", 1273 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1274 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1275 | "dependencies": { 1276 | "forwarded": "0.2.0", 1277 | "ipaddr.js": "1.9.1" 1278 | }, 1279 | "engines": { 1280 | "node": ">= 0.10" 1281 | } 1282 | }, 1283 | "node_modules/punycode": { 1284 | "version": "1.4.1", 1285 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 1286 | "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", 1287 | "dev": true 1288 | }, 1289 | "node_modules/quick-format-unescaped": { 1290 | "version": "4.0.4", 1291 | "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", 1292 | "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" 1293 | }, 1294 | "node_modules/range-parser": { 1295 | "version": "1.2.0", 1296 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1297 | "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", 1298 | "dev": true, 1299 | "engines": { 1300 | "node": ">= 0.6" 1301 | } 1302 | }, 1303 | "node_modules/rc": { 1304 | "version": "1.2.8", 1305 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 1306 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 1307 | "dev": true, 1308 | "dependencies": { 1309 | "deep-extend": "^0.6.0", 1310 | "ini": "~1.3.0", 1311 | "minimist": "^1.2.0", 1312 | "strip-json-comments": "~2.0.1" 1313 | }, 1314 | "bin": { 1315 | "rc": "cli.js" 1316 | } 1317 | }, 1318 | "node_modules/real-require": { 1319 | "version": "0.2.0", 1320 | "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", 1321 | "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", 1322 | "engines": { 1323 | "node": ">= 12.13.0" 1324 | } 1325 | }, 1326 | "node_modules/registry-auth-token": { 1327 | "version": "3.3.2", 1328 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", 1329 | "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", 1330 | "dev": true, 1331 | "dependencies": { 1332 | "rc": "^1.1.6", 1333 | "safe-buffer": "^5.0.1" 1334 | } 1335 | }, 1336 | "node_modules/registry-url": { 1337 | "version": "3.1.0", 1338 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", 1339 | "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", 1340 | "dev": true, 1341 | "dependencies": { 1342 | "rc": "^1.0.1" 1343 | }, 1344 | "engines": { 1345 | "node": ">=0.10.0" 1346 | } 1347 | }, 1348 | "node_modules/require-from-string": { 1349 | "version": "2.0.2", 1350 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 1351 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 1352 | "engines": { 1353 | "node": ">=0.10.0" 1354 | } 1355 | }, 1356 | "node_modules/ret": { 1357 | "version": "0.2.2", 1358 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", 1359 | "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", 1360 | "engines": { 1361 | "node": ">=4" 1362 | } 1363 | }, 1364 | "node_modules/reusify": { 1365 | "version": "1.0.4", 1366 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1367 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1368 | "engines": { 1369 | "iojs": ">=1.0.0", 1370 | "node": ">=0.10.0" 1371 | } 1372 | }, 1373 | "node_modules/rfdc": { 1374 | "version": "1.3.0", 1375 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", 1376 | "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" 1377 | }, 1378 | "node_modules/safe-buffer": { 1379 | "version": "5.1.2", 1380 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1381 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1382 | "dev": true 1383 | }, 1384 | "node_modules/safe-regex2": { 1385 | "version": "2.0.0", 1386 | "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", 1387 | "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", 1388 | "dependencies": { 1389 | "ret": "~0.2.0" 1390 | } 1391 | }, 1392 | "node_modules/safe-stable-stringify": { 1393 | "version": "2.4.3", 1394 | "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", 1395 | "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", 1396 | "engines": { 1397 | "node": ">=10" 1398 | } 1399 | }, 1400 | "node_modules/secure-json-parse": { 1401 | "version": "2.7.0", 1402 | "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", 1403 | "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" 1404 | }, 1405 | "node_modules/semver": { 1406 | "version": "7.5.4", 1407 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1408 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1409 | "dependencies": { 1410 | "lru-cache": "^6.0.0" 1411 | }, 1412 | "bin": { 1413 | "semver": "bin/semver.js" 1414 | }, 1415 | "engines": { 1416 | "node": ">=10" 1417 | } 1418 | }, 1419 | "node_modules/serve": { 1420 | "version": "14.2.1", 1421 | "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.1.tgz", 1422 | "integrity": "sha512-48er5fzHh7GCShLnNyPBRPEjs2I6QBozeGr02gaacROiyS/8ARADlj595j39iZXAqBbJHH/ivJJyPRWY9sQWZA==", 1423 | "dev": true, 1424 | "dependencies": { 1425 | "@zeit/schemas": "2.29.0", 1426 | "ajv": "8.11.0", 1427 | "arg": "5.0.2", 1428 | "boxen": "7.0.0", 1429 | "chalk": "5.0.1", 1430 | "chalk-template": "0.4.0", 1431 | "clipboardy": "3.0.0", 1432 | "compression": "1.7.4", 1433 | "is-port-reachable": "4.0.0", 1434 | "serve-handler": "6.1.5", 1435 | "update-check": "1.5.4" 1436 | }, 1437 | "bin": { 1438 | "serve": "build/main.js" 1439 | }, 1440 | "engines": { 1441 | "node": ">= 14" 1442 | } 1443 | }, 1444 | "node_modules/serve-handler": { 1445 | "version": "6.1.5", 1446 | "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", 1447 | "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", 1448 | "dev": true, 1449 | "dependencies": { 1450 | "bytes": "3.0.0", 1451 | "content-disposition": "0.5.2", 1452 | "fast-url-parser": "1.1.3", 1453 | "mime-types": "2.1.18", 1454 | "minimatch": "3.1.2", 1455 | "path-is-inside": "1.0.2", 1456 | "path-to-regexp": "2.2.1", 1457 | "range-parser": "1.2.0" 1458 | } 1459 | }, 1460 | "node_modules/serve-handler/node_modules/mime-db": { 1461 | "version": "1.33.0", 1462 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 1463 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", 1464 | "dev": true, 1465 | "engines": { 1466 | "node": ">= 0.6" 1467 | } 1468 | }, 1469 | "node_modules/serve-handler/node_modules/mime-types": { 1470 | "version": "2.1.18", 1471 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 1472 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 1473 | "dev": true, 1474 | "dependencies": { 1475 | "mime-db": "~1.33.0" 1476 | }, 1477 | "engines": { 1478 | "node": ">= 0.6" 1479 | } 1480 | }, 1481 | "node_modules/serve/node_modules/ajv": { 1482 | "version": "8.11.0", 1483 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", 1484 | "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", 1485 | "dev": true, 1486 | "dependencies": { 1487 | "fast-deep-equal": "^3.1.1", 1488 | "json-schema-traverse": "^1.0.0", 1489 | "require-from-string": "^2.0.2", 1490 | "uri-js": "^4.2.2" 1491 | }, 1492 | "funding": { 1493 | "type": "github", 1494 | "url": "https://github.com/sponsors/epoberezkin" 1495 | } 1496 | }, 1497 | "node_modules/set-cookie-parser": { 1498 | "version": "2.6.0", 1499 | "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", 1500 | "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" 1501 | }, 1502 | "node_modules/shebang-command": { 1503 | "version": "2.0.0", 1504 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1505 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1506 | "dev": true, 1507 | "dependencies": { 1508 | "shebang-regex": "^3.0.0" 1509 | }, 1510 | "engines": { 1511 | "node": ">=8" 1512 | } 1513 | }, 1514 | "node_modules/shebang-regex": { 1515 | "version": "3.0.0", 1516 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1517 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1518 | "dev": true, 1519 | "engines": { 1520 | "node": ">=8" 1521 | } 1522 | }, 1523 | "node_modules/signal-exit": { 1524 | "version": "3.0.7", 1525 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1526 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 1527 | "dev": true 1528 | }, 1529 | "node_modules/sonic-boom": { 1530 | "version": "3.7.0", 1531 | "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", 1532 | "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", 1533 | "dependencies": { 1534 | "atomic-sleep": "^1.0.0" 1535 | } 1536 | }, 1537 | "node_modules/split2": { 1538 | "version": "4.2.0", 1539 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 1540 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 1541 | "engines": { 1542 | "node": ">= 10.x" 1543 | } 1544 | }, 1545 | "node_modules/string-width": { 1546 | "version": "5.1.2", 1547 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 1548 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 1549 | "dev": true, 1550 | "dependencies": { 1551 | "eastasianwidth": "^0.2.0", 1552 | "emoji-regex": "^9.2.2", 1553 | "strip-ansi": "^7.0.1" 1554 | }, 1555 | "engines": { 1556 | "node": ">=12" 1557 | }, 1558 | "funding": { 1559 | "url": "https://github.com/sponsors/sindresorhus" 1560 | } 1561 | }, 1562 | "node_modules/strip-ansi": { 1563 | "version": "7.1.0", 1564 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 1565 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 1566 | "dev": true, 1567 | "dependencies": { 1568 | "ansi-regex": "^6.0.1" 1569 | }, 1570 | "engines": { 1571 | "node": ">=12" 1572 | }, 1573 | "funding": { 1574 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 1575 | } 1576 | }, 1577 | "node_modules/strip-final-newline": { 1578 | "version": "2.0.0", 1579 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", 1580 | "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", 1581 | "dev": true, 1582 | "engines": { 1583 | "node": ">=6" 1584 | } 1585 | }, 1586 | "node_modules/strip-json-comments": { 1587 | "version": "2.0.1", 1588 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1589 | "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", 1590 | "dev": true, 1591 | "engines": { 1592 | "node": ">=0.10.0" 1593 | } 1594 | }, 1595 | "node_modules/supports-color": { 1596 | "version": "7.2.0", 1597 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1598 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1599 | "dev": true, 1600 | "dependencies": { 1601 | "has-flag": "^4.0.0" 1602 | }, 1603 | "engines": { 1604 | "node": ">=8" 1605 | } 1606 | }, 1607 | "node_modules/thread-stream": { 1608 | "version": "2.4.1", 1609 | "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", 1610 | "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", 1611 | "dependencies": { 1612 | "real-require": "^0.2.0" 1613 | } 1614 | }, 1615 | "node_modules/toad-cache": { 1616 | "version": "3.3.1", 1617 | "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.3.1.tgz", 1618 | "integrity": "sha512-oE5vIpiyKEuyYJiyp0gYhiD1o7BmiPCJZX9pboK9X6EfdYYmNsk8m7J1kBwMt6H/avuDsCdEhassrMMxwW7h3Q==", 1619 | "engines": { 1620 | "node": ">=12" 1621 | } 1622 | }, 1623 | "node_modules/type-fest": { 1624 | "version": "2.19.0", 1625 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", 1626 | "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", 1627 | "dev": true, 1628 | "engines": { 1629 | "node": ">=12.20" 1630 | }, 1631 | "funding": { 1632 | "url": "https://github.com/sponsors/sindresorhus" 1633 | } 1634 | }, 1635 | "node_modules/update-check": { 1636 | "version": "1.5.4", 1637 | "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", 1638 | "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", 1639 | "dev": true, 1640 | "dependencies": { 1641 | "registry-auth-token": "3.3.2", 1642 | "registry-url": "3.1.0" 1643 | } 1644 | }, 1645 | "node_modules/uri-js": { 1646 | "version": "4.4.1", 1647 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1648 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1649 | "dependencies": { 1650 | "punycode": "^2.1.0" 1651 | } 1652 | }, 1653 | "node_modules/uri-js/node_modules/punycode": { 1654 | "version": "2.3.1", 1655 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1656 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1657 | "engines": { 1658 | "node": ">=6" 1659 | } 1660 | }, 1661 | "node_modules/vary": { 1662 | "version": "1.1.2", 1663 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1664 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1665 | "dev": true, 1666 | "engines": { 1667 | "node": ">= 0.8" 1668 | } 1669 | }, 1670 | "node_modules/which": { 1671 | "version": "2.0.2", 1672 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1673 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1674 | "dev": true, 1675 | "dependencies": { 1676 | "isexe": "^2.0.0" 1677 | }, 1678 | "bin": { 1679 | "node-which": "bin/node-which" 1680 | }, 1681 | "engines": { 1682 | "node": ">= 8" 1683 | } 1684 | }, 1685 | "node_modules/widest-line": { 1686 | "version": "4.0.1", 1687 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", 1688 | "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", 1689 | "dev": true, 1690 | "dependencies": { 1691 | "string-width": "^5.0.1" 1692 | }, 1693 | "engines": { 1694 | "node": ">=12" 1695 | }, 1696 | "funding": { 1697 | "url": "https://github.com/sponsors/sindresorhus" 1698 | } 1699 | }, 1700 | "node_modules/wrap-ansi": { 1701 | "version": "8.1.0", 1702 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 1703 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 1704 | "dev": true, 1705 | "dependencies": { 1706 | "ansi-styles": "^6.1.0", 1707 | "string-width": "^5.0.1", 1708 | "strip-ansi": "^7.0.1" 1709 | }, 1710 | "engines": { 1711 | "node": ">=12" 1712 | }, 1713 | "funding": { 1714 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1715 | } 1716 | }, 1717 | "node_modules/xtend": { 1718 | "version": "4.0.2", 1719 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1720 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 1721 | "engines": { 1722 | "node": ">=0.4" 1723 | } 1724 | }, 1725 | "node_modules/yallist": { 1726 | "version": "4.0.0", 1727 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1728 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 1729 | } 1730 | } 1731 | } 1732 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "the-ultimate-docker-compose-cheat-sheet", 3 | "version": "0.1.0", 4 | "description": "Learn Docker Compose", 5 | "main": "./src/server.js", 6 | "scripts": { 7 | "cleanup": "rm -rf node_modules && rm -rf build && rm -rf .cache && rm -rf .parcel-cache && rm -rf dist", 8 | "comment": "echo \"All build and start commands are only example commands and would never be used like this in a procution environment\"", 9 | "start:server": "node ./src/server/index.js", 10 | "build:server": "mkdir -p ./build && cp ./src/server/index.js ./build", 11 | "start:client": "mkdir -p ./dist && cp ./src/client/index.js ./dist && cp ./src/client/index.html ./dist && serve ./dist -p 80", 12 | "build:client": "mkdir -p ./dist && cp ./src/client/index.js ./dist && cp ./src/client/index.html ./dist" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+ssh://git@github.com/aichbauer/the-ultimate-docker-compose-cheat-sheet.git" 17 | }, 18 | "keywords": [ 19 | "docker compose cheat sheet" 20 | ], 21 | "author": "Lukas Aichbauer, MSc (https://devopscycle.com)", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/aichbauer/the-ultimate-docker-compose-cheat-sheet/issues" 25 | }, 26 | "homepage": "https://github.com/aichbauer/the-ultimate-docker-compose-cheat-sheet#readme", 27 | "dependencies": { 28 | "@fastify/cors": "^8.4.1", 29 | "@fastify/postgres": "^5.2.2", 30 | "fastify": "^4.24.3", 31 | "pg": "^8.11.3" 32 | }, 33 | "devDependencies": { 34 | "serve": "^14.2.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Frontend 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/client/index.js: -------------------------------------------------------------------------------- 1 | (async () => { 2 | const res = await fetch('http://localhost:3000'); 3 | const data = await res.json(); 4 | 5 | const app = document.getElementById('app'); 6 | 7 | const ul = document.createElement('ul'); 8 | app.appendChild(ul); 9 | data.messages.forEach((item) => { 10 | const li = document.createElement('li'); 11 | li.innerHTML = item.message; 12 | ul.appendChild(li); 13 | }); 14 | 15 | const button = document.createElement('button'); 16 | button.innerHTML = 'Create New Message'; 17 | app.appendChild(button); 18 | button.addEventListener('click', async () => { 19 | const res = await fetch('http://localhost:3000', { 20 | method: 'POST', 21 | }); 22 | const data = await res.json(); 23 | 24 | data.messages.forEach((item) => { 25 | const li = document.createElement('li'); 26 | li.innerHTML = item.message; 27 | ul.appendChild(li); 28 | }); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /src/server/index.js: -------------------------------------------------------------------------------- 1 | const fastify = require('fastify'); 2 | const cors = require('@fastify/cors'); 3 | const fastifyPostgres = require('@fastify/postgres'); 4 | 5 | const app = fastify({ 6 | logger: true, 7 | }); 8 | const port = 3000; 9 | const host = '0.0.0.0'; 10 | 11 | app.register(cors); 12 | 13 | app.register(fastifyPostgres, { 14 | // you should use environment variables for a production environment 15 | // and never put your database credentials in your code 16 | connectionString: 'postgres://user:password@database/database', 17 | ssl: false, 18 | }); 19 | 20 | app.get('/', async (_, reply) => { 21 | try { 22 | const client = await app.pg.connect() 23 | const { rows } = await client.query( 24 | 'SELECT * from messages;', 25 | ); 26 | 27 | if (rows.length === 0) { 28 | return reply 29 | .status(404) 30 | .send({ 31 | messages: rows, 32 | }); 33 | } 34 | 35 | return reply 36 | .status(200) 37 | .send({ 38 | messages: rows, 39 | }); 40 | } catch (err) { 41 | app.log.error('error getting messages'); 42 | app.log.error(err); 43 | 44 | return reply 45 | .status(500) 46 | .send({ 47 | error: 'Internal Server Error', 48 | }); 49 | } 50 | }); 51 | 52 | app.post('/', async (_, reply) => { 53 | try { 54 | const client = await app.pg.connect(); 55 | 56 | const { rows } = await client.query( 57 | 'INSERT INTO messages (message) VALUES ($1) RETURNING *;', 58 | ['Hello World'], 59 | ); 60 | 61 | return reply 62 | .status(201) 63 | .send({ 64 | messages: rows, 65 | }); 66 | } catch (err) { 67 | app.log.error('error creating message'); 68 | app.log.error(err); 69 | 70 | return reply 71 | .status(500) 72 | .send({ 73 | error: 'Internal Server Error', 74 | }); 75 | } 76 | }); 77 | 78 | 79 | const start = async () => { 80 | try { 81 | app.log.info(`Server listening on port ${port}`); 82 | try { 83 | await app.after(); 84 | const client = await app.pg.connect(); 85 | 86 | await client.query( 87 | 'CREATE TABLE IF NOT EXISTS messages (id SERIAL PRIMARY KEY, message TEXT);', 88 | ); 89 | app.log.info('Connected to database'); 90 | } catch (err) { 91 | app.log.error('error creating table'); 92 | app.log.error(err); 93 | } 94 | await app.listen({ 95 | port, 96 | host, 97 | }); 98 | } catch (err) { 99 | app.log.error(err); 100 | process.exit(1); 101 | } 102 | } 103 | start(); 104 | --------------------------------------------------------------------------------